mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 11:36:00 +00:00
Merge "Implement keymint V1 aidl interfaces, service module, and vts tests." am: 0ab081bfa6 am: ce18601982 am: ed6b1b32cb
Original change: https://android-review.googlesource.com/c/platform/hardware/interfaces/+/1298415 Change-Id: I9c8d02fc4cd2d636a329d98357e036e078c600b3
This commit is contained in:
@@ -298,6 +298,14 @@
|
||||
<instance>strongbox</instance>
|
||||
</interface>
|
||||
</hal>
|
||||
<hal format="aidl" optional="true">
|
||||
<name>android.hardware.keymint</name>
|
||||
<interface>
|
||||
<name>IKeyMintDevice</name>
|
||||
<instance>default</instance>
|
||||
<instance>strongbox</instance>
|
||||
</interface>
|
||||
</hal>
|
||||
<hal format="aidl" optional="true">
|
||||
<name>android.hardware.light</name>
|
||||
<interface>
|
||||
|
||||
@@ -20,12 +20,3 @@ aidl_interface {
|
||||
"2",
|
||||
],
|
||||
}
|
||||
|
||||
// This is a reminder that the next version of keymaster should be frozen at
|
||||
// version "5" to avoid confusion with other versions of this interface.
|
||||
cc_library {
|
||||
name: "android.hardware.keymaster-V3-java",
|
||||
}
|
||||
cc_library {
|
||||
name: "android.hardware.keymaster-V4-java",
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2020 The Android Open Source Project
|
||||
* 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.
|
||||
|
||||
@@ -16,6 +16,14 @@
|
||||
|
||||
package android.hardware.keymaster;
|
||||
|
||||
|
||||
/**
|
||||
* Time in milliseconds since some arbitrary point in time. Time must be monotonically increasing,
|
||||
* and a secure environment's notion of "current time" must not repeat until the Android device
|
||||
* reboots, or until at least 50 million years have elapsed (note that this requirement is satisfied
|
||||
* by setting the clock to zero during each boot, and then counting time accurately).
|
||||
*/
|
||||
|
||||
@VintfStability
|
||||
parcelable Timestamp {
|
||||
long milliSeconds;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2020 The Android Open Source Project
|
||||
* 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.
|
||||
@@ -18,7 +18,6 @@ package android.hardware.keymaster;
|
||||
|
||||
import android.hardware.keymaster.SecurityLevel;
|
||||
import android.hardware.keymaster.Timestamp;
|
||||
import android.hardware.keymaster.HardwareAuthenticatorType;
|
||||
|
||||
/**
|
||||
* VerificationToken instances are used for secure environments to authenticate one another.
|
||||
@@ -40,6 +39,7 @@ parcelable VerificationToken {
|
||||
*/
|
||||
Timestamp timestamp;
|
||||
|
||||
|
||||
/**
|
||||
* SecurityLevel of the secure environment that generated the token.
|
||||
*/
|
||||
|
||||
21
keymint/aidl/Android.bp
Normal file
21
keymint/aidl/Android.bp
Normal file
@@ -0,0 +1,21 @@
|
||||
aidl_interface {
|
||||
name: "android.hardware.keymint",
|
||||
vendor_available: true,
|
||||
srcs: [
|
||||
"android/hardware/keymint/*.aidl",
|
||||
],
|
||||
stability: "vintf",
|
||||
backend: {
|
||||
java: {
|
||||
sdk_version: "module_current",
|
||||
},
|
||||
ndk: {
|
||||
vndk: {
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
rust: {
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
3
keymint/aidl/OWNERS
Normal file
3
keymint/aidl/OWNERS
Normal file
@@ -0,0 +1,3 @@
|
||||
jdanis@google.com
|
||||
seleneh@google.com
|
||||
swillden@google.com
|
||||
@@ -0,0 +1,26 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
|
||||
// edit this file. It looks like you are doing that because you have modified
|
||||
// an AIDL interface in a backward-incompatible way, e.g., deleting a function
|
||||
// from an interface or a field from a parcelable and it broke the build. That
|
||||
// breakage is intended.
|
||||
//
|
||||
// You must not make a backward incompatible changes to the AIDL files built
|
||||
// with the aidl_interface module type with versions property set. The module
|
||||
// type is used to build AIDL files in a way that they can be used across
|
||||
// independently updatable components of the system. If a device is shipped
|
||||
// with such a backward incompatible change, it has a high risk of breaking
|
||||
// later when a module using the interface is updated, e.g., Mainline modules.
|
||||
|
||||
package android.hardware.keymint;
|
||||
@Backing(type="int") @VintfStability
|
||||
enum Algorithm {
|
||||
RSA = 1,
|
||||
EC = 3,
|
||||
AES = 32,
|
||||
TRIPLE_DES = 33,
|
||||
HMAC = 128,
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
|
||||
// edit this file. It looks like you are doing that because you have modified
|
||||
// an AIDL interface in a backward-incompatible way, e.g., deleting a function
|
||||
// from an interface or a field from a parcelable and it broke the build. That
|
||||
// breakage is intended.
|
||||
//
|
||||
// You must not make a backward incompatible changes to the AIDL files built
|
||||
// with the aidl_interface module type with versions property set. The module
|
||||
// type is used to build AIDL files in a way that they can be used across
|
||||
// independently updatable components of the system. If a device is shipped
|
||||
// with such a backward incompatible change, it has a high risk of breaking
|
||||
// later when a module using the interface is updated, e.g., Mainline modules.
|
||||
|
||||
package android.hardware.keymint;
|
||||
@VintfStability
|
||||
parcelable BeginResult {
|
||||
long challenge;
|
||||
android.hardware.keymint.KeyParameter[] params;
|
||||
android.hardware.keymint.IKeyMintOperation operation;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
|
||||
// edit this file. It looks like you are doing that because you have modified
|
||||
// an AIDL interface in a backward-incompatible way, e.g., deleting a function
|
||||
// from an interface or a field from a parcelable and it broke the build. That
|
||||
// breakage is intended.
|
||||
//
|
||||
// You must not make a backward incompatible changes to the AIDL files built
|
||||
// with the aidl_interface module type with versions property set. The module
|
||||
// type is used to build AIDL files in a way that they can be used across
|
||||
// independently updatable components of the system. If a device is shipped
|
||||
// with such a backward incompatible change, it has a high risk of breaking
|
||||
// later when a module using the interface is updated, e.g., Mainline modules.
|
||||
|
||||
package android.hardware.keymint;
|
||||
@Backing(type="int") @VintfStability
|
||||
enum BlockMode {
|
||||
ECB = 1,
|
||||
CBC = 2,
|
||||
CTR = 3,
|
||||
GCM = 32,
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
|
||||
// edit this file. It looks like you are doing that because you have modified
|
||||
// an AIDL interface in a backward-incompatible way, e.g., deleting a function
|
||||
// from an interface or a field from a parcelable and it broke the build. That
|
||||
// breakage is intended.
|
||||
//
|
||||
// You must not make a backward incompatible changes to the AIDL files built
|
||||
// with the aidl_interface module type with versions property set. The module
|
||||
// type is used to build AIDL files in a way that they can be used across
|
||||
// independently updatable components of the system. If a device is shipped
|
||||
// with such a backward incompatible change, it has a high risk of breaking
|
||||
// later when a module using the interface is updated, e.g., Mainline modules.
|
||||
|
||||
package android.hardware.keymint;
|
||||
@VintfStability
|
||||
parcelable ByteArray {
|
||||
byte[] data;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
|
||||
// edit this file. It looks like you are doing that because you have modified
|
||||
// an AIDL interface in a backward-incompatible way, e.g., deleting a function
|
||||
// from an interface or a field from a parcelable and it broke the build. That
|
||||
// breakage is intended.
|
||||
//
|
||||
// You must not make a backward incompatible changes to the AIDL files built
|
||||
// with the aidl_interface module type with versions property set. The module
|
||||
// type is used to build AIDL files in a way that they can be used across
|
||||
// independently updatable components of the system. If a device is shipped
|
||||
// with such a backward incompatible change, it has a high risk of breaking
|
||||
// later when a module using the interface is updated, e.g., Mainline modules.
|
||||
|
||||
package android.hardware.keymint;
|
||||
@VintfStability
|
||||
parcelable Certificate {
|
||||
byte[] encodedCertificate;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
|
||||
// edit this file. It looks like you are doing that because you have modified
|
||||
// an AIDL interface in a backward-incompatible way, e.g., deleting a function
|
||||
// from an interface or a field from a parcelable and it broke the build. That
|
||||
// breakage is intended.
|
||||
//
|
||||
// You must not make a backward incompatible changes to the AIDL files built
|
||||
// with the aidl_interface module type with versions property set. The module
|
||||
// type is used to build AIDL files in a way that they can be used across
|
||||
// independently updatable components of the system. If a device is shipped
|
||||
// with such a backward incompatible change, it has a high risk of breaking
|
||||
// later when a module using the interface is updated, e.g., Mainline modules.
|
||||
|
||||
package android.hardware.keymint;
|
||||
@Backing(type="int") @VintfStability
|
||||
enum Digest {
|
||||
NONE = 0,
|
||||
MD5 = 1,
|
||||
SHA1 = 2,
|
||||
SHA_2_224 = 3,
|
||||
SHA_2_256 = 4,
|
||||
SHA_2_384 = 5,
|
||||
SHA_2_512 = 6,
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
|
||||
// edit this file. It looks like you are doing that because you have modified
|
||||
// an AIDL interface in a backward-incompatible way, e.g., deleting a function
|
||||
// from an interface or a field from a parcelable and it broke the build. That
|
||||
// breakage is intended.
|
||||
//
|
||||
// You must not make a backward incompatible changes to the AIDL files built
|
||||
// with the aidl_interface module type with versions property set. The module
|
||||
// type is used to build AIDL files in a way that they can be used across
|
||||
// independently updatable components of the system. If a device is shipped
|
||||
// with such a backward incompatible change, it has a high risk of breaking
|
||||
// later when a module using the interface is updated, e.g., Mainline modules.
|
||||
|
||||
package android.hardware.keymint;
|
||||
@Backing(type="int") @VintfStability
|
||||
enum EcCurve {
|
||||
P_224 = 0,
|
||||
P_256 = 1,
|
||||
P_384 = 2,
|
||||
P_521 = 3,
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
|
||||
// edit this file. It looks like you are doing that because you have modified
|
||||
// an AIDL interface in a backward-incompatible way, e.g., deleting a function
|
||||
// from an interface or a field from a parcelable and it broke the build. That
|
||||
// breakage is intended.
|
||||
//
|
||||
// You must not make a backward incompatible changes to the AIDL files built
|
||||
// with the aidl_interface module type with versions property set. The module
|
||||
// type is used to build AIDL files in a way that they can be used across
|
||||
// independently updatable components of the system. If a device is shipped
|
||||
// with such a backward incompatible change, it has a high risk of breaking
|
||||
// later when a module using the interface is updated, e.g., Mainline modules.
|
||||
|
||||
package android.hardware.keymint;
|
||||
@Backing(type="int") @VintfStability
|
||||
enum ErrorCode {
|
||||
OK = 0,
|
||||
ROOT_OF_TRUST_ALREADY_SET = -1,
|
||||
UNSUPPORTED_PURPOSE = -2,
|
||||
INCOMPATIBLE_PURPOSE = -3,
|
||||
UNSUPPORTED_ALGORITHM = -4,
|
||||
INCOMPATIBLE_ALGORITHM = -5,
|
||||
UNSUPPORTED_KEY_SIZE = -6,
|
||||
UNSUPPORTED_BLOCK_MODE = -7,
|
||||
INCOMPATIBLE_BLOCK_MODE = -8,
|
||||
UNSUPPORTED_MAC_LENGTH = -9,
|
||||
UNSUPPORTED_PADDING_MODE = -10,
|
||||
INCOMPATIBLE_PADDING_MODE = -11,
|
||||
UNSUPPORTED_DIGEST = -12,
|
||||
INCOMPATIBLE_DIGEST = -13,
|
||||
INVALID_EXPIRATION_TIME = -14,
|
||||
INVALID_USER_ID = -15,
|
||||
INVALID_AUTHORIZATION_TIMEOUT = -16,
|
||||
UNSUPPORTED_KEY_FORMAT = -17,
|
||||
INCOMPATIBLE_KEY_FORMAT = -18,
|
||||
UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM = -19,
|
||||
UNSUPPORTED_KEY_VERIFICATION_ALGORITHM = -20,
|
||||
INVALID_INPUT_LENGTH = -21,
|
||||
KEY_EXPORT_OPTIONS_INVALID = -22,
|
||||
DELEGATION_NOT_ALLOWED = -23,
|
||||
KEY_NOT_YET_VALID = -24,
|
||||
KEY_EXPIRED = -25,
|
||||
KEY_USER_NOT_AUTHENTICATED = -26,
|
||||
OUTPUT_PARAMETER_NULL = -27,
|
||||
INVALID_OPERATION_HANDLE = -28,
|
||||
INSUFFICIENT_BUFFER_SPACE = -29,
|
||||
VERIFICATION_FAILED = -30,
|
||||
TOO_MANY_OPERATIONS = -31,
|
||||
UNEXPECTED_NULL_POINTER = -32,
|
||||
INVALID_KEY_BLOB = -33,
|
||||
IMPORTED_KEY_NOT_ENCRYPTED = -34,
|
||||
IMPORTED_KEY_DECRYPTION_FAILED = -35,
|
||||
IMPORTED_KEY_NOT_SIGNED = -36,
|
||||
IMPORTED_KEY_VERIFICATION_FAILED = -37,
|
||||
INVALID_ARGUMENT = -38,
|
||||
UNSUPPORTED_TAG = -39,
|
||||
INVALID_TAG = -40,
|
||||
MEMORY_ALLOCATION_FAILED = -41,
|
||||
IMPORT_PARAMETER_MISMATCH = -44,
|
||||
SECURE_HW_ACCESS_DENIED = -45,
|
||||
OPERATION_CANCELLED = -46,
|
||||
CONCURRENT_ACCESS_CONFLICT = -47,
|
||||
SECURE_HW_BUSY = -48,
|
||||
SECURE_HW_COMMUNICATION_FAILED = -49,
|
||||
UNSUPPORTED_EC_FIELD = -50,
|
||||
MISSING_NONCE = -51,
|
||||
INVALID_NONCE = -52,
|
||||
MISSING_MAC_LENGTH = -53,
|
||||
KEY_RATE_LIMIT_EXCEEDED = -54,
|
||||
CALLER_NONCE_PROHIBITED = -55,
|
||||
KEY_MAX_OPS_EXCEEDED = -56,
|
||||
INVALID_MAC_LENGTH = -57,
|
||||
MISSING_MIN_MAC_LENGTH = -58,
|
||||
UNSUPPORTED_MIN_MAC_LENGTH = -59,
|
||||
UNSUPPORTED_KDF = -60,
|
||||
UNSUPPORTED_EC_CURVE = -61,
|
||||
KEY_REQUIRES_UPGRADE = -62,
|
||||
ATTESTATION_CHALLENGE_MISSING = -63,
|
||||
KEYMINT_NOT_CONFIGURED = -64,
|
||||
ATTESTATION_APPLICATION_ID_MISSING = -65,
|
||||
CANNOT_ATTEST_IDS = -66,
|
||||
ROLLBACK_RESISTANCE_UNAVAILABLE = -67,
|
||||
HARDWARE_TYPE_UNAVAILABLE = -68,
|
||||
PROOF_OF_PRESENCE_REQUIRED = -69,
|
||||
CONCURRENT_PROOF_OF_PRESENCE_REQUESTED = -70,
|
||||
NO_USER_CONFIRMATION = -71,
|
||||
DEVICE_LOCKED = -72,
|
||||
EARLY_BOOT_ENDED = -73,
|
||||
ATTESTATION_KEYS_NOT_PROVISIONED = -74,
|
||||
ATTESTATION_IDS_NOT_PROVISIONED = -75,
|
||||
INVALID_OPERATION = -76,
|
||||
STORAGE_KEY_UNSUPPORTED = -77,
|
||||
UNIMPLEMENTED = -100,
|
||||
VERSION_MISMATCH = -101,
|
||||
UNKNOWN_ERROR = -1000,
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
|
||||
// edit this file. It looks like you are doing that because you have modified
|
||||
// an AIDL interface in a backward-incompatible way, e.g., deleting a function
|
||||
// from an interface or a field from a parcelable and it broke the build. That
|
||||
// breakage is intended.
|
||||
//
|
||||
// You must not make a backward incompatible changes to the AIDL files built
|
||||
// with the aidl_interface module type with versions property set. The module
|
||||
// type is used to build AIDL files in a way that they can be used across
|
||||
// independently updatable components of the system. If a device is shipped
|
||||
// with such a backward incompatible change, it has a high risk of breaking
|
||||
// later when a module using the interface is updated, e.g., Mainline modules.
|
||||
|
||||
package android.hardware.keymint;
|
||||
@VintfStability
|
||||
parcelable HardwareAuthToken {
|
||||
long challenge;
|
||||
long userId;
|
||||
long authenticatorId;
|
||||
android.hardware.keymint.HardwareAuthenticatorType authenticatorType;
|
||||
android.hardware.keymint.Timestamp timestamp;
|
||||
byte[] mac;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
|
||||
// edit this file. It looks like you are doing that because you have modified
|
||||
// an AIDL interface in a backward-incompatible way, e.g., deleting a function
|
||||
// from an interface or a field from a parcelable and it broke the build. That
|
||||
// breakage is intended.
|
||||
//
|
||||
// You must not make a backward incompatible changes to the AIDL files built
|
||||
// with the aidl_interface module type with versions property set. The module
|
||||
// type is used to build AIDL files in a way that they can be used across
|
||||
// independently updatable components of the system. If a device is shipped
|
||||
// with such a backward incompatible change, it has a high risk of breaking
|
||||
// later when a module using the interface is updated, e.g., Mainline modules.
|
||||
|
||||
package android.hardware.keymint;
|
||||
@Backing(type="int") @VintfStability
|
||||
enum HardwareAuthenticatorType {
|
||||
NONE = 0,
|
||||
PASSWORD = 1,
|
||||
FINGERPRINT = 2,
|
||||
ANY = -1,
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
|
||||
// edit this file. It looks like you are doing that because you have modified
|
||||
// an AIDL interface in a backward-incompatible way, e.g., deleting a function
|
||||
// from an interface or a field from a parcelable and it broke the build. That
|
||||
// breakage is intended.
|
||||
//
|
||||
// You must not make a backward incompatible changes to the AIDL files built
|
||||
// with the aidl_interface module type with versions property set. The module
|
||||
// type is used to build AIDL files in a way that they can be used across
|
||||
// independently updatable components of the system. If a device is shipped
|
||||
// with such a backward incompatible change, it has a high risk of breaking
|
||||
// later when a module using the interface is updated, e.g., Mainline modules.
|
||||
|
||||
package android.hardware.keymint;
|
||||
@VintfStability
|
||||
interface IKeyMintDevice {
|
||||
android.hardware.keymint.KeyMintHardwareInfo getHardwareInfo();
|
||||
android.hardware.keymint.VerificationToken verifyAuthorization(in long challenge, in android.hardware.keymint.HardwareAuthToken token);
|
||||
void addRngEntropy(in byte[] data);
|
||||
void generateKey(in android.hardware.keymint.KeyParameter[] keyParams, out android.hardware.keymint.ByteArray generatedKeyBlob, out android.hardware.keymint.KeyCharacteristics generatedKeyCharacteristics, out android.hardware.keymint.Certificate[] outCertChain);
|
||||
void importKey(in android.hardware.keymint.KeyParameter[] inKeyParams, in android.hardware.keymint.KeyFormat inKeyFormat, in byte[] inKeyData, out android.hardware.keymint.ByteArray outImportedKeyBlob, out android.hardware.keymint.KeyCharacteristics outImportedKeyCharacteristics, out android.hardware.keymint.Certificate[] outCertChain);
|
||||
void importWrappedKey(in byte[] inWrappedKeyData, in byte[] inWrappingKeyBlob, in byte[] inMaskingKey, in android.hardware.keymint.KeyParameter[] inUnwrappingParams, in long inPasswordSid, in long inBiometricSid, out android.hardware.keymint.ByteArray outImportedKeyBlob, out android.hardware.keymint.KeyCharacteristics outImportedKeyCharacteristics);
|
||||
byte[] upgradeKey(in byte[] inKeyBlobToUpgrade, in android.hardware.keymint.KeyParameter[] inUpgradeParams);
|
||||
void deleteKey(in byte[] inKeyBlob);
|
||||
void deleteAllKeys();
|
||||
void destroyAttestationIds();
|
||||
android.hardware.keymint.BeginResult begin(in android.hardware.keymint.KeyPurpose inPurpose, in byte[] inKeyBlob, in android.hardware.keymint.KeyParameter[] inParams, in android.hardware.keymint.HardwareAuthToken inAuthToken);
|
||||
const int AUTH_TOKEN_MAC_LENGTH = 32;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
|
||||
// edit this file. It looks like you are doing that because you have modified
|
||||
// an AIDL interface in a backward-incompatible way, e.g., deleting a function
|
||||
// from an interface or a field from a parcelable and it broke the build. That
|
||||
// breakage is intended.
|
||||
//
|
||||
// You must not make a backward incompatible changes to the AIDL files built
|
||||
// with the aidl_interface module type with versions property set. The module
|
||||
// type is used to build AIDL files in a way that they can be used across
|
||||
// independently updatable components of the system. If a device is shipped
|
||||
// with such a backward incompatible change, it has a high risk of breaking
|
||||
// later when a module using the interface is updated, e.g., Mainline modules.
|
||||
|
||||
package android.hardware.keymint;
|
||||
@VintfStability
|
||||
interface IKeyMintOperation {
|
||||
int update(in @nullable android.hardware.keymint.KeyParameterArray inParams, in @nullable byte[] input, in @nullable android.hardware.keymint.HardwareAuthToken inAuthToken, in @nullable android.hardware.keymint.VerificationToken inVerificationToken, out @nullable android.hardware.keymint.KeyParameterArray outParams, out @nullable android.hardware.keymint.ByteArray output);
|
||||
byte[] finish(in @nullable android.hardware.keymint.KeyParameterArray inParams, in @nullable byte[] input, in @nullable byte[] inSignature, in @nullable android.hardware.keymint.HardwareAuthToken authToken, in @nullable android.hardware.keymint.VerificationToken inVerificationToken, out @nullable android.hardware.keymint.KeyParameterArray outParams);
|
||||
void abort();
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
|
||||
// edit this file. It looks like you are doing that because you have modified
|
||||
// an AIDL interface in a backward-incompatible way, e.g., deleting a function
|
||||
// from an interface or a field from a parcelable and it broke the build. That
|
||||
// breakage is intended.
|
||||
//
|
||||
// You must not make a backward incompatible changes to the AIDL files built
|
||||
// with the aidl_interface module type with versions property set. The module
|
||||
// type is used to build AIDL files in a way that they can be used across
|
||||
// independently updatable components of the system. If a device is shipped
|
||||
// with such a backward incompatible change, it has a high risk of breaking
|
||||
// later when a module using the interface is updated, e.g., Mainline modules.
|
||||
|
||||
package android.hardware.keymint;
|
||||
@VintfStability
|
||||
parcelable KeyCharacteristics {
|
||||
android.hardware.keymint.KeyParameter[] softwareEnforced;
|
||||
android.hardware.keymint.KeyParameter[] hardwareEnforced;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
|
||||
// edit this file. It looks like you are doing that because you have modified
|
||||
// an AIDL interface in a backward-incompatible way, e.g., deleting a function
|
||||
// from an interface or a field from a parcelable and it broke the build. That
|
||||
// breakage is intended.
|
||||
//
|
||||
// You must not make a backward incompatible changes to the AIDL files built
|
||||
// with the aidl_interface module type with versions property set. The module
|
||||
// type is used to build AIDL files in a way that they can be used across
|
||||
// independently updatable components of the system. If a device is shipped
|
||||
// with such a backward incompatible change, it has a high risk of breaking
|
||||
// later when a module using the interface is updated, e.g., Mainline modules.
|
||||
|
||||
package android.hardware.keymint;
|
||||
@Backing(type="int") @VintfStability
|
||||
enum KeyDerivationFunction {
|
||||
NONE = 0,
|
||||
RFC5869_SHA256 = 1,
|
||||
ISO18033_2_KDF1_SHA1 = 2,
|
||||
ISO18033_2_KDF1_SHA256 = 3,
|
||||
ISO18033_2_KDF2_SHA1 = 4,
|
||||
ISO18033_2_KDF2_SHA256 = 5,
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
|
||||
// edit this file. It looks like you are doing that because you have modified
|
||||
// an AIDL interface in a backward-incompatible way, e.g., deleting a function
|
||||
// from an interface or a field from a parcelable and it broke the build. That
|
||||
// breakage is intended.
|
||||
//
|
||||
// You must not make a backward incompatible changes to the AIDL files built
|
||||
// with the aidl_interface module type with versions property set. The module
|
||||
// type is used to build AIDL files in a way that they can be used across
|
||||
// independently updatable components of the system. If a device is shipped
|
||||
// with such a backward incompatible change, it has a high risk of breaking
|
||||
// later when a module using the interface is updated, e.g., Mainline modules.
|
||||
|
||||
package android.hardware.keymint;
|
||||
@Backing(type="int") @VintfStability
|
||||
enum KeyFormat {
|
||||
X509 = 0,
|
||||
PKCS8 = 1,
|
||||
RAW = 3,
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
|
||||
// edit this file. It looks like you are doing that because you have modified
|
||||
// an AIDL interface in a backward-incompatible way, e.g., deleting a function
|
||||
// from an interface or a field from a parcelable and it broke the build. That
|
||||
// breakage is intended.
|
||||
//
|
||||
// You must not make a backward incompatible changes to the AIDL files built
|
||||
// with the aidl_interface module type with versions property set. The module
|
||||
// type is used to build AIDL files in a way that they can be used across
|
||||
// independently updatable components of the system. If a device is shipped
|
||||
// with such a backward incompatible change, it has a high risk of breaking
|
||||
// later when a module using the interface is updated, e.g., Mainline modules.
|
||||
|
||||
package android.hardware.keymint;
|
||||
@VintfStability
|
||||
parcelable KeyMintHardwareInfo {
|
||||
int versionNumber;
|
||||
android.hardware.keymint.SecurityLevel securityLevel;
|
||||
@utf8InCpp String keyMintName;
|
||||
@utf8InCpp String keyMintAuthorName;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
|
||||
// edit this file. It looks like you are doing that because you have modified
|
||||
// an AIDL interface in a backward-incompatible way, e.g., deleting a function
|
||||
// from an interface or a field from a parcelable and it broke the build. That
|
||||
// breakage is intended.
|
||||
//
|
||||
// You must not make a backward incompatible changes to the AIDL files built
|
||||
// with the aidl_interface module type with versions property set. The module
|
||||
// type is used to build AIDL files in a way that they can be used across
|
||||
// independently updatable components of the system. If a device is shipped
|
||||
// with such a backward incompatible change, it has a high risk of breaking
|
||||
// later when a module using the interface is updated, e.g., Mainline modules.
|
||||
|
||||
package android.hardware.keymint;
|
||||
@Backing(type="int") @VintfStability
|
||||
enum KeyOrigin {
|
||||
GENERATED = 0,
|
||||
DERIVED = 1,
|
||||
IMPORTED = 2,
|
||||
RESERVED = 3,
|
||||
SECURELY_IMPORTED = 4,
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
|
||||
// edit this file. It looks like you are doing that because you have modified
|
||||
// an AIDL interface in a backward-incompatible way, e.g., deleting a function
|
||||
// from an interface or a field from a parcelable and it broke the build. That
|
||||
// breakage is intended.
|
||||
//
|
||||
// You must not make a backward incompatible changes to the AIDL files built
|
||||
// with the aidl_interface module type with versions property set. The module
|
||||
// type is used to build AIDL files in a way that they can be used across
|
||||
// independently updatable components of the system. If a device is shipped
|
||||
// with such a backward incompatible change, it has a high risk of breaking
|
||||
// later when a module using the interface is updated, e.g., Mainline modules.
|
||||
|
||||
package android.hardware.keymint;
|
||||
@VintfStability
|
||||
parcelable KeyParameter {
|
||||
android.hardware.keymint.Tag tag;
|
||||
boolean boolValue;
|
||||
int integer;
|
||||
long longInteger;
|
||||
byte[] blob;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
|
||||
// edit this file. It looks like you are doing that because you have modified
|
||||
// an AIDL interface in a backward-incompatible way, e.g., deleting a function
|
||||
// from an interface or a field from a parcelable and it broke the build. That
|
||||
// breakage is intended.
|
||||
//
|
||||
// You must not make a backward incompatible changes to the AIDL files built
|
||||
// with the aidl_interface module type with versions property set. The module
|
||||
// type is used to build AIDL files in a way that they can be used across
|
||||
// independently updatable components of the system. If a device is shipped
|
||||
// with such a backward incompatible change, it has a high risk of breaking
|
||||
// later when a module using the interface is updated, e.g., Mainline modules.
|
||||
|
||||
package android.hardware.keymint;
|
||||
@VintfStability
|
||||
parcelable KeyParameterArray {
|
||||
android.hardware.keymint.KeyParameter[] params;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
|
||||
// edit this file. It looks like you are doing that because you have modified
|
||||
// an AIDL interface in a backward-incompatible way, e.g., deleting a function
|
||||
// from an interface or a field from a parcelable and it broke the build. That
|
||||
// breakage is intended.
|
||||
//
|
||||
// You must not make a backward incompatible changes to the AIDL files built
|
||||
// with the aidl_interface module type with versions property set. The module
|
||||
// type is used to build AIDL files in a way that they can be used across
|
||||
// independently updatable components of the system. If a device is shipped
|
||||
// with such a backward incompatible change, it has a high risk of breaking
|
||||
// later when a module using the interface is updated, e.g., Mainline modules.
|
||||
|
||||
package android.hardware.keymint;
|
||||
@Backing(type="int") @VintfStability
|
||||
enum KeyPurpose {
|
||||
ENCRYPT = 0,
|
||||
DECRYPT = 1,
|
||||
SIGN = 2,
|
||||
VERIFY = 3,
|
||||
WRAP_KEY = 5,
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
|
||||
// edit this file. It looks like you are doing that because you have modified
|
||||
// an AIDL interface in a backward-incompatible way, e.g., deleting a function
|
||||
// from an interface or a field from a parcelable and it broke the build. That
|
||||
// breakage is intended.
|
||||
//
|
||||
// You must not make a backward incompatible changes to the AIDL files built
|
||||
// with the aidl_interface module type with versions property set. The module
|
||||
// type is used to build AIDL files in a way that they can be used across
|
||||
// independently updatable components of the system. If a device is shipped
|
||||
// with such a backward incompatible change, it has a high risk of breaking
|
||||
// later when a module using the interface is updated, e.g., Mainline modules.
|
||||
|
||||
package android.hardware.keymint;
|
||||
@Backing(type="int") @VintfStability
|
||||
enum PaddingMode {
|
||||
NONE = 1,
|
||||
RSA_OAEP = 2,
|
||||
RSA_PSS = 3,
|
||||
RSA_PKCS1_1_5_ENCRYPT = 4,
|
||||
RSA_PKCS1_1_5_SIGN = 5,
|
||||
PKCS7 = 64,
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
|
||||
// edit this file. It looks like you are doing that because you have modified
|
||||
// an AIDL interface in a backward-incompatible way, e.g., deleting a function
|
||||
// from an interface or a field from a parcelable and it broke the build. That
|
||||
// breakage is intended.
|
||||
//
|
||||
// You must not make a backward incompatible changes to the AIDL files built
|
||||
// with the aidl_interface module type with versions property set. The module
|
||||
// type is used to build AIDL files in a way that they can be used across
|
||||
// independently updatable components of the system. If a device is shipped
|
||||
// with such a backward incompatible change, it has a high risk of breaking
|
||||
// later when a module using the interface is updated, e.g., Mainline modules.
|
||||
|
||||
package android.hardware.keymint;
|
||||
@Backing(type="int") @VintfStability
|
||||
enum SecurityLevel {
|
||||
SOFTWARE = 0,
|
||||
TRUSTED_ENVIRONMENT = 1,
|
||||
STRONGBOX = 2,
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
|
||||
// edit this file. It looks like you are doing that because you have modified
|
||||
// an AIDL interface in a backward-incompatible way, e.g., deleting a function
|
||||
// from an interface or a field from a parcelable and it broke the build. That
|
||||
// breakage is intended.
|
||||
//
|
||||
// You must not make a backward incompatible changes to the AIDL files built
|
||||
// with the aidl_interface module type with versions property set. The module
|
||||
// type is used to build AIDL files in a way that they can be used across
|
||||
// independently updatable components of the system. If a device is shipped
|
||||
// with such a backward incompatible change, it has a high risk of breaking
|
||||
// later when a module using the interface is updated, e.g., Mainline modules.
|
||||
|
||||
package android.hardware.keymint;
|
||||
@Backing(type="int") @VintfStability
|
||||
enum Tag {
|
||||
INVALID = 0,
|
||||
PURPOSE = 536870913,
|
||||
ALGORITHM = 268435458,
|
||||
KEY_SIZE = 805306371,
|
||||
BLOCK_MODE = 536870916,
|
||||
DIGEST = 536870917,
|
||||
PADDING = 536870918,
|
||||
CALLER_NONCE = 1879048199,
|
||||
MIN_MAC_LENGTH = 805306376,
|
||||
EC_CURVE = 268435466,
|
||||
RSA_PUBLIC_EXPONENT = 1342177480,
|
||||
INCLUDE_UNIQUE_ID = 1879048394,
|
||||
BLOB_USAGE_REQUIREMENTS = 268435757,
|
||||
BOOTLOADER_ONLY = 1879048494,
|
||||
ROLLBACK_RESISTANCE = 1879048495,
|
||||
HARDWARE_TYPE = 268435760,
|
||||
EARLY_BOOT_ONLY = 1879048497,
|
||||
ACTIVE_DATETIME = 1610613136,
|
||||
ORIGINATION_EXPIRE_DATETIME = 1610613137,
|
||||
USAGE_EXPIRE_DATETIME = 1610613138,
|
||||
MIN_SECONDS_BETWEEN_OPS = 805306771,
|
||||
MAX_USES_PER_BOOT = 805306772,
|
||||
USER_ID = 805306869,
|
||||
USER_SECURE_ID = 1073742326,
|
||||
NO_AUTH_REQUIRED = 1879048695,
|
||||
USER_AUTH_TYPE = 268435960,
|
||||
AUTH_TIMEOUT = 805306873,
|
||||
ALLOW_WHILE_ON_BODY = 1879048698,
|
||||
TRUSTED_USER_PRESENCE_REQUIRED = 1879048699,
|
||||
TRUSTED_CONFIRMATION_REQUIRED = 1879048700,
|
||||
UNLOCKED_DEVICE_REQUIRED = 1879048701,
|
||||
APPLICATION_ID = -1879047591,
|
||||
APPLICATION_DATA = -1879047492,
|
||||
CREATION_DATETIME = 1610613437,
|
||||
ORIGIN = 268436158,
|
||||
ROOT_OF_TRUST = -1879047488,
|
||||
OS_VERSION = 805307073,
|
||||
OS_PATCHLEVEL = 805307074,
|
||||
UNIQUE_ID = -1879047485,
|
||||
ATTESTATION_CHALLENGE = -1879047484,
|
||||
ATTESTATION_APPLICATION_ID = -1879047483,
|
||||
ATTESTATION_ID_BRAND = -1879047482,
|
||||
ATTESTATION_ID_DEVICE = -1879047481,
|
||||
ATTESTATION_ID_PRODUCT = -1879047480,
|
||||
ATTESTATION_ID_SERIAL = -1879047479,
|
||||
ATTESTATION_ID_IMEI = -1879047478,
|
||||
ATTESTATION_ID_MEID = -1879047477,
|
||||
ATTESTATION_ID_MANUFACTURER = -1879047476,
|
||||
ATTESTATION_ID_MODEL = -1879047475,
|
||||
VENDOR_PATCHLEVEL = 805307086,
|
||||
BOOT_PATCHLEVEL = 805307087,
|
||||
DEVICE_UNIQUE_ATTESTATION = 1879048912,
|
||||
IDENTITY_CREDENTIAL_KEY = 1879048913,
|
||||
STORAGE_KEY = 1879048914,
|
||||
ASSOCIATED_DATA = -1879047192,
|
||||
NONCE = -1879047191,
|
||||
MAC_LENGTH = 805307371,
|
||||
RESET_SINCE_ID_ROTATION = 1879049196,
|
||||
CONFIRMATION_TOKEN = -1879047187,
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
|
||||
// edit this file. It looks like you are doing that because you have modified
|
||||
// an AIDL interface in a backward-incompatible way, e.g., deleting a function
|
||||
// from an interface or a field from a parcelable and it broke the build. That
|
||||
// breakage is intended.
|
||||
//
|
||||
// You must not make a backward incompatible changes to the AIDL files built
|
||||
// with the aidl_interface module type with versions property set. The module
|
||||
// type is used to build AIDL files in a way that they can be used across
|
||||
// independently updatable components of the system. If a device is shipped
|
||||
// with such a backward incompatible change, it has a high risk of breaking
|
||||
// later when a module using the interface is updated, e.g., Mainline modules.
|
||||
|
||||
package android.hardware.keymint;
|
||||
@Backing(type="int") @VintfStability
|
||||
enum TagType {
|
||||
INVALID = 0,
|
||||
ENUM = 268435456,
|
||||
ENUM_REP = 536870912,
|
||||
UINT = 805306368,
|
||||
UINT_REP = 1073741824,
|
||||
ULONG = 1342177280,
|
||||
DATE = 1610612736,
|
||||
BOOL = 1879048192,
|
||||
BIGNUM = -2147483648,
|
||||
BYTES = -1879048192,
|
||||
ULONG_REP = -1610612736,
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
|
||||
// edit this file. It looks like you are doing that because you have modified
|
||||
// an AIDL interface in a backward-incompatible way, e.g., deleting a function
|
||||
// from an interface or a field from a parcelable and it broke the build. That
|
||||
// breakage is intended.
|
||||
//
|
||||
// You must not make a backward incompatible changes to the AIDL files built
|
||||
// with the aidl_interface module type with versions property set. The module
|
||||
// type is used to build AIDL files in a way that they can be used across
|
||||
// independently updatable components of the system. If a device is shipped
|
||||
// with such a backward incompatible change, it has a high risk of breaking
|
||||
// later when a module using the interface is updated, e.g., Mainline modules.
|
||||
|
||||
package android.hardware.keymint;
|
||||
@VintfStability
|
||||
parcelable Timestamp {
|
||||
long milliSeconds;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
|
||||
// edit this file. It looks like you are doing that because you have modified
|
||||
// an AIDL interface in a backward-incompatible way, e.g., deleting a function
|
||||
// from an interface or a field from a parcelable and it broke the build. That
|
||||
// breakage is intended.
|
||||
//
|
||||
// You must not make a backward incompatible changes to the AIDL files built
|
||||
// with the aidl_interface module type with versions property set. The module
|
||||
// type is used to build AIDL files in a way that they can be used across
|
||||
// independently updatable components of the system. If a device is shipped
|
||||
// with such a backward incompatible change, it has a high risk of breaking
|
||||
// later when a module using the interface is updated, e.g., Mainline modules.
|
||||
|
||||
package android.hardware.keymint;
|
||||
@VintfStability
|
||||
parcelable VerificationToken {
|
||||
long challenge;
|
||||
android.hardware.keymint.Timestamp timestamp;
|
||||
android.hardware.keymint.SecurityLevel securityLevel;
|
||||
byte[] mac;
|
||||
}
|
||||
37
keymint/aidl/android/hardware/keymint/Algorithm.aidl
Normal file
37
keymint/aidl/android/hardware/keymint/Algorithm.aidl
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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.keymint;
|
||||
|
||||
|
||||
/**
|
||||
* Algorithms provided by IKeyMintDevice implementations.
|
||||
*/
|
||||
@VintfStability
|
||||
@Backing(type="int")
|
||||
enum Algorithm {
|
||||
/** Asymmetric algorithms. */
|
||||
RSA = 1,
|
||||
/** 2 removed, do not reuse. */
|
||||
EC = 3,
|
||||
|
||||
/** Block cipher algorithms */
|
||||
AES = 32,
|
||||
TRIPLE_DES = 33,
|
||||
|
||||
/** MAC algorithms */
|
||||
HMAC = 128,
|
||||
}
|
||||
39
keymint/aidl/android/hardware/keymint/BeginResult.aidl
Normal file
39
keymint/aidl/android/hardware/keymint/BeginResult.aidl
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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.keymint;
|
||||
|
||||
|
||||
import android.hardware.keymint.IKeyMintOperation;
|
||||
import android.hardware.keymint.KeyParameter;
|
||||
|
||||
|
||||
/**
|
||||
* This is all the results returned by the IKeyMintDevice begin() function.
|
||||
*/
|
||||
@VintfStability
|
||||
parcelable BeginResult {
|
||||
/* This is the challenge used in verifyAuthorization. It must be a nonce. */
|
||||
long challenge;
|
||||
|
||||
/**
|
||||
* begin() uses this field to return additional data from the operation
|
||||
* initialization, notably to return the IV or nonce from operations
|
||||
* that generate an IV or nonce.
|
||||
*/
|
||||
KeyParameter[] params;
|
||||
IKeyMintOperation operation;
|
||||
}
|
||||
39
keymint/aidl/android/hardware/keymint/BlockMode.aidl
Normal file
39
keymint/aidl/android/hardware/keymint/BlockMode.aidl
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* 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.keymint;
|
||||
|
||||
|
||||
/**
|
||||
* Symmetric block cipher modes provided by IKeyMintDevice implementations.
|
||||
*/
|
||||
@VintfStability
|
||||
@Backing(type="int")
|
||||
enum BlockMode {
|
||||
/*
|
||||
* Unauthenticated modes, usable only for encryption/decryption and not generally recommended
|
||||
* except for compatibility with existing other protocols.
|
||||
*/
|
||||
ECB = 1,
|
||||
CBC = 2,
|
||||
CTR = 3,
|
||||
|
||||
/*
|
||||
* Authenticated modes, usable for encryption/decryption and signing/verification. Recommended
|
||||
* over unauthenticated modes for all purposes.
|
||||
*/
|
||||
GCM = 32,
|
||||
}
|
||||
27
keymint/aidl/android/hardware/keymint/ByteArray.aidl
Normal file
27
keymint/aidl/android/hardware/keymint/ByteArray.aidl
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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.keymint;
|
||||
|
||||
|
||||
/**
|
||||
* This is used to contain a byte[], to make out parameters of byte arrays
|
||||
* more convenient for callers.
|
||||
*/
|
||||
@VintfStability
|
||||
parcelable ByteArray {
|
||||
byte[] data;
|
||||
}
|
||||
29
keymint/aidl/android/hardware/keymint/Certificate.aidl
Normal file
29
keymint/aidl/android/hardware/keymint/Certificate.aidl
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 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.keymint;
|
||||
|
||||
/**
|
||||
* This encodes the IKeyMintDevice attestation generated certificate.
|
||||
*/
|
||||
|
||||
@VintfStability
|
||||
parcelable Certificate {
|
||||
/**
|
||||
* EncodedCertificate contains the bytes of a DER-encoded X.509 certificate.
|
||||
*/
|
||||
byte[] encodedCertificate;
|
||||
}
|
||||
33
keymint/aidl/android/hardware/keymint/Digest.aidl
Normal file
33
keymint/aidl/android/hardware/keymint/Digest.aidl
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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.keymint;
|
||||
|
||||
|
||||
/**
|
||||
* Digests provided by keyMint implementations.
|
||||
*/
|
||||
@VintfStability
|
||||
@Backing(type="int")
|
||||
enum Digest {
|
||||
NONE = 0,
|
||||
MD5 = 1,
|
||||
SHA1 = 2,
|
||||
SHA_2_224 = 3,
|
||||
SHA_2_256 = 4,
|
||||
SHA_2_384 = 5,
|
||||
SHA_2_512 = 6,
|
||||
}
|
||||
30
keymint/aidl/android/hardware/keymint/EcCurve.aidl
Normal file
30
keymint/aidl/android/hardware/keymint/EcCurve.aidl
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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.keymint;
|
||||
|
||||
|
||||
/**
|
||||
* Supported EC curves, used in ECDSA
|
||||
*/
|
||||
@VintfStability
|
||||
@Backing(type="int")
|
||||
enum EcCurve {
|
||||
P_224 = 0,
|
||||
P_256 = 1,
|
||||
P_384 = 2,
|
||||
P_521 = 3,
|
||||
}
|
||||
110
keymint/aidl/android/hardware/keymint/ErrorCode.aidl
Normal file
110
keymint/aidl/android/hardware/keymint/ErrorCode.aidl
Normal file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* 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.keymint;
|
||||
|
||||
|
||||
/**
|
||||
* KeyMint error codes. Aidl will return these error codes as service specific
|
||||
* errors in EX_SERVICE_SPECIFIC.
|
||||
*/
|
||||
@VintfStability
|
||||
@Backing(type="int")
|
||||
enum ErrorCode {
|
||||
OK = 0,
|
||||
ROOT_OF_TRUST_ALREADY_SET = -1,
|
||||
UNSUPPORTED_PURPOSE = -2,
|
||||
INCOMPATIBLE_PURPOSE = -3,
|
||||
UNSUPPORTED_ALGORITHM = -4,
|
||||
INCOMPATIBLE_ALGORITHM = -5,
|
||||
UNSUPPORTED_KEY_SIZE = -6,
|
||||
UNSUPPORTED_BLOCK_MODE = -7,
|
||||
INCOMPATIBLE_BLOCK_MODE = -8,
|
||||
UNSUPPORTED_MAC_LENGTH = -9,
|
||||
UNSUPPORTED_PADDING_MODE = -10,
|
||||
INCOMPATIBLE_PADDING_MODE = -11,
|
||||
UNSUPPORTED_DIGEST = -12,
|
||||
INCOMPATIBLE_DIGEST = -13,
|
||||
INVALID_EXPIRATION_TIME = -14,
|
||||
INVALID_USER_ID = -15,
|
||||
INVALID_AUTHORIZATION_TIMEOUT = -16,
|
||||
UNSUPPORTED_KEY_FORMAT = -17,
|
||||
INCOMPATIBLE_KEY_FORMAT = -18,
|
||||
UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM = -19, /** For PKCS8 & PKCS12 */
|
||||
UNSUPPORTED_KEY_VERIFICATION_ALGORITHM = -20, /** For PKCS8 & PKCS12 */
|
||||
INVALID_INPUT_LENGTH = -21,
|
||||
KEY_EXPORT_OPTIONS_INVALID = -22,
|
||||
DELEGATION_NOT_ALLOWED = -23,
|
||||
KEY_NOT_YET_VALID = -24,
|
||||
KEY_EXPIRED = -25,
|
||||
KEY_USER_NOT_AUTHENTICATED = -26,
|
||||
OUTPUT_PARAMETER_NULL = -27,
|
||||
INVALID_OPERATION_HANDLE = -28,
|
||||
INSUFFICIENT_BUFFER_SPACE = -29,
|
||||
VERIFICATION_FAILED = -30,
|
||||
TOO_MANY_OPERATIONS = -31,
|
||||
UNEXPECTED_NULL_POINTER = -32,
|
||||
INVALID_KEY_BLOB = -33,
|
||||
IMPORTED_KEY_NOT_ENCRYPTED = -34,
|
||||
IMPORTED_KEY_DECRYPTION_FAILED = -35,
|
||||
IMPORTED_KEY_NOT_SIGNED = -36,
|
||||
IMPORTED_KEY_VERIFICATION_FAILED = -37,
|
||||
INVALID_ARGUMENT = -38,
|
||||
UNSUPPORTED_TAG = -39,
|
||||
INVALID_TAG = -40,
|
||||
MEMORY_ALLOCATION_FAILED = -41,
|
||||
IMPORT_PARAMETER_MISMATCH = -44,
|
||||
SECURE_HW_ACCESS_DENIED = -45,
|
||||
OPERATION_CANCELLED = -46,
|
||||
CONCURRENT_ACCESS_CONFLICT = -47,
|
||||
SECURE_HW_BUSY = -48,
|
||||
SECURE_HW_COMMUNICATION_FAILED = -49,
|
||||
UNSUPPORTED_EC_FIELD = -50,
|
||||
MISSING_NONCE = -51,
|
||||
INVALID_NONCE = -52,
|
||||
MISSING_MAC_LENGTH = -53,
|
||||
KEY_RATE_LIMIT_EXCEEDED = -54,
|
||||
CALLER_NONCE_PROHIBITED = -55,
|
||||
KEY_MAX_OPS_EXCEEDED = -56,
|
||||
INVALID_MAC_LENGTH = -57,
|
||||
MISSING_MIN_MAC_LENGTH = -58,
|
||||
UNSUPPORTED_MIN_MAC_LENGTH = -59,
|
||||
UNSUPPORTED_KDF = -60,
|
||||
UNSUPPORTED_EC_CURVE = -61,
|
||||
KEY_REQUIRES_UPGRADE = -62,
|
||||
ATTESTATION_CHALLENGE_MISSING = -63,
|
||||
KEYMINT_NOT_CONFIGURED = -64,
|
||||
ATTESTATION_APPLICATION_ID_MISSING = -65,
|
||||
CANNOT_ATTEST_IDS = -66,
|
||||
ROLLBACK_RESISTANCE_UNAVAILABLE = -67,
|
||||
HARDWARE_TYPE_UNAVAILABLE = -68,
|
||||
PROOF_OF_PRESENCE_REQUIRED = -69,
|
||||
CONCURRENT_PROOF_OF_PRESENCE_REQUESTED = -70,
|
||||
NO_USER_CONFIRMATION = -71,
|
||||
DEVICE_LOCKED = -72,
|
||||
EARLY_BOOT_ENDED = -73,
|
||||
ATTESTATION_KEYS_NOT_PROVISIONED = -74,
|
||||
ATTESTATION_IDS_NOT_PROVISIONED = -75,
|
||||
INVALID_OPERATION = -76,
|
||||
STORAGE_KEY_UNSUPPORTED = -77,
|
||||
|
||||
UNIMPLEMENTED = -100,
|
||||
VERSION_MISMATCH = -101,
|
||||
|
||||
UNKNOWN_ERROR = -1000,
|
||||
|
||||
// Implementer's namespace for error codes starts at -10000.
|
||||
}
|
||||
84
keymint/aidl/android/hardware/keymint/HardwareAuthToken.aidl
Normal file
84
keymint/aidl/android/hardware/keymint/HardwareAuthToken.aidl
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright 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.keymint;
|
||||
|
||||
import android.hardware.keymint.Timestamp;
|
||||
import android.hardware.keymint.HardwareAuthenticatorType;
|
||||
|
||||
/**
|
||||
* HardwareAuthToken is used to prove successful user authentication, to unlock the use of a key.
|
||||
*
|
||||
* HardwareAuthTokens are produced by other secure environment applications, notably GateKeeper and
|
||||
* biometric authenticators, in response to successful user authentication events. These tokens are passed to
|
||||
* begin(), update(), and finish() to prove that authentication occurred. See those methods for
|
||||
* more details. It is up to the caller to determine which of the generated auth tokens is
|
||||
* appropriate for a given key operation.
|
||||
*/
|
||||
@VintfStability
|
||||
parcelable HardwareAuthToken {
|
||||
|
||||
/**
|
||||
* challenge is a value that's used to enable authentication tokens to authorize specific
|
||||
* events. The primary use case for challenge is to authorize an IKeyMintDevice cryptographic
|
||||
* operation, for keys that require authentication per operation. See begin() for details.
|
||||
*/
|
||||
long challenge;
|
||||
|
||||
/**
|
||||
* userId is the a "secure" user ID. It is not related to any Android user ID or UID, but is
|
||||
* created in the Gatekeeper application in the secure environment.
|
||||
*/
|
||||
long userId;
|
||||
|
||||
/**
|
||||
* authenticatorId is the a "secure" user ID. It is not related to any Android user ID or UID,
|
||||
* but is created in an authentication application in the secure environment, such as the
|
||||
* Fingerprint application.
|
||||
*/
|
||||
long authenticatorId;
|
||||
|
||||
/**
|
||||
* authenticatorType describes the type of authentication that took place, e.g. password or
|
||||
* fingerprint.
|
||||
*/
|
||||
HardwareAuthenticatorType authenticatorType;
|
||||
|
||||
/**
|
||||
* timestamp indicates when the user authentication took place, in milliseconds since some
|
||||
* starting point (generally the most recent device boot) which all of the applications within
|
||||
* one secure environment must agree upon. This timestamp is used to determine whether or not
|
||||
* the authentication occurred recently enough to unlock a key (see Tag::AUTH_TIMEOUT).
|
||||
*/
|
||||
Timestamp timestamp;
|
||||
|
||||
/**
|
||||
* MACs are computed with a backward-compatible method, used by Keymaster 3.0, Gatekeeper 1.0
|
||||
* and Fingerprint 1.0, as well as pre-treble HALs.
|
||||
*
|
||||
* The MAC is Constants::AUTH_TOKEN_MAC_LENGTH bytes in length and is computed as follows:
|
||||
*
|
||||
* HMAC_SHA256(
|
||||
* H, 0 || challenge || user_id || authenticator_id || authenticator_type || timestamp)
|
||||
*
|
||||
* where ``||'' represents concatenation, the leading zero is a single byte, and all integers
|
||||
* are represented as unsigned values, the full width of the type. The challenge, userId and
|
||||
* authenticatorId values are in machine order, but authenticatorType and timestamp are in
|
||||
* network order (big-endian). This odd construction is compatible with the hw_auth_token_t
|
||||
* structure.
|
||||
*/
|
||||
byte[] mac;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 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.keymint;
|
||||
|
||||
/**
|
||||
* Hardware authentication type, used by HardwareAuthTokens to specify the mechanism used to
|
||||
* authentiate the user, and in KeyCharacteristics to specify the allowable mechanisms for
|
||||
* authenticating to activate a key.
|
||||
*/
|
||||
@VintfStability
|
||||
@Backing(type="int")
|
||||
enum HardwareAuthenticatorType {
|
||||
NONE = 0,
|
||||
PASSWORD = 1 << 0,
|
||||
FINGERPRINT = 1 << 1,
|
||||
// Additional entries must be powers of 2.
|
||||
ANY = 0xFFFFFFFF,
|
||||
}
|
||||
790
keymint/aidl/android/hardware/keymint/IKeyMintDevice.aidl
Normal file
790
keymint/aidl/android/hardware/keymint/IKeyMintDevice.aidl
Normal file
@@ -0,0 +1,790 @@
|
||||
/*
|
||||
* 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.keymint;
|
||||
|
||||
import android.hardware.keymint.BeginResult;
|
||||
import android.hardware.keymint.ByteArray;
|
||||
import android.hardware.keymint.Certificate;
|
||||
import android.hardware.keymint.HardwareAuthToken;
|
||||
import android.hardware.keymint.IKeyMintOperation;
|
||||
import android.hardware.keymint.KeyCharacteristics;
|
||||
import android.hardware.keymint.KeyFormat;
|
||||
import android.hardware.keymint.KeyParameter;
|
||||
import android.hardware.keymint.KeyMintHardwareInfo;
|
||||
import android.hardware.keymint.KeyPurpose;
|
||||
import android.hardware.keymint.SecurityLevel;
|
||||
import android.hardware.keymint.VerificationToken;
|
||||
|
||||
/**
|
||||
* KeyMint device definition.
|
||||
*
|
||||
* == Features ==
|
||||
*
|
||||
* An IKeyMintDevice provides cryptographic services, including the following categories of
|
||||
* operations:
|
||||
*
|
||||
* o Key generation
|
||||
* o Import of asymmetric keys
|
||||
* o Import of raw symmetric keys
|
||||
* o Asymmetric decryption with appropriate padding modes
|
||||
* o Asymmetric signing with digesting and appropriate padding modes
|
||||
* o Symmetric encryption and decryption in appropriate modes, including an AEAD mode
|
||||
* o Generation and verification of symmetric message authentication codes
|
||||
* o Attestation to the presence and configuration of asymmetric keys.
|
||||
*
|
||||
* Protocol elements, such as purpose, mode and padding, as well as access control constraints, must
|
||||
* be specified by the caller when keys are generated or imported and must be permanently bound to
|
||||
* the key, ensuring that the key cannot be used in any other way.
|
||||
*
|
||||
* In addition to the list above, IKeyMintDevice implementations must provide one more service
|
||||
* which is not exposed as an API but used internally: Random number generation. The random number
|
||||
* generator must be high-quality and must be used for generation of keys, initialization vectors,
|
||||
* random padding and other elements of secure protocols that require randomness.
|
||||
*
|
||||
* == Types of IKeyMintDevices ==
|
||||
*
|
||||
* All of the operations and storage of key material must occur in a secure environment. Secure
|
||||
* environments may be either:
|
||||
*
|
||||
* 1. Isolated execution environments, such as a separate virtual machine, hypervisor or
|
||||
* purpose-built trusted execution environment like ARM TrustZone. The isolated environment
|
||||
* must provide complete separation from the Android kernel and user space (collectively called
|
||||
* the "non-secure world", or NSW) so that nothing running in the NSW can observe or manipulate
|
||||
* the results of any computation in the isolated environment. Isolated execution environments
|
||||
* are identified by the SecurityLevel TRUSTED_ENVIRONMENT.
|
||||
*
|
||||
* 2. Completely separate, purpose-built and certified secure CPUs, called "StrongBox" devices.
|
||||
* Examples of StrongBox devices are embedded Secure Elements (eSE) or on-SoC secure processing
|
||||
* units (iSE). StrongBox environments are identified by the SecurityLevel STRONGBOX. To
|
||||
* qualify as a StrongBox, a device must meet the requirements specified in CDD 9.11.2.
|
||||
*
|
||||
* == Necessary Primitives ==
|
||||
*
|
||||
* All IKeyMintDevice implementations must provide support for the following:
|
||||
*
|
||||
* o RSA
|
||||
*
|
||||
* - TRUSTED_ENVIRONMENT IKeyMintDevices must support 2048, 3072 and 4096-bit keys.
|
||||
* STRONGBOX IKeyMintDevices must support 2048-bit keys.
|
||||
* - Public exponent F4 (2^16+1)
|
||||
* - Unpadded, RSASSA-PSS and RSASSA-PKCS1-v1_5 padding modes for RSA signing
|
||||
* - TRUSTED_ENVIRONMENT IKeyMintDevices must support MD5, SHA1, SHA-2 224, SHA-2 256, SHA-2
|
||||
* 384 and SHA-2 512 digest modes for RSA signing. STRONGBOX IKeyMintDevices must support
|
||||
* SHA-2 256.
|
||||
* - Unpadded, RSAES-OAEP and RSAES-PKCS1-v1_5 padding modes for RSA encryption.
|
||||
*
|
||||
* o ECDSA
|
||||
*
|
||||
* - TRUSTED_ENVIRONMENT IKeyMintDevices must support NIST curves P-224, P-256, P-384 and
|
||||
* P-521. STRONGBOX IKeyMintDevices must support NIST curve P-256.
|
||||
* - TRUSTED_ENVIRONMENT IKeyMintDevices must support SHA1, SHA-2 224, SHA-2 256, SHA-2
|
||||
* 384 and SHA-2 512 digest modes. STRONGBOX IKeyMintDevices must support SHA-2 256.
|
||||
*
|
||||
* o AES
|
||||
*
|
||||
* - 128 and 256-bit keys
|
||||
* - CBC, CTR, ECB and GCM modes. The GCM mode must not allow the use of tags smaller than 96
|
||||
* bits or nonce lengths other than 96 bits.
|
||||
* - CBC and ECB modes must support unpadded and PKCS7 padding modes. With no padding CBC and
|
||||
* ECB-mode operations must fail with ErrorCode::INVALID_INPUT_LENGTH if the input isn't a
|
||||
* multiple of the AES block size. With PKCS7 padding, GCM and CTR operations must fail with
|
||||
* ErrorCode::INCOMPATIBLE_PADDING_MODE.
|
||||
*
|
||||
* o 3DES
|
||||
*
|
||||
* - 168-bit keys.
|
||||
* - CBC and ECB mode.
|
||||
|
||||
* - CBC and ECB modes must support unpadded and PKCS7 padding modes. With no padding CBC and
|
||||
* ECB-mode operations must fail with ErrorCode::INVALID_INPUT_LENGTH if the input isn't a
|
||||
* multiple of the DES block size.
|
||||
*
|
||||
* o HMAC
|
||||
*
|
||||
* - Any key size that is between 64 and 512 bits (inclusive) and a multiple of 8 must be
|
||||
* supported. STRONGBOX IKeyMintDevices must not support keys larger than 512 bits.
|
||||
* - TRUSTED_ENVIRONMENT IKeyMintDevices must support MD-5, SHA1, SHA-2-224, SHA-2-256,
|
||||
* SHA-2-384 and SHA-2-512. STRONGBOX IKeyMintDevices must support SHA-2-256.
|
||||
*
|
||||
* == Key Access Control ==
|
||||
*
|
||||
* Hardware-based keys that can never be extracted from the device don't provide much security if an
|
||||
* attacker can use them at will (though they're more secure than keys which can be
|
||||
* exfiltrated). Therefore, IKeyMintDevice must enforce access controls.
|
||||
*
|
||||
* Access controls are defined as an "authorization list" of tag/value pairs. Authorization tags
|
||||
* are 32-bit integers from the Tag enum, and the values are a variety of types, defined in the
|
||||
* TagType enum. Some tags may be repeated to specify multiple values. Whether a tag may be
|
||||
* repeated is specified in the documentation for the tag and in the TagType. When a key is
|
||||
* created or imported, the caller specifies an authorization list. The IKeyMintDevice must divide
|
||||
* the caller-provided authorizations into two lists, those it enforces in tee secure zone and
|
||||
* those enforced in the strongBox hardware. These two lists are returned as the "teeEnforced"
|
||||
* and "strongboxEnforced" elements of the KeyCharacteristics struct. Note that software enforced
|
||||
* authorization list entries are not returned because they are not enforced by keymint. The
|
||||
* IKeyMintDevice must also add the following authorizations to the appropriate list:
|
||||
*
|
||||
* o Tag::OS_VERSION
|
||||
* o Tag::OS_PATCHLEVEL
|
||||
* o Tag::VENDOR_PATCHLEVEL
|
||||
* o Tag::BOOT_PATCHLEVEL
|
||||
* o Tag::ORIGIN
|
||||
*
|
||||
* The IKeyMintDevice must ignore unknown tags.
|
||||
*
|
||||
* The caller must always provide the current date time in the keyParameter CREATION_DATETIME
|
||||
* tags.
|
||||
*
|
||||
* All authorization tags and their values, both teeEnforced and strongboxEnforced, including
|
||||
* unknown tags, must be cryptographically bound to the private/secret key material such that any
|
||||
* modification of the portion of the key blob that contains the authorization list makes it
|
||||
* impossible for the secure environment to obtain the private/secret key material. The
|
||||
* recommended approach to meet this requirement is to use the full set of authorization tags
|
||||
* associated with a key as input to a secure key derivation function used to derive a key that
|
||||
* is used to encrypt the private/secret key material.
|
||||
*
|
||||
* IKeyMintDevice implementations ignore any tags they cannot enforce and do not return them
|
||||
* in KeyCharacteristics. For example, Tag::ORIGINATION_EXPIRE_DATETIME provides the date and
|
||||
* time after which a key may not be used to encrypt or sign new messages. Unless the
|
||||
* IKeyMintDevice has access to a secure source of current date/time information, it is not
|
||||
* possible for the IKeyMintDevice to enforce this tag. An IKeyMintDevice implementation will
|
||||
* not rely on the non-secure world's notion of time, because it could be controlled by an
|
||||
* attacker. Similarly, it cannot rely on GPSr time, even if it has exclusive control of the
|
||||
* GPSr, because that might be spoofed by attacker RF signals.
|
||||
*
|
||||
* IKeyMintDevices do not use or enforce any tags they place in the softwareEnforced
|
||||
* list. The IKeyMintDevice caller must enforce them, and it is unnecessary to enforce them
|
||||
* twice.
|
||||
*
|
||||
* Some tags must be enforced by the IKeyMintDevice. See the detailed documentation on each Tag
|
||||
* in Tag.aidl.
|
||||
*
|
||||
* == Root of Trust Binding ==
|
||||
*
|
||||
* IKeyMintDevice keys must be bound to a root of trust, which is a bitstring that must be
|
||||
* provided to the secure environment (by an unspecified, implementation-defined mechanism) during
|
||||
* startup, preferably by the bootloader. This bitstring must be cryptographically bound to every
|
||||
* key managed by the IKeyMintDevice. As above, the recommended mechanism for this cryptographic
|
||||
* binding is to include the Root of Trust data in the input to the key derivation function used to
|
||||
* derive a key that is used to encryp the private/secret key material.
|
||||
*
|
||||
* The root of trust consists of a bitstring that must be derived from the public key used by
|
||||
* Verified Boot to verify the signature on the boot image and from the lock state of the
|
||||
* device. If the public key is changed to allow a different system image to be used or if the
|
||||
* lock state is changed, then all of the IKeyMintDevice-protected keys created by the previous
|
||||
* system state must be unusable, unless the previous state is restored. The goal is to increase
|
||||
* the value of the software-enforced key access controls by making it impossible for an attacker-
|
||||
* installed operating system to use IKeyMintDevice keys.
|
||||
*
|
||||
* == Version Binding ==
|
||||
*
|
||||
* All keys must also be bound to the operating system and patch level of the system image and the
|
||||
* patch levels of the vendor image and boot image. This ensures that an attacker who discovers a
|
||||
* weakness in an old version of the software cannot roll a device back to the vulnerable version
|
||||
* and use keys created with the newer version. In addition, when a key with a given version and
|
||||
* patch level is used on a device that has been upgraded to a newer version or patch level, the
|
||||
* key must be upgraded (See IKeyMintDevice::upgradeKey()) before it can be used, and the previous
|
||||
* version of the key must be invalidated. In this way, as the device is upgraded, the keys will
|
||||
* "ratchet" forward along with the device, but any reversion of the device to a previous release
|
||||
* will cause the keys to be unusable.
|
||||
*
|
||||
* This version information must be associated with every key as a set of tag/value pairs in the
|
||||
* hardwareEnforced authorization list. Tag::OS_VERSION, Tag::OS_PATCHLEVEL,
|
||||
* Tag::VENDOR_PATCHLEVEL, and Tag::BOOT_PATCHLEVEL must be cryptographically bound to every
|
||||
* IKeyMintDevice key, as described in the Key Access Control section above.
|
||||
*/
|
||||
@VintfStability
|
||||
interface IKeyMintDevice {
|
||||
const int AUTH_TOKEN_MAC_LENGTH = 32;
|
||||
|
||||
/**
|
||||
* @return info which contains information about the underlying IKeyMintDevice hardware, such
|
||||
* as version number, security level, keyMint name and author name.
|
||||
*/
|
||||
KeyMintHardwareInfo getHardwareInfo();
|
||||
|
||||
/**
|
||||
* Verify authorizations for another IKeyMintDevice instance.
|
||||
*
|
||||
* On systems with both a StrongBox and a TEE IKeyMintDevice instance it is sometimes useful
|
||||
* to ask the TEE KeyMintDevice to verify authorizations for a key hosted in StrongBox.
|
||||
*
|
||||
* For every StrongBox operation, Keystore is required to call this method on the TEE KeyMint,
|
||||
* passing in the StrongBox key's hardwareEnforced authorization list and the challenge
|
||||
* returned by StrongBox begin(). Keystore must then pass the VerificationToken to the
|
||||
* subsequent invocations of StrongBox update() and finish().
|
||||
*
|
||||
* StrongBox implementations must return ErrorCode::UNIMPLEMENTED.
|
||||
*
|
||||
* @param the challenge returned by StrongBox's keyMint's begin().
|
||||
*
|
||||
* @param authToken A HardwareAuthToken if needed to authorize key usage.
|
||||
*
|
||||
* @return error ErrorCode::OK on success or ErrorCode::UNIMPLEMENTED if the KeyMintDevice is
|
||||
* a StrongBox. If the IKeyMintDevice cannot verify one or more elements of
|
||||
* parametersToVerify it must not return an error code, but just omit the unverified
|
||||
* parameter from the VerificationToken.
|
||||
*
|
||||
* @return token the verification token. See VerificationToken in VerificationToken.aidl for
|
||||
* details.
|
||||
*/
|
||||
VerificationToken verifyAuthorization(in long challenge,
|
||||
in HardwareAuthToken token);
|
||||
|
||||
/**
|
||||
* Adds entropy to the RNG used by KeyMint. Entropy added through this method must not be the
|
||||
* only source of entropy used, and a secure mixing function must be used to mix the entropy
|
||||
* provided by this method with internally-generated entropy. The mixing function must be
|
||||
* secure in the sense that if any one of the mixing function inputs is provided with any data
|
||||
* the attacker cannot predict (or control), then the output of the seeded CRNG is
|
||||
* indistinguishable from random. Thus, if the entropy from any source is good, the output
|
||||
* must be good.
|
||||
*
|
||||
* TODO(seleneh) specify what mixing functions and cprng we allow.
|
||||
*
|
||||
* @param data Bytes to be mixed into the CRNG seed. The caller must not provide more than 2
|
||||
* KiB of data per invocation.
|
||||
*
|
||||
* @return error ErrorCode::OK on success; ErrorCode::INVALID_INPUT_LENGTH if the caller
|
||||
* provides more than 2 KiB of data.
|
||||
*/
|
||||
void addRngEntropy(in byte[] data);
|
||||
|
||||
/**
|
||||
* Generates a new cryptographic key, specifying associated parameters, which must be
|
||||
* cryptographically bound to the key. IKeyMintDevice implementations must disallow any use
|
||||
* of a key in any way inconsistent with the authorizations specified at generation time. With
|
||||
* respect to parameters that the secure environment cannot enforce, the secure envionment's
|
||||
* obligation is limited to ensuring that the unenforceable parameters associated with the key
|
||||
* cannot be modified. In addition, the characteristics returned by generateKey places
|
||||
* parameters correctly in the tee-enforced and strongbox-enforced lists.
|
||||
*
|
||||
* In addition to the parameters provided, generateKey must add the following to the returned
|
||||
* characteristics.
|
||||
*
|
||||
* o Tag::ORIGIN with the value KeyOrigin::GENERATED.
|
||||
*
|
||||
* o Tag::BLOB_USAGE_REQUIREMENTS with the appropriate value (see KeyBlobUsageRequirements in
|
||||
* Tag.aidl).
|
||||
*
|
||||
* o Tag::OS_VERSION, Tag::OS_PATCHLEVEL, Tag::VENDOR_PATCHLEVEL and Tag::BOOT_PATCHLEVEL with
|
||||
* appropriate values.
|
||||
*
|
||||
* The parameters provided to generateKey depend on the type of key being generated. This
|
||||
* section summarizes the necessary and optional tags for each type of key. Tag::ALGORITHM is
|
||||
* always necessary, to specify the type.
|
||||
*
|
||||
* == RSA Keys ==
|
||||
*
|
||||
* The following parameters are required to generate an RSA key:
|
||||
*
|
||||
* o Tag::Key_SIZE specifies the size of the public modulus, in bits. If omitted, generateKey
|
||||
* must return ErrorCode::UNSUPPORTED_KEY_SIZE. Required values for TEE IKeyMintDevice
|
||||
* implementations are 1024, 2048, 3072 and 4096. StrongBox IKeyMintDevice implementations
|
||||
* must support 2048.
|
||||
*
|
||||
* o Tag::RSA_PUBLIC_EXPONENT specifies the RSA public exponent value. If omitted, generateKey
|
||||
* must return ErrorCode::INVALID_ARGUMENT. The values 3 and 65537 must be supported. It is
|
||||
* recommended to support all prime values up to 2^64. If provided with a non-prime value,
|
||||
* generateKey must return ErrorCode::INVALID_ARGUMENT.
|
||||
*
|
||||
* The following parameters are not necessary to generate a usable RSA key, but generateKey must
|
||||
* not return an error if they are omitted:
|
||||
*
|
||||
* o Tag::PURPOSE specifies allowed purposes. All KeyPurpose values (see KeyPurpose.aidl)
|
||||
* except AGREE_KEY must be supported for RSA keys.
|
||||
*
|
||||
* o Tag::DIGEST specifies digest algorithms that may be used with the new key. TEE
|
||||
* IKeyMintDevice implementatiosn must support all Digest values (see digest.aidl) for RSA
|
||||
* keys. StrongBox IKeyMintDevice implementations must support SHA_2_256.
|
||||
*
|
||||
* o Tag::PADDING specifies the padding modes that may be used with the new
|
||||
* key. IKeyMintDevice implementations must support PaddingMode::NONE,
|
||||
* PaddingMode::RSA_OAEP, PaddingMode::RSA_PSS, PaddingMode::RSA_PKCS1_1_5_ENCRYPT and
|
||||
* PaddingMode::RSA_PKCS1_1_5_SIGN for RSA keys.
|
||||
*
|
||||
* == ECDSA Keys ==
|
||||
*
|
||||
* Either Tag::KEY_SIZE or Tag::EC_CURVE must be provided to generate an ECDSA key. If neither
|
||||
* is provided, generateKey must return ErrorCode::UNSUPPORTED_KEY_SIZE. If Tag::KEY_SIZE is
|
||||
* provided, the possible values are 224, 256, 384 and 521, and must be mapped to Tag::EC_CURVE
|
||||
* values P_224, P_256, P_384 and P_521, respectively. TEE IKeyMintDevice implementations
|
||||
* must support all curves. StrongBox implementations must support P_256.
|
||||
*
|
||||
* == AES Keys ==
|
||||
*
|
||||
* Only Tag::KEY_SIZE is required to generate an AES key. If omitted, generateKey must return
|
||||
* ErrorCode::UNSUPPORTED_KEY_SIZE. 128 and 256-bit key sizes must be supported.
|
||||
*
|
||||
* If Tag::BLOCK_MODE is specified with value BlockMode::GCM, then the caller must also provide
|
||||
* Tag::MIN_MAC_LENGTH. If omitted, generateKey must return ErrorCode::MISSING_MIN_MAC_LENGTH.
|
||||
*
|
||||
*
|
||||
* @param keyParams Key generation parameters are defined as KeyMintDevice tag/value pairs,
|
||||
* provided in params. See above for detailed specifications of which tags are required
|
||||
* for which types of keys.
|
||||
*
|
||||
* @return generatedKeyBlob Opaque descriptor of the generated key. The recommended
|
||||
* implementation strategy is to include an encrypted copy of the key material, wrapped
|
||||
* in a key unavailable outside secure hardware.
|
||||
*
|
||||
* @return generatedKeyCharacteristics Description of the generated key, divided into two sets:
|
||||
* hardware-enforced and software-enforced. The description here applies equally
|
||||
* to the key characteristics lists returned by generateKey, importKey and
|
||||
* importWrappedKey. The characteristics returned by this parameter completely
|
||||
* describe the type and usage of the specified key.
|
||||
*
|
||||
* The rule that IKeyMintDevice implementations must use for deciding whether a
|
||||
* given tag belongs in the hardware-enforced or software-enforced list is that if
|
||||
* the meaning of the tag is fully assured by secure hardware, it is hardware
|
||||
* enforced. Otherwise, it's software enforced.
|
||||
*
|
||||
* @return outCertChain If the key is an asymmetric key, and proper keyparameters for
|
||||
* attestation (such as challenge) is provided, then this parameter will return the
|
||||
* attestation certificate. If the signing of the attestation certificate is from a
|
||||
* factory key, additional certificates back to the root attestation certificate will
|
||||
* also be provided. Clients will need to check root certificate against a known-good
|
||||
* value. The certificates must be DER-encoded. Caller needs to provide
|
||||
* CREATION_DATETIME as one of the attestation parameters, otherwise the attestation
|
||||
* certificate will not contain the creation datetime. The first certificate in the
|
||||
* vector is the attestation for the generated key itself, the next certificate is
|
||||
* the key that signs the first certificate, and so forth. The last certificate in
|
||||
* the chain is the root certificate. If the key is a symmetric key, then no
|
||||
* certificate will be returned and this variable will return empty. TODO: change
|
||||
* certificate return to a single certificate and make it nullable b/163604282.
|
||||
*/
|
||||
void generateKey(in KeyParameter[] keyParams, out ByteArray generatedKeyBlob,
|
||||
out KeyCharacteristics generatedKeyCharacteristics,
|
||||
out Certificate[] outCertChain);
|
||||
|
||||
/**
|
||||
* Imports key material into an IKeyMintDevice. Key definition parameters and return values
|
||||
* are the same as for generateKey, with the following exceptions:
|
||||
*
|
||||
* o Tag::KEY_SIZE is not necessary in the input parameters. If not provided, the
|
||||
* IKeyMintDevice must deduce the value from the provided key material and add the tag and
|
||||
* value to the key characteristics. If Tag::KEY_SIZE is provided, the IKeyMintDevice must
|
||||
* validate it against the key material. In the event of a mismatch, importKey must return
|
||||
* ErrorCode::IMPORT_PARAMETER_MISMATCH.
|
||||
*
|
||||
* o Tag::RSA_PUBLIC_EXPONENT (for RSA keys only) is not necessary in the input parameters. If
|
||||
* not provided, the IKeyMintDevice must deduce the value from the provided key material and
|
||||
* add the tag and value to the key characteristics. If Tag::RSA_PUBLIC_EXPONENT is provided,
|
||||
* the IKeyMintDevice must validate it against the key material. In the event of a
|
||||
* mismatch, importKey must return ErrorCode::IMPORT_PARAMETER_MISMATCH.
|
||||
*
|
||||
* o Tag::ORIGIN (returned in keyCharacteristics) must have the value KeyOrigin::IMPORTED.
|
||||
*
|
||||
* @param inKeyParams Key generation parameters are defined as KeyMintDevice tag/value pairs,
|
||||
* provided in params.
|
||||
*
|
||||
* @param inKeyFormat The format of the key material to import. See KeyFormat in
|
||||
* keyformat.aidl.
|
||||
*
|
||||
* @param inKeyData The key material to import, in the format specified in keyFormat.
|
||||
*
|
||||
* @return outImportedKeyBlob descriptor of the imported key. The format of the keyblob will
|
||||
* be the google specified keyblob format.
|
||||
*
|
||||
* @return outImportedKeyCharacteristics Description of the generated key. See the
|
||||
* keyCharacteristics description in generateKey.
|
||||
*
|
||||
* @return outCertChain If the key is an asymmetric key, and proper keyparameters for
|
||||
* attestation (such as challenge) is provided, then this parameter will return the
|
||||
* attestation certificate. If the signing of the attestation certificate is from a
|
||||
* factory key, additional certificates back to the root attestation certificate will
|
||||
* also be provided. Clients will need to check root certificate against a known-good
|
||||
* value. The certificates must be DER-encoded. Caller needs to provide
|
||||
* CREATION_DATETIME as one of the attestation parameters, otherwise the attestation
|
||||
* certificate will not contain the creation datetime. The first certificate in the
|
||||
* vector is the attestation for the generated key itself, the next certificate is
|
||||
* the key that signs the first certificate, and so forth. The last certificate in
|
||||
* the chain is the root certificate. If the key is a symmetric key, then no
|
||||
* certificate will be returned and this variable will return empty.
|
||||
*/
|
||||
void importKey(in KeyParameter[] inKeyParams, in KeyFormat inKeyFormat,
|
||||
in byte[] inKeyData, out ByteArray outImportedKeyBlob,
|
||||
out KeyCharacteristics outImportedKeyCharacteristics,
|
||||
out Certificate[] outCertChain);
|
||||
|
||||
/**
|
||||
* Securely imports a key, or key pair, returning a key blob and a description of the imported
|
||||
* key.
|
||||
*
|
||||
* @param inWrappedKeyData The wrapped key material to import.
|
||||
* TODO(seleneh) Decide if we want the wrapped key in DER-encoded ASN.1 format or CBOR
|
||||
* format or both. And specify the standarized format.
|
||||
*
|
||||
* KeyDescription ::= SEQUENCE(
|
||||
* keyFormat INTEGER, # Values from KeyFormat enum.
|
||||
* keyParams AuthorizationList,
|
||||
* )
|
||||
*
|
||||
* SecureKeyWrapper ::= SEQUENCE(
|
||||
* version INTEGER, # Contains value 0
|
||||
* encryptedTransportKey OCTET_STRING,
|
||||
* initializationVector OCTET_STRING,
|
||||
* keyDescription KeyDescription,
|
||||
* encryptedKey OCTET_STRING,
|
||||
* tag OCTET_STRING
|
||||
* )
|
||||
*
|
||||
* Where:
|
||||
*
|
||||
* o keyFormat is an integer from the KeyFormat enum, defining the format of the plaintext
|
||||
* key material.
|
||||
* o keyParams is the characteristics of the key to be imported (as with generateKey or
|
||||
* importKey). If the secure import is successful, these characteristics must be
|
||||
* associated with the key exactly as if the key material had been insecurely imported
|
||||
* with the IKeyMintDevice::importKey. See attestKey() for documentation of the
|
||||
* AuthorizationList schema.
|
||||
* o encryptedTransportKey is a 256-bit AES key, XORed with a masking key and then encrypted
|
||||
* with the wrapping key specified by wrappingKeyBlob.
|
||||
* o keyDescription is a KeyDescription, above.
|
||||
* o encryptedKey is the key material of the key to be imported, in format keyFormat, and
|
||||
* encrypted with encryptedEphemeralKey in AES-GCM mode, with the DER-encoded
|
||||
* representation of keyDescription provided as additional authenticated data.
|
||||
* o tag is the tag produced by the AES-GCM encryption of encryptedKey.
|
||||
*
|
||||
* So, importWrappedKey does the following:
|
||||
*
|
||||
* 1. Get the private key material for wrappingKeyBlob, verifying that the wrapping key has
|
||||
* purpose KEY_WRAP, padding mode RSA_OAEP, and digest SHA_2_256, returning the
|
||||
* error INCOMPATIBLE_PURPOSE, INCOMPATIBLE_PADDING_MODE, or INCOMPATIBLE_DIGEST if any
|
||||
* of those requirements fail.
|
||||
* 2. Extract the encryptedTransportKey field from the SecureKeyWrapper, and decrypt
|
||||
* it with the wrapping key.
|
||||
* 3. XOR the result of step 2 with maskingKey.
|
||||
* 4. Use the result of step 3 as an AES-GCM key to decrypt encryptedKey, using the encoded
|
||||
* value of keyDescription as the additional authenticated data. Call the result
|
||||
* "keyData" for the next step.
|
||||
* 5. Perform the equivalent of calling importKey(keyParams, keyFormat, keyData), except
|
||||
* that the origin tag should be set to SECURELY_IMPORTED.
|
||||
*
|
||||
* @param inWrappingKeyBlob The opaque key descriptor returned by generateKey() or importKey().
|
||||
* This key must have been created with Purpose::WRAP_KEY.
|
||||
*
|
||||
* @param inMaskingKey The 32-byte value XOR'd with the transport key in the SecureWrappedKey
|
||||
* structure.
|
||||
*
|
||||
* @param inUnwrappingParams must contain any parameters needed to perform the unwrapping
|
||||
* operation. For example, if the wrapping key is an AES key the block and padding
|
||||
* modes must be specified in this argument.
|
||||
*
|
||||
* @param inPasswordSid specifies the password secure ID (SID) of the user that owns the key
|
||||
* being installed. If the authorization list in wrappedKeyData contains a
|
||||
* Tag::USER_SECURE_IDwith a value that has the HardwareAuthenticatorType::PASSWORD
|
||||
* bit set, the constructed key must be bound to the SID value provided by this
|
||||
* argument. If the wrappedKeyData does not contain such a tag and value, this argument
|
||||
* must be ignored.
|
||||
*
|
||||
* @param inBiometricSid specifies the biometric secure ID (SID) of the user that owns the key
|
||||
* being installed. If the authorization list in wrappedKeyData contains a
|
||||
* Tag::USER_SECURE_ID with a value that has the HardwareAuthenticatorType::FINGERPRINT
|
||||
* bit set, the constructed key must be bound to the SID value provided by this argument.
|
||||
* If the wrappedKeyData does not contain such a tag and value, this argument must be
|
||||
* ignored.
|
||||
*
|
||||
* @return outImportedKeyBlob Opaque descriptor of the imported key. It is recommended that
|
||||
* the keyBlob contain a copy of the key material, wrapped in a key unavailable outside
|
||||
* secure hardware.
|
||||
*
|
||||
* @return outImportedKeyCharacteristics Description of the generated key. See the description
|
||||
* of keyCharacteristics parameter in generateKey.
|
||||
*/
|
||||
void importWrappedKey(in byte[] inWrappedKeyData,
|
||||
in byte[] inWrappingKeyBlob,
|
||||
in byte[] inMaskingKey,
|
||||
in KeyParameter[] inUnwrappingParams,
|
||||
in long inPasswordSid,
|
||||
in long inBiometricSid,
|
||||
out ByteArray outImportedKeyBlob,
|
||||
out KeyCharacteristics outImportedKeyCharacteristics);
|
||||
|
||||
/**
|
||||
* Upgrades an old key blob. Keys can become "old" in two ways: IKeyMintDevice can be
|
||||
* upgraded to a new version with an incompatible key blob format, or the system can be updated
|
||||
* to invalidate the OS version (OS_VERSION tag), system patch level (OS_PATCHLEVEL tag),
|
||||
* vendor patch level (VENDOR_PATCH_LEVEL tag), boot patch level (BOOT_PATCH_LEVEL tag) or
|
||||
* other, implementation-defined patch level (keyMint implementers are encouraged to extend
|
||||
* this HAL with a minor version extension to define validatable patch levels for other
|
||||
* images; tags must be defined in the implementer's namespace, starting at 10000). In either
|
||||
* case, attempts to use an old key blob with begin() must result in IKeyMintDevice returning
|
||||
* ErrorCode::KEY_REQUIRES_UPGRADE. The caller must use this method to upgrade the key blob.
|
||||
*
|
||||
* The upgradeKey method must examine each version or patch level associated with the key. If
|
||||
* any one of them is higher than the corresponding current device value upgradeKey() must
|
||||
* return ErrorCode::INVALID_ARGUMENT. There is one exception: it is always permissible to
|
||||
* "downgrade" from any OS_VERSION number to OS_VERSION 0. For example, if the key has
|
||||
* OS_VERSION 080001, it is permisible to upgrade the key if the current system version is
|
||||
* 080100, because the new version is larger, or if the current system version is 0, because
|
||||
* upgrades to 0 are always allowed. If the system version were 080000, however, keyMint must
|
||||
* return ErrorCode::INVALID_ARGUMENT because that value is smaller than 080001. Values other
|
||||
* than OS_VERSION must never be downgraded.
|
||||
*
|
||||
* Note that Keymaster versions 2 and 3 required that the system and boot images have the same
|
||||
* patch level and OS version. This requirement is relaxed for 4.0::IKeymasterDevice and
|
||||
* IKeyMintDevice, and the OS version in the boot image footer is no longer used.
|
||||
*
|
||||
* @param inKeyBlobToUpgrade The opaque descriptor returned by generateKey() or importKey();
|
||||
*
|
||||
* @param inUpgradeParams A parameter list containing any parameters needed to complete the
|
||||
* upgrade, including Tag::APPLICATION_ID and Tag::APPLICATION_DATA.
|
||||
*
|
||||
* @return A new key blob that references the same key as keyBlobToUpgrade, but is in the new
|
||||
* format, or has the new version data.
|
||||
*/
|
||||
byte[] upgradeKey(in byte[] inKeyBlobToUpgrade, in KeyParameter[] inUpgradeParams);
|
||||
|
||||
/**
|
||||
* Deletes the key, or key pair, associated with the key blob. Calling this function on
|
||||
* a key with Tag::ROLLBACK_RESISTANCE in its hardware-enforced authorization list must
|
||||
* render the key permanently unusable. Keys without Tag::ROLLBACK_RESISTANCE may or
|
||||
* may not be rendered unusable.
|
||||
*
|
||||
* @param inKeyBlob The opaque descriptor returned by generateKey() or importKey();
|
||||
*/
|
||||
void deleteKey(in byte[] inKeyBlob);
|
||||
|
||||
/**
|
||||
* Deletes all keys in the hardware keystore. Used when keystore is reset completely. After
|
||||
* this function is called all keys with Tag::ROLLBACK_RESISTANCE in their hardware-enforced
|
||||
* authorization lists must be rendered permanently unusable. Keys without
|
||||
* Tag::ROLLBACK_RESISTANCE may or may not be rendered unusable.
|
||||
*
|
||||
* @return error See the ErrorCode enum.
|
||||
*/
|
||||
void deleteAllKeys();
|
||||
|
||||
/**
|
||||
* Destroys knowledge of the device's ids. This prevents all device id attestation in the
|
||||
* future. The destruction must be permanent so that not even a factory reset will restore the
|
||||
* device ids.
|
||||
*
|
||||
* Device id attestation may be provided only if this method is fully implemented, allowing the
|
||||
* user to permanently disable device id attestation. If this cannot be guaranteed, the device
|
||||
* must never attest any device ids.
|
||||
*
|
||||
* This is a NOP if device id attestation is not supported.
|
||||
*/
|
||||
void destroyAttestationIds();
|
||||
|
||||
/**
|
||||
* Begins a cryptographic operation using the specified key. If all is well, begin() must
|
||||
* return ErrorCode::OK and create an operation handle which must be passed to subsequent calls
|
||||
* to update(), finish() or abort().
|
||||
*
|
||||
* It is critical that each call to begin() be paired with a subsequent call to finish() or
|
||||
* abort(), to allow the IKeyMintDevice implementation to clean up any internal operation
|
||||
* state. The caller's failure to do this may leak internal state space or other internal
|
||||
* resources and may eventually cause begin() to return ErrorCode::TOO_MANY_OPERATIONS when it
|
||||
* runs out of space for operations. Any result other than ErrorCode::OK from begin(), update()
|
||||
* or finish() implicitly aborts the operation, in which case abort() need not be called (and
|
||||
* must return ErrorCode::INVALID_OPERATION_HANDLE if called). IKeyMintDevice implementations
|
||||
* must support 32 concurrent operations.
|
||||
*
|
||||
* If Tag::APPLICATION_ID or Tag::APPLICATION_DATA were specified during key generation or
|
||||
* import, calls to begin must include those tags with the originally-specified values in the
|
||||
* inParams argument to this method. If not, begin() must return ErrorCode::INVALID_KEY_BLOB.
|
||||
*
|
||||
* == Authorization Enforcement ==
|
||||
*
|
||||
* The following key authorization parameters must be enforced by the IKeyMintDevice secure
|
||||
* environment if the tags were returned in the "hardwareEnforced" list in the
|
||||
* KeyCharacteristics. Public key operations, meaning KeyPurpose::ENCRYPT and
|
||||
* KeyPurpose::VERIFY must be allowed to succeed even if authorization requirements are not met.
|
||||
*
|
||||
* -- All Key Types --
|
||||
*
|
||||
* The tags in this section apply to all key types. See below for additional key type-specific
|
||||
* tags.
|
||||
*
|
||||
* o Tag::PURPOSE: The purpose specified in the begin() call must match one of the purposes in
|
||||
* the key authorizations. If the specified purpose does not match, begin() must return
|
||||
* ErrorCode::UNSUPPORTED_PURPOSE.
|
||||
*
|
||||
* o Tag::ACTIVE_DATETIME can only be enforced if a trusted UTC time source is available. If
|
||||
* the current date and time is prior to the tag value, begin() must return
|
||||
* ErrorCode::KEY_NOT_YET_VALID.
|
||||
*
|
||||
* o Tag::ORIGINATION_EXPIRE_DATETIME can only be enforced if a trusted UTC time source is
|
||||
* available. If the current date and time is later than the tag value and the purpose is
|
||||
* KeyPurpose::ENCRYPT or KeyPurpose::SIGN, begin() must return ErrorCode::KEY_EXPIRED.
|
||||
*
|
||||
* o Tag::USAGE_EXPIRE_DATETIME can only be enforced if a trusted UTC time source is
|
||||
* available. If the current date and time is later than the tag value and the purpose is
|
||||
* KeyPurpose::DECRYPT or KeyPurpose::VERIFY, begin() must return ErrorCode::KEY_EXPIRED.
|
||||
*
|
||||
* o Tag::MAX_USES_PER_BOOT must be compared against a secure counter that tracks the uses of
|
||||
* the key since boot time. If the count of previous uses exceeds the tag value, begin() must
|
||||
* return ErrorCode::KEY_MAX_OPS_EXCEEDED.
|
||||
*
|
||||
* o Tag::USER_SECURE_ID must be enforced by this method if and only if the key also has
|
||||
* Tag::AUTH_TIMEOUT (if it does not have Tag::AUTH_TIMEOUT, the Tag::USER_SECURE_ID
|
||||
* requirement must be enforced by update() and finish()). If the key has both, then this
|
||||
* method must receive a non-empty HardwareAuthToken in the authToken argument. For the auth
|
||||
* token to be valid, all of the following have to be true:
|
||||
*
|
||||
* o The HMAC field must validate correctly.
|
||||
*
|
||||
* o At least one of the Tag::USER_SECURE_ID values from the key must match at least one of
|
||||
* the secure ID values in the token.
|
||||
*
|
||||
* o The key must have a Tag::USER_AUTH_TYPE that matches the auth type in the token.
|
||||
*
|
||||
* o The timestamp in the auth token plus the value of the Tag::AUTH_TIMEOUT must be less than
|
||||
* the current secure timestamp (which is a monotonic timer counting milliseconds since
|
||||
* boot.)
|
||||
*
|
||||
* If any of these conditions are not met, begin() must return
|
||||
* ErrorCode::KEY_USER_NOT_AUTHENTICATED.
|
||||
*
|
||||
* o Tag::CALLER_NONCE allows the caller to specify a nonce or initialization vector (IV). If
|
||||
* the key doesn't have this tag, but the caller provided Tag::NONCE to this method,
|
||||
* ErrorCode::CALLER_NONCE_PROHIBITED must be returned.
|
||||
*
|
||||
* o Tag::BOOTLOADER_ONLY specifies that only the bootloader may use the key. If this method is
|
||||
* called with a bootloader-only key after the bootloader has finished executing, it must
|
||||
* return ErrorCode::INVALID_KEY_BLOB. The mechanism for notifying the IKeyMintDevice that
|
||||
* the bootloader has finished executing is implementation-defined.
|
||||
*
|
||||
* -- RSA Keys --
|
||||
*
|
||||
* All RSA key operations must specify exactly one padding mode in inParams. If unspecified or
|
||||
* specified more than once, the begin() must return ErrorCode::UNSUPPORTED_PADDING_MODE.
|
||||
*
|
||||
* RSA signing and verification operations need a digest, as do RSA encryption and decryption
|
||||
* operations with OAEP padding mode. For those cases, the caller must specify exactly one
|
||||
* digest in inParams. If unspecified or specified more than once, begin() must return
|
||||
* ErrorCode::UNSUPPORTED_DIGEST.
|
||||
*
|
||||
* Private key operations (KeyPurpose::DECRYPT and KeyPurpose::SIGN) need authorization of
|
||||
* digest and padding, which means that the key authorizations need to contain the specified
|
||||
* values. If not, begin() must return ErrorCode::INCOMPATIBLE_DIGEST or
|
||||
* ErrorCode::INCOMPATIBLE_PADDING, as appropriate. Public key operations (KeyPurpose::ENCRYPT
|
||||
* and KeyPurpose::VERIFY) are permitted with unauthorized digest or padding modes.
|
||||
*
|
||||
* With the exception of PaddingMode::NONE, all RSA padding modes are applicable only to certain
|
||||
* purposes. Specifically, PaddingMode::RSA_PKCS1_1_5_SIGN and PaddingMode::RSA_PSS only
|
||||
* support signing and verification, while PaddingMode::RSA_PKCS1_1_5_ENCRYPT and
|
||||
* PaddingMode::RSA_OAEP only support encryption and decryption. begin() must return
|
||||
* ErrorCode::UNSUPPORTED_PADDING_MODE if the specified mode does not support the specified
|
||||
* purpose.
|
||||
*
|
||||
* There are some important interactions between padding modes and digests:
|
||||
*
|
||||
* o PaddingMode::NONE indicates that a "raw" RSA operation is performed. If signing or
|
||||
* verifying, Digest::NONE is specified for the digest. No digest is necessary for unpadded
|
||||
* encryption or decryption.
|
||||
*
|
||||
* o PaddingMode::RSA_PKCS1_1_5_SIGN padding requires a digest. The digest may be Digest::NONE,
|
||||
* in which case the KeyMint implementation cannot build a proper PKCS#1 v1.5 signature
|
||||
* structure, because it cannot add the DigestInfo structure. Instead, the IKeyMintDevice
|
||||
* must construct 0x00 || 0x01 || PS || 0x00 || M, where M is the provided message and PS is a
|
||||
* random padding string at least eight bytes in length. The size of the RSA key has to be at
|
||||
* least 11 bytes larger than the message, otherwise begin() must return
|
||||
* ErrorCode::INVALID_INPUT_LENGTH.
|
||||
*
|
||||
* o PaddingMode::RSA_PKCS1_1_1_5_ENCRYPT padding does not require a digest.
|
||||
*
|
||||
* o PaddingMode::RSA_PSS padding requires a digest, which may not be Digest::NONE. If
|
||||
* Digest::NONE is specified, the begin() must return ErrorCode::INCOMPATIBLE_DIGEST. In
|
||||
* addition, the size of the RSA key must be at least 2 + D bytes larger than the output size
|
||||
* of the digest, where D is the size of the digest, in bytes. Otherwise begin() must
|
||||
* return ErrorCode::INCOMPATIBLE_DIGEST. The salt size must be D.
|
||||
*
|
||||
* o PaddingMode::RSA_OAEP padding requires a digest, which may not be Digest::NONE. If
|
||||
* Digest::NONE is specified, begin() must return ErrorCode::INCOMPATIBLE_DIGEST. The OAEP
|
||||
* mask generation function must be MGF1 and the MGF1 digest must be SHA1, regardless of the
|
||||
* OAEP digest specified.
|
||||
*
|
||||
* -- EC Keys --
|
||||
*
|
||||
* EC key operations must specify exactly one padding mode in inParams. If unspecified or
|
||||
* specified more than once, begin() must return ErrorCode::UNSUPPORTED_PADDING_MODE.
|
||||
*
|
||||
* Private key operations (KeyPurpose::SIGN) need authorization of digest and padding, which
|
||||
* means that the key authorizations must contain the specified values. If not, begin() must
|
||||
* return ErrorCode::INCOMPATIBLE_DIGEST. Public key operations (KeyPurpose::VERIFY) are
|
||||
* permitted with unauthorized digest or padding.
|
||||
*
|
||||
* -- AES Keys --
|
||||
*
|
||||
* AES key operations must specify exactly one block mode (Tag::BLOCK_MODE) and one padding mode
|
||||
* (Tag::PADDING) in inParams. If either value is unspecified or specified more than once,
|
||||
* begin() must return ErrorCode::UNSUPPORTED_BLOCK_MODE or
|
||||
* ErrorCode::UNSUPPORTED_PADDING_MODE. The specified modes must be authorized by the key,
|
||||
* otherwise begin() must return ErrorCode::INCOMPATIBLE_BLOCK_MODE or
|
||||
* ErrorCode::INCOMPATIBLE_PADDING_MODE.
|
||||
*
|
||||
* If the block mode is BlockMode::GCM, inParams must specify Tag::MAC_LENGTH, and the specified
|
||||
* value must be a multiple of 8 that is not greater than 128 or less than the value of
|
||||
* Tag::MIN_MAC_LENGTH in the key authorizations. For MAC lengths greater than 128 or
|
||||
* non-multiples of 8, begin() must return ErrorCode::UNSUPPORTED_MAC_LENGTH. For values less
|
||||
* than the key's minimum length, begin() must return ErrorCode::INVALID_MAC_LENGTH.
|
||||
*
|
||||
* If the block mode is BlockMode::GCM or BlockMode::CTR, the specified padding mode must be
|
||||
* PaddingMode::NONE. For BlockMode::ECB or BlockMode::CBC, the mode may be PaddingMode::NONE
|
||||
* or PaddingMode::PKCS7. If the padding mode doesn't meet these conditions, begin() must
|
||||
* return ErrorCode::INCOMPATIBLE_PADDING_MODE.
|
||||
*
|
||||
* If the block mode is BlockMode::CBC, BlockMode::CTR, or BlockMode::GCM, an initialization
|
||||
* vector or nonce is required. In most cases, callers shouldn't provide an IV or nonce and the
|
||||
* IKeyMintDevice implementation must generate a random IV or nonce and return it via
|
||||
* Tag::NONCE in outParams. CBC and CTR IVs are 16 bytes. GCM nonces are 12 bytes. If the key
|
||||
* authorizations contain Tag::CALLER_NONCE, then the caller may provide an IV/nonce with
|
||||
* Tag::NONCE in inParams. If a nonce is provided when Tag::CALLER_NONCE is not authorized,
|
||||
* begin() must return ErrorCode::CALLER_NONCE_PROHIBITED. If a nonce is not provided when
|
||||
* Tag::CALLER_NONCE is authorized, IKeyMintDevice msut generate a random IV/nonce.
|
||||
*
|
||||
* -- HMAC keys --
|
||||
*
|
||||
* HMAC key operations must specify Tag::MAC_LENGTH in inParams. The specified value must be a
|
||||
* multiple of 8 that is not greater than the digest length or less than the value of
|
||||
* Tag::MIN_MAC_LENGTH in the key authorizations. For MAC lengths greater than the digest
|
||||
* length or non-multiples of 8, begin() must return ErrorCode::UNSUPPORTED_MAC_LENGTH. For
|
||||
* values less than the key's minimum length, begin() must return ErrorCode::INVALID_MAC_LENGTH.
|
||||
*
|
||||
* @param inPurpose The purpose of the operation, one of KeyPurpose::ENCRYPT,
|
||||
* KeyPurpose::DECRYPT, KeyPurpose::SIGN or KeyPurpose::VERIFY. Note that for AEAD
|
||||
* modes, encryption and decryption imply signing and verification, respectively, but
|
||||
* must be specified as KeyPurpose::ENCRYPT and KeyPurpose::DECRYPT.
|
||||
*
|
||||
* @param inKeyBlob The opaque key descriptor returned by generateKey() or importKey(). The key
|
||||
* must have a purpose compatible with purpose and all of its usage requirements must be
|
||||
* satisfied, or begin() must return an appropriate error code (see above).
|
||||
*
|
||||
* @param inParams Additional parameters for the operation. If Tag::APPLICATION_ID or
|
||||
* Tag::APPLICATION_DATA were provided during generation, they must be provided here, or
|
||||
* the operation must fail with ErrorCode::INVALID_KEY_BLOB. For operations that require
|
||||
* a nonce or IV, on keys that were generated with Tag::CALLER_NONCE, inParams may
|
||||
* contain a tag Tag::NONCE. If Tag::NONCE is provided for a key without
|
||||
* Tag:CALLER_NONCE, ErrorCode::CALLER_NONCE_PROHIBITED must be returned.
|
||||
*
|
||||
* @param inAuthToken Authentication token. Callers that provide no token must set all numeric
|
||||
* fields to zero and the MAC must be an empty vector. TODO: make this field nullable.
|
||||
* b/173483024.
|
||||
*
|
||||
* @return BeginResult as output, which contains the challenge, KeyParameters which haves
|
||||
* additional data from the operation initialization, notably to return the IV or nonce
|
||||
* from operations that generate an IV or nonce, and IKeyMintOperation object pointer
|
||||
* which is used to perform update(), finish() or abort() operations.
|
||||
*/
|
||||
BeginResult begin(in KeyPurpose inPurpose,
|
||||
in byte[] inKeyBlob,
|
||||
in KeyParameter[] inParams,
|
||||
in HardwareAuthToken inAuthToken);
|
||||
}
|
||||
270
keymint/aidl/android/hardware/keymint/IKeyMintOperation.aidl
Normal file
270
keymint/aidl/android/hardware/keymint/IKeyMintOperation.aidl
Normal file
@@ -0,0 +1,270 @@
|
||||
/*
|
||||
* 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.keymint;
|
||||
|
||||
import android.hardware.keymint.ByteArray;
|
||||
import android.hardware.keymint.HardwareAuthToken;
|
||||
import android.hardware.keymint.KeyParameter;
|
||||
import android.hardware.keymint.KeyParameterArray;
|
||||
import android.hardware.keymint.VerificationToken;
|
||||
|
||||
@VintfStability
|
||||
interface IKeyMintOperation {
|
||||
/**
|
||||
* Provides data to, and possibly receives output from, an ongoing cryptographic operation begun
|
||||
* with begin().
|
||||
*
|
||||
* If operation is in an invalid state (was aborted or had an error) update() must return
|
||||
* ErrorCode::INVALID_OPERATION_HANDLE.
|
||||
*
|
||||
* To provide more flexibility for buffer handling, implementations of this method have the
|
||||
* option of consuming less data than was provided. The caller is responsible for looping to
|
||||
* feed the rest of the data in subsequent calls. The amount of input consumed must be returned
|
||||
* in the inputConsumed parameter. Implementations must always consume at least one byte,
|
||||
* unless the operation cannot accept any more; if more than zero bytes are provided and zero
|
||||
* bytes are consumed, callers must consider this an error and abort the operation.
|
||||
* TODO(seleneh) update the code to always consume alll the input data. b/168665179.
|
||||
*
|
||||
* Implementations may also choose how much data to return, as a result of the update. This is
|
||||
* only relevant for encryption and decryption operations, because signing and verification
|
||||
* return no data until finish. It is recommended to return data as early as possible, rather
|
||||
* than buffer it.
|
||||
*
|
||||
* If this method returns an error code other than ErrorCode::OK, the operation is aborted and
|
||||
* the operation handle must be invalidated. Any future use of the handle, with this method,
|
||||
* finish, or abort, must return ErrorCode::INVALID_OPERATION_HANDLE.
|
||||
*
|
||||
* == Authorization Enforcement ==
|
||||
*
|
||||
* Key authorization enforcement is performed primarily in begin(). The one exception is the
|
||||
* case where the key has:
|
||||
*
|
||||
* o One or more Tag::USER_SECURE_IDs, and
|
||||
*
|
||||
* o Does not have a Tag::AUTH_TIMEOUT
|
||||
*
|
||||
* In this case, the key requires an authorization per operation, and the update method must
|
||||
* receive a non-empty and valid HardwareAuthToken. For the auth token to be valid, all of the
|
||||
* following has to be true:
|
||||
*
|
||||
* o The HMAC field must validate correctly.
|
||||
*
|
||||
* o At least one of the Tag::USER_SECURE_ID values from the key must match at least one of
|
||||
* the secure ID values in the token.
|
||||
*
|
||||
* o The key must have a Tag::USER_AUTH_TYPE that matches the auth type in the token.
|
||||
*
|
||||
* o The challenge field in the auth token must contain the operationHandle
|
||||
*
|
||||
* If any of these conditions are not met, update() must return
|
||||
* ErrorCode::KEY_USER_NOT_AUTHENTICATED.
|
||||
*
|
||||
* The caller must provide the auth token on every call to update() and finish().
|
||||
*
|
||||
* -- RSA keys --
|
||||
*
|
||||
* For signing and verification operations with Digest::NONE, this method must accept the entire
|
||||
* block to be signed or verified in a single update. It may not consume only a portion of the
|
||||
* block in these cases. However, the caller may choose to provide the data in multiple
|
||||
* updates, and update() must accept the data this way as well. If the caller provides more
|
||||
* data to sign than can be used (length of data exceeds RSA key size), update() must return
|
||||
* ErrorCode::INVALID_INPUT_LENGTH.
|
||||
*
|
||||
* -- ECDSA keys --
|
||||
*
|
||||
* For signing and verification operations with Digest::NONE, this method must accept the entire
|
||||
* block to be signed or verified in a single update. This method may not consume only a
|
||||
* portion of the block. However, the caller may choose to provide the data in multiple updates
|
||||
* and update() must accept the data this way as well. If the caller provides more data to sign
|
||||
* than can be used, the data is silently truncated. (This differs from the handling of excess
|
||||
* data provided in similar RSA operations. The reason for this is compatibility with legacy
|
||||
* clients.)
|
||||
*
|
||||
* -- AES keys --
|
||||
*
|
||||
* AES GCM mode supports "associated authentication data," provided via the Tag::ASSOCIATED_DATA
|
||||
* tag in the inParams argument. The associated data may be provided in repeated calls
|
||||
* (important if the data is too large to send in a single block) but must always precede data
|
||||
* to be encrypted or decrypted. An update call may receive both associated data and data to
|
||||
* encrypt/decrypt, but subsequent updates must not include associated data. If the caller
|
||||
* provides associated data to an update call after a call that includes data to
|
||||
* encrypt/decrypt, update() must return ErrorCode::INVALID_TAG.
|
||||
*
|
||||
* For GCM encryption, the AEAD tag must be appended to the ciphertext by finish(). During
|
||||
* decryption, the last Tag::MAC_LENGTH bytes of the data provided to the last update call must
|
||||
* be the AEAD tag. Since a given invocation of update cannot know if it's the last invocation,
|
||||
* it must process all but the tag length and buffer the possible tag data for processing during
|
||||
* finish().
|
||||
*
|
||||
* TODO: update() needs to be refactored b/168665179.
|
||||
*
|
||||
* @param inParams Additional parameters for the operation. For AEAD modes, this is used to
|
||||
* specify Tag::ADDITIONAL_DATA. Note that additional data may be provided in multiple
|
||||
* calls to update(), but only until input data has been provided.
|
||||
*
|
||||
* @param input Data to be processed. Note that update() may or may not consume all of the data
|
||||
* provided. See return value.
|
||||
*
|
||||
* @param verificationToken Verification token, used to prove that another IKeymasterDevice HAL
|
||||
* has verified some parameters, and to deliver the other HAL's current timestamp, if
|
||||
* needed. If not provided, all fields must be initialized to zero and vectors must be
|
||||
* empty.
|
||||
*
|
||||
* @return error Returns ErrorCode encountered in keymint as service specific errors. See the
|
||||
* ErrorCode enum in ErrorCode.aidl.
|
||||
*
|
||||
* @return int Amount of data that was consumed by update(). If this is less than the
|
||||
* amount provided, the caller may provide the remainder in a subsequent call to
|
||||
* update() or finish(). Every call to update must consume at least one byte, unless
|
||||
* the input is empty, and implementations should consume as much data as reasonably
|
||||
* possible for each call.
|
||||
*
|
||||
* @return outParams returns the updated key parameters from the blob, if needed.
|
||||
* operation.
|
||||
*
|
||||
* @return out variable output The output data, if any.
|
||||
*/
|
||||
int update(in @nullable KeyParameterArray inParams,
|
||||
in @nullable byte[] input,
|
||||
in @nullable HardwareAuthToken inAuthToken,
|
||||
in @nullable VerificationToken inVerificationToken,
|
||||
out @nullable KeyParameterArray outParams,
|
||||
out @nullable ByteArray output);
|
||||
|
||||
/**
|
||||
* Finalizes a cryptographic operation begun with begin() and invalidates operation.
|
||||
*
|
||||
* This method is the last one called in an operation, so all processed data must be returned.
|
||||
*
|
||||
* Whether it completes successfully or returns an error, this method finalizes the operation.
|
||||
* Any future use of the operation, with finish(), update(), or abort(), must return
|
||||
* ErrorCode::INVALID_OPERATION_HANDLE.
|
||||
*
|
||||
* Signing operations return the signature as the output. Verification operations accept the
|
||||
* signature in the signature parameter, and return no output.
|
||||
*
|
||||
* == Authorization enforcement ==
|
||||
*
|
||||
* Key authorization enforcement is performed primarily in begin(). The exceptions are
|
||||
* authorization per operation keys and confirmation-required keys.
|
||||
*
|
||||
* Authorization per operation keys are the case where the key has one or more
|
||||
* Tag::USER_SECURE_IDs, and does not have a Tag::AUTH_TIMEOUT. In this case, the key requires
|
||||
* an authorization per operation, and the finish method must receive a non-empty and valid
|
||||
* authToken. For the auth token to be valid, all of the following has to be true:
|
||||
*
|
||||
* o The HMAC field must validate correctly.
|
||||
*
|
||||
* o At least one of the Tag::USER_SECURE_ID values from the key must match at least one of
|
||||
* the secure ID values in the token.
|
||||
*
|
||||
* o The key must have a Tag::USER_AUTH_TYPE that matches the auth type in the token.
|
||||
*
|
||||
* o The challenge field in the auth token must contain the operation challenge.
|
||||
*
|
||||
* If any of these conditions are not met, update() must return
|
||||
* ErrorCode::KEY_USER_NOT_AUTHENTICATED.
|
||||
*
|
||||
* The caller must provide the auth token on every call to update() and finish().
|
||||
*
|
||||
* Confirmation-required keys are keys that were generated with
|
||||
* Tag::TRUSTED_CONFIRMATION_REQUIRED. For these keys, when doing a signing operation the
|
||||
* caller must pass a KeyParameter Tag::CONFIRMATION_TOKEN to finish(). Implementations must
|
||||
* check the confirmation token by computing the 32-byte HMAC-SHA256 over all of the
|
||||
* to-be-signed data, prefixed with the 18-byte UTF-8 encoded string "confirmation token". If
|
||||
* the computed value does not match the Tag::CONFIRMATION_TOKEN parameter, finish() must not
|
||||
* produce a signature and must return ErrorCode::NO_USER_CONFIRMATION.
|
||||
*
|
||||
* -- RSA keys --
|
||||
*
|
||||
* Some additional requirements, depending on the padding mode:
|
||||
*
|
||||
* o PaddingMode::NONE. For unpadded signing and encryption operations, if the provided data is
|
||||
* shorter than the key, the data must be zero-padded on the left before
|
||||
* signing/encryption. If the data is the same length as the key, but numerically larger,
|
||||
* finish() must return ErrorCode::INVALID_ARGUMENT. For verification and decryption
|
||||
* operations, the data must be exactly as long as the key. Otherwise, return
|
||||
* ErrorCode::INVALID_INPUT_LENGTH.
|
||||
*
|
||||
* o PaddingMode::RSA_PSS. For PSS-padded signature operations, the PSS salt length must match
|
||||
* the size of the PSS digest selected. The digest specified with Tag::DIGEST in inputParams
|
||||
* on begin() must be used as the PSS digest algorithm, MGF1 must be used as the mask
|
||||
* generation function and SHA1 must be used as the MGF1 digest algorithm.
|
||||
*
|
||||
* o PaddingMode::RSA_OAEP. The digest specified with Tag::DIGEST in inputParams on begin is
|
||||
* used as the OAEP digest algorithm, MGF1 must be used as the mask generation function and
|
||||
* and SHA1 must be used as the MGF1 digest algorithm.
|
||||
*
|
||||
* -- ECDSA keys --
|
||||
*
|
||||
* If the data provided for unpadded signing or verification is too long, truncate it.
|
||||
*
|
||||
* -- AES keys --
|
||||
*
|
||||
* Some additional conditions, depending on block mode:
|
||||
*
|
||||
* o BlockMode::ECB or BlockMode::CBC. If padding is PaddingMode::NONE and the data length is
|
||||
* not a multiple of the AES block size, finish() must return
|
||||
* ErrorCode::INVALID_INPUT_LENGTH. If padding is PaddingMode::PKCS7, pad the data per the
|
||||
* PKCS#7 specification, including adding an additional padding block if the data is a multiple
|
||||
* of the block length.
|
||||
*
|
||||
* o BlockMode::GCM. During encryption, after processing all plaintext, compute the tag
|
||||
* (Tag::MAC_LENGTH bytes) and append it to the returned ciphertext. During decryption,
|
||||
* process the last Tag::MAC_LENGTH bytes as the tag. If tag verification fails, finish()
|
||||
* must return ErrorCode::VERIFICATION_FAILED.
|
||||
*
|
||||
* TODO: update() will need to be refactored into 2 function. b/168665179.
|
||||
*
|
||||
* @param inParams Additional parameters for the operation. For AEAD modes, this is used to
|
||||
* specify Tag::ADDITIONAL_DATA, but only if no input data was provided to update().
|
||||
*
|
||||
* @param input Data to be processed, per the parameters established in the call to begin().
|
||||
* finish() must consume all provided data or return ErrorCode::INVALID_INPUT_LENGTH.
|
||||
*
|
||||
* @param signature The signature to be verified if the purpose specified in the begin() call
|
||||
* was KeyPurpose::VERIFY.
|
||||
*
|
||||
* @param authToken Authentication token. Can be nullable if not provided.
|
||||
*
|
||||
* @param verificationToken Verification token, used to prove that another IKeyMintDevice HAL
|
||||
* has verified some parameters, and to deliver the other HAL's current timestamp, if
|
||||
* needed. Can be nullable if not needed.
|
||||
*
|
||||
* @return outParams Any output parameters generated by finish().
|
||||
*
|
||||
* @return The output data, if any.
|
||||
*/
|
||||
byte[] finish(in @nullable KeyParameterArray inParams, in @nullable byte[] input,
|
||||
in @nullable byte[] inSignature,
|
||||
in @nullable HardwareAuthToken authToken,
|
||||
in @nullable VerificationToken inVerificationToken,
|
||||
out @nullable KeyParameterArray outParams);
|
||||
|
||||
/**
|
||||
* Aborts a cryptographic operation begun with begin(), freeing all internal resources. If an
|
||||
* operation was finalized, calling update, finish, or abort yields
|
||||
* ErrorCode::INVALID_OPERATION_HANDLE. An operation is finalized if finish or abort was
|
||||
* called on it, or if update returned an ErrorCode.
|
||||
*
|
||||
* @param operationHandle The operation handle returned by begin(). This handle must be
|
||||
* invalid when abort() returns.
|
||||
*
|
||||
* @return error See the ErrorCode enum in ErrorCode.aidl.
|
||||
*/
|
||||
void abort();
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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.keymint;
|
||||
|
||||
import android.hardware.keymint.KeyParameter;
|
||||
|
||||
/**
|
||||
* KeyCharacteristics defines the attributes of a key, including cryptographic parameters, and usage
|
||||
* restrictions. It consits of two vectors of KeyParameters, one for "softwareEnforced" attributes
|
||||
* and one for "hardwareEnforced" attributes.
|
||||
*
|
||||
* KeyCharacteristics objects are returned by generateKey, importKey, importWrappedKey and
|
||||
* getKeyCharacteristics. The IKeyMintDevice secure environment is responsible for allocating the
|
||||
* parameters, all of which are Tags with associated values, to the correct vector. The
|
||||
* hardwareEnforced vector must contain only those attributes which are enforced by secure hardware.
|
||||
* All others should be in the softwareEnforced vector. See the definitions of individual Tag enums
|
||||
* for specification of which must be hardware-enforced, which may be software-enforced and which
|
||||
* must never appear in KeyCharacteristics.
|
||||
*/
|
||||
@VintfStability
|
||||
parcelable KeyCharacteristics {
|
||||
/* TODO(seleneh) get rid of the software enforced in keymint. replace hardware enforced with
|
||||
* tee enforced and strongbox enforced.
|
||||
*/
|
||||
KeyParameter[] softwareEnforced;
|
||||
KeyParameter[] hardwareEnforced;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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.keymint;
|
||||
|
||||
/**
|
||||
* Key derivation functions, mostly used in ECIES.
|
||||
*/
|
||||
@VintfStability
|
||||
@Backing(type="int")
|
||||
enum KeyDerivationFunction {
|
||||
/** Do not apply a key derivation function; use the raw agreed key */
|
||||
NONE = 0,
|
||||
/** HKDF defined in RFC 5869 with SHA256 */
|
||||
RFC5869_SHA256 = 1,
|
||||
/** KDF1 defined in ISO 18033-2 with SHA1 */
|
||||
ISO18033_2_KDF1_SHA1 = 2,
|
||||
/** KDF1 defined in ISO 18033-2 with SHA256 */
|
||||
ISO18033_2_KDF1_SHA256 = 3,
|
||||
/** KDF2 defined in ISO 18033-2 with SHA1 */
|
||||
ISO18033_2_KDF2_SHA1 = 4,
|
||||
/** KDF2 defined in ISO 18033-2 with SHA256 */
|
||||
ISO18033_2_KDF2_SHA256 = 5,
|
||||
}
|
||||
32
keymint/aidl/android/hardware/keymint/KeyFormat.aidl
Normal file
32
keymint/aidl/android/hardware/keymint/KeyFormat.aidl
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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.keymint;
|
||||
|
||||
|
||||
/**
|
||||
* Formats for key import and export.
|
||||
*/
|
||||
@VintfStability
|
||||
@Backing(type="int")
|
||||
enum KeyFormat {
|
||||
/** X.509 certificate format, for public key export. */
|
||||
X509 = 0,
|
||||
/** PCKS#8 format, asymmetric key pair import. */
|
||||
PKCS8 = 1,
|
||||
/** Raw bytes, for symmetric key import. */
|
||||
RAW = 3,
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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.keymint;
|
||||
|
||||
import android.hardware.keymint.SecurityLevel;
|
||||
|
||||
|
||||
/**
|
||||
* KeyMintHardwareInfo is the hardware information returned by calling KeyMint getHardwareInfo()
|
||||
*/
|
||||
|
||||
@VintfStability
|
||||
parcelable KeyMintHardwareInfo {
|
||||
/**
|
||||
* Implementation version of the keymint hardware. The version number is implementation
|
||||
* defined, and not necessarily globally meaningful. The version is used to distinguish
|
||||
* between different versions of a given implementation.
|
||||
* TODO(seleneh) add the version related info to the code.
|
||||
*/
|
||||
int versionNumber;
|
||||
|
||||
/* securityLevel is the security level of the IKeyMintDevice implementation accessed
|
||||
* through this aidl package. */
|
||||
SecurityLevel securityLevel;
|
||||
|
||||
/* keyMintName is the name of the IKeyMintDevice implementation. */
|
||||
@utf8InCpp String keyMintName;
|
||||
|
||||
/* keyMintAuthorName is the name of the author of the IKeyMintDevice implementation
|
||||
* (organization name, not individual). This name is implementation defined,
|
||||
* so it can be used to distinguish between different implementations from the
|
||||
* same author.
|
||||
*/
|
||||
@utf8InCpp String keyMintAuthorName;
|
||||
}
|
||||
46
keymint/aidl/android/hardware/keymint/KeyOrigin.aidl
Normal file
46
keymint/aidl/android/hardware/keymint/KeyOrigin.aidl
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.keymint;
|
||||
|
||||
|
||||
/**
|
||||
* The origin of a key (or pair), i.e. where it was generated. Note that ORIGIN can be found in
|
||||
* either the hardware-enforced or software-enforced list for a key, indicating whether the key is
|
||||
* hardware or software-based. Specifically, a key with GENERATED in the hardware-enforced list
|
||||
* must be guaranteed never to have existed outide the secure hardware.
|
||||
*/
|
||||
@VintfStability
|
||||
@Backing(type="int")
|
||||
enum KeyOrigin {
|
||||
/** Generated in keyMint. Should not exist outside the TEE. */
|
||||
GENERATED = 0,
|
||||
|
||||
/** Derived inside keyMint. Likely exists off-device. */
|
||||
DERIVED = 1,
|
||||
|
||||
/** Imported into keyMint. Existed as cleartext in Android. */
|
||||
IMPORTED = 2,
|
||||
|
||||
/** Previously used for another purpose that is now obsolete. */
|
||||
RESERVED = 3,
|
||||
|
||||
/**
|
||||
* Securely imported into KeyMint. Was created elsewhere, and passed securely through Android
|
||||
* to secure hardware.
|
||||
*/
|
||||
SECURELY_IMPORTED = 4,
|
||||
}
|
||||
56
keymint/aidl/android/hardware/keymint/KeyParameter.aidl
Normal file
56
keymint/aidl/android/hardware/keymint/KeyParameter.aidl
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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.keymint;
|
||||
|
||||
|
||||
import android.hardware.keymint.Algorithm;
|
||||
import android.hardware.keymint.BlockMode;
|
||||
import android.hardware.keymint.Digest;
|
||||
import android.hardware.keymint.EcCurve;
|
||||
import android.hardware.keymint.HardwareAuthenticatorType;
|
||||
import android.hardware.keymint.KeyDerivationFunction;
|
||||
import android.hardware.keymint.KeyOrigin;
|
||||
import android.hardware.keymint.KeyPurpose;
|
||||
import android.hardware.keymint.PaddingMode;
|
||||
import android.hardware.keymint.SecurityLevel;
|
||||
import android.hardware.keymint.Tag;
|
||||
|
||||
|
||||
/**
|
||||
* Identifies the key authorization parameters to be used with keyMint. This is usually
|
||||
* provided as an array of KeyParameters to IKeyMintDevice or Operation.
|
||||
*
|
||||
* TODO(seleneh): Union was not supported in aidl when this cl is first drafted. So we just had
|
||||
* the Tags, and bool, int, long, int[], and we will cast to the appropate types base on the
|
||||
* Tag value. We need to update this defination to distingish Algorithm, BlockMode,
|
||||
* PaddingMode, KeyOrigin...etc later, as union support is recently added to aidl.
|
||||
* b/173253030
|
||||
*/
|
||||
@VintfStability
|
||||
parcelable KeyParameter {
|
||||
/**
|
||||
* Identify what type of key parameter this parcelable actually holds, and based on the type
|
||||
* of tag is int, long, bool, or byte[], one of the fields below will be referenced.
|
||||
*/
|
||||
Tag tag;
|
||||
|
||||
boolean boolValue;
|
||||
int integer;
|
||||
long longInteger;
|
||||
// TODO: change this to nullable.
|
||||
byte[] blob;
|
||||
}
|
||||
31
keymint/aidl/android/hardware/keymint/KeyParameterArray.aidl
Normal file
31
keymint/aidl/android/hardware/keymint/KeyParameterArray.aidl
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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.keymint;
|
||||
|
||||
import android.hardware.keymint.KeyParameter;
|
||||
|
||||
/**
|
||||
* Identifies the key authorization parameters to be used with keyMint. This is usually
|
||||
* provided as an array of KeyParameters to IKeyMintDevice or Operation.
|
||||
*/
|
||||
@VintfStability
|
||||
parcelable KeyParameterArray {
|
||||
/**
|
||||
* Identify list of key parameters corresponding to a particular key blob.
|
||||
*/
|
||||
KeyParameter[] params;
|
||||
}
|
||||
43
keymint/aidl/android/hardware/keymint/KeyPurpose.aidl
Normal file
43
keymint/aidl/android/hardware/keymint/KeyPurpose.aidl
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.keymint;
|
||||
|
||||
|
||||
/**
|
||||
* Possible purposes of a key (or pair).
|
||||
*/
|
||||
@VintfStability
|
||||
@Backing(type = "int")
|
||||
enum KeyPurpose {
|
||||
/* Usable with RSA, EC and AES keys. */
|
||||
ENCRYPT = 0,
|
||||
|
||||
/* Usable with RSA, EC and AES keys. */
|
||||
DECRYPT = 1,
|
||||
|
||||
/* Usable with RSA, EC and HMAC keys. */
|
||||
SIGN = 2,
|
||||
|
||||
/* Usable with RSA, EC and HMAC keys. */
|
||||
VERIFY = 3,
|
||||
|
||||
/* 4 is reserved */
|
||||
/* Usable with wrapping keys. */
|
||||
WRAP_KEY = 5,
|
||||
|
||||
/* TODO(seleneh) add AGREE_KEY and ATTEST_KEY and their corresponding codes and tests later*/
|
||||
}
|
||||
36
keymint/aidl/android/hardware/keymint/PaddingMode.aidl
Normal file
36
keymint/aidl/android/hardware/keymint/PaddingMode.aidl
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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.keymint;
|
||||
|
||||
/**
|
||||
* TODO(seleneh) update the description.
|
||||
*
|
||||
* Padding modes that may be applied to plaintext for encryption operations. This list includes
|
||||
* padding modes for both symmetric and asymmetric algorithms. Note that implementations should not
|
||||
* provide all possible combinations of algorithm and padding, only the
|
||||
* cryptographically-appropriate pairs.
|
||||
*/
|
||||
@VintfStability
|
||||
@Backing(type="int")
|
||||
enum PaddingMode {
|
||||
NONE = 1, /* deprecated */
|
||||
RSA_OAEP = 2,
|
||||
RSA_PSS = 3,
|
||||
RSA_PKCS1_1_5_ENCRYPT = 4,
|
||||
RSA_PKCS1_1_5_SIGN = 5,
|
||||
PKCS7 = 64,
|
||||
}
|
||||
32
keymint/aidl/android/hardware/keymint/SecurityLevel.aidl
Normal file
32
keymint/aidl/android/hardware/keymint/SecurityLevel.aidl
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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.keymint;
|
||||
|
||||
/**
|
||||
* Device security levels.
|
||||
*/
|
||||
@VintfStability
|
||||
@Backing(type="int")
|
||||
enum SecurityLevel {
|
||||
SOFTWARE = 0,
|
||||
TRUSTED_ENVIRONMENT = 1,
|
||||
/**
|
||||
* STRONGBOX specifies that the secure hardware satisfies the requirements specified in CDD
|
||||
* 9.11.2.
|
||||
*/
|
||||
STRONGBOX = 2,
|
||||
}
|
||||
892
keymint/aidl/android/hardware/keymint/Tag.aidl
Normal file
892
keymint/aidl/android/hardware/keymint/Tag.aidl
Normal file
@@ -0,0 +1,892 @@
|
||||
/*
|
||||
* 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.keymint;
|
||||
|
||||
import android.hardware.keymint.TagType;
|
||||
|
||||
// TODO(seleneh) : note aidl currently does not support double nested enum definitions such as
|
||||
// ROOT_OF_TRUST = TagType:BYTES | 704. So we are forced to write definations as
|
||||
// ROOT_OF_TRUST = (9 << 28) for now. Will need to flip this back later when aidl support is added.
|
||||
|
||||
/**
|
||||
* Tag specifies various kinds of tags that can be set in KeyParameter to identify what kind of
|
||||
* data are stored in KeyParameter.
|
||||
*/
|
||||
@VintfStability
|
||||
@Backing(type = "int")
|
||||
enum Tag {
|
||||
/**
|
||||
* Tag::INVALID should never be set. It means you hit an error.
|
||||
*/
|
||||
INVALID = (0 << 28) | 0,
|
||||
|
||||
/**
|
||||
* Tag::PURPOSE specifies the set of purposes for which the key may be used. Possible values
|
||||
* are defined in the KeyPurpose enumeration.
|
||||
*
|
||||
* This tag is repeatable; keys may be generated with multiple values, although an operation has
|
||||
* a single purpose. When begin() is called to start an operation, the purpose of the operation
|
||||
* is specified. If the purpose specified for the operation is not authorized by the key (the
|
||||
* key didn't have a corresponding Tag::PURPOSE provided during generation/import), the
|
||||
* operation must fail with ErrorCode::INCOMPATIBLE_PURPOSE.
|
||||
*
|
||||
* Must be hardware-enforced.
|
||||
*/
|
||||
PURPOSE = (2 << 28) | 1, /* TagType:ENUM_REP */
|
||||
|
||||
/**
|
||||
* Tag::ALGORITHM specifies the cryptographic algorithm with which the key is used. This tag
|
||||
* must be provided to generateKey and importKey, and must be specified in the wrapped key
|
||||
* provided to importWrappedKey.
|
||||
*
|
||||
* Must be hardware-enforced.
|
||||
*/
|
||||
ALGORITHM = (1 << 28) | 2, /* TagType:ENUM */
|
||||
|
||||
/**
|
||||
* Tag::KEY_SIZE pecifies the size, in bits, of the key, measuring in the normal way for the
|
||||
* key's algorithm. For example, for RSA keys, Tag::KEY_SIZE specifies the size of the public
|
||||
* modulus. For AES keys it specifies the length of the secret key material. For 3DES keys it
|
||||
* specifies the length of the key material, not counting parity bits (though parity bits must
|
||||
* be provided for import, etc.). Since only three-key 3DES keys are supported, 3DES
|
||||
* Tag::KEY_SIZE must be 168.
|
||||
*
|
||||
* Must be hardware-enforced.
|
||||
*/
|
||||
KEY_SIZE = (3 << 28) | 3, /* TagType:UINT */
|
||||
|
||||
/**
|
||||
* Tag::BLOCK_MODE specifies the block cipher mode(s) with which the key may be used. This tag
|
||||
* is only relevant to AES and 3DES keys. Possible values are defined by the BlockMode enum.
|
||||
*
|
||||
* This tag is repeatable for key generation/import. For AES and 3DES operations the caller
|
||||
* must specify a Tag::BLOCK_MODE in the additionalParams argument of begin(). If the mode is
|
||||
* missing or the specified mode is not in the modes specified for the key during
|
||||
* generation/import, the operation must fail with ErrorCode::INCOMPATIBLE_BLOCK_MODE.
|
||||
*
|
||||
* Must be hardware-enforced.
|
||||
*/
|
||||
BLOCK_MODE = (2 << 28) | 4,
|
||||
/* BlockMode. */ /* TagType:ENUM_REP */
|
||||
|
||||
/**
|
||||
* Tag::DIGEST specifies the digest algorithms that may be used with the key to perform signing
|
||||
* and verification operations. This tag is relevant to RSA, ECDSA and HMAC keys. Possible
|
||||
* values are defined by the Digest enum.
|
||||
*
|
||||
* This tag is repeatable for key generation/import. For signing and verification operations,
|
||||
* the caller must specify a digest in the additionalParams argument of begin(). If the digest
|
||||
* is missing or the specified digest is not in the digests associated with the key, the
|
||||
* operation must fail with ErrorCode::INCOMPATIBLE_DIGEST.
|
||||
*
|
||||
* Must be hardware-enforced.
|
||||
*/
|
||||
DIGEST = (2 << 28) | 5, /* TagType:ENUM_REP */
|
||||
|
||||
/**
|
||||
* Tag::PADDING specifies the padding modes that may be used with the key. This tag is relevant
|
||||
* to RSA, AES and 3DES keys. Possible values are defined by the PaddingMode enum.
|
||||
*
|
||||
* PaddingMode::RSA_OAEP and PaddingMode::RSA_PKCS1_1_5_ENCRYPT are used only for RSA
|
||||
* encryption/decryption keys and specify RSA OAEP padding and RSA PKCS#1 v1.5 randomized
|
||||
* padding, respectively. PaddingMode::RSA_PSS and PaddingMode::RSA_PKCS1_1_5_SIGN are used
|
||||
* only for RSA signing/verification keys and specify RSA PSS padding and RSA PKCS#1 v1.5
|
||||
* deterministic padding, respectively.
|
||||
*
|
||||
* PaddingMode::NONE may be used with either RSA, AES or 3DES keys. For AES or 3DES keys, if
|
||||
* PaddingMode::NONE is used with block mode ECB or CBC and the data to be encrypted or
|
||||
* decrypted is not a multiple of the AES block size in length, the call to finish() must fail
|
||||
* with ErrorCode::INVALID_INPUT_LENGTH.
|
||||
*
|
||||
* PaddingMode::PKCS7 may only be used with AES and 3DES keys, and only with ECB and CBC modes.
|
||||
*
|
||||
* In any case, if the caller specifies a padding mode that is not usable with the key's
|
||||
* algorithm, the generation or import method must return ErrorCode::INCOMPATIBLE_PADDING_MODE.
|
||||
*
|
||||
* This tag is repeatable. A padding mode must be specified in the call to begin(). If the
|
||||
* specified mode is not authorized for the key, the operation must fail with
|
||||
* ErrorCode::INCOMPATIBLE_BLOCK_MODE.
|
||||
*
|
||||
* Must be hardware-enforced.
|
||||
*/
|
||||
PADDING = (2 << 28) | 6, /* TagType:ENUM_REP */
|
||||
|
||||
/**
|
||||
* Tag::CALLER_NONCE specifies that the caller can provide a nonce for nonce-requiring
|
||||
* operations. This tag is boolean, so the possible values are true (if the tag is present) and
|
||||
* false (if the tag is not present).
|
||||
*
|
||||
* This tag is used only for AES and 3DES keys, and is only relevant for CBC, CTR and GCM block
|
||||
* modes. If the tag is not present in a key's authorization list, implementations must reject
|
||||
* any operation that provides Tag::NONCE to begin() with ErrorCode::CALLER_NONCE_PROHIBITED.
|
||||
*
|
||||
* Must be hardware-enforced.
|
||||
*/
|
||||
CALLER_NONCE = (7 << 28) | 7, /* TagType:BOOL */
|
||||
|
||||
/**
|
||||
* Tag::MIN_MAC_LENGTH specifies the minimum length of MAC that can be requested or verified
|
||||
* with this key for HMAC keys and AES keys that support GCM mode.
|
||||
*
|
||||
* This value is the minimum MAC length, in bits. It must be a multiple of 8 bits. For HMAC
|
||||
* keys, the value must be least 64 and no more than 512. For GCM keys, the value must be at
|
||||
* least 96 and no more than 128. If the provided value violates these requirements,
|
||||
* generateKey() or importKey() must return ErrorCode::UNSUPPORTED_KEY_SIZE.
|
||||
*
|
||||
* Must be hardware-enforced.
|
||||
*/
|
||||
MIN_MAC_LENGTH = (3 << 28) | 8, /* TagType:UINT */
|
||||
|
||||
// Tag 9 reserved
|
||||
|
||||
/**
|
||||
* Tag::EC_CURVE specifies the elliptic curve. EC key generation requests may have
|
||||
* Tag:EC_CURVE, Tag::KEY_SIZE, or both. If both are provided and the size and curve do not
|
||||
* match, IKeyMintDevice must return ErrorCode::INVALID_ARGUMENT.
|
||||
*
|
||||
* Must be hardware-enforced.
|
||||
*/
|
||||
EC_CURVE = (1 << 28) | 10, /* TagType:ENUM */
|
||||
|
||||
/**
|
||||
* Tag::RSA_PUBLIC_EXPONENT specifies the value of the public exponent for an RSA key pair.
|
||||
* This tag is relevant only to RSA keys, and is required for all RSA keys.
|
||||
*
|
||||
* The value is a 64-bit unsigned integer that satisfies the requirements of an RSA public
|
||||
* exponent. This value must be a prime number. IKeyMintDevice implementations must support
|
||||
* the value 2^16+1 and may support other reasonable values. If no exponent is specified or if
|
||||
* the specified exponent is not supported, key generation must fail with
|
||||
* ErrorCode::INVALID_ARGUMENT.
|
||||
*
|
||||
* Must be hardware-enforced.
|
||||
*/
|
||||
RSA_PUBLIC_EXPONENT = (5 << 28) | 200, /* TagType:ULONG */
|
||||
|
||||
// Tag 201 reserved
|
||||
|
||||
/**
|
||||
* Tag::INCLUDE_UNIQUE_ID is specified during key generation to indicate that an attestation
|
||||
* certificate for the generated key should contain an application-scoped and time-bounded
|
||||
* device-unique ID. See Tag::UNIQUE_ID.
|
||||
*
|
||||
* Must be hardware-enforced.
|
||||
*/
|
||||
INCLUDE_UNIQUE_ID = (7 << 28) | 202, /* TagType:BOOL */
|
||||
|
||||
/**
|
||||
* TODO(seleneh) this tag needs to be deleted from all codes.
|
||||
*
|
||||
* Tag::BLOB_USAGE_REQUIREMENTS specifies the necessary system environment conditions for the
|
||||
* generated key to be used. Possible values are defined by the KeyBlobUsageRequirements enum.
|
||||
*
|
||||
* This tag is specified by the caller during key generation or import to require that the key
|
||||
* is usable in the specified condition. If the caller specifies Tag::BLOB_USAGE_REQUIREMENTS
|
||||
* with value KeyBlobUsageRequirements::STANDALONE the IKeyMintDevice must return a key blob
|
||||
* that can be used without file system support. This is critical for devices with encrypted
|
||||
* disks, where the file system may not be available until after a KeyMint key is used to
|
||||
* decrypt the disk.
|
||||
*
|
||||
* Must be hardware-enforced.
|
||||
*/
|
||||
BLOB_USAGE_REQUIREMENTS = (1 << 28) | 301, /* TagType:ENUM */
|
||||
|
||||
/**
|
||||
* Tag::BOOTLOADER_ONLY specifies only the bootloader can use the key.
|
||||
*
|
||||
* Any attempt to use a key with Tag::BOOTLOADER_ONLY from the Android system must fail with
|
||||
* ErrorCode::INVALID_KEY_BLOB.
|
||||
*
|
||||
* Must be hardware-enforced.
|
||||
*/
|
||||
BOOTLOADER_ONLY = (7 << 28) | 302, /* TagType:BOOL */
|
||||
|
||||
/**
|
||||
* Tag::ROLLBACK_RESISTANCE specifies that the key has rollback resistance, meaning that when
|
||||
* deleted with deleteKey() or deleteAllKeys(), the key is guaranteed to be permanently deleted
|
||||
* and unusable. It's possible that keys without this tag could be deleted and then restored
|
||||
* from backup.
|
||||
*
|
||||
* This tag is specified by the caller during key generation or import to require. If the
|
||||
* IKeyMintDevice cannot guarantee rollback resistance for the specified key, it must return
|
||||
* ErrorCode::ROLLBACK_RESISTANCE_UNAVAILABLE. IKeyMintDevice implementations are not
|
||||
* required to support rollback resistance.
|
||||
*
|
||||
* Must be hardwared-enforced.
|
||||
*/
|
||||
ROLLBACK_RESISTANCE = (7 << 28) | 303, /* TagType:BOOL */
|
||||
|
||||
// Reserved for future use.
|
||||
HARDWARE_TYPE = (1 << 28) | 304, /* TagType:ENUM */
|
||||
|
||||
/**
|
||||
* Keys tagged with EARLY_BOOT_ONLY may only be used, or created, during early boot, until
|
||||
* IKeyMintDevice::earlyBootEnded() is called.
|
||||
*/
|
||||
EARLY_BOOT_ONLY = (7 << 28) | 305, /* TagType:BOOL */
|
||||
|
||||
/**
|
||||
* Tag::ACTIVE_DATETIME specifies the date and time at which the key becomes active, in
|
||||
* milliseconds since Jan 1, 1970. If a key with this tag is used prior to the specified date
|
||||
* and time, IKeyMintDevice::begin() must return ErrorCode::KEY_NOT_YET_VALID;
|
||||
*
|
||||
* Need not be hardware-enforced.
|
||||
*/
|
||||
ACTIVE_DATETIME = (6 << 28) | 400,
|
||||
/* Start of validity. */ /* TagType:DATE */
|
||||
|
||||
/**
|
||||
* Tag::ORIGINATION_EXPIRE_DATETIME specifies the date and time at which the key expires for
|
||||
* signing and encryption purposes. After this time, any attempt to use a key with
|
||||
* KeyPurpose::SIGN or KeyPurpose::ENCRYPT provided to begin() must fail with
|
||||
* ErrorCode::KEY_EXPIRED.
|
||||
*
|
||||
* The value is a 64-bit integer representing milliseconds since January 1, 1970.
|
||||
*
|
||||
* Need not be hardware-enforced.
|
||||
*/
|
||||
ORIGINATION_EXPIRE_DATETIME = (6 << 28) | 401, /* TagType:DATE */
|
||||
|
||||
/**
|
||||
* Tag::USAGE_EXPIRE_DATETIME specifies the date and time at which the key expires for
|
||||
* verification and decryption purposes. After this time, any attempt to use a key with
|
||||
* KeyPurpose::VERIFY or KeyPurpose::DECRYPT provided to begin() must fail with
|
||||
* ErrorCode::KEY_EXPIRED.
|
||||
*
|
||||
* The value is a 64-bit integer representing milliseconds since January 1, 1970.
|
||||
*
|
||||
* Need not be hardware-enforced.
|
||||
*/
|
||||
USAGE_EXPIRE_DATETIME = (6 << 28) | 402, /* TagType:DATE */
|
||||
|
||||
/**
|
||||
* TODO(seleneh) this tag need to be deleted.
|
||||
*
|
||||
* TODO(seleneh) this tag need to be deleted.
|
||||
*
|
||||
* Tag::MIN_SECONDS_BETWEEN_OPS specifies the minimum amount of time that elapses between
|
||||
* allowed operations using a key. This can be used to rate-limit uses of keys in contexts
|
||||
* where unlimited use may enable brute force attacks.
|
||||
*
|
||||
* The value is a 32-bit integer representing seconds between allowed operations.
|
||||
*
|
||||
* When a key with this tag is used in an operation, the IKeyMintDevice must start a timer
|
||||
* during the finish() or abort() call. Any call to begin() that is received before the timer
|
||||
* indicates that the interval specified by Tag::MIN_SECONDS_BETWEEN_OPS has elapsed must fail
|
||||
* with ErrorCode::KEY_RATE_LIMIT_EXCEEDED. This implies that the IKeyMintDevice must keep a
|
||||
* table of use counters for keys with this tag. Because memory is often limited, this table
|
||||
* may have a fixed maximum size and KeyMint may fail operations that attempt to use keys with
|
||||
* this tag when the table is full. The table must acommodate at least 8 in-use keys and
|
||||
* aggressively reuse table slots when key minimum-usage intervals expire. If an operation
|
||||
* fails because the table is full, KeyMint returns ErrorCode::TOO_MANY_OPERATIONS.
|
||||
*
|
||||
* Must be hardware-enforced.
|
||||
*/
|
||||
MIN_SECONDS_BETWEEN_OPS = (3 << 28) | 403, /* TagType:UINT */
|
||||
|
||||
/**
|
||||
* Tag::MAX_USES_PER_BOOT specifies the maximum number of times that a key may be used between
|
||||
* system reboots. This is another mechanism to rate-limit key use.
|
||||
*
|
||||
* The value is a 32-bit integer representing uses per boot.
|
||||
*
|
||||
* When a key with this tag is used in an operation, a key-associated counter must be
|
||||
* incremented during the begin() call. After the key counter has exceeded this value, all
|
||||
* subsequent attempts to use the key must fail with ErrorCode::MAX_OPS_EXCEEDED, until the
|
||||
* device is restarted. This implies that the IKeyMintDevice must keep a table of use
|
||||
* counters for keys with this tag. Because KeyMint memory is often limited, this table can
|
||||
* have a fixed maximum size and KeyMint can fail operations that attempt to use keys with
|
||||
* this tag when the table is full. The table needs to acommodate at least 8 keys. If an
|
||||
* operation fails because the table is full, IKeyMintDevice must
|
||||
* ErrorCode::TOO_MANY_OPERATIONS.
|
||||
*
|
||||
* Must be hardware-enforced.
|
||||
*/
|
||||
MAX_USES_PER_BOOT = (3 << 28) | 404, /* TagType:UINT */
|
||||
|
||||
/**
|
||||
* Tag::USER_ID specifies the ID of the Android user that is permitted to use the key.
|
||||
*
|
||||
* Must not be hardware-enforced.
|
||||
*/
|
||||
USER_ID = (3 << 28) | 501, /* TagType:UINT */
|
||||
|
||||
/**
|
||||
* Tag::USER_SECURE_ID specifies that a key may only be used under a particular secure user
|
||||
* authentication state. This tag is mutually exclusive with Tag::NO_AUTH_REQUIRED.
|
||||
*
|
||||
* The value is a 64-bit integer specifying the authentication policy state value which must be
|
||||
* present in the userId or authenticatorId field of a HardwareAuthToken provided to begin(),
|
||||
* update(), or finish(). If a key with Tag::USER_SECURE_ID is used without a HardwareAuthToken
|
||||
* with the matching userId or authenticatorId, the IKeyMintDevice must return
|
||||
* ErrorCode::KEY_USER_NOT_AUTHENTICATED.
|
||||
*
|
||||
* Tag::USER_SECURE_ID interacts with Tag::AUTH_TIMEOUT in a very important way. If
|
||||
* Tag::AUTH_TIMEOUT is present in the key's characteristics then the key is a "timeout-based"
|
||||
* key, and may only be used if the difference between the current time when begin() is called
|
||||
* and the timestamp in the HardwareAuthToken is less than the value in Tag::AUTH_TIMEOUT * 1000
|
||||
* (the multiplier is because Tag::AUTH_TIMEOUT is in seconds, but the HardwareAuthToken
|
||||
* timestamp is in milliseconds). Otherwise the IKeyMintDevice must returrn
|
||||
* ErrorCode::KEY_USER_NOT_AUTHENTICATED.
|
||||
*
|
||||
* If Tag::AUTH_TIMEOUT is not present, then the key is an "auth-per-operation" key. In this
|
||||
* case, begin() must not require a HardwareAuthToken with appropriate contents. Instead,
|
||||
* update() and finish() must receive a HardwareAuthToken with Tag::USER_SECURE_ID value in
|
||||
* userId or authenticatorId fields, and the current operation's operation handle in the
|
||||
* challenge field. Otherwise the IKeyMintDevice must returrn
|
||||
* ErrorCode::KEY_USER_NOT_AUTHENTICATED.
|
||||
*
|
||||
* This tag is repeatable. If repeated, and any one of the values matches the HardwareAuthToken
|
||||
* as described above, the key is authorized for use. Otherwise the operation must fail with
|
||||
* ErrorCode::KEY_USER_NOT_AUTHENTICATED.
|
||||
*
|
||||
* Must be hardware-enforced.
|
||||
*/
|
||||
USER_SECURE_ID = (4 << 28) | 502, /* TagType:UINT_REP */
|
||||
|
||||
/**
|
||||
* Tag::NO_AUTH_REQUIRED specifies that no authentication is required to use this key. This tag
|
||||
* is mutually exclusive with Tag::USER_SECURE_ID.
|
||||
*
|
||||
* Must be hardware-enforced.
|
||||
*/
|
||||
NO_AUTH_REQUIRED = (7 << 28) | 503, /* TagType:BOOL */
|
||||
|
||||
/**
|
||||
* Tag::USER_AUTH_TYPE specifies the types of user authenticators that may be used to authorize
|
||||
* this key.
|
||||
*
|
||||
* The value is one or more values from HardwareAuthenticatorType, ORed together.
|
||||
*
|
||||
* When IKeyMintDevice is requested to perform an operation with a key with this tag, it must
|
||||
* receive a HardwareAuthToken and one or more bits must be set in both the HardwareAuthToken's
|
||||
* authenticatorType field and the Tag::USER_AUTH_TYPE value. That is, it must be true that
|
||||
*
|
||||
* (token.authenticatorType & tag_user_auth_type) != 0
|
||||
*
|
||||
* where token.authenticatorType is the authenticatorType field of the HardwareAuthToken and
|
||||
* tag_user_auth_type is the value of Tag:USER_AUTH_TYPE.
|
||||
*
|
||||
* Must be hardware-enforced.
|
||||
*/
|
||||
USER_AUTH_TYPE = (1 << 28) | 504, /* TagType:ENUM */
|
||||
|
||||
/**
|
||||
* Tag::AUTH_TIMEOUT specifies the time in seconds for which the key is authorized for use,
|
||||
* after user authentication. If
|
||||
* Tag::USER_SECURE_ID is present and this tag is not, then the key requies authentication for
|
||||
* every usage (see begin() for the details of the authentication-per-operation flow).
|
||||
*
|
||||
* The value is a 32-bit integer specifying the time in seconds after a successful
|
||||
* authentication of the user specified by Tag::USER_SECURE_ID with the authentication method
|
||||
* specified by Tag::USER_AUTH_TYPE that the key can be used.
|
||||
*
|
||||
* Must be hardware-enforced.
|
||||
*/
|
||||
AUTH_TIMEOUT = (3 << 28) | 505, /* TagType:UINT */
|
||||
|
||||
/**
|
||||
* Tag::ALLOW_WHILE_ON_BODY specifies that the key may be used after authentication timeout if
|
||||
* device is still on-body (requires on-body sensor).
|
||||
*
|
||||
* Cannot be hardware-enforced.
|
||||
*/
|
||||
ALLOW_WHILE_ON_BODY = (7 << 28) | 506, /* TagType:BOOL */
|
||||
|
||||
/**
|
||||
* TRUSTED_USER_PRESENCE_REQUIRED is an optional feature that specifies that this key must be
|
||||
* unusable except when the user has provided proof of physical presence. Proof of physical
|
||||
* presence must be a signal that cannot be triggered by an attacker who doesn't have one of:
|
||||
*
|
||||
* a) Physical control of the device or
|
||||
*
|
||||
* b) Control of the secure environment that holds the key.
|
||||
*
|
||||
* For instance, proof of user identity may be considered proof of presence if it meets the
|
||||
* requirements. However, proof of identity established in one security domain (e.g. TEE) does
|
||||
* not constitute proof of presence in another security domain (e.g. StrongBox), and no
|
||||
* mechanism analogous to the authentication token is defined for communicating proof of
|
||||
* presence across security domains.
|
||||
*
|
||||
* Some examples:
|
||||
*
|
||||
* A hardware button hardwired to a pin on a StrongBox device in such a way that nothing
|
||||
* other than a button press can trigger the signal constitutes proof of physical presence
|
||||
* for StrongBox keys.
|
||||
*
|
||||
* Fingerprint authentication provides proof of presence (and identity) for TEE keys if the
|
||||
* TEE has exclusive control of the fingerprint scanner and performs fingerprint matching.
|
||||
*
|
||||
* Password authentication does not provide proof of presence to either TEE or StrongBox,
|
||||
* even if TEE or StrongBox does the password matching, because password input is handled by
|
||||
* the non-secure world, which means an attacker who has compromised Android can spoof
|
||||
* password authentication.
|
||||
*
|
||||
* Note that no mechanism is defined for delivering proof of presence to an IKeyMintDevice,
|
||||
* except perhaps as implied by an auth token. This means that KeyMint must be able to check
|
||||
* proof of presence some other way. Further, the proof of presence must be performed between
|
||||
* begin() and the first call to update() or finish(). If the first update() or the finish()
|
||||
* call is made without proof of presence, the keyMint method must return
|
||||
* ErrorCode::PROOF_OF_PRESENCE_REQUIRED and abort the operation. The caller must delay the
|
||||
* update() or finish() call until proof of presence has been provided, which means the caller
|
||||
* must also have some mechanism for verifying that the proof has been provided.
|
||||
*
|
||||
* Only one operation requiring TUP may be in flight at a time. If begin() has already been
|
||||
* called on one key with TRUSTED_USER_PRESENCE_REQUIRED, and another begin() comes in for that
|
||||
* key or another with TRUSTED_USER_PRESENCE_REQUIRED, KeyMint must return
|
||||
* ErrorCode::CONCURRENT_PROOF_OF_PRESENCE_REQUESTED.
|
||||
*
|
||||
* Must be hardware-enforced.
|
||||
*/
|
||||
TRUSTED_USER_PRESENCE_REQUIRED = (7 << 28) | 507, /* TagType:BOOL */
|
||||
|
||||
/** Tag::TRUSTED_CONFIRMATION_REQUIRED is only applicable to keys with KeyPurpose SIGN, and
|
||||
* specifies that this key must not be usable unless the user provides confirmation of the data
|
||||
* to be signed. Confirmation is proven to keyMint via an approval token. See
|
||||
* CONFIRMATION_TOKEN, as well as the ConfirmatinUI HAL.
|
||||
*
|
||||
* If an attempt to use a key with this tag does not have a cryptographically valid
|
||||
* CONFIRMATION_TOKEN provided to finish() or if the data provided to update()/finish() does not
|
||||
* match the data described in the token, keyMint must return NO_USER_CONFIRMATION.
|
||||
*
|
||||
* Must be hardware-enforced.
|
||||
*/
|
||||
TRUSTED_CONFIRMATION_REQUIRED = (7 << 28) | 508, /* TagType:BOOL */
|
||||
|
||||
/**
|
||||
* Tag::UNLOCKED_DEVICE_REQUIRED specifies that the key may only be used when the device is
|
||||
* unlocked.
|
||||
*
|
||||
* Must be software-enforced.
|
||||
*/
|
||||
UNLOCKED_DEVICE_REQUIRED = (7 << 28) | 509, /* TagType:BOOL */
|
||||
|
||||
/**
|
||||
* Tag::APPLICATION_ID. When provided to generateKey or importKey, this tag specifies data
|
||||
* that is necessary during all uses of the key. In particular, calls to exportKey() and
|
||||
* getKeyCharacteristics() must provide the same value to the clientId parameter, and calls to
|
||||
* begin must provide this tag and the same associated data as part of the inParams set. If
|
||||
* the correct data is not provided, the method must return ErrorCode::INVALID_KEY_BLOB.
|
||||
*
|
||||
* The content of this tag must be bound to the key cryptographically, meaning it must not be
|
||||
* possible for an adversary who has access to all of the secure world secrets but does not have
|
||||
* access to the tag content to decrypt the key without brute-forcing the tag content, which
|
||||
* applications can prevent by specifying sufficiently high-entropy content.
|
||||
*
|
||||
* Must never appear in KeyCharacteristics.
|
||||
*/
|
||||
APPLICATION_ID = (9 << 28) | 601, /* TagType:BYTES */
|
||||
|
||||
/*
|
||||
* Semantically unenforceable tags, either because they have no specific meaning or because
|
||||
* they're informational only.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Tag::APPLICATION_DATA. When provided to generateKey or importKey, this tag specifies data
|
||||
* that is necessary during all uses of the key. In particular, calls to exportKey() and
|
||||
* getKeyCharacteristics() must provide the same value to the appData parameter, and calls to
|
||||
* begin must provide this tag and the same associated data as part of the inParams set. If
|
||||
* the correct data is not provided, the method must return ErrorCode::INVALID_KEY_BLOB.
|
||||
*
|
||||
* The content of this tag msut be bound to the key cryptographically, meaning it must not be
|
||||
* possible for an adversary who has access to all of the secure world secrets but does not have
|
||||
* access to the tag content to decrypt the key without brute-forcing the tag content, which
|
||||
* applications can prevent by specifying sufficiently high-entropy content.
|
||||
*
|
||||
* Must never appear in KeyCharacteristics.
|
||||
*/
|
||||
APPLICATION_DATA = (9 << 28) | 700, /* TagType:BYTES */
|
||||
|
||||
/**
|
||||
* Tag::CREATION_DATETIME specifies the date and time the key was created, in milliseconds since
|
||||
* January 1, 1970. This tag is optional and informational only.
|
||||
*
|
||||
* Tag::CREATED is informational only, and not enforced by anything. Must be in the
|
||||
* software-enforced list, if provided.
|
||||
*/
|
||||
CREATION_DATETIME = (6 << 28) | 701, /* TagType:DATE */
|
||||
|
||||
/**
|
||||
* Tag::ORIGIN specifies where the key was created, if known. This tag must not be specified
|
||||
* during key generation or import, and must be added to the key characteristics by the
|
||||
* IKeyMintDevice. The possible values are defined in the KeyOrigin enum.
|
||||
*
|
||||
* Must be hardware-enforced.
|
||||
*/
|
||||
ORIGIN = (1 << 28) | 702, /* TagType:ENUM */
|
||||
|
||||
// 703 is unused.
|
||||
|
||||
/**
|
||||
* Tag::ROOT_OF_TRUST specifies the root of trust associated with the key used by verified boot
|
||||
* to validate the system. It describes the boot key, verified boot state, boot hash, and
|
||||
* whether device is locked. This tag is never provided to or returned from KeyMint in the
|
||||
* key characteristics. It exists only to define the tag for use in the attestation record.
|
||||
*
|
||||
* Must never appear in KeyCharacteristics.
|
||||
*/
|
||||
ROOT_OF_TRUST = (9 << 28) | 704, /* TagType:BYTES */
|
||||
|
||||
/**
|
||||
* Tag::OS_VERSION specifies the system OS version with which the key may be used. This tag is
|
||||
* never sent to the IKeyMintDevice, but is added to the hardware-enforced authorization list
|
||||
* by the TA. Any attempt to use a key with a Tag::OS_VERSION value different from the
|
||||
* currently-running OS version must cause begin(), getKeyCharacteristics() or exportKey() to
|
||||
* return ErrorCode::KEY_REQUIRES_UPGRADE. See upgradeKey() for details.
|
||||
*
|
||||
* The value of the tag is an integer of the form MMmmss, where MM is the major version number,
|
||||
* mm is the minor version number, and ss is the sub-minor version number. For example, for a
|
||||
* key generated on Android version 4.0.3, the value would be 040003.
|
||||
*
|
||||
* The IKeyMintDevice HAL must read the current OS version from the system property
|
||||
* ro.build.version.release and deliver it to the secure environment when the HAL is first
|
||||
* loaded (mechanism is implementation-defined). The secure environment must not accept another
|
||||
* version until after the next boot. If the content of ro.build.version.release has additional
|
||||
* version information after the sub-minor version number, it must not be included in
|
||||
* Tag::OS_VERSION. If the content is non-numeric, the secure environment must use 0 as the
|
||||
* system version.
|
||||
*
|
||||
* Must be hardware-enforced.
|
||||
*/
|
||||
OS_VERSION = (3 << 28) | 705, /* TagType:UINT */
|
||||
|
||||
/**
|
||||
* Tag::OS_PATCHLEVEL specifies the system security patch level with which the key may be used.
|
||||
* This tag is never sent to the keyMint TA, but is added to the hardware-enforced
|
||||
* authorization list by the TA. Any attempt to use a key with a Tag::OS_PATCHLEVEL value
|
||||
* different from the currently-running system patchlevel must cause begin(),
|
||||
* getKeyCharacteristics() or exportKey() to return ErrorCode::KEY_REQUIRES_UPGRADE. See
|
||||
* upgradeKey() for details.
|
||||
*
|
||||
* The value of the tag is an integer of the form YYYYMM, where YYYY is the four-digit year of
|
||||
* the last update and MM is the two-digit month of the last update. For example, for a key
|
||||
* generated on an Android device last updated in December 2015, the value would be 201512.
|
||||
*
|
||||
* The IKeyMintDevice HAL must read the current system patchlevel from the system property
|
||||
* ro.build.version.security_patch and deliver it to the secure environment when the HAL is
|
||||
* first loaded (mechanism is implementation-defined). The secure environment must not accept
|
||||
* another patchlevel until after the next boot.
|
||||
*
|
||||
* Must be hardware-enforced.
|
||||
*/
|
||||
OS_PATCHLEVEL = (3 << 28) | 706, /* TagType:UINT */
|
||||
|
||||
/**
|
||||
* Tag::UNIQUE_ID specifies a unique, time-based identifier. This tag is never provided to or
|
||||
* returned from KeyMint in the key characteristics. It exists only to define the tag for use
|
||||
* in the attestation record.
|
||||
*
|
||||
* When a key with Tag::INCLUDE_UNIQUE_ID is attested, the unique ID is added to the attestation
|
||||
* record. The value is a 128-bit hash that is unique per device and per calling application,
|
||||
* and changes monthly and on most password resets. It is computed with:
|
||||
*
|
||||
* HMAC_SHA256(T || C || R, HBK)
|
||||
*
|
||||
* Where:
|
||||
*
|
||||
* T is the "temporal counter value", computed by dividing the value of
|
||||
* Tag::CREATION_DATETIME by 2592000000, dropping any remainder. T changes every 30 days
|
||||
* (2592000000 = 30 * 24 * 60 * 60 * 1000).
|
||||
*
|
||||
* C is the value of Tag::ATTESTATION_APPLICATION_ID that is provided to attestKey().
|
||||
*
|
||||
* R is 1 if Tag::RESET_SINCE_ID_ROTATION was provided to attestKey or 0 if the tag was not
|
||||
* provided.
|
||||
*
|
||||
* HBK is a unique hardware-bound secret known to the secure environment and never revealed
|
||||
* by it. The secret must contain at least 128 bits of entropy and be unique to the
|
||||
* individual device (probabilistic uniqueness is acceptable).
|
||||
*
|
||||
* HMAC_SHA256 is the HMAC function, with SHA-2-256 as the hash.
|
||||
*
|
||||
* The output of the HMAC function must be truncated to 128 bits.
|
||||
*
|
||||
* Must be hardware-enforced.
|
||||
*/
|
||||
UNIQUE_ID = (9 << 28) | 707, /* TagType:BYTES */
|
||||
|
||||
/**
|
||||
* Tag::ATTESTATION_CHALLENGE is used to deliver a "challenge" value to the attestKey() method,
|
||||
* which must place the value in the KeyDescription SEQUENCE of the attestation extension. See
|
||||
* attestKey().
|
||||
*
|
||||
* Must never appear in KeyCharacteristics.
|
||||
*/
|
||||
ATTESTATION_CHALLENGE = (9 << 28) | 708, /* TagType:BYTES */
|
||||
|
||||
/**
|
||||
* Tag::ATTESTATION_APPLICATION_ID identifies the set of applications which may use a key, used
|
||||
* only with attestKey().
|
||||
*
|
||||
* The content of Tag::ATTESTATION_APPLICATION_ID is a DER-encoded ASN.1 structure, with the
|
||||
* following schema:
|
||||
*
|
||||
* AttestationApplicationId ::= SEQUENCE {
|
||||
* packageInfoRecords SET OF PackageInfoRecord,
|
||||
* signatureDigests SET OF OCTET_STRING,
|
||||
* }
|
||||
*
|
||||
* PackageInfoRecord ::= SEQUENCE {
|
||||
* packageName OCTET_STRING,
|
||||
* version INTEGER,
|
||||
* }
|
||||
*
|
||||
* See system/security/keystore/keystore_attestation_id.cpp for details of construction.
|
||||
* IKeyMintDevice implementers do not need to create or parse the ASN.1 structure, but only
|
||||
* copy the tag value into the attestation record. The DER-encoded string must not exceed 1 KiB
|
||||
* in length.
|
||||
*
|
||||
* Cannot be hardware-enforced.
|
||||
*/
|
||||
ATTESTATION_APPLICATION_ID = (9 << 28) | 709, /* TagType:BYTES */
|
||||
|
||||
/**
|
||||
* Tag::ATTESTATION_ID_BRAND provides the device's brand name, as returned by Build.BRAND in
|
||||
* Android, to attestKey(). This field must be set only when requesting attestation of the
|
||||
* device's identifiers.
|
||||
*
|
||||
* If the device does not support ID attestation (or destroyAttestationIds() was previously
|
||||
* called and the device can no longer attest its IDs), any key attestation request that
|
||||
* includes this tag must fail with ErrorCode::CANNOT_ATTEST_IDS.
|
||||
*
|
||||
* Must never appear in KeyCharacteristics.
|
||||
*/
|
||||
ATTESTATION_ID_BRAND = (9 << 28) | 710, /* TagType:BYTES */
|
||||
|
||||
/**
|
||||
* Tag::ATTESTATION_ID_DEVICE provides the device's device name, as returned by Build.DEVICE in
|
||||
* Android, to attestKey(). This field must be set only when requesting attestation of the
|
||||
* device's identifiers.
|
||||
*
|
||||
* If the device does not support ID attestation (or destroyAttestationIds() was previously
|
||||
* called and the device can no longer attest its IDs), any key attestation request that
|
||||
* includes this tag must fail with ErrorCode::CANNOT_ATTEST_IDS.
|
||||
*
|
||||
* Must never appear in KeyCharacteristics.
|
||||
*/
|
||||
ATTESTATION_ID_DEVICE = (9 << 28) | 711, /* TagType:BYTES */
|
||||
|
||||
/**
|
||||
* Tag::ATTESTATION_ID_PRODUCT provides the device's product name, as returned by Build.PRODUCT
|
||||
* in Android, to attestKey(). This field must be set only when requesting attestation of the
|
||||
* device's identifiers.
|
||||
*
|
||||
* If the device does not support ID attestation (or destroyAttestationIds() was previously
|
||||
* called and the device can no longer attest its IDs), any key attestation request that
|
||||
* includes this tag must fail with ErrorCode::CANNOT_ATTEST_IDS.
|
||||
*
|
||||
* Must never appear in KeyCharacteristics.
|
||||
*/
|
||||
ATTESTATION_ID_PRODUCT = (9 << 28) | 712, /* TagType:BYTES */
|
||||
|
||||
/**
|
||||
* Tag::ATTESTATION_ID_SERIAL the device's serial number. This field must be set only when
|
||||
* requesting attestation of the device's identifiers.
|
||||
*
|
||||
* If the device does not support ID attestation (or destroyAttestationIds() was previously
|
||||
* called and the device can no longer attest its IDs), any key attestation request that
|
||||
* includes this tag must fail with ErrorCode::CANNOT_ATTEST_IDS.
|
||||
*
|
||||
* Must never appear in KeyCharacteristics.
|
||||
*/
|
||||
ATTESTATION_ID_SERIAL = (9 << 28) | 713, /* TagType:BYTES */
|
||||
|
||||
/**
|
||||
* Tag::ATTESTATION_ID_IMEI provides the IMEIs for all radios on the device to attestKey().
|
||||
* This field must be set only when requesting attestation of the device's identifiers.
|
||||
*
|
||||
* If the device does not support ID attestation (or destroyAttestationIds() was previously
|
||||
* called and the device can no longer attest its IDs), any key attestation request that
|
||||
* includes this tag must fail with ErrorCode::CANNOT_ATTEST_IDS.
|
||||
*
|
||||
* Must never appear in KeyCharacteristics.
|
||||
*/
|
||||
ATTESTATION_ID_IMEI = (9 << 28) | 714, /* TagType:BYTES */
|
||||
|
||||
/**
|
||||
* Tag::ATTESTATION_ID_MEID provides the MEIDs for all radios on the device to attestKey().
|
||||
* This field must be set only when requesting attestation of the device's identifiers.
|
||||
*
|
||||
* If the device does not support ID attestation (or destroyAttestationIds() was previously
|
||||
* called and the device can no longer attest its IDs), any key attestation request that
|
||||
* includes this tag must fail with ErrorCode::CANNOT_ATTEST_IDS.
|
||||
*
|
||||
* Must never appear in KeyCharacteristics.
|
||||
*/
|
||||
ATTESTATION_ID_MEID = (9 << 28) | 715, /* TagType:BYTES */
|
||||
|
||||
/**
|
||||
* Tag::ATTESTATION_ID_MANUFACTURER provides the device's manufacturer name, as returned by
|
||||
* Build.MANUFACTURER in Android, to attstKey(). This field must be set only when requesting
|
||||
* attestation of the device's identifiers.
|
||||
*
|
||||
* If the device does not support ID attestation (or destroyAttestationIds() was previously
|
||||
* called and the device can no longer attest its IDs), any key attestation request that
|
||||
* includes this tag must fail with ErrorCode::CANNOT_ATTEST_IDS.
|
||||
*
|
||||
* Must never appear in KeyCharacteristics.
|
||||
*/
|
||||
ATTESTATION_ID_MANUFACTURER = (9 << 28) | 716, /* TagType:BYTES */
|
||||
|
||||
/**
|
||||
* Tag::ATTESTATION_ID_MODEL provides the device's model name, as returned by Build.MODEL in
|
||||
* Android, to attestKey(). This field must be set only when requesting attestation of the
|
||||
* device's identifiers.
|
||||
*
|
||||
* If the device does not support ID attestation (or destroyAttestationIds() was previously
|
||||
* called and the device can no longer attest its IDs), any key attestation request that
|
||||
* includes this tag must fail with ErrorCode::CANNOT_ATTEST_IDS.
|
||||
*
|
||||
* Must never appear in KeyCharacteristics.
|
||||
*/
|
||||
ATTESTATION_ID_MODEL = (9 << 28) | 717, /* TagType:BYTES */
|
||||
|
||||
/**
|
||||
* Tag::VENDOR_PATCHLEVEL specifies the vendor image security patch level with which the key may
|
||||
* be used. This tag is never sent to the keyMint TA, but is added to the hardware-enforced
|
||||
* authorization list by the TA. Any attempt to use a key with a Tag::VENDOR_PATCHLEVEL value
|
||||
* different from the currently-running system patchlevel must cause begin(),
|
||||
* getKeyCharacteristics() or exportKey() to return ErrorCode::KEY_REQUIRES_UPGRADE. See
|
||||
* upgradeKey() for details.
|
||||
*
|
||||
* The value of the tag is an integer of the form YYYYMMDD, where YYYY is the four-digit year of
|
||||
* the last update, MM is the two-digit month and DD is the two-digit day of the last
|
||||
* update. For example, for a key generated on an Android device last updated on June 5, 2018,
|
||||
* the value would be 20180605.
|
||||
*
|
||||
* The IKeyMintDevice HAL must read the current vendor patchlevel from the system property
|
||||
* ro.vendor.build.security_patch and deliver it to the secure environment when the HAL is first
|
||||
* loaded (mechanism is implementation-defined). The secure environment must not accept another
|
||||
* patchlevel until after the next boot.
|
||||
*
|
||||
* Must be hardware-enforced.
|
||||
*/
|
||||
VENDOR_PATCHLEVEL = (3 << 28) | 718, /* TagType:UINT */
|
||||
|
||||
/**
|
||||
* Tag::BOOT_PATCHLEVEL specifies the boot image (kernel) security patch level with which the
|
||||
* key may be used. This tag is never sent to the keyMint TA, but is added to the
|
||||
* hardware-enforced authorization list by the TA. Any attempt to use a key with a
|
||||
* Tag::BOOT_PATCHLEVEL value different from the currently-running system patchlevel must
|
||||
* cause begin(), getKeyCharacteristics() or exportKey() to return
|
||||
* ErrorCode::KEY_REQUIRES_UPGRADE. See upgradeKey() for details.
|
||||
*
|
||||
* The value of the tag is an integer of the form YYYYMMDD, where YYYY is the four-digit year of
|
||||
* the last update, MM is the two-digit month and DD is the two-digit day of the last
|
||||
* update. For example, for a key generated on an Android device last updated on June 5, 2018,
|
||||
* the value would be 20180605. If the day is not known, 00 may be substituted.
|
||||
*
|
||||
* During each boot, the bootloader must provide the patch level of the boot image to the secure
|
||||
* envirionment (mechanism is implementation-defined).
|
||||
*
|
||||
* Must be hardware-enforced.
|
||||
*/
|
||||
BOOT_PATCHLEVEL = (3 << 28) | 719, /* TagType:UINT */
|
||||
|
||||
/**
|
||||
* DEVICE_UNIQUE_ATTESTATION is an argument to IKeyMintDevice::attestKey(). It indicates that
|
||||
* attestation using a device-unique key is requested, rather than a batch key. When a
|
||||
* device-unique key is used, only the attestation certificate is returned; no additional
|
||||
* chained certificates are provided. It's up to the caller to recognize the device-unique
|
||||
* signing key. Only SecurityLevel::STRONGBOX IKeyMintDevices may support device-unique
|
||||
* attestations. SecurityLevel::TRUSTED_ENVIRONMENT IKeyMintDevices must return
|
||||
* ErrorCode::INVALID_ARGUMENT if they receive DEVICE_UNIQUE_ATTESTATION.
|
||||
* SecurityLevel::STRONGBOX IKeyMintDevices need not support DEVICE_UNIQUE_ATTESTATION, and
|
||||
* return ErrorCode::CANNOT_ATTEST_IDS if they do not support it.
|
||||
*
|
||||
* IKeyMintDevice implementations that support device-unique attestation MUST add the
|
||||
* DEVICE_UNIQUE_ATTESTATION tag to device-unique attestations.
|
||||
*/
|
||||
DEVICE_UNIQUE_ATTESTATION = (7 << 28) | 720, /* TagType:BOOL */
|
||||
|
||||
/**
|
||||
* IDENTITY_CREDENTIAL_KEY is never used by IKeyMintDevice, is not a valid argument to key
|
||||
* generation or any operation, is never returned by any method and is never used in a key
|
||||
* attestation. It is used in attestations produced by the IIdentityCredential HAL when that
|
||||
* HAL attests to Credential Keys. IIdentityCredential produces KeyMint-style attestations.
|
||||
*/
|
||||
IDENTITY_CREDENTIAL_KEY = (7 << 28) | 721, /* TagType:BOOL */
|
||||
|
||||
/**
|
||||
* To prevent keys from being compromised if an attacker acquires read access to system / kernel
|
||||
* memory, some inline encryption hardware supports protecting storage encryption keys in
|
||||
* hardware without software having access to or the ability to set the plaintext keys.
|
||||
* Instead, software only sees wrapped version of these keys.
|
||||
*
|
||||
* STORAGE_KEY is used to denote that a key generated or imported is a key used for storage
|
||||
* encryption. Keys of this type can either be generated or imported or secure imported using
|
||||
* keyMint. exportKey() can be used to re-wrap storage key with a per-boot ephemeral key
|
||||
* wrapped key once the key characteristics are enforced.
|
||||
*
|
||||
* Keys with this tag cannot be used for any operation within keyMint.
|
||||
* ErrorCode::INVALID_OPERATION is returned when a key with Tag::STORAGE_KEY is provided to
|
||||
* begin().
|
||||
*/
|
||||
STORAGE_KEY = (7 << 28) | 722, /* TagType:BOOL */
|
||||
|
||||
/**
|
||||
* Tag::ASSOCIATED_DATA Provides "associated data" for AES-GCM encryption or decryption. This
|
||||
* tag is provided to update and specifies data that is not encrypted/decrypted, but is used in
|
||||
* computing the GCM tag.
|
||||
*
|
||||
* Must never appear KeyCharacteristics.
|
||||
*/
|
||||
ASSOCIATED_DATA = (9 << 28) | 1000, /* TagType:BYTES */
|
||||
|
||||
/**
|
||||
* Tag::NONCE is used to provide or return a nonce or Initialization Vector (IV) for AES-GCM,
|
||||
* AES-CBC, AES-CTR, or 3DES-CBC encryption or decryption. This tag is provided to begin during
|
||||
* encryption and decryption operations. It is only provided to begin if the key has
|
||||
* Tag::CALLER_NONCE. If not provided, an appropriate nonce or IV must be randomly generated by
|
||||
* KeyMint and returned from begin.
|
||||
*
|
||||
* The value is a blob, an arbitrary-length array of bytes. Allowed lengths depend on the mode:
|
||||
* GCM nonces are 12 bytes in length; AES-CBC and AES-CTR IVs are 16 bytes in length, 3DES-CBC
|
||||
* IVs are 8 bytes in length.
|
||||
*
|
||||
* Must never appear in KeyCharacteristics.
|
||||
*/
|
||||
NONCE = (9 << 28) | 1001, /* TagType:BYTES */
|
||||
|
||||
/**
|
||||
* Tag::MAC_LENGTH provides the requested length of a MAC or GCM authentication tag, in bits.
|
||||
*
|
||||
* The value is the MAC length in bits. It must be a multiple of 8 and at least as large as the
|
||||
* value of Tag::MIN_MAC_LENGTH associated with the key. Otherwise, begin() must return
|
||||
* ErrorCode::INVALID_MAC_LENGTH.
|
||||
*
|
||||
* Must never appear in KeyCharacteristics.
|
||||
*/
|
||||
MAC_LENGTH = (3 << 28) | 1003, /* TagType:UINT */
|
||||
|
||||
/**
|
||||
* Tag::RESET_SINCE_ID_ROTATION specifies whether the device has been factory reset since the
|
||||
* last unique ID rotation. Used for key attestation.
|
||||
*
|
||||
* Must never appear in KeyCharacteristics.
|
||||
*/
|
||||
RESET_SINCE_ID_ROTATION = (7 << 28) | 1004, /* TagType:BOOL */
|
||||
|
||||
/**
|
||||
* Tag::CONFIRMATION_TOKEN is used to deliver a cryptographic token proving that the user
|
||||
* confirmed a signing request. The content is a full-length HMAC-SHA256 value. See the
|
||||
* ConfirmationUI HAL for details of token computation.
|
||||
*
|
||||
* Must never appear in KeyCharacteristics.
|
||||
*/
|
||||
CONFIRMATION_TOKEN = (9 << 28) | 1005, /* TagType:BYTES */
|
||||
}
|
||||
47
keymint/aidl/android/hardware/keymint/TagType.aidl
Normal file
47
keymint/aidl/android/hardware/keymint/TagType.aidl
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* 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.keymint;
|
||||
|
||||
/**
|
||||
* TagType classifies Tags in Tag.aidl into various groups of data.
|
||||
*/
|
||||
@VintfStability
|
||||
@Backing(type="int")
|
||||
enum TagType {
|
||||
/** Invalid type, used to designate a tag as uninitialized. */
|
||||
INVALID = 0 << 28,
|
||||
/** Enumeration value. */
|
||||
ENUM = 1 << 28,
|
||||
/** Repeatable enumeration value. */
|
||||
ENUM_REP = 2 << 28,
|
||||
/** 32-bit unsigned integer. */
|
||||
UINT = 3 << 28,
|
||||
/** Repeatable 32-bit unsigned integer. */
|
||||
UINT_REP = 4 << 28,
|
||||
/** 64-bit unsigned integer. */
|
||||
ULONG = 5 << 28,
|
||||
/** 64-bit unsigned integer representing a date and time, in milliseconds since 1 Jan 1970. */
|
||||
DATE = 6 << 28,
|
||||
/** Boolean. If a tag with this type is present, the value is "true". If absent, "false". */
|
||||
BOOL = 7 << 28,
|
||||
/** Byte string containing an arbitrary-length integer, big-endian ordering. */
|
||||
BIGNUM = 8 << 28,
|
||||
/** Byte string */
|
||||
BYTES = 9 << 28,
|
||||
/** Repeatable 64-bit unsigned integer */
|
||||
ULONG_REP = 10 << 28,
|
||||
}
|
||||
28
keymint/aidl/android/hardware/keymint/Timestamp.aidl
Normal file
28
keymint/aidl/android/hardware/keymint/Timestamp.aidl
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 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.keymint;
|
||||
|
||||
/**
|
||||
* Time in milliseconds since some arbitrary point in time. Time must be monotonically increasing,
|
||||
* and a secure environment's notion of "current time" must not repeat until the Android device
|
||||
* reboots, or until at least 50 million years have elapsed (note that this requirement is satisfied
|
||||
* by setting the clock to zero during each boot, and then counting time accurately).
|
||||
*/
|
||||
@VintfStability
|
||||
parcelable Timestamp {
|
||||
long milliSeconds;
|
||||
}
|
||||
68
keymint/aidl/android/hardware/keymint/VerificationToken.aidl
Normal file
68
keymint/aidl/android/hardware/keymint/VerificationToken.aidl
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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.keymint;
|
||||
|
||||
import android.hardware.keymint.SecurityLevel;
|
||||
import android.hardware.keymint.Timestamp;
|
||||
|
||||
/**
|
||||
* VerificationToken instances are used for secure environments to authenticate one another.
|
||||
*
|
||||
* This version of the parcelable currently don't use the parametersVerified field since it's not
|
||||
* needed for time-based verification. This can be added in a later version, if needed.
|
||||
*/
|
||||
@VintfStability
|
||||
parcelable VerificationToken {
|
||||
/**
|
||||
* The operation handle, used to ensure freshness.
|
||||
*/
|
||||
long challenge;
|
||||
|
||||
/**
|
||||
* The current time of the secure environment that generates the VerificationToken. This can be
|
||||
* checked against auth tokens generated by the same secure environment, which avoids needing to
|
||||
* synchronize clocks.
|
||||
*/
|
||||
Timestamp timestamp;
|
||||
|
||||
/**
|
||||
* SecurityLevel of the secure environment that generated the token.
|
||||
*/
|
||||
SecurityLevel securityLevel;
|
||||
|
||||
/**
|
||||
* 32-byte HMAC-SHA256 of the above values, computed as:
|
||||
*
|
||||
* HMAC(H,
|
||||
* "Auth Verification" || challenge || timestamp || securityLevel || parametersVerified)
|
||||
*
|
||||
* where:
|
||||
*
|
||||
* ``HMAC'' is the shared HMAC key (see computeSharedHmac() in IKeyMint).
|
||||
*
|
||||
* ``||'' represents concatenation
|
||||
*
|
||||
* The representation of challenge and timestamp is as 64-bit unsigned integers in big-endian
|
||||
* order. securityLevel is represented as a 32-bit unsigned integer in big-endian order.
|
||||
*
|
||||
* If parametersVerified is non-empty, the representation of parametersVerified is an ASN.1 DER
|
||||
* encoded representation of the values. The ASN.1 schema used is the AuthorizationList schema
|
||||
* from the Keystore attestation documentation. If parametersVerified is empty, it is simply
|
||||
* omitted from the HMAC computation.
|
||||
*/
|
||||
byte[] mac;
|
||||
}
|
||||
26
keymint/aidl/default/Android.bp
Normal file
26
keymint/aidl/default/Android.bp
Normal file
@@ -0,0 +1,26 @@
|
||||
cc_binary {
|
||||
name: "android.hardware.keymint@1.0-service",
|
||||
relative_install_path: "hw",
|
||||
init_rc: ["android.hardware.keymint@1.0-service.rc"],
|
||||
vintf_fragments: ["android.hardware.keymint@1.0-service.xml"],
|
||||
vendor: true,
|
||||
cflags: [
|
||||
"-Wall",
|
||||
"-Wextra",
|
||||
],
|
||||
shared_libs: [
|
||||
"android.hardware.keymint-ndk_platform",
|
||||
"libbase",
|
||||
"libbinder_ndk",
|
||||
"libcppbor",
|
||||
"libcrypto",
|
||||
"liblog",
|
||||
"libkeymaster_portable",
|
||||
"libkeymint1",
|
||||
"libpuresoftkeymasterdevice",
|
||||
"libutils",
|
||||
],
|
||||
srcs: [
|
||||
"service.cpp",
|
||||
],
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
service vendor.keymint-default /vendor/bin/hw/android.hardware.keymint@1.0-service
|
||||
class early_hal
|
||||
user nobody
|
||||
@@ -0,0 +1,6 @@
|
||||
<manifest version="1.0" type="device">
|
||||
<hal format="aidl">
|
||||
<name>android.hardware.keymint</name>
|
||||
<fqname>IKeyMintDevice/default</fqname>
|
||||
</hal>
|
||||
</manifest>
|
||||
45
keymint/aidl/default/service.cpp
Normal file
45
keymint/aidl/default/service.cpp
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 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.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "android.hardware.keymint1-service"
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <android/binder_manager.h>
|
||||
#include <android/binder_process.h>
|
||||
|
||||
#include <AndroidKeyMint1Device.h>
|
||||
#include <keymaster/soft_keymaster_logger.h>
|
||||
|
||||
using aidl::android::hardware::keymint::SecurityLevel;
|
||||
using aidl::android::hardware::keymint::V1_0::AndroidKeyMint1Device;
|
||||
|
||||
int main() {
|
||||
// Zero threads seems like a useless pool, but below we'll join this thread to it, increasing
|
||||
// the pool size to 1.
|
||||
ABinderProcess_setThreadPoolMaxThreadCount(0);
|
||||
std::shared_ptr<AndroidKeyMint1Device> km5 =
|
||||
ndk::SharedRefBase::make<AndroidKeyMint1Device>(SecurityLevel::SOFTWARE);
|
||||
|
||||
keymaster::SoftKeymasterLogger logger;
|
||||
const auto instanceName = std::string(AndroidKeyMint1Device::descriptor) + "/default";
|
||||
LOG(INFO) << "instance: " << instanceName;
|
||||
binder_status_t status =
|
||||
AServiceManager_addService(km5->asBinder().get(), instanceName.c_str());
|
||||
CHECK(status == STATUS_OK);
|
||||
|
||||
ABinderProcess_joinThreadPool();
|
||||
return EXIT_FAILURE; // should not reach
|
||||
}
|
||||
66
keymint/aidl/vts/functional/Android.bp
Normal file
66
keymint/aidl/vts/functional/Android.bp
Normal file
@@ -0,0 +1,66 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
cc_test {
|
||||
name: "VtsAidlKeyMintV1_0TargetTest",
|
||||
defaults: [
|
||||
"VtsHalTargetTestDefaults",
|
||||
"use_libaidlvintf_gtest_helper_static",
|
||||
],
|
||||
srcs: [
|
||||
"keyMint1Test.cpp",
|
||||
"VerificationTokenTest.cpp",
|
||||
],
|
||||
shared_libs: [
|
||||
"libbinder",
|
||||
"libcrypto",
|
||||
"libkeymint1",
|
||||
"libkeymintSupport",
|
||||
],
|
||||
static_libs: [
|
||||
"android.hardware.keymint-cpp",
|
||||
"libcppbor",
|
||||
"libkeyMint1VtsTestUtil",
|
||||
],
|
||||
test_suites: [
|
||||
"general-tests",
|
||||
"vts",
|
||||
],
|
||||
}
|
||||
|
||||
cc_test_library {
|
||||
name: "libkeyMint1VtsTestUtil",
|
||||
defaults: [
|
||||
"VtsHalTargetTestDefaults",
|
||||
"use_libaidlvintf_gtest_helper_static",
|
||||
],
|
||||
srcs: [
|
||||
"KeyMintAidlTestBase.cpp",
|
||||
],
|
||||
export_include_dirs: [
|
||||
".",
|
||||
],
|
||||
shared_libs: [
|
||||
"libbinder",
|
||||
"libcrypto",
|
||||
"libkeymint1",
|
||||
"libkeymintSupport",
|
||||
],
|
||||
static_libs: [
|
||||
"android.hardware.keymint-cpp",
|
||||
"libcppbor",
|
||||
],
|
||||
}
|
||||
33
keymint/aidl/vts/functional/AndroidTest.xml
Normal file
33
keymint/aidl/vts/functional/AndroidTest.xml
Normal file
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
<configuration description="Runs VtsAidlKeyMintV1_0TargetTest.">
|
||||
<option name="test-suite-tag" value="apct" />
|
||||
<option name="test-suite-tag" value="apct-native" />
|
||||
|
||||
<target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer">
|
||||
</target_preparer>
|
||||
|
||||
<target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
|
||||
<option name="cleanup" value="true" />
|
||||
<option name="push" value="VtsAidlKeyMintV1_0TargetTest->/data/local/tmp/VtsAidlKeyMintV1_0TargetTest" />
|
||||
</target_preparer>
|
||||
|
||||
<test class="com.android.tradefed.testtype.GTest" >
|
||||
<option name="native-test-device-path" value="/data/local/tmp" />
|
||||
<option name="module-name" value="VtsAidlKeyMintV1_0TargetTest" />
|
||||
<option name="native-test-timeout" value="900000"/>
|
||||
</test>
|
||||
</configuration>
|
||||
756
keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
Normal file
756
keymint/aidl/vts/functional/KeyMintAidlTestBase.cpp
Normal file
@@ -0,0 +1,756 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "KeyMintAidlTestBase.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <vector>
|
||||
|
||||
#include <android-base/logging.h>
|
||||
|
||||
#include <keymintSupport/key_param_output.h>
|
||||
#include <keymintSupport/keymint_utils.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace keymint {
|
||||
|
||||
using namespace std::literals::chrono_literals;
|
||||
using std::endl;
|
||||
using std::optional;
|
||||
|
||||
::std::ostream& operator<<(::std::ostream& os, const AuthorizationSet& set) {
|
||||
if (set.size() == 0)
|
||||
os << "(Empty)" << ::std::endl;
|
||||
else {
|
||||
os << "\n";
|
||||
for (size_t i = 0; i < set.size(); ++i) os << set[i] << ::std::endl;
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
namespace test {
|
||||
|
||||
ErrorCode KeyMintAidlTestBase::GetReturnErrorCode(Status result) {
|
||||
if (result.isOk()) return ErrorCode::OK;
|
||||
|
||||
if (result.exceptionCode() == binder::Status::EX_SERVICE_SPECIFIC) {
|
||||
return static_cast<ErrorCode>(result.serviceSpecificErrorCode());
|
||||
}
|
||||
|
||||
return ErrorCode::UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
void KeyMintAidlTestBase::InitializeKeyMint(sp<IKeyMintDevice> keyMint) {
|
||||
ASSERT_NE(keyMint, nullptr);
|
||||
keymint_ = keyMint;
|
||||
|
||||
KeyMintHardwareInfo info;
|
||||
ASSERT_TRUE(keymint_->getHardwareInfo(&info).isOk());
|
||||
|
||||
securityLevel_ = info.securityLevel;
|
||||
name_.assign(info.keyMintName.begin(), info.keyMintName.end());
|
||||
author_.assign(info.keyMintAuthorName.begin(), info.keyMintAuthorName.end());
|
||||
|
||||
os_version_ = getOsVersion();
|
||||
os_patch_level_ = getOsPatchlevel();
|
||||
}
|
||||
|
||||
void KeyMintAidlTestBase::SetUp() {
|
||||
InitializeKeyMint(
|
||||
android::waitForDeclaredService<IKeyMintDevice>(String16(GetParam().c_str())));
|
||||
}
|
||||
|
||||
ErrorCode KeyMintAidlTestBase::GenerateKey(const AuthorizationSet& key_desc,
|
||||
vector<uint8_t>* keyBlob, KeyCharacteristics* keyChar) {
|
||||
EXPECT_NE(keyBlob, nullptr) << "Key blob pointer must not be null. Test bug";
|
||||
EXPECT_NE(keyChar, nullptr)
|
||||
<< "Previous characteristics not deleted before generating key. Test bug.";
|
||||
|
||||
// Aidl does not clear these output parameters if the function returns
|
||||
// error. This is different from hal where output parameter is always
|
||||
// cleared due to hal returning void. So now we need to do our own clearing
|
||||
// of the output variables prior to calling keyMint aidl libraries.
|
||||
keyBlob->clear();
|
||||
keyChar->softwareEnforced.clear();
|
||||
keyChar->hardwareEnforced.clear();
|
||||
certChain_.clear();
|
||||
|
||||
Status result;
|
||||
ByteArray blob;
|
||||
|
||||
result = keymint_->generateKey(key_desc.vector_data(), &blob, keyChar, &certChain_);
|
||||
|
||||
// On result, blob & characteristics should be empty.
|
||||
if (result.isOk()) {
|
||||
if (SecLevel() != SecurityLevel::SOFTWARE) {
|
||||
EXPECT_GT(keyChar->hardwareEnforced.size(), 0);
|
||||
}
|
||||
EXPECT_GT(keyChar->softwareEnforced.size(), 0);
|
||||
// TODO(seleneh) in a later version where we return @nullable
|
||||
// single Certificate, check non-null single certificate is always
|
||||
// non-empty.
|
||||
*keyBlob = blob.data;
|
||||
}
|
||||
|
||||
return GetReturnErrorCode(result);
|
||||
}
|
||||
|
||||
ErrorCode KeyMintAidlTestBase::GenerateKey(const AuthorizationSet& key_desc) {
|
||||
return GenerateKey(key_desc, &key_blob_, &key_characteristics_);
|
||||
}
|
||||
|
||||
ErrorCode KeyMintAidlTestBase::ImportKey(const AuthorizationSet& key_desc, KeyFormat format,
|
||||
const string& key_material, vector<uint8_t>* key_blob,
|
||||
KeyCharacteristics* key_characteristics) {
|
||||
Status result;
|
||||
|
||||
certChain_.clear();
|
||||
key_characteristics->softwareEnforced.clear();
|
||||
key_characteristics->hardwareEnforced.clear();
|
||||
key_blob->clear();
|
||||
|
||||
ByteArray blob;
|
||||
result = keymint_->importKey(key_desc.vector_data(), format,
|
||||
vector<uint8_t>(key_material.begin(), key_material.end()), &blob,
|
||||
key_characteristics, &certChain_);
|
||||
|
||||
if (result.isOk()) {
|
||||
if (SecLevel() != SecurityLevel::SOFTWARE) {
|
||||
EXPECT_GT(key_characteristics->hardwareEnforced.size(), 0);
|
||||
}
|
||||
EXPECT_GT(key_characteristics->softwareEnforced.size(), 0);
|
||||
*key_blob = blob.data;
|
||||
}
|
||||
|
||||
return GetReturnErrorCode(result);
|
||||
}
|
||||
|
||||
ErrorCode KeyMintAidlTestBase::ImportKey(const AuthorizationSet& key_desc, KeyFormat format,
|
||||
const string& key_material) {
|
||||
return ImportKey(key_desc, format, key_material, &key_blob_, &key_characteristics_);
|
||||
}
|
||||
|
||||
ErrorCode KeyMintAidlTestBase::ImportWrappedKey(string wrapped_key, string wrapping_key,
|
||||
const AuthorizationSet& wrapping_key_desc,
|
||||
string masking_key,
|
||||
const AuthorizationSet& unwrapping_params) {
|
||||
Status result;
|
||||
EXPECT_EQ(ErrorCode::OK, ImportKey(wrapping_key_desc, KeyFormat::PKCS8, wrapping_key));
|
||||
|
||||
ByteArray outBlob;
|
||||
key_characteristics_.softwareEnforced.clear();
|
||||
key_characteristics_.hardwareEnforced.clear();
|
||||
|
||||
result = keymint_->importWrappedKey(vector<uint8_t>(wrapped_key.begin(), wrapped_key.end()),
|
||||
key_blob_,
|
||||
vector<uint8_t>(masking_key.begin(), masking_key.end()),
|
||||
unwrapping_params.vector_data(), 0 /* passwordSid */,
|
||||
0 /* biometricSid */, &outBlob, &key_characteristics_);
|
||||
|
||||
if (result.isOk()) {
|
||||
key_blob_ = outBlob.data;
|
||||
if (SecLevel() != SecurityLevel::SOFTWARE) {
|
||||
EXPECT_GT(key_characteristics_.hardwareEnforced.size(), 0);
|
||||
}
|
||||
EXPECT_GT(key_characteristics_.softwareEnforced.size(), 0);
|
||||
}
|
||||
|
||||
return GetReturnErrorCode(result);
|
||||
}
|
||||
|
||||
ErrorCode KeyMintAidlTestBase::DeleteKey(vector<uint8_t>* key_blob, bool keep_key_blob) {
|
||||
Status result = keymint_->deleteKey(*key_blob);
|
||||
if (!keep_key_blob) {
|
||||
*key_blob = vector<uint8_t>();
|
||||
}
|
||||
|
||||
EXPECT_TRUE(result.isOk()) << result.serviceSpecificErrorCode() << endl;
|
||||
return GetReturnErrorCode(result);
|
||||
}
|
||||
|
||||
ErrorCode KeyMintAidlTestBase::DeleteKey(bool keep_key_blob) {
|
||||
return DeleteKey(&key_blob_, keep_key_blob);
|
||||
}
|
||||
|
||||
ErrorCode KeyMintAidlTestBase::DeleteAllKeys() {
|
||||
Status result = keymint_->deleteAllKeys();
|
||||
EXPECT_TRUE(result.isOk()) << result.serviceSpecificErrorCode() << endl;
|
||||
return GetReturnErrorCode(result);
|
||||
}
|
||||
|
||||
void KeyMintAidlTestBase::CheckedDeleteKey(vector<uint8_t>* key_blob, bool keep_key_blob) {
|
||||
ErrorCode result = DeleteKey(key_blob, keep_key_blob);
|
||||
EXPECT_TRUE(result == ErrorCode::OK || result == ErrorCode::UNIMPLEMENTED) << result << endl;
|
||||
}
|
||||
|
||||
void KeyMintAidlTestBase::CheckedDeleteKey() {
|
||||
CheckedDeleteKey(&key_blob_);
|
||||
}
|
||||
|
||||
ErrorCode KeyMintAidlTestBase::Begin(KeyPurpose purpose, const vector<uint8_t>& key_blob,
|
||||
const AuthorizationSet& in_params,
|
||||
AuthorizationSet* out_params, sp<IKeyMintOperation>& op) {
|
||||
SCOPED_TRACE("Begin");
|
||||
Status result;
|
||||
BeginResult out;
|
||||
result = keymint_->begin(purpose, key_blob, in_params.vector_data(), HardwareAuthToken(), &out);
|
||||
|
||||
if (result.isOk()) {
|
||||
*out_params = out.params;
|
||||
challenge_ = out.challenge;
|
||||
op = out.operation;
|
||||
}
|
||||
|
||||
return GetReturnErrorCode(result);
|
||||
}
|
||||
|
||||
ErrorCode KeyMintAidlTestBase::Begin(KeyPurpose purpose, const vector<uint8_t>& key_blob,
|
||||
const AuthorizationSet& in_params,
|
||||
AuthorizationSet* out_params) {
|
||||
SCOPED_TRACE("Begin");
|
||||
Status result;
|
||||
BeginResult out;
|
||||
|
||||
result = keymint_->begin(purpose, key_blob, in_params.vector_data(), HardwareAuthToken(), &out);
|
||||
|
||||
if (result.isOk()) {
|
||||
*out_params = out.params;
|
||||
challenge_ = out.challenge;
|
||||
op_ = out.operation;
|
||||
}
|
||||
|
||||
return GetReturnErrorCode(result);
|
||||
}
|
||||
|
||||
ErrorCode KeyMintAidlTestBase::Begin(KeyPurpose purpose, const AuthorizationSet& in_params,
|
||||
AuthorizationSet* out_params) {
|
||||
SCOPED_TRACE("Begin");
|
||||
EXPECT_EQ(nullptr, op_);
|
||||
return Begin(purpose, key_blob_, in_params, out_params);
|
||||
}
|
||||
|
||||
ErrorCode KeyMintAidlTestBase::Begin(KeyPurpose purpose, const AuthorizationSet& in_params) {
|
||||
SCOPED_TRACE("Begin");
|
||||
AuthorizationSet out_params;
|
||||
ErrorCode result = Begin(purpose, in_params, &out_params);
|
||||
EXPECT_TRUE(out_params.empty());
|
||||
return result;
|
||||
}
|
||||
|
||||
ErrorCode KeyMintAidlTestBase::Update(const AuthorizationSet& in_params, const string& input,
|
||||
AuthorizationSet* out_params, string* output,
|
||||
int32_t* input_consumed) {
|
||||
SCOPED_TRACE("Update");
|
||||
|
||||
Status result;
|
||||
EXPECT_NE(op_, nullptr);
|
||||
if (!op_) {
|
||||
return ErrorCode::UNEXPECTED_NULL_POINTER;
|
||||
}
|
||||
|
||||
KeyParameterArray key_params;
|
||||
key_params.params = in_params.vector_data();
|
||||
|
||||
KeyParameterArray in_keyParams;
|
||||
in_keyParams.params = in_params.vector_data();
|
||||
|
||||
optional<KeyParameterArray> out_keyParams;
|
||||
optional<ByteArray> o_put;
|
||||
result = op_->update(in_keyParams, vector<uint8_t>(input.begin(), input.end()), {}, {},
|
||||
&out_keyParams, &o_put, input_consumed);
|
||||
|
||||
if (result.isOk()) {
|
||||
if (o_put) {
|
||||
output->append(o_put->data.begin(), o_put->data.end());
|
||||
}
|
||||
|
||||
if (out_keyParams) {
|
||||
out_params->push_back(AuthorizationSet(out_keyParams->params));
|
||||
}
|
||||
}
|
||||
|
||||
return GetReturnErrorCode(result);
|
||||
}
|
||||
|
||||
ErrorCode KeyMintAidlTestBase::Update(const string& input, string* out, int32_t* input_consumed) {
|
||||
SCOPED_TRACE("Update");
|
||||
AuthorizationSet out_params;
|
||||
ErrorCode result =
|
||||
Update(AuthorizationSet() /* in_params */, input, &out_params, out, input_consumed);
|
||||
EXPECT_TRUE(out_params.empty());
|
||||
return result;
|
||||
}
|
||||
|
||||
ErrorCode KeyMintAidlTestBase::Finish(const AuthorizationSet& in_params, const string& input,
|
||||
const string& signature, AuthorizationSet* out_params,
|
||||
string* output) {
|
||||
SCOPED_TRACE("Finish");
|
||||
Status result;
|
||||
|
||||
EXPECT_NE(op_, nullptr);
|
||||
if (!op_) {
|
||||
return ErrorCode::UNEXPECTED_NULL_POINTER;
|
||||
}
|
||||
|
||||
KeyParameterArray key_params;
|
||||
key_params.params = in_params.vector_data();
|
||||
|
||||
KeyParameterArray in_keyParams;
|
||||
in_keyParams.params = in_params.vector_data();
|
||||
|
||||
optional<KeyParameterArray> out_keyParams;
|
||||
optional<vector<uint8_t>> o_put;
|
||||
|
||||
vector<uint8_t> oPut;
|
||||
result = op_->finish(in_keyParams, vector<uint8_t>(input.begin(), input.end()),
|
||||
vector<uint8_t>(signature.begin(), signature.end()), {}, {},
|
||||
&out_keyParams, &oPut);
|
||||
|
||||
if (result.isOk()) {
|
||||
if (out_keyParams) {
|
||||
out_params->push_back(AuthorizationSet(out_keyParams->params));
|
||||
}
|
||||
|
||||
output->append(oPut.begin(), oPut.end());
|
||||
}
|
||||
|
||||
op_.clear(); // So dtor doesn't Abort().
|
||||
return GetReturnErrorCode(result);
|
||||
}
|
||||
|
||||
ErrorCode KeyMintAidlTestBase::Finish(const string& message, string* output) {
|
||||
SCOPED_TRACE("Finish");
|
||||
AuthorizationSet out_params;
|
||||
string finish_output;
|
||||
ErrorCode result = Finish(AuthorizationSet() /* in_params */, message, "" /* signature */,
|
||||
&out_params, output);
|
||||
if (result != ErrorCode::OK) {
|
||||
return result;
|
||||
}
|
||||
EXPECT_EQ(0U, out_params.size());
|
||||
return result;
|
||||
}
|
||||
|
||||
ErrorCode KeyMintAidlTestBase::Finish(const string& message, const string& signature,
|
||||
string* output) {
|
||||
SCOPED_TRACE("Finish");
|
||||
AuthorizationSet out_params;
|
||||
ErrorCode result =
|
||||
Finish(AuthorizationSet() /* in_params */, message, signature, &out_params, output);
|
||||
|
||||
if (result != ErrorCode::OK) {
|
||||
return result;
|
||||
}
|
||||
|
||||
EXPECT_EQ(0U, out_params.size());
|
||||
return result;
|
||||
}
|
||||
|
||||
ErrorCode KeyMintAidlTestBase::Abort(const sp<IKeyMintOperation>& op) {
|
||||
SCOPED_TRACE("Abort");
|
||||
|
||||
EXPECT_NE(op, nullptr);
|
||||
if (!op) {
|
||||
return ErrorCode::UNEXPECTED_NULL_POINTER;
|
||||
}
|
||||
|
||||
Status retval = op->abort();
|
||||
EXPECT_TRUE(retval.isOk());
|
||||
return static_cast<ErrorCode>(retval.serviceSpecificErrorCode());
|
||||
}
|
||||
|
||||
ErrorCode KeyMintAidlTestBase::Abort() {
|
||||
SCOPED_TRACE("Abort");
|
||||
|
||||
EXPECT_NE(op_, nullptr);
|
||||
if (!op_) {
|
||||
return ErrorCode::UNEXPECTED_NULL_POINTER;
|
||||
}
|
||||
|
||||
Status retval = op_->abort();
|
||||
return static_cast<ErrorCode>(retval.serviceSpecificErrorCode());
|
||||
}
|
||||
|
||||
void KeyMintAidlTestBase::AbortIfNeeded() {
|
||||
SCOPED_TRACE("AbortIfNeeded");
|
||||
if (op_) {
|
||||
EXPECT_EQ(ErrorCode::OK, Abort());
|
||||
op_.clear();
|
||||
}
|
||||
}
|
||||
|
||||
string KeyMintAidlTestBase::ProcessMessage(const vector<uint8_t>& key_blob, KeyPurpose operation,
|
||||
const string& message, const AuthorizationSet& in_params,
|
||||
AuthorizationSet* out_params) {
|
||||
SCOPED_TRACE("ProcessMessage");
|
||||
AuthorizationSet begin_out_params;
|
||||
ErrorCode result = Begin(operation, key_blob, in_params, &begin_out_params);
|
||||
EXPECT_EQ(ErrorCode::OK, result);
|
||||
if (result != ErrorCode::OK) {
|
||||
return "";
|
||||
}
|
||||
|
||||
string output;
|
||||
int32_t consumed = 0;
|
||||
AuthorizationSet update_params;
|
||||
AuthorizationSet update_out_params;
|
||||
result = Update(update_params, message, &update_out_params, &output, &consumed);
|
||||
EXPECT_EQ(ErrorCode::OK, result);
|
||||
if (result != ErrorCode::OK) {
|
||||
return "";
|
||||
}
|
||||
|
||||
string unused;
|
||||
AuthorizationSet finish_params;
|
||||
AuthorizationSet finish_out_params;
|
||||
EXPECT_EQ(ErrorCode::OK,
|
||||
Finish(finish_params, message.substr(consumed), unused, &finish_out_params, &output));
|
||||
|
||||
out_params->push_back(begin_out_params);
|
||||
out_params->push_back(finish_out_params);
|
||||
return output;
|
||||
}
|
||||
|
||||
string KeyMintAidlTestBase::SignMessage(const vector<uint8_t>& key_blob, const string& message,
|
||||
const AuthorizationSet& params) {
|
||||
SCOPED_TRACE("SignMessage");
|
||||
AuthorizationSet out_params;
|
||||
string signature = ProcessMessage(key_blob, KeyPurpose::SIGN, message, params, &out_params);
|
||||
EXPECT_TRUE(out_params.empty());
|
||||
return signature;
|
||||
}
|
||||
|
||||
string KeyMintAidlTestBase::SignMessage(const string& message, const AuthorizationSet& params) {
|
||||
SCOPED_TRACE("SignMessage");
|
||||
return SignMessage(key_blob_, message, params);
|
||||
}
|
||||
|
||||
string KeyMintAidlTestBase::MacMessage(const string& message, Digest digest, size_t mac_length) {
|
||||
SCOPED_TRACE("MacMessage");
|
||||
return SignMessage(
|
||||
key_blob_, message,
|
||||
AuthorizationSetBuilder().Digest(digest).Authorization(TAG_MAC_LENGTH, mac_length));
|
||||
}
|
||||
|
||||
void KeyMintAidlTestBase::CheckHmacTestVector(const string& key, const string& message,
|
||||
Digest digest, const string& expected_mac) {
|
||||
SCOPED_TRACE("CheckHmacTestVector");
|
||||
ASSERT_EQ(ErrorCode::OK,
|
||||
ImportKey(AuthorizationSetBuilder()
|
||||
.Authorization(TAG_NO_AUTH_REQUIRED)
|
||||
.HmacKey(key.size() * 8)
|
||||
.Authorization(TAG_MIN_MAC_LENGTH, expected_mac.size() * 8)
|
||||
.Digest(digest),
|
||||
KeyFormat::RAW, key));
|
||||
string signature = MacMessage(message, digest, expected_mac.size() * 8);
|
||||
EXPECT_EQ(expected_mac, signature)
|
||||
<< "Test vector didn't match for key of size " << key.size() << " message of size "
|
||||
<< message.size() << " and digest " << digest;
|
||||
CheckedDeleteKey();
|
||||
}
|
||||
|
||||
void KeyMintAidlTestBase::CheckAesCtrTestVector(const string& key, const string& nonce,
|
||||
const string& message,
|
||||
const string& expected_ciphertext) {
|
||||
SCOPED_TRACE("CheckAesCtrTestVector");
|
||||
ASSERT_EQ(ErrorCode::OK, ImportKey(AuthorizationSetBuilder()
|
||||
.Authorization(TAG_NO_AUTH_REQUIRED)
|
||||
.AesEncryptionKey(key.size() * 8)
|
||||
.BlockMode(BlockMode::CTR)
|
||||
.Authorization(TAG_CALLER_NONCE)
|
||||
.Padding(PaddingMode::NONE),
|
||||
KeyFormat::RAW, key));
|
||||
|
||||
auto params = AuthorizationSetBuilder()
|
||||
.Authorization(TAG_NONCE, nonce.data(), nonce.size())
|
||||
.BlockMode(BlockMode::CTR)
|
||||
.Padding(PaddingMode::NONE);
|
||||
AuthorizationSet out_params;
|
||||
string ciphertext = EncryptMessage(key_blob_, message, params, &out_params);
|
||||
EXPECT_EQ(expected_ciphertext, ciphertext);
|
||||
}
|
||||
|
||||
void KeyMintAidlTestBase::CheckTripleDesTestVector(KeyPurpose purpose, BlockMode block_mode,
|
||||
PaddingMode padding_mode, const string& key,
|
||||
const string& iv, const string& input,
|
||||
const string& expected_output) {
|
||||
auto authset = AuthorizationSetBuilder()
|
||||
.TripleDesEncryptionKey(key.size() * 7)
|
||||
.BlockMode(block_mode)
|
||||
.Authorization(TAG_NO_AUTH_REQUIRED)
|
||||
.Padding(padding_mode);
|
||||
if (iv.size()) authset.Authorization(TAG_CALLER_NONCE);
|
||||
ASSERT_EQ(ErrorCode::OK, ImportKey(authset, KeyFormat::RAW, key));
|
||||
ASSERT_GT(key_blob_.size(), 0U);
|
||||
|
||||
auto begin_params = AuthorizationSetBuilder().BlockMode(block_mode).Padding(padding_mode);
|
||||
if (iv.size()) begin_params.Authorization(TAG_NONCE, iv.data(), iv.size());
|
||||
AuthorizationSet output_params;
|
||||
string output = ProcessMessage(key_blob_, purpose, input, begin_params, &output_params);
|
||||
EXPECT_EQ(expected_output, output);
|
||||
}
|
||||
|
||||
void KeyMintAidlTestBase::VerifyMessage(const vector<uint8_t>& key_blob, const string& message,
|
||||
const string& signature, const AuthorizationSet& params) {
|
||||
SCOPED_TRACE("VerifyMessage");
|
||||
AuthorizationSet begin_out_params;
|
||||
ASSERT_EQ(ErrorCode::OK, Begin(KeyPurpose::VERIFY, key_blob, params, &begin_out_params));
|
||||
|
||||
string output;
|
||||
AuthorizationSet update_params;
|
||||
AuthorizationSet update_out_params;
|
||||
int32_t consumed;
|
||||
ASSERT_EQ(ErrorCode::OK,
|
||||
Update(update_params, message, &update_out_params, &output, &consumed));
|
||||
EXPECT_TRUE(output.empty());
|
||||
EXPECT_GT(consumed, 0U);
|
||||
|
||||
string unused;
|
||||
AuthorizationSet finish_params;
|
||||
AuthorizationSet finish_out_params;
|
||||
EXPECT_EQ(ErrorCode::OK, Finish(finish_params, message.substr(consumed), signature,
|
||||
&finish_out_params, &output));
|
||||
op_.clear();
|
||||
EXPECT_TRUE(output.empty());
|
||||
}
|
||||
|
||||
void KeyMintAidlTestBase::VerifyMessage(const string& message, const string& signature,
|
||||
const AuthorizationSet& params) {
|
||||
SCOPED_TRACE("VerifyMessage");
|
||||
VerifyMessage(key_blob_, message, signature, params);
|
||||
}
|
||||
|
||||
string KeyMintAidlTestBase::EncryptMessage(const vector<uint8_t>& key_blob, const string& message,
|
||||
const AuthorizationSet& in_params,
|
||||
AuthorizationSet* out_params) {
|
||||
SCOPED_TRACE("EncryptMessage");
|
||||
return ProcessMessage(key_blob, KeyPurpose::ENCRYPT, message, in_params, out_params);
|
||||
}
|
||||
|
||||
string KeyMintAidlTestBase::EncryptMessage(const string& message, const AuthorizationSet& params,
|
||||
AuthorizationSet* out_params) {
|
||||
SCOPED_TRACE("EncryptMessage");
|
||||
return EncryptMessage(key_blob_, message, params, out_params);
|
||||
}
|
||||
|
||||
string KeyMintAidlTestBase::EncryptMessage(const string& message, const AuthorizationSet& params) {
|
||||
SCOPED_TRACE("EncryptMessage");
|
||||
AuthorizationSet out_params;
|
||||
string ciphertext = EncryptMessage(message, params, &out_params);
|
||||
EXPECT_TRUE(out_params.empty()) << "Output params should be empty. Contained: " << out_params;
|
||||
return ciphertext;
|
||||
}
|
||||
|
||||
string KeyMintAidlTestBase::EncryptMessage(const string& message, BlockMode block_mode,
|
||||
PaddingMode padding) {
|
||||
SCOPED_TRACE("EncryptMessage");
|
||||
auto params = AuthorizationSetBuilder().BlockMode(block_mode).Padding(padding);
|
||||
AuthorizationSet out_params;
|
||||
string ciphertext = EncryptMessage(message, params, &out_params);
|
||||
EXPECT_TRUE(out_params.empty()) << "Output params should be empty. Contained: " << out_params;
|
||||
return ciphertext;
|
||||
}
|
||||
|
||||
string KeyMintAidlTestBase::EncryptMessage(const string& message, BlockMode block_mode,
|
||||
PaddingMode padding, vector<uint8_t>* iv_out) {
|
||||
SCOPED_TRACE("EncryptMessage");
|
||||
auto params = AuthorizationSetBuilder().BlockMode(block_mode).Padding(padding);
|
||||
AuthorizationSet out_params;
|
||||
string ciphertext = EncryptMessage(message, params, &out_params);
|
||||
EXPECT_EQ(1U, out_params.size());
|
||||
auto ivVal = out_params.GetTagValue(TAG_NONCE);
|
||||
EXPECT_TRUE(ivVal.isOk());
|
||||
if (ivVal.isOk()) *iv_out = ivVal.value();
|
||||
return ciphertext;
|
||||
}
|
||||
|
||||
string KeyMintAidlTestBase::EncryptMessage(const string& message, BlockMode block_mode,
|
||||
PaddingMode padding, const vector<uint8_t>& iv_in) {
|
||||
SCOPED_TRACE("EncryptMessage");
|
||||
auto params = AuthorizationSetBuilder()
|
||||
.BlockMode(block_mode)
|
||||
.Padding(padding)
|
||||
.Authorization(TAG_NONCE, iv_in);
|
||||
AuthorizationSet out_params;
|
||||
string ciphertext = EncryptMessage(message, params, &out_params);
|
||||
return ciphertext;
|
||||
}
|
||||
|
||||
string KeyMintAidlTestBase::EncryptMessage(const string& message, BlockMode block_mode,
|
||||
PaddingMode padding, uint8_t mac_length_bits,
|
||||
const vector<uint8_t>& iv_in) {
|
||||
SCOPED_TRACE("EncryptMessage");
|
||||
auto params = AuthorizationSetBuilder()
|
||||
.BlockMode(block_mode)
|
||||
.Padding(padding)
|
||||
.Authorization(TAG_MAC_LENGTH, mac_length_bits)
|
||||
.Authorization(TAG_NONCE, iv_in);
|
||||
AuthorizationSet out_params;
|
||||
string ciphertext = EncryptMessage(message, params, &out_params);
|
||||
return ciphertext;
|
||||
}
|
||||
|
||||
string KeyMintAidlTestBase::DecryptMessage(const vector<uint8_t>& key_blob,
|
||||
const string& ciphertext,
|
||||
const AuthorizationSet& params) {
|
||||
SCOPED_TRACE("DecryptMessage");
|
||||
AuthorizationSet out_params;
|
||||
string plaintext =
|
||||
ProcessMessage(key_blob, KeyPurpose::DECRYPT, ciphertext, params, &out_params);
|
||||
EXPECT_TRUE(out_params.empty());
|
||||
return plaintext;
|
||||
}
|
||||
|
||||
string KeyMintAidlTestBase::DecryptMessage(const string& ciphertext,
|
||||
const AuthorizationSet& params) {
|
||||
SCOPED_TRACE("DecryptMessage");
|
||||
return DecryptMessage(key_blob_, ciphertext, params);
|
||||
}
|
||||
|
||||
string KeyMintAidlTestBase::DecryptMessage(const string& ciphertext, BlockMode block_mode,
|
||||
PaddingMode padding_mode, const vector<uint8_t>& iv) {
|
||||
SCOPED_TRACE("DecryptMessage");
|
||||
auto params = AuthorizationSetBuilder()
|
||||
.BlockMode(block_mode)
|
||||
.Padding(padding_mode)
|
||||
.Authorization(TAG_NONCE, iv);
|
||||
return DecryptMessage(key_blob_, ciphertext, params);
|
||||
}
|
||||
|
||||
std::pair<ErrorCode, vector<uint8_t>> KeyMintAidlTestBase::UpgradeKey(
|
||||
const vector<uint8_t>& key_blob) {
|
||||
std::pair<ErrorCode, vector<uint8_t>> retval;
|
||||
vector<uint8_t> outKeyBlob;
|
||||
Status result = keymint_->upgradeKey(key_blob, vector<KeyParameter>(), &outKeyBlob);
|
||||
ErrorCode errorcode = GetReturnErrorCode(result);
|
||||
retval = std::tie(errorcode, outKeyBlob);
|
||||
|
||||
return retval;
|
||||
}
|
||||
vector<uint32_t> KeyMintAidlTestBase::ValidKeySizes(Algorithm algorithm) {
|
||||
switch (algorithm) {
|
||||
case Algorithm::RSA:
|
||||
switch (SecLevel()) {
|
||||
case SecurityLevel::SOFTWARE:
|
||||
case SecurityLevel::TRUSTED_ENVIRONMENT:
|
||||
return {2048, 3072, 4096};
|
||||
case SecurityLevel::STRONGBOX:
|
||||
return {2048};
|
||||
default:
|
||||
ADD_FAILURE() << "Invalid security level " << uint32_t(SecLevel());
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case Algorithm::EC:
|
||||
switch (SecLevel()) {
|
||||
case SecurityLevel::SOFTWARE:
|
||||
case SecurityLevel::TRUSTED_ENVIRONMENT:
|
||||
return {224, 256, 384, 521};
|
||||
case SecurityLevel::STRONGBOX:
|
||||
return {256};
|
||||
default:
|
||||
ADD_FAILURE() << "Invalid security level " << uint32_t(SecLevel());
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case Algorithm::AES:
|
||||
return {128, 256};
|
||||
case Algorithm::TRIPLE_DES:
|
||||
return {168};
|
||||
case Algorithm::HMAC: {
|
||||
vector<uint32_t> retval((512 - 64) / 8 + 1);
|
||||
uint32_t size = 64 - 8;
|
||||
std::generate(retval.begin(), retval.end(), [&]() { return (size += 8); });
|
||||
return retval;
|
||||
}
|
||||
default:
|
||||
ADD_FAILURE() << "Invalid Algorithm: " << algorithm;
|
||||
return {};
|
||||
}
|
||||
ADD_FAILURE() << "Should be impossible to get here";
|
||||
return {};
|
||||
}
|
||||
|
||||
vector<uint32_t> KeyMintAidlTestBase::InvalidKeySizes(Algorithm algorithm) {
|
||||
if (SecLevel() == SecurityLevel::STRONGBOX) {
|
||||
switch (algorithm) {
|
||||
case Algorithm::RSA:
|
||||
return {3072, 4096};
|
||||
case Algorithm::EC:
|
||||
return {224, 384, 521};
|
||||
case Algorithm::AES:
|
||||
return {192};
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
vector<EcCurve> KeyMintAidlTestBase::ValidCurves() {
|
||||
if (securityLevel_ == SecurityLevel::STRONGBOX) {
|
||||
return {EcCurve::P_256};
|
||||
} else {
|
||||
return {EcCurve::P_224, EcCurve::P_256, EcCurve::P_384, EcCurve::P_521};
|
||||
}
|
||||
}
|
||||
|
||||
vector<EcCurve> KeyMintAidlTestBase::InvalidCurves() {
|
||||
if (SecLevel() == SecurityLevel::TRUSTED_ENVIRONMENT) return {};
|
||||
CHECK(SecLevel() == SecurityLevel::STRONGBOX);
|
||||
return {EcCurve::P_224, EcCurve::P_384, EcCurve::P_521};
|
||||
}
|
||||
|
||||
vector<Digest> KeyMintAidlTestBase::ValidDigests(bool withNone, bool withMD5) {
|
||||
switch (SecLevel()) {
|
||||
case SecurityLevel::SOFTWARE:
|
||||
case SecurityLevel::TRUSTED_ENVIRONMENT:
|
||||
if (withNone) {
|
||||
if (withMD5)
|
||||
return {Digest::NONE, Digest::MD5, Digest::SHA1,
|
||||
Digest::SHA_2_224, Digest::SHA_2_256, Digest::SHA_2_384,
|
||||
Digest::SHA_2_512};
|
||||
else
|
||||
return {Digest::NONE, Digest::SHA1, Digest::SHA_2_224,
|
||||
Digest::SHA_2_256, Digest::SHA_2_384, Digest::SHA_2_512};
|
||||
} else {
|
||||
if (withMD5)
|
||||
return {Digest::MD5, Digest::SHA1, Digest::SHA_2_224,
|
||||
Digest::SHA_2_256, Digest::SHA_2_384, Digest::SHA_2_512};
|
||||
else
|
||||
return {Digest::SHA1, Digest::SHA_2_224, Digest::SHA_2_256, Digest::SHA_2_384,
|
||||
Digest::SHA_2_512};
|
||||
}
|
||||
break;
|
||||
case SecurityLevel::STRONGBOX:
|
||||
if (withNone)
|
||||
return {Digest::NONE, Digest::SHA_2_256};
|
||||
else
|
||||
return {Digest::SHA_2_256};
|
||||
break;
|
||||
default:
|
||||
ADD_FAILURE() << "Invalid security level " << uint32_t(SecLevel());
|
||||
break;
|
||||
}
|
||||
ADD_FAILURE() << "Should be impossible to get here";
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
} // namespace keymint
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
197
keymint/aidl/vts/functional/KeyMintAidlTestBase.h
Normal file
197
keymint/aidl/vts/functional/KeyMintAidlTestBase.h
Normal file
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef VTS_KEYMINT_AIDL_TEST_UTILS_H
|
||||
#define VTS_KEYMINT_AIDL_TEST_UTILS_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <aidl/Gtest.h>
|
||||
#include <aidl/Vintf.h>
|
||||
#include <android/hardware/keymint/ErrorCode.h>
|
||||
#include <android/hardware/keymint/IKeyMintDevice.h>
|
||||
#include <binder/IServiceManager.h>
|
||||
#include <binder/ProcessState.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <keymintSupport/authorization_set.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace keymint {
|
||||
namespace test {
|
||||
|
||||
using ::android::sp;
|
||||
using binder::Status;
|
||||
using ::std::shared_ptr;
|
||||
using ::std::string;
|
||||
using ::std::vector;
|
||||
|
||||
constexpr uint64_t kOpHandleSentinel = 0xFFFFFFFFFFFFFFFF;
|
||||
|
||||
::std::ostream& operator<<(::std::ostream& os, const AuthorizationSet& set);
|
||||
|
||||
class KeyMintAidlTestBase : public ::testing::TestWithParam<string> {
|
||||
public:
|
||||
void SetUp() override;
|
||||
void TearDown() override {
|
||||
if (key_blob_.size()) {
|
||||
CheckedDeleteKey();
|
||||
}
|
||||
AbortIfNeeded();
|
||||
}
|
||||
|
||||
void InitializeKeyMint(sp<IKeyMintDevice> keyMint);
|
||||
IKeyMintDevice& keyMint() { return *keymint_; }
|
||||
uint32_t os_version() { return os_version_; }
|
||||
uint32_t os_patch_level() { return os_patch_level_; }
|
||||
|
||||
ErrorCode GetReturnErrorCode(Status result);
|
||||
ErrorCode GenerateKey(const AuthorizationSet& key_desc, vector<uint8_t>* key_blob,
|
||||
KeyCharacteristics* key_characteristics);
|
||||
|
||||
ErrorCode GenerateKey(const AuthorizationSet& key_desc);
|
||||
|
||||
ErrorCode ImportKey(const AuthorizationSet& key_desc, KeyFormat format,
|
||||
const string& key_material, vector<uint8_t>* key_blob,
|
||||
KeyCharacteristics* key_characteristics);
|
||||
ErrorCode ImportKey(const AuthorizationSet& key_desc, KeyFormat format,
|
||||
const string& key_material);
|
||||
|
||||
ErrorCode ImportWrappedKey(string wrapped_key, string wrapping_key,
|
||||
const AuthorizationSet& wrapping_key_desc, string masking_key,
|
||||
const AuthorizationSet& unwrapping_params);
|
||||
|
||||
ErrorCode DeleteKey(vector<uint8_t>* key_blob, bool keep_key_blob = false);
|
||||
ErrorCode DeleteKey(bool keep_key_blob = false);
|
||||
|
||||
ErrorCode DeleteAllKeys();
|
||||
|
||||
void CheckedDeleteKey(vector<uint8_t>* key_blob, bool keep_key_blob = false);
|
||||
void CheckedDeleteKey();
|
||||
|
||||
ErrorCode Begin(KeyPurpose purpose, const vector<uint8_t>& key_blob,
|
||||
const AuthorizationSet& in_params, AuthorizationSet* out_params,
|
||||
sp<IKeyMintOperation>& op);
|
||||
ErrorCode Begin(KeyPurpose purpose, const vector<uint8_t>& key_blob,
|
||||
const AuthorizationSet& in_params, AuthorizationSet* out_params);
|
||||
ErrorCode Begin(KeyPurpose purpose, const AuthorizationSet& in_params,
|
||||
AuthorizationSet* out_params);
|
||||
ErrorCode Begin(KeyPurpose purpose, const AuthorizationSet& in_params);
|
||||
|
||||
ErrorCode Update(const AuthorizationSet& in_params, const string& input,
|
||||
AuthorizationSet* out_params, string* output, int32_t* input_consumed);
|
||||
ErrorCode Update(const string& input, string* out, int32_t* input_consumed);
|
||||
|
||||
ErrorCode Finish(const AuthorizationSet& in_params, const string& input,
|
||||
const string& signature, AuthorizationSet* out_params, string* output);
|
||||
ErrorCode Finish(const string& message, string* output);
|
||||
ErrorCode Finish(const string& message, const string& signature, string* output);
|
||||
ErrorCode Finish(string* output) { return Finish(string(), output); }
|
||||
|
||||
ErrorCode Abort();
|
||||
ErrorCode Abort(const sp<IKeyMintOperation>& op);
|
||||
void AbortIfNeeded();
|
||||
|
||||
string ProcessMessage(const vector<uint8_t>& key_blob, KeyPurpose operation,
|
||||
const string& message, const AuthorizationSet& in_params,
|
||||
AuthorizationSet* out_params);
|
||||
|
||||
string SignMessage(const vector<uint8_t>& key_blob, const string& message,
|
||||
const AuthorizationSet& params);
|
||||
string SignMessage(const string& message, const AuthorizationSet& params);
|
||||
|
||||
string MacMessage(const string& message, Digest digest, size_t mac_length);
|
||||
|
||||
void CheckHmacTestVector(const string& key, const string& message, Digest digest,
|
||||
const string& expected_mac);
|
||||
|
||||
void CheckAesCtrTestVector(const string& key, const string& nonce, const string& message,
|
||||
const string& expected_ciphertext);
|
||||
|
||||
void CheckTripleDesTestVector(KeyPurpose purpose, BlockMode block_mode,
|
||||
PaddingMode padding_mode, const string& key, const string& iv,
|
||||
const string& input, const string& expected_output);
|
||||
|
||||
void VerifyMessage(const vector<uint8_t>& key_blob, const string& message,
|
||||
const string& signature, const AuthorizationSet& params);
|
||||
void VerifyMessage(const string& message, const string& signature,
|
||||
const AuthorizationSet& params);
|
||||
|
||||
string EncryptMessage(const vector<uint8_t>& key_blob, const string& message,
|
||||
const AuthorizationSet& in_params, AuthorizationSet* out_params);
|
||||
string EncryptMessage(const string& message, const AuthorizationSet& params,
|
||||
AuthorizationSet* out_params);
|
||||
string EncryptMessage(const string& message, const AuthorizationSet& params);
|
||||
string EncryptMessage(const string& message, BlockMode block_mode, PaddingMode padding);
|
||||
string EncryptMessage(const string& message, BlockMode block_mode, PaddingMode padding,
|
||||
vector<uint8_t>* iv_out);
|
||||
string EncryptMessage(const string& message, BlockMode block_mode, PaddingMode padding,
|
||||
const vector<uint8_t>& iv_in);
|
||||
string EncryptMessage(const string& message, BlockMode block_mode, PaddingMode padding,
|
||||
uint8_t mac_length_bits, const vector<uint8_t>& iv_in);
|
||||
|
||||
string DecryptMessage(const vector<uint8_t>& key_blob, const string& ciphertext,
|
||||
const AuthorizationSet& params);
|
||||
string DecryptMessage(const string& ciphertext, const AuthorizationSet& params);
|
||||
string DecryptMessage(const string& ciphertext, BlockMode block_mode, PaddingMode padding_mode,
|
||||
const vector<uint8_t>& iv);
|
||||
|
||||
std::pair<ErrorCode, vector<uint8_t>> UpgradeKey(const vector<uint8_t>& key_blob);
|
||||
|
||||
bool IsSecure() { return securityLevel_ != SecurityLevel::SOFTWARE; }
|
||||
SecurityLevel SecLevel() { return securityLevel_; }
|
||||
|
||||
vector<uint32_t> ValidKeySizes(Algorithm algorithm);
|
||||
vector<uint32_t> InvalidKeySizes(Algorithm algorithm);
|
||||
|
||||
vector<EcCurve> ValidCurves();
|
||||
vector<EcCurve> InvalidCurves();
|
||||
|
||||
vector<Digest> ValidDigests(bool withNone, bool withMD5);
|
||||
|
||||
static vector<string> build_params() {
|
||||
auto params = android::getAidlHalInstanceNames(IKeyMintDevice::descriptor);
|
||||
return params;
|
||||
}
|
||||
|
||||
sp<IKeyMintOperation> op_;
|
||||
vector<Certificate> certChain_;
|
||||
vector<uint8_t> key_blob_;
|
||||
KeyCharacteristics key_characteristics_;
|
||||
|
||||
private:
|
||||
sp<IKeyMintDevice> keymint_;
|
||||
uint32_t os_version_;
|
||||
uint32_t os_patch_level_;
|
||||
|
||||
SecurityLevel securityLevel_;
|
||||
string name_;
|
||||
string author_;
|
||||
long challenge_;
|
||||
};
|
||||
|
||||
#define INSTANTIATE_KEYMINT_AIDL_TEST(name) \
|
||||
INSTANTIATE_TEST_SUITE_P(PerInstance, name, \
|
||||
testing::ValuesIn(KeyMintAidlTestBase::build_params()), \
|
||||
android::PrintInstanceNameToString)
|
||||
|
||||
} // namespace test
|
||||
} // namespace keymint
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
||||
#endif // VTS_KEYMINT_AIDL_TEST_UTILS_H
|
||||
174
keymint/aidl/vts/functional/VerificationTokenTest.cpp
Normal file
174
keymint/aidl/vts/functional/VerificationTokenTest.cpp
Normal file
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "KeyMintAidlTestBase.h"
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace keymint {
|
||||
namespace test {
|
||||
|
||||
class VerificationTokenTest : public KeyMintAidlTestBase {
|
||||
protected:
|
||||
struct VerifyAuthorizationResult {
|
||||
ErrorCode error;
|
||||
VerificationToken token;
|
||||
};
|
||||
|
||||
VerifyAuthorizationResult verifyAuthorization(uint64_t operationHandle,
|
||||
const HardwareAuthToken& authToken) {
|
||||
VerifyAuthorizationResult result;
|
||||
|
||||
Status err;
|
||||
err = keyMint().verifyAuthorization(operationHandle, //
|
||||
authToken, //
|
||||
&result.token);
|
||||
|
||||
result.error = GetReturnErrorCode(err);
|
||||
return result;
|
||||
}
|
||||
|
||||
uint64_t getTime() {
|
||||
struct timespec timespec;
|
||||
EXPECT_EQ(0, clock_gettime(CLOCK_BOOTTIME, ×pec));
|
||||
return timespec.tv_sec * 1000 + timespec.tv_nsec / 1000000;
|
||||
}
|
||||
|
||||
int sleep_ms(uint32_t milliseconds) {
|
||||
struct timespec sleep_time = {static_cast<time_t>(milliseconds / 1000),
|
||||
static_cast<long>(milliseconds % 1000) * 1000000};
|
||||
while (sleep_time.tv_sec || sleep_time.tv_nsec) {
|
||||
if (nanosleep(&sleep_time /* to wait */,
|
||||
&sleep_time /* remaining (on interrruption) */) == 0) {
|
||||
sleep_time = {};
|
||||
} else {
|
||||
if (errno != EINTR) return errno;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* VerificationTokens exist to facilitate cross-KeyMint verification of requirements. As
|
||||
* such, the precise capabilities required will vary depending on the specific vendor
|
||||
* implementations. Essentially, VerificationTokens are a "hook" to enable vendor
|
||||
* implementations to communicate, so the precise usage is defined by those vendors. The only
|
||||
* thing we really can test is that tokens can be created by TEE keyMints, and that the
|
||||
* timestamps increase as expected.
|
||||
*/
|
||||
TEST_P(VerificationTokenTest, TestCreation) {
|
||||
auto result1 = verifyAuthorization(1 /* operation handle */, HardwareAuthToken());
|
||||
auto result1_time = getTime();
|
||||
|
||||
if (SecLevel() == SecurityLevel::STRONGBOX) {
|
||||
// StrongBox should not implement verifyAuthorization.
|
||||
EXPECT_EQ(ErrorCode::UNIMPLEMENTED, result1.error);
|
||||
return;
|
||||
}
|
||||
|
||||
ASSERT_EQ(ErrorCode::OK, result1.error);
|
||||
EXPECT_EQ(1U, result1.token.challenge);
|
||||
EXPECT_EQ(SecLevel(), result1.token.securityLevel);
|
||||
EXPECT_GT(result1.token.timestamp.milliSeconds, 0U);
|
||||
|
||||
constexpr uint32_t time_to_sleep = 200;
|
||||
sleep_ms(time_to_sleep);
|
||||
|
||||
auto result2 = verifyAuthorization(2 /* operation handle */, HardwareAuthToken());
|
||||
|
||||
auto result2_time = getTime();
|
||||
ASSERT_EQ(ErrorCode::OK, result2.error);
|
||||
EXPECT_EQ(2U, result2.token.challenge);
|
||||
EXPECT_EQ(SecLevel(), result2.token.securityLevel);
|
||||
|
||||
auto host_time_delta = result2_time - result1_time;
|
||||
|
||||
EXPECT_GE(host_time_delta, time_to_sleep)
|
||||
<< "We slept for " << time_to_sleep << " ms, the clock must have advanced by that much";
|
||||
EXPECT_LE(host_time_delta, time_to_sleep + 20)
|
||||
<< "The verifyAuthorization call took " << (host_time_delta - time_to_sleep)
|
||||
<< " ms? That's awful!";
|
||||
|
||||
auto km_time_delta =
|
||||
result2.token.timestamp.milliSeconds - result1.token.timestamp.milliSeconds;
|
||||
|
||||
// If not too much else is going on on the system, the time delta should be quite close. Allow
|
||||
// 2 ms of slop just to avoid test flakiness.
|
||||
//
|
||||
// TODO(swillden): see if we can output values so they can be gathered across many runs and
|
||||
// report if times aren't nearly always <1ms apart.
|
||||
EXPECT_LE(host_time_delta, km_time_delta + 2);
|
||||
EXPECT_LE(km_time_delta, host_time_delta + 2);
|
||||
ASSERT_EQ(result1.token.mac.size(), result2.token.mac.size());
|
||||
ASSERT_NE(0,
|
||||
memcmp(result1.token.mac.data(), result2.token.mac.data(), result1.token.mac.size()));
|
||||
}
|
||||
|
||||
/*
|
||||
* Test that the mac changes when the time stamp changes. This is does not guarantee that the time
|
||||
* stamp is included in the mac but on failure we know that it is not. Other than in the test
|
||||
* case above we call verifyAuthorization with the exact same set of parameters.
|
||||
*/
|
||||
TEST_P(VerificationTokenTest, MacChangesOnChangingTimestamp) {
|
||||
auto result1 = verifyAuthorization(0 /* operation handle */, HardwareAuthToken());
|
||||
auto result1_time = getTime();
|
||||
|
||||
if (SecLevel() == SecurityLevel::STRONGBOX) {
|
||||
// StrongBox should not implement verifyAuthorization.
|
||||
EXPECT_EQ(ErrorCode::UNIMPLEMENTED, result1.error);
|
||||
return;
|
||||
}
|
||||
|
||||
EXPECT_EQ(ErrorCode::OK, result1.error);
|
||||
EXPECT_EQ(0U, result1.token.challenge);
|
||||
EXPECT_EQ(SecLevel(), result1.token.securityLevel);
|
||||
EXPECT_GT(result1.token.timestamp.milliSeconds, 0U);
|
||||
|
||||
constexpr uint32_t time_to_sleep = 200;
|
||||
sleep_ms(time_to_sleep);
|
||||
|
||||
auto result2 = verifyAuthorization(0 /* operation handle */, HardwareAuthToken());
|
||||
// ASSERT_TRUE(result2.callSuccessful);
|
||||
auto result2_time = getTime();
|
||||
EXPECT_EQ(ErrorCode::OK, result2.error);
|
||||
EXPECT_EQ(0U, result2.token.challenge);
|
||||
EXPECT_EQ(SecLevel(), result2.token.securityLevel);
|
||||
|
||||
auto host_time_delta = result2_time - result1_time;
|
||||
|
||||
EXPECT_GE(host_time_delta, time_to_sleep)
|
||||
<< "We slept for " << time_to_sleep << " ms, the clock must have advanced by that much";
|
||||
EXPECT_LE(host_time_delta, time_to_sleep + 20)
|
||||
<< "The verifyAuthorization call took " << (host_time_delta - time_to_sleep)
|
||||
<< " ms? That's awful!";
|
||||
|
||||
auto km_time_delta =
|
||||
result2.token.timestamp.milliSeconds - result1.token.timestamp.milliSeconds;
|
||||
|
||||
EXPECT_LE(host_time_delta, km_time_delta + 2);
|
||||
EXPECT_LE(km_time_delta, host_time_delta + 2);
|
||||
ASSERT_EQ(result1.token.mac.size(), result2.token.mac.size());
|
||||
ASSERT_NE(0,
|
||||
memcmp(result1.token.mac.data(), result2.token.mac.data(), result1.token.mac.size()));
|
||||
}
|
||||
|
||||
INSTANTIATE_KEYMINT_AIDL_TEST(VerificationTokenTest);
|
||||
|
||||
} // namespace test
|
||||
} // namespace keymint
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
4069
keymint/aidl/vts/functional/keyMint1Test.cpp
Normal file
4069
keymint/aidl/vts/functional/keyMint1Test.cpp
Normal file
File diff suppressed because it is too large
Load Diff
39
keymint/support/Android.bp
Normal file
39
keymint/support/Android.bp
Normal file
@@ -0,0 +1,39 @@
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
|
||||
cc_library {
|
||||
name: "libkeymintSupport",
|
||||
cflags: [
|
||||
"-Wall",
|
||||
"-Wextra",
|
||||
"-Werror",
|
||||
],
|
||||
srcs: [
|
||||
"attestation_record.cpp",
|
||||
"authorization_set.cpp",
|
||||
"keymint_utils.cpp",
|
||||
"key_param_output.cpp",
|
||||
],
|
||||
export_include_dirs: [
|
||||
"include",
|
||||
],
|
||||
shared_libs: [
|
||||
"android.hardware.keymint-cpp",
|
||||
"libbase",
|
||||
"libcrypto",
|
||||
"libutils",
|
||||
],
|
||||
}
|
||||
4
keymint/support/OWNERS
Normal file
4
keymint/support/OWNERS
Normal file
@@ -0,0 +1,4 @@
|
||||
jbires@google.com
|
||||
jdanis@google.com
|
||||
seleneh@google.com
|
||||
swillden@google.com
|
||||
387
keymint/support/attestation_record.cpp
Normal file
387
keymint/support/attestation_record.cpp
Normal file
@@ -0,0 +1,387 @@
|
||||
/*
|
||||
* Copyright 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.
|
||||
*/
|
||||
|
||||
#include <keymintSupport/attestation_record.h>
|
||||
|
||||
#include <android/hardware/keymint/Tag.h>
|
||||
#include <android/hardware/keymint/TagType.h>
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <openssl/asn1t.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
#include <keymintSupport/authorization_set.h>
|
||||
#include <keymintSupport/openssl_utils.h>
|
||||
|
||||
#define AT __FILE__ ":" << __LINE__
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace keymint {
|
||||
|
||||
struct stack_st_ASN1_TYPE_Delete {
|
||||
void operator()(stack_st_ASN1_TYPE* p) { sk_ASN1_TYPE_free(p); }
|
||||
};
|
||||
|
||||
struct ASN1_STRING_Delete {
|
||||
void operator()(ASN1_STRING* p) { ASN1_STRING_free(p); }
|
||||
};
|
||||
|
||||
struct ASN1_TYPE_Delete {
|
||||
void operator()(ASN1_TYPE* p) { ASN1_TYPE_free(p); }
|
||||
};
|
||||
|
||||
#define ASN1_INTEGER_SET STACK_OF(ASN1_INTEGER)
|
||||
|
||||
typedef struct km_root_of_trust {
|
||||
ASN1_OCTET_STRING* verified_boot_key;
|
||||
ASN1_BOOLEAN device_locked;
|
||||
ASN1_ENUMERATED* verified_boot_state;
|
||||
ASN1_OCTET_STRING* verified_boot_hash;
|
||||
} KM_ROOT_OF_TRUST;
|
||||
|
||||
ASN1_SEQUENCE(KM_ROOT_OF_TRUST) = {
|
||||
ASN1_SIMPLE(KM_ROOT_OF_TRUST, verified_boot_key, ASN1_OCTET_STRING),
|
||||
ASN1_SIMPLE(KM_ROOT_OF_TRUST, device_locked, ASN1_BOOLEAN),
|
||||
ASN1_SIMPLE(KM_ROOT_OF_TRUST, verified_boot_state, ASN1_ENUMERATED),
|
||||
ASN1_SIMPLE(KM_ROOT_OF_TRUST, verified_boot_hash, ASN1_OCTET_STRING),
|
||||
} ASN1_SEQUENCE_END(KM_ROOT_OF_TRUST);
|
||||
IMPLEMENT_ASN1_FUNCTIONS(KM_ROOT_OF_TRUST);
|
||||
|
||||
typedef struct km_auth_list {
|
||||
ASN1_INTEGER_SET* purpose;
|
||||
ASN1_INTEGER* algorithm;
|
||||
ASN1_INTEGER* key_size;
|
||||
ASN1_INTEGER_SET* digest;
|
||||
ASN1_INTEGER_SET* padding;
|
||||
ASN1_INTEGER* ec_curve;
|
||||
ASN1_INTEGER* rsa_public_exponent;
|
||||
ASN1_INTEGER* active_date_time;
|
||||
ASN1_INTEGER* origination_expire_date_time;
|
||||
ASN1_INTEGER* usage_expire_date_time;
|
||||
ASN1_NULL* no_auth_required;
|
||||
ASN1_INTEGER* user_auth_type;
|
||||
ASN1_INTEGER* auth_timeout;
|
||||
ASN1_NULL* allow_while_on_body;
|
||||
ASN1_NULL* all_applications;
|
||||
ASN1_OCTET_STRING* application_id;
|
||||
ASN1_INTEGER* creation_date_time;
|
||||
ASN1_INTEGER* origin;
|
||||
ASN1_NULL* rollback_resistance;
|
||||
KM_ROOT_OF_TRUST* root_of_trust;
|
||||
ASN1_INTEGER* os_version;
|
||||
ASN1_INTEGER* os_patchlevel;
|
||||
ASN1_OCTET_STRING* attestation_application_id;
|
||||
ASN1_NULL* trusted_user_presence_required;
|
||||
ASN1_NULL* trusted_confirmation_required;
|
||||
ASN1_NULL* unlocked_device_required;
|
||||
ASN1_INTEGER* vendor_patchlevel;
|
||||
ASN1_INTEGER* boot_patchlevel;
|
||||
ASN1_NULL* early_boot_only;
|
||||
ASN1_NULL* device_unique_attestation;
|
||||
ASN1_NULL* storage_key;
|
||||
ASN1_NULL* identity_credential;
|
||||
} KM_AUTH_LIST;
|
||||
|
||||
ASN1_SEQUENCE(KM_AUTH_LIST) = {
|
||||
ASN1_EXP_SET_OF_OPT(KM_AUTH_LIST, purpose, ASN1_INTEGER, TAG_PURPOSE.maskedTag()),
|
||||
ASN1_EXP_OPT(KM_AUTH_LIST, algorithm, ASN1_INTEGER, TAG_ALGORITHM.maskedTag()),
|
||||
ASN1_EXP_OPT(KM_AUTH_LIST, key_size, ASN1_INTEGER, TAG_KEY_SIZE.maskedTag()),
|
||||
ASN1_EXP_SET_OF_OPT(KM_AUTH_LIST, digest, ASN1_INTEGER, TAG_DIGEST.maskedTag()),
|
||||
ASN1_EXP_SET_OF_OPT(KM_AUTH_LIST, padding, ASN1_INTEGER, TAG_PADDING.maskedTag()),
|
||||
ASN1_EXP_OPT(KM_AUTH_LIST, ec_curve, ASN1_INTEGER, TAG_EC_CURVE.maskedTag()),
|
||||
ASN1_EXP_OPT(KM_AUTH_LIST, rsa_public_exponent, ASN1_INTEGER,
|
||||
TAG_RSA_PUBLIC_EXPONENT.maskedTag()),
|
||||
ASN1_EXP_OPT(KM_AUTH_LIST, rollback_resistance, ASN1_NULL,
|
||||
TAG_ROLLBACK_RESISTANCE.maskedTag()),
|
||||
ASN1_EXP_OPT(KM_AUTH_LIST, active_date_time, ASN1_INTEGER, TAG_ACTIVE_DATETIME.maskedTag()),
|
||||
ASN1_EXP_OPT(KM_AUTH_LIST, origination_expire_date_time, ASN1_INTEGER,
|
||||
TAG_ORIGINATION_EXPIRE_DATETIME.maskedTag()),
|
||||
ASN1_EXP_OPT(KM_AUTH_LIST, usage_expire_date_time, ASN1_INTEGER,
|
||||
TAG_USAGE_EXPIRE_DATETIME.maskedTag()),
|
||||
ASN1_EXP_OPT(KM_AUTH_LIST, no_auth_required, ASN1_NULL, TAG_NO_AUTH_REQUIRED.maskedTag()),
|
||||
ASN1_EXP_OPT(KM_AUTH_LIST, user_auth_type, ASN1_INTEGER, TAG_USER_AUTH_TYPE.maskedTag()),
|
||||
ASN1_EXP_OPT(KM_AUTH_LIST, auth_timeout, ASN1_INTEGER, TAG_AUTH_TIMEOUT.maskedTag()),
|
||||
ASN1_EXP_OPT(KM_AUTH_LIST, allow_while_on_body, ASN1_NULL,
|
||||
TAG_ALLOW_WHILE_ON_BODY.maskedTag()),
|
||||
ASN1_EXP_OPT(KM_AUTH_LIST, trusted_user_presence_required, ASN1_NULL,
|
||||
TAG_TRUSTED_USER_PRESENCE_REQUIRED.maskedTag()),
|
||||
ASN1_EXP_OPT(KM_AUTH_LIST, trusted_confirmation_required, ASN1_NULL,
|
||||
TAG_TRUSTED_CONFIRMATION_REQUIRED.maskedTag()),
|
||||
ASN1_EXP_OPT(KM_AUTH_LIST, unlocked_device_required, ASN1_NULL,
|
||||
TAG_UNLOCKED_DEVICE_REQUIRED.maskedTag()),
|
||||
ASN1_EXP_OPT(KM_AUTH_LIST, creation_date_time, ASN1_INTEGER,
|
||||
TAG_CREATION_DATETIME.maskedTag()),
|
||||
ASN1_EXP_OPT(KM_AUTH_LIST, origin, ASN1_INTEGER, TAG_ORIGIN.maskedTag()),
|
||||
ASN1_EXP_OPT(KM_AUTH_LIST, root_of_trust, KM_ROOT_OF_TRUST, TAG_ROOT_OF_TRUST.maskedTag()),
|
||||
ASN1_EXP_OPT(KM_AUTH_LIST, os_version, ASN1_INTEGER, TAG_OS_VERSION.maskedTag()),
|
||||
ASN1_EXP_OPT(KM_AUTH_LIST, os_patchlevel, ASN1_INTEGER, TAG_OS_PATCHLEVEL.maskedTag()),
|
||||
ASN1_EXP_OPT(KM_AUTH_LIST, vendor_patchlevel, ASN1_INTEGER,
|
||||
TAG_VENDOR_PATCHLEVEL.maskedTag()),
|
||||
ASN1_EXP_OPT(KM_AUTH_LIST, boot_patchlevel, ASN1_INTEGER, TAG_BOOT_PATCHLEVEL.maskedTag()),
|
||||
ASN1_EXP_OPT(KM_AUTH_LIST, attestation_application_id, ASN1_OCTET_STRING,
|
||||
TAG_ATTESTATION_APPLICATION_ID.maskedTag()),
|
||||
ASN1_EXP_OPT(KM_AUTH_LIST, early_boot_only, ASN1_NULL, TAG_EARLY_BOOT_ONLY.maskedTag()),
|
||||
ASN1_EXP_OPT(KM_AUTH_LIST, device_unique_attestation, ASN1_NULL,
|
||||
TAG_DEVICE_UNIQUE_ATTESTATION.maskedTag()),
|
||||
ASN1_EXP_OPT(KM_AUTH_LIST, storage_key, ASN1_NULL, TAG_STORAGE_KEY.maskedTag()),
|
||||
ASN1_EXP_OPT(KM_AUTH_LIST, identity_credential, ASN1_NULL,
|
||||
TAG_IDENTITY_CREDENTIAL_KEY.maskedTag()),
|
||||
|
||||
} ASN1_SEQUENCE_END(KM_AUTH_LIST);
|
||||
IMPLEMENT_ASN1_FUNCTIONS(KM_AUTH_LIST);
|
||||
|
||||
typedef struct km_key_description {
|
||||
ASN1_INTEGER* attestation_version;
|
||||
ASN1_ENUMERATED* attestation_security_level;
|
||||
ASN1_INTEGER* keymint_version;
|
||||
ASN1_ENUMERATED* keymint_security_level;
|
||||
ASN1_OCTET_STRING* attestation_challenge;
|
||||
KM_AUTH_LIST* software_enforced;
|
||||
KM_AUTH_LIST* tee_enforced;
|
||||
ASN1_INTEGER* unique_id;
|
||||
} KM_KEY_DESCRIPTION;
|
||||
|
||||
ASN1_SEQUENCE(KM_KEY_DESCRIPTION) = {
|
||||
ASN1_SIMPLE(KM_KEY_DESCRIPTION, attestation_version, ASN1_INTEGER),
|
||||
ASN1_SIMPLE(KM_KEY_DESCRIPTION, attestation_security_level, ASN1_ENUMERATED),
|
||||
ASN1_SIMPLE(KM_KEY_DESCRIPTION, keymint_version, ASN1_INTEGER),
|
||||
ASN1_SIMPLE(KM_KEY_DESCRIPTION, keymint_security_level, ASN1_ENUMERATED),
|
||||
ASN1_SIMPLE(KM_KEY_DESCRIPTION, attestation_challenge, ASN1_OCTET_STRING),
|
||||
ASN1_SIMPLE(KM_KEY_DESCRIPTION, unique_id, ASN1_OCTET_STRING),
|
||||
ASN1_SIMPLE(KM_KEY_DESCRIPTION, software_enforced, KM_AUTH_LIST),
|
||||
ASN1_SIMPLE(KM_KEY_DESCRIPTION, tee_enforced, KM_AUTH_LIST),
|
||||
} ASN1_SEQUENCE_END(KM_KEY_DESCRIPTION);
|
||||
IMPLEMENT_ASN1_FUNCTIONS(KM_KEY_DESCRIPTION);
|
||||
|
||||
template <Tag tag>
|
||||
void copyAuthTag(const stack_st_ASN1_INTEGER* stack, TypedTag<TagType::ENUM_REP, tag> ttag,
|
||||
AuthorizationSet* auth_list) {
|
||||
typedef typename TypedTag2ValueType<decltype(ttag)>::type ValueT;
|
||||
for (size_t i = 0; i < sk_ASN1_INTEGER_num(stack); ++i) {
|
||||
auth_list->push_back(
|
||||
ttag, static_cast<ValueT>(ASN1_INTEGER_get(sk_ASN1_INTEGER_value(stack, i))));
|
||||
}
|
||||
}
|
||||
|
||||
template <Tag tag>
|
||||
void copyAuthTag(const ASN1_INTEGER* asn1_int, TypedTag<TagType::ENUM, tag> ttag,
|
||||
AuthorizationSet* auth_list) {
|
||||
typedef typename TypedTag2ValueType<decltype(ttag)>::type ValueT;
|
||||
if (!asn1_int) return;
|
||||
auth_list->push_back(ttag, static_cast<ValueT>(ASN1_INTEGER_get(asn1_int)));
|
||||
}
|
||||
|
||||
template <Tag tag>
|
||||
void copyAuthTag(const ASN1_INTEGER* asn1_int, TypedTag<TagType::UINT, tag> ttag,
|
||||
AuthorizationSet* auth_list) {
|
||||
if (!asn1_int) return;
|
||||
auth_list->push_back(ttag, ASN1_INTEGER_get(asn1_int));
|
||||
}
|
||||
|
||||
BIGNUM* construct_uint_max() {
|
||||
BIGNUM* value = BN_new();
|
||||
BIGNUM_Ptr one(BN_new());
|
||||
BN_one(one.get());
|
||||
BN_lshift(value, one.get(), 32);
|
||||
return value;
|
||||
}
|
||||
|
||||
uint64_t BignumToUint64(BIGNUM* num) {
|
||||
static_assert((sizeof(BN_ULONG) == sizeof(uint32_t)) || (sizeof(BN_ULONG) == sizeof(uint64_t)),
|
||||
"This implementation only supports 32 and 64-bit BN_ULONG");
|
||||
if (sizeof(BN_ULONG) == sizeof(uint32_t)) {
|
||||
BIGNUM_Ptr uint_max(construct_uint_max());
|
||||
BIGNUM_Ptr hi(BN_new()), lo(BN_new());
|
||||
BN_CTX_Ptr ctx(BN_CTX_new());
|
||||
BN_div(hi.get(), lo.get(), num, uint_max.get(), ctx.get());
|
||||
return static_cast<uint64_t>(BN_get_word(hi.get())) << 32 | BN_get_word(lo.get());
|
||||
} else if (sizeof(BN_ULONG) == sizeof(uint64_t)) {
|
||||
return BN_get_word(num);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
template <Tag tag>
|
||||
void copyAuthTag(const ASN1_INTEGER* asn1_int, TypedTag<TagType::ULONG, tag> ttag,
|
||||
AuthorizationSet* auth_list) {
|
||||
if (!asn1_int) return;
|
||||
BIGNUM_Ptr num(ASN1_INTEGER_to_BN(asn1_int, nullptr));
|
||||
auth_list->push_back(ttag, BignumToUint64(num.get()));
|
||||
}
|
||||
|
||||
template <Tag tag>
|
||||
void copyAuthTag(const ASN1_INTEGER* asn1_int, TypedTag<TagType::DATE, tag> ttag,
|
||||
AuthorizationSet* auth_list) {
|
||||
if (!asn1_int) return;
|
||||
BIGNUM_Ptr num(ASN1_INTEGER_to_BN(asn1_int, nullptr));
|
||||
auth_list->push_back(ttag, BignumToUint64(num.get()));
|
||||
}
|
||||
|
||||
template <Tag tag>
|
||||
void copyAuthTag(const ASN1_NULL* asn1_null, TypedTag<TagType::BOOL, tag> ttag,
|
||||
AuthorizationSet* auth_list) {
|
||||
if (!asn1_null) return;
|
||||
auth_list->push_back(ttag);
|
||||
}
|
||||
|
||||
template <Tag tag>
|
||||
void copyAuthTag(const ASN1_OCTET_STRING* asn1_string, TypedTag<TagType::BYTES, tag> ttag,
|
||||
AuthorizationSet* auth_list) {
|
||||
if (!asn1_string) return;
|
||||
vector<uint8_t> buf(asn1_string->data, asn1_string->data + asn1_string->length);
|
||||
auth_list->push_back(ttag, buf);
|
||||
}
|
||||
|
||||
// Extract the values from the specified ASN.1 record and place them in auth_list.
|
||||
static ErrorCode extract_auth_list(const KM_AUTH_LIST* record, AuthorizationSet* auth_list) {
|
||||
if (!record) return ErrorCode::OK;
|
||||
|
||||
copyAuthTag(record->active_date_time, TAG_ACTIVE_DATETIME, auth_list);
|
||||
copyAuthTag(record->algorithm, TAG_ALGORITHM, auth_list);
|
||||
copyAuthTag(record->application_id, TAG_APPLICATION_ID, auth_list);
|
||||
copyAuthTag(record->auth_timeout, TAG_AUTH_TIMEOUT, auth_list);
|
||||
copyAuthTag(record->creation_date_time, TAG_CREATION_DATETIME, auth_list);
|
||||
copyAuthTag(record->digest, TAG_DIGEST, auth_list);
|
||||
copyAuthTag(record->ec_curve, TAG_EC_CURVE, auth_list);
|
||||
copyAuthTag(record->key_size, TAG_KEY_SIZE, auth_list);
|
||||
copyAuthTag(record->no_auth_required, TAG_NO_AUTH_REQUIRED, auth_list);
|
||||
copyAuthTag(record->origin, TAG_ORIGIN, auth_list);
|
||||
copyAuthTag(record->origination_expire_date_time, TAG_ORIGINATION_EXPIRE_DATETIME, auth_list);
|
||||
copyAuthTag(record->os_patchlevel, TAG_OS_PATCHLEVEL, auth_list);
|
||||
copyAuthTag(record->os_version, TAG_OS_VERSION, auth_list);
|
||||
copyAuthTag(record->padding, TAG_PADDING, auth_list);
|
||||
copyAuthTag(record->purpose, TAG_PURPOSE, auth_list);
|
||||
copyAuthTag(record->rollback_resistance, TAG_ROLLBACK_RESISTANCE, auth_list);
|
||||
copyAuthTag(record->rsa_public_exponent, TAG_RSA_PUBLIC_EXPONENT, auth_list);
|
||||
copyAuthTag(record->usage_expire_date_time, TAG_USAGE_EXPIRE_DATETIME, auth_list);
|
||||
copyAuthTag(record->user_auth_type, TAG_USER_AUTH_TYPE, auth_list);
|
||||
copyAuthTag(record->attestation_application_id, TAG_ATTESTATION_APPLICATION_ID, auth_list);
|
||||
copyAuthTag(record->vendor_patchlevel, TAG_VENDOR_PATCHLEVEL, auth_list);
|
||||
copyAuthTag(record->boot_patchlevel, TAG_BOOT_PATCHLEVEL, auth_list);
|
||||
copyAuthTag(record->trusted_user_presence_required, TAG_TRUSTED_USER_PRESENCE_REQUIRED,
|
||||
auth_list);
|
||||
copyAuthTag(record->trusted_confirmation_required, TAG_TRUSTED_CONFIRMATION_REQUIRED,
|
||||
auth_list);
|
||||
copyAuthTag(record->unlocked_device_required, TAG_UNLOCKED_DEVICE_REQUIRED, auth_list);
|
||||
copyAuthTag(record->early_boot_only, TAG_EARLY_BOOT_ONLY, auth_list);
|
||||
copyAuthTag(record->device_unique_attestation, TAG_DEVICE_UNIQUE_ATTESTATION, auth_list);
|
||||
copyAuthTag(record->storage_key, TAG_STORAGE_KEY, auth_list);
|
||||
copyAuthTag(record->identity_credential, TAG_IDENTITY_CREDENTIAL_KEY, auth_list);
|
||||
|
||||
return ErrorCode::OK;
|
||||
}
|
||||
|
||||
MAKE_OPENSSL_PTR_TYPE(KM_KEY_DESCRIPTION)
|
||||
|
||||
// Parse the DER-encoded attestation record, placing the results in keymint_version,
|
||||
// attestation_challenge, software_enforced, tee_enforced and unique_id.
|
||||
ErrorCode parse_attestation_record(const uint8_t* asn1_key_desc, size_t asn1_key_desc_len,
|
||||
uint32_t* attestation_version, //
|
||||
SecurityLevel* attestation_security_level,
|
||||
uint32_t* keymint_version, SecurityLevel* keymint_security_level,
|
||||
vector<uint8_t>* attestation_challenge,
|
||||
AuthorizationSet* software_enforced,
|
||||
AuthorizationSet* tee_enforced, //
|
||||
vector<uint8_t>* unique_id) {
|
||||
const uint8_t* p = asn1_key_desc;
|
||||
KM_KEY_DESCRIPTION_Ptr record(d2i_KM_KEY_DESCRIPTION(nullptr, &p, asn1_key_desc_len));
|
||||
if (!record.get()) return ErrorCode::UNKNOWN_ERROR;
|
||||
|
||||
*attestation_version = ASN1_INTEGER_get(record->attestation_version);
|
||||
*attestation_security_level =
|
||||
static_cast<SecurityLevel>(ASN1_ENUMERATED_get(record->attestation_security_level));
|
||||
*keymint_version = ASN1_INTEGER_get(record->keymint_version);
|
||||
*keymint_security_level =
|
||||
static_cast<SecurityLevel>(ASN1_ENUMERATED_get(record->keymint_security_level));
|
||||
|
||||
auto& chall = record->attestation_challenge;
|
||||
attestation_challenge->resize(chall->length);
|
||||
memcpy(attestation_challenge->data(), chall->data, chall->length);
|
||||
auto& uid = record->unique_id;
|
||||
unique_id->resize(uid->length);
|
||||
memcpy(unique_id->data(), uid->data, uid->length);
|
||||
|
||||
ErrorCode error = extract_auth_list(record->software_enforced, software_enforced);
|
||||
if (error != ErrorCode::OK) return error;
|
||||
|
||||
return extract_auth_list(record->tee_enforced, tee_enforced);
|
||||
}
|
||||
|
||||
ErrorCode parse_root_of_trust(const uint8_t* asn1_key_desc, size_t asn1_key_desc_len,
|
||||
vector<uint8_t>* verified_boot_key,
|
||||
keymint_verified_boot_t* verified_boot_state, bool* device_locked,
|
||||
vector<uint8_t>* verified_boot_hash) {
|
||||
if (!verified_boot_key || !verified_boot_state || !device_locked || !verified_boot_hash) {
|
||||
LOG(ERROR) << AT << "null pointer input(s)";
|
||||
return ErrorCode::INVALID_ARGUMENT;
|
||||
}
|
||||
const uint8_t* p = asn1_key_desc;
|
||||
KM_KEY_DESCRIPTION_Ptr record(d2i_KM_KEY_DESCRIPTION(nullptr, &p, asn1_key_desc_len));
|
||||
if (!record.get()) {
|
||||
LOG(ERROR) << AT << "Failed record parsing";
|
||||
return ErrorCode::UNKNOWN_ERROR;
|
||||
}
|
||||
|
||||
KM_ROOT_OF_TRUST* root_of_trust = nullptr;
|
||||
if (record->tee_enforced && record->tee_enforced->root_of_trust) {
|
||||
root_of_trust = record->tee_enforced->root_of_trust;
|
||||
} else if (record->software_enforced && record->software_enforced->root_of_trust) {
|
||||
root_of_trust = record->software_enforced->root_of_trust;
|
||||
} else {
|
||||
LOG(ERROR) << AT << " Failed root of trust parsing";
|
||||
return ErrorCode::INVALID_ARGUMENT;
|
||||
}
|
||||
if (!root_of_trust->verified_boot_key) {
|
||||
LOG(ERROR) << AT << " Failed verified boot key parsing";
|
||||
return ErrorCode::INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
auto& vb_key = root_of_trust->verified_boot_key;
|
||||
verified_boot_key->resize(vb_key->length);
|
||||
memcpy(verified_boot_key->data(), vb_key->data, vb_key->length);
|
||||
|
||||
*verified_boot_state = static_cast<keymint_verified_boot_t>(
|
||||
ASN1_ENUMERATED_get(root_of_trust->verified_boot_state));
|
||||
if (!verified_boot_state) {
|
||||
LOG(ERROR) << AT << " Failed verified boot state parsing";
|
||||
return ErrorCode::INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
*device_locked = root_of_trust->device_locked;
|
||||
if (!device_locked) {
|
||||
LOG(ERROR) << AT << " Failed device locked parsing";
|
||||
return ErrorCode::INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
auto& vb_hash = root_of_trust->verified_boot_hash;
|
||||
if (!vb_hash) {
|
||||
LOG(ERROR) << AT << " Failed verified boot hash parsing";
|
||||
return ErrorCode::INVALID_ARGUMENT;
|
||||
}
|
||||
verified_boot_hash->resize(vb_hash->length);
|
||||
memcpy(verified_boot_hash->data(), vb_hash->data, vb_hash->length);
|
||||
return ErrorCode::OK; // KM_ERROR_OK;
|
||||
}
|
||||
|
||||
} // namespace keymint
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
529
keymint/support/authorization_set.cpp
Normal file
529
keymint/support/authorization_set.cpp
Normal file
@@ -0,0 +1,529 @@
|
||||
/*
|
||||
* Copyright 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.
|
||||
*/
|
||||
|
||||
#include <keymintSupport/authorization_set.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include <android-base/logging.h>
|
||||
#include <sstream>
|
||||
|
||||
#include <android/hardware/keymint/Algorithm.h>
|
||||
#include <android/hardware/keymint/BlockMode.h>
|
||||
#include <android/hardware/keymint/Digest.h>
|
||||
#include <android/hardware/keymint/KeyParameter.h>
|
||||
#include <android/hardware/keymint/KeyPurpose.h>
|
||||
#include <android/hardware/keymint/TagType.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace keymint {
|
||||
|
||||
void AuthorizationSet::Sort() {
|
||||
std::sort(data_.begin(), data_.end());
|
||||
}
|
||||
|
||||
void AuthorizationSet::Deduplicate() {
|
||||
if (data_.empty()) return;
|
||||
|
||||
Sort();
|
||||
std::vector<KeyParameter> result;
|
||||
|
||||
auto curr = data_.begin();
|
||||
auto prev = curr++;
|
||||
for (; curr != data_.end(); ++prev, ++curr) {
|
||||
if (prev->tag == Tag::INVALID) continue;
|
||||
|
||||
if (*prev != *curr) {
|
||||
result.push_back(std::move(*prev));
|
||||
}
|
||||
}
|
||||
result.push_back(std::move(*prev));
|
||||
|
||||
std::swap(data_, result);
|
||||
}
|
||||
|
||||
void AuthorizationSet::Union(const AuthorizationSet& other) {
|
||||
data_.insert(data_.end(), other.data_.begin(), other.data_.end());
|
||||
Deduplicate();
|
||||
}
|
||||
|
||||
void AuthorizationSet::Subtract(const AuthorizationSet& other) {
|
||||
Deduplicate();
|
||||
|
||||
auto i = other.begin();
|
||||
while (i != other.end()) {
|
||||
int pos = -1;
|
||||
do {
|
||||
pos = find(i->tag, pos);
|
||||
if (pos != -1 && (*i == data_[pos])) {
|
||||
data_.erase(data_.begin() + pos);
|
||||
break;
|
||||
}
|
||||
} while (pos != -1);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
void AuthorizationSet::Filter(std::function<bool(const KeyParameter&)> doKeep) {
|
||||
std::vector<KeyParameter> result;
|
||||
for (auto& param : data_) {
|
||||
if (doKeep(param)) {
|
||||
result.push_back(std::move(param));
|
||||
}
|
||||
}
|
||||
std::swap(data_, result);
|
||||
}
|
||||
|
||||
KeyParameter& AuthorizationSet::operator[](int at) {
|
||||
return data_[at];
|
||||
}
|
||||
|
||||
const KeyParameter& AuthorizationSet::operator[](int at) const {
|
||||
return data_[at];
|
||||
}
|
||||
|
||||
void AuthorizationSet::Clear() {
|
||||
data_.clear();
|
||||
}
|
||||
|
||||
size_t AuthorizationSet::GetTagCount(Tag tag) const {
|
||||
size_t count = 0;
|
||||
for (int pos = -1; (pos = find(tag, pos)) != -1;) ++count;
|
||||
return count;
|
||||
}
|
||||
|
||||
int AuthorizationSet::find(Tag tag, int begin) const {
|
||||
auto iter = data_.begin() + (1 + begin);
|
||||
|
||||
while (iter != data_.end() && iter->tag != tag) ++iter;
|
||||
|
||||
if (iter != data_.end()) return iter - data_.begin();
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool AuthorizationSet::erase(int index) {
|
||||
auto pos = data_.begin() + index;
|
||||
if (pos != data_.end()) {
|
||||
data_.erase(pos);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
NullOr<const KeyParameter&> AuthorizationSet::GetEntry(Tag tag) const {
|
||||
int pos = find(tag);
|
||||
if (pos == -1) return {};
|
||||
return data_[pos];
|
||||
}
|
||||
|
||||
/**
|
||||
* Persistent format is:
|
||||
* | 32 bit indirect_size |
|
||||
* --------------------------------
|
||||
* | indirect_size bytes of data | this is where the blob data is stored
|
||||
* --------------------------------
|
||||
* | 32 bit element_count | number of entries
|
||||
* | 32 bit elements_size | total bytes used by entries (entries have variable length)
|
||||
* --------------------------------
|
||||
* | elementes_size bytes of data | where the elements are stored
|
||||
*/
|
||||
|
||||
/**
|
||||
* Persistent format of blobs and bignums:
|
||||
* | 32 bit tag |
|
||||
* | 32 bit blob_length |
|
||||
* | 32 bit indirect_offset |
|
||||
*/
|
||||
|
||||
struct OutStreams {
|
||||
std::ostream& indirect;
|
||||
std::ostream& elements;
|
||||
size_t skipped;
|
||||
};
|
||||
|
||||
OutStreams& serializeParamValue(OutStreams& out, const vector<uint8_t>& blob) {
|
||||
uint32_t buffer;
|
||||
|
||||
// write blob_length
|
||||
auto blob_length = blob.size();
|
||||
if (blob_length > std::numeric_limits<uint32_t>::max()) {
|
||||
out.elements.setstate(std::ios_base::badbit);
|
||||
return out;
|
||||
}
|
||||
buffer = blob_length;
|
||||
out.elements.write(reinterpret_cast<const char*>(&buffer), sizeof(uint32_t));
|
||||
|
||||
// write indirect_offset
|
||||
auto offset = out.indirect.tellp();
|
||||
if (offset < 0 || offset > std::numeric_limits<uint32_t>::max() ||
|
||||
uint32_t(offset) + uint32_t(blob_length) < uint32_t(offset)) { // overflow check
|
||||
out.elements.setstate(std::ios_base::badbit);
|
||||
return out;
|
||||
}
|
||||
buffer = offset;
|
||||
out.elements.write(reinterpret_cast<const char*>(&buffer), sizeof(uint32_t));
|
||||
|
||||
// write blob to indirect stream
|
||||
if (blob_length) out.indirect.write(reinterpret_cast<const char*>(&blob[0]), blob_length);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
OutStreams& serializeParamValue(OutStreams& out, const T& value) {
|
||||
out.elements.write(reinterpret_cast<const char*>(&value), sizeof(T));
|
||||
return out;
|
||||
}
|
||||
|
||||
OutStreams& serialize(TAG_INVALID_t&&, OutStreams& out, const KeyParameter&) {
|
||||
// skip invalid entries.
|
||||
++out.skipped;
|
||||
return out;
|
||||
}
|
||||
template <typename T>
|
||||
OutStreams& serialize(T ttag, OutStreams& out, const KeyParameter& param) {
|
||||
out.elements.write(reinterpret_cast<const char*>(¶m.tag), sizeof(int32_t));
|
||||
return serializeParamValue(out, accessTagValue(ttag, param));
|
||||
}
|
||||
|
||||
template <typename... T>
|
||||
struct choose_serializer;
|
||||
template <typename... Tags>
|
||||
struct choose_serializer<MetaList<Tags...>> {
|
||||
static OutStreams& serialize(OutStreams& out, const KeyParameter& param) {
|
||||
return choose_serializer<Tags...>::serialize(out, param);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct choose_serializer<> {
|
||||
static OutStreams& serialize(OutStreams& out, const KeyParameter& param) {
|
||||
LOG(WARNING) << "Trying to serialize unknown tag " << unsigned(param.tag)
|
||||
<< ". Did you forget to add it to all_tags_t?";
|
||||
++out.skipped;
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
template <TagType tag_type, Tag tag, typename... Tail>
|
||||
struct choose_serializer<android::hardware::keymint::TypedTag<tag_type, tag>, Tail...> {
|
||||
static OutStreams& serialize(OutStreams& out, const KeyParameter& param) {
|
||||
if (param.tag == tag) {
|
||||
return android::hardware::keymint::serialize(TypedTag<tag_type, tag>(), out, param);
|
||||
} else {
|
||||
return choose_serializer<Tail...>::serialize(out, param);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
OutStreams& serialize(OutStreams& out, const KeyParameter& param) {
|
||||
return choose_serializer<all_tags_t>::serialize(out, param);
|
||||
}
|
||||
|
||||
std::ostream& serialize(std::ostream& out, const std::vector<KeyParameter>& params) {
|
||||
std::stringstream indirect;
|
||||
std::stringstream elements;
|
||||
OutStreams streams = {indirect, elements, 0};
|
||||
for (const auto& param : params) {
|
||||
serialize(streams, param);
|
||||
}
|
||||
if (indirect.bad() || elements.bad()) {
|
||||
out.setstate(std::ios_base::badbit);
|
||||
return out;
|
||||
}
|
||||
auto pos = indirect.tellp();
|
||||
if (pos < 0 || pos > std::numeric_limits<uint32_t>::max()) {
|
||||
out.setstate(std::ios_base::badbit);
|
||||
return out;
|
||||
}
|
||||
uint32_t indirect_size = pos;
|
||||
pos = elements.tellp();
|
||||
if (pos < 0 || pos > std::numeric_limits<uint32_t>::max()) {
|
||||
out.setstate(std::ios_base::badbit);
|
||||
return out;
|
||||
}
|
||||
uint32_t elements_size = pos;
|
||||
uint32_t element_count = params.size() - streams.skipped;
|
||||
|
||||
out.write(reinterpret_cast<const char*>(&indirect_size), sizeof(uint32_t));
|
||||
|
||||
pos = out.tellp();
|
||||
if (indirect_size) out << indirect.rdbuf();
|
||||
assert(out.tellp() - pos == indirect_size);
|
||||
|
||||
out.write(reinterpret_cast<const char*>(&element_count), sizeof(uint32_t));
|
||||
out.write(reinterpret_cast<const char*>(&elements_size), sizeof(uint32_t));
|
||||
|
||||
pos = out.tellp();
|
||||
if (elements_size) out << elements.rdbuf();
|
||||
assert(out.tellp() - pos == elements_size);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
struct InStreams {
|
||||
std::istream& indirect;
|
||||
std::istream& elements;
|
||||
size_t invalids;
|
||||
};
|
||||
|
||||
InStreams& deserializeParamValue(InStreams& in, vector<uint8_t>* blob) {
|
||||
uint32_t blob_length = 0;
|
||||
uint32_t offset = 0;
|
||||
in.elements.read(reinterpret_cast<char*>(&blob_length), sizeof(uint32_t));
|
||||
blob->resize(blob_length);
|
||||
in.elements.read(reinterpret_cast<char*>(&offset), sizeof(uint32_t));
|
||||
in.indirect.seekg(offset);
|
||||
in.indirect.read(reinterpret_cast<char*>(&(*blob)[0]), blob->size());
|
||||
return in;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
InStreams& deserializeParamValue(InStreams& in, T* value) {
|
||||
in.elements.read(reinterpret_cast<char*>(value), sizeof(T));
|
||||
return in;
|
||||
}
|
||||
|
||||
InStreams& deserialize(TAG_INVALID_t&&, InStreams& in, KeyParameter*) {
|
||||
// there should be no invalid KeyParameters but if handle them as zero sized.
|
||||
++in.invalids;
|
||||
return in;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
InStreams& deserialize(T&& ttag, InStreams& in, KeyParameter* param) {
|
||||
return deserializeParamValue(in, &accessTagValue(ttag, *param));
|
||||
}
|
||||
|
||||
template <typename... T>
|
||||
struct choose_deserializer;
|
||||
template <typename... Tags>
|
||||
struct choose_deserializer<MetaList<Tags...>> {
|
||||
static InStreams& deserialize(InStreams& in, KeyParameter* param) {
|
||||
return choose_deserializer<Tags...>::deserialize(in, param);
|
||||
}
|
||||
};
|
||||
template <>
|
||||
struct choose_deserializer<> {
|
||||
static InStreams& deserialize(InStreams& in, KeyParameter*) {
|
||||
// encountered an unknown tag -> fail parsing
|
||||
in.elements.setstate(std::ios_base::badbit);
|
||||
return in;
|
||||
}
|
||||
};
|
||||
template <TagType tag_type, Tag tag, typename... Tail>
|
||||
struct choose_deserializer<TypedTag<tag_type, tag>, Tail...> {
|
||||
static InStreams& deserialize(InStreams& in, KeyParameter* param) {
|
||||
if (param->tag == tag) {
|
||||
return android::hardware::keymint::deserialize(TypedTag<tag_type, tag>(), in, param);
|
||||
} else {
|
||||
return choose_deserializer<Tail...>::deserialize(in, param);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
InStreams& deserialize(InStreams& in, KeyParameter* param) {
|
||||
in.elements.read(reinterpret_cast<char*>(¶m->tag), sizeof(Tag));
|
||||
return choose_deserializer<all_tags_t>::deserialize(in, param);
|
||||
}
|
||||
|
||||
std::istream& deserialize(std::istream& in, std::vector<KeyParameter>* params) {
|
||||
uint32_t indirect_size = 0;
|
||||
in.read(reinterpret_cast<char*>(&indirect_size), sizeof(uint32_t));
|
||||
std::string indirect_buffer(indirect_size, '\0');
|
||||
if (indirect_buffer.size() != indirect_size) {
|
||||
in.setstate(std::ios_base::badbit);
|
||||
return in;
|
||||
}
|
||||
in.read(&indirect_buffer[0], indirect_buffer.size());
|
||||
|
||||
uint32_t element_count = 0;
|
||||
in.read(reinterpret_cast<char*>(&element_count), sizeof(uint32_t));
|
||||
uint32_t elements_size = 0;
|
||||
in.read(reinterpret_cast<char*>(&elements_size), sizeof(uint32_t));
|
||||
|
||||
std::string elements_buffer(elements_size, '\0');
|
||||
if (elements_buffer.size() != elements_size) {
|
||||
in.setstate(std::ios_base::badbit);
|
||||
return in;
|
||||
}
|
||||
in.read(&elements_buffer[0], elements_buffer.size());
|
||||
|
||||
if (in.bad()) return in;
|
||||
|
||||
// TODO write one-shot stream buffer to avoid copying here
|
||||
std::stringstream indirect(indirect_buffer);
|
||||
std::stringstream elements(elements_buffer);
|
||||
InStreams streams = {indirect, elements, 0};
|
||||
|
||||
params->resize(element_count);
|
||||
|
||||
for (uint32_t i = 0; i < element_count; ++i) {
|
||||
deserialize(streams, &(*params)[i]);
|
||||
}
|
||||
|
||||
/*
|
||||
* There are legacy blobs which have invalid tags in them due to a bug during serialization.
|
||||
* This makes sure that invalid tags are filtered from the result before it is returned.
|
||||
*/
|
||||
if (streams.invalids > 0) {
|
||||
std::vector<KeyParameter> filtered(element_count - streams.invalids);
|
||||
auto ifiltered = filtered.begin();
|
||||
for (auto& p : *params) {
|
||||
if (p.tag != Tag::INVALID) {
|
||||
*ifiltered++ = std::move(p);
|
||||
}
|
||||
}
|
||||
*params = std::move(filtered);
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
||||
void AuthorizationSet::Serialize(std::ostream* out) const {
|
||||
serialize(*out, data_);
|
||||
}
|
||||
|
||||
void AuthorizationSet::Deserialize(std::istream* in) {
|
||||
deserialize(*in, &data_);
|
||||
}
|
||||
|
||||
AuthorizationSetBuilder& AuthorizationSetBuilder::RsaKey(uint32_t key_size,
|
||||
uint64_t public_exponent) {
|
||||
Authorization(TAG_ALGORITHM, Algorithm::RSA);
|
||||
Authorization(TAG_KEY_SIZE, key_size);
|
||||
Authorization(TAG_RSA_PUBLIC_EXPONENT, public_exponent);
|
||||
return *this;
|
||||
}
|
||||
|
||||
AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaKey(uint32_t key_size) {
|
||||
Authorization(TAG_ALGORITHM, Algorithm::EC);
|
||||
Authorization(TAG_KEY_SIZE, key_size);
|
||||
return *this;
|
||||
}
|
||||
|
||||
AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaKey(EcCurve curve) {
|
||||
Authorization(TAG_ALGORITHM, Algorithm::EC);
|
||||
Authorization(TAG_EC_CURVE, curve);
|
||||
return *this;
|
||||
}
|
||||
|
||||
AuthorizationSetBuilder& AuthorizationSetBuilder::AesKey(uint32_t key_size) {
|
||||
Authorization(TAG_ALGORITHM, Algorithm::AES);
|
||||
return Authorization(TAG_KEY_SIZE, key_size);
|
||||
}
|
||||
|
||||
AuthorizationSetBuilder& AuthorizationSetBuilder::TripleDesKey(uint32_t key_size) {
|
||||
Authorization(TAG_ALGORITHM, Algorithm::TRIPLE_DES);
|
||||
return Authorization(TAG_KEY_SIZE, key_size);
|
||||
}
|
||||
|
||||
AuthorizationSetBuilder& AuthorizationSetBuilder::HmacKey(uint32_t key_size) {
|
||||
Authorization(TAG_ALGORITHM, Algorithm::HMAC);
|
||||
Authorization(TAG_KEY_SIZE, key_size);
|
||||
return SigningKey();
|
||||
}
|
||||
|
||||
AuthorizationSetBuilder& AuthorizationSetBuilder::RsaSigningKey(uint32_t key_size,
|
||||
uint64_t public_exponent) {
|
||||
RsaKey(key_size, public_exponent);
|
||||
return SigningKey();
|
||||
}
|
||||
|
||||
AuthorizationSetBuilder& AuthorizationSetBuilder::RsaEncryptionKey(uint32_t key_size,
|
||||
uint64_t public_exponent) {
|
||||
RsaKey(key_size, public_exponent);
|
||||
return EncryptionKey();
|
||||
}
|
||||
|
||||
AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaSigningKey(uint32_t key_size) {
|
||||
EcdsaKey(key_size);
|
||||
return SigningKey();
|
||||
}
|
||||
|
||||
AuthorizationSetBuilder& AuthorizationSetBuilder::EcdsaSigningKey(EcCurve curve) {
|
||||
EcdsaKey(curve);
|
||||
return SigningKey();
|
||||
}
|
||||
|
||||
AuthorizationSetBuilder& AuthorizationSetBuilder::AesEncryptionKey(uint32_t key_size) {
|
||||
AesKey(key_size);
|
||||
return EncryptionKey();
|
||||
}
|
||||
|
||||
AuthorizationSetBuilder& AuthorizationSetBuilder::TripleDesEncryptionKey(uint32_t key_size) {
|
||||
TripleDesKey(key_size);
|
||||
return EncryptionKey();
|
||||
}
|
||||
|
||||
AuthorizationSetBuilder& AuthorizationSetBuilder::SigningKey() {
|
||||
Authorization(TAG_PURPOSE, KeyPurpose::SIGN);
|
||||
return Authorization(TAG_PURPOSE, KeyPurpose::VERIFY);
|
||||
}
|
||||
|
||||
AuthorizationSetBuilder& AuthorizationSetBuilder::EncryptionKey() {
|
||||
Authorization(TAG_PURPOSE, KeyPurpose::ENCRYPT);
|
||||
return Authorization(TAG_PURPOSE, KeyPurpose::DECRYPT);
|
||||
}
|
||||
|
||||
AuthorizationSetBuilder& AuthorizationSetBuilder::NoDigestOrPadding() {
|
||||
Authorization(TAG_DIGEST, Digest::NONE);
|
||||
return Authorization(TAG_PADDING, PaddingMode::NONE);
|
||||
}
|
||||
|
||||
AuthorizationSetBuilder& AuthorizationSetBuilder::EcbMode() {
|
||||
return Authorization(TAG_BLOCK_MODE, BlockMode::ECB);
|
||||
}
|
||||
|
||||
AuthorizationSetBuilder& AuthorizationSetBuilder::GcmModeMinMacLen(uint32_t minMacLength) {
|
||||
return BlockMode(BlockMode::GCM)
|
||||
.Padding(PaddingMode::NONE)
|
||||
.Authorization(TAG_MIN_MAC_LENGTH, minMacLength);
|
||||
}
|
||||
|
||||
AuthorizationSetBuilder& AuthorizationSetBuilder::GcmModeMacLen(uint32_t macLength) {
|
||||
return BlockMode(BlockMode::GCM)
|
||||
.Padding(PaddingMode::NONE)
|
||||
.Authorization(TAG_MAC_LENGTH, macLength);
|
||||
}
|
||||
|
||||
AuthorizationSetBuilder& AuthorizationSetBuilder::BlockMode(
|
||||
std::initializer_list<android::hardware::keymint::BlockMode> blockModes) {
|
||||
for (auto mode : blockModes) {
|
||||
push_back(TAG_BLOCK_MODE, mode);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
AuthorizationSetBuilder& AuthorizationSetBuilder::Digest(
|
||||
std::vector<android::hardware::keymint::Digest> digests) {
|
||||
for (auto digest : digests) {
|
||||
push_back(TAG_DIGEST, digest);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
AuthorizationSetBuilder& AuthorizationSetBuilder::Padding(
|
||||
std::initializer_list<PaddingMode> paddingModes) {
|
||||
for (auto paddingMode : paddingModes) {
|
||||
push_back(TAG_PADDING, paddingMode);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
} // namespace keymint
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
95
keymint/support/include/keymintSupport/attestation_record.h
Normal file
95
keymint/support/include/keymintSupport/attestation_record.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <android/hardware/keymint/ErrorCode.h>
|
||||
#include <android/hardware/keymint/IKeyMintDevice.h>
|
||||
|
||||
#include <keymintSupport/attestation_record.h>
|
||||
#include <keymintSupport/authorization_set.h>
|
||||
#include <keymintSupport/openssl_utils.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace keymint {
|
||||
|
||||
using android::hardware::keymint::KeyParameter;
|
||||
using android::hardware::keymint::Tag;
|
||||
using android::hardware::keymint::TAG_ALGORITHM;
|
||||
|
||||
class AuthorizationSet;
|
||||
|
||||
/**
|
||||
* The OID for Android attestation records. For the curious, it breaks down as follows:
|
||||
*
|
||||
* 1 = ISO
|
||||
* 3 = org
|
||||
* 6 = DoD (Huh? OIDs are weird.)
|
||||
* 1 = IANA
|
||||
* 4 = Private
|
||||
* 1 = Enterprises
|
||||
* 11129 = Google
|
||||
* 2 = Google security
|
||||
* 1 = certificate extension
|
||||
* 17 = Android attestation extension.
|
||||
*/
|
||||
static const char kAttestionRecordOid[] = "1.3.6.1.4.1.11129.2.1.17";
|
||||
|
||||
enum keymint_verified_boot_t {
|
||||
KM_VERIFIED_BOOT_VERIFIED = 0,
|
||||
KM_VERIFIED_BOOT_SELF_SIGNED = 1,
|
||||
KM_VERIFIED_BOOT_UNVERIFIED = 2,
|
||||
KM_VERIFIED_BOOT_FAILED = 3,
|
||||
};
|
||||
|
||||
struct RootOfTrust {
|
||||
SecurityLevel security_level;
|
||||
vector<uint8_t> verified_boot_key;
|
||||
vector<uint8_t> verified_boot_hash;
|
||||
keymint_verified_boot_t verified_boot_state;
|
||||
bool device_locked;
|
||||
};
|
||||
|
||||
struct AttestationRecord {
|
||||
RootOfTrust root_of_trust;
|
||||
uint32_t attestation_version;
|
||||
SecurityLevel attestation_security_level;
|
||||
uint32_t keymint_version;
|
||||
SecurityLevel keymint_security_level;
|
||||
std::vector<uint8_t> attestation_challenge;
|
||||
AuthorizationSet software_enforced;
|
||||
AuthorizationSet hardware_enforced;
|
||||
std::vector<uint8_t> unique_id;
|
||||
};
|
||||
|
||||
ErrorCode parse_attestation_record(const uint8_t* asn1_key_desc, size_t asn1_key_desc_len,
|
||||
uint32_t* attestation_version, //
|
||||
SecurityLevel* attestation_security_level,
|
||||
uint32_t* keymint_version, SecurityLevel* keymint_security_level,
|
||||
std::vector<uint8_t>* attestation_challenge,
|
||||
AuthorizationSet* software_enforced,
|
||||
AuthorizationSet* tee_enforced, //
|
||||
std::vector<uint8_t>* unique_id);
|
||||
|
||||
ErrorCode parse_root_of_trust(const uint8_t* asn1_key_desc, size_t asn1_key_desc_len,
|
||||
std::vector<uint8_t>* verified_boot_key,
|
||||
keymint_verified_boot_t* verified_boot_state, bool* device_locked,
|
||||
std::vector<uint8_t>* verified_boot_hash);
|
||||
|
||||
} // namespace keymint
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
329
keymint/support/include/keymintSupport/authorization_set.h
Normal file
329
keymint/support/include/keymintSupport/authorization_set.h
Normal file
@@ -0,0 +1,329 @@
|
||||
/*
|
||||
* Copyright 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.
|
||||
*/
|
||||
|
||||
#ifndef SYSTEM_SECURITY_KEYSTORE_KM4_AUTHORIZATION_SET_H_
|
||||
#define SYSTEM_SECURITY_KEYSTORE_KM4_AUTHORIZATION_SET_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <android/hardware/keymint/BlockMode.h>
|
||||
#include <android/hardware/keymint/Digest.h>
|
||||
#include <android/hardware/keymint/EcCurve.h>
|
||||
#include <android/hardware/keymint/PaddingMode.h>
|
||||
|
||||
#include <keymintSupport/keymint_tags.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace keymint {
|
||||
|
||||
using android::hardware::keymint::BlockMode;
|
||||
using android::hardware::keymint::Digest;
|
||||
using android::hardware::keymint::EcCurve;
|
||||
using android::hardware::keymint::PaddingMode;
|
||||
|
||||
using std::vector;
|
||||
|
||||
class AuthorizationSetBuilder;
|
||||
|
||||
/**
|
||||
* An ordered collection of KeyParameters. It provides memory ownership and some convenient
|
||||
* functionality for sorting, deduplicating, joining, and subtracting sets of KeyParameters.
|
||||
* For serialization, wrap the backing store of this structure in a vector<KeyParameter>.
|
||||
*/
|
||||
class AuthorizationSet {
|
||||
public:
|
||||
typedef KeyParameter value_type;
|
||||
|
||||
/**
|
||||
* Construct an empty, dynamically-allocated, growable AuthorizationSet.
|
||||
*/
|
||||
AuthorizationSet(){};
|
||||
|
||||
// Copy constructor.
|
||||
AuthorizationSet(const AuthorizationSet& other) : data_(other.data_) {}
|
||||
|
||||
// Move constructor.
|
||||
AuthorizationSet(AuthorizationSet&& other) noexcept : data_(std::move(other.data_)) {}
|
||||
|
||||
// Constructor from vector<KeyParameter>
|
||||
AuthorizationSet(const vector<KeyParameter>& other) { *this = other; }
|
||||
|
||||
// Copy assignment.
|
||||
AuthorizationSet& operator=(const AuthorizationSet& other) {
|
||||
data_ = other.data_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Move assignment.
|
||||
AuthorizationSet& operator=(AuthorizationSet&& other) noexcept {
|
||||
data_ = std::move(other.data_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
AuthorizationSet& operator=(const vector<KeyParameter>& other) {
|
||||
if (other.size() > 0) {
|
||||
data_.resize(other.size());
|
||||
for (size_t i = 0; i < data_.size(); ++i) {
|
||||
/* This makes a deep copy even of embedded blobs.
|
||||
* See assignment operator/copy constructor of vector.*/
|
||||
data_[i] = other[i];
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear existing authorization set data
|
||||
*/
|
||||
void Clear();
|
||||
|
||||
~AuthorizationSet() = default;
|
||||
|
||||
/**
|
||||
* Returns the size of the set.
|
||||
*/
|
||||
size_t size() const { return data_.size(); }
|
||||
|
||||
/**
|
||||
* Returns true if the set is empty.
|
||||
*/
|
||||
bool empty() const { return size() == 0; }
|
||||
|
||||
/**
|
||||
* Returns the data in the set, directly. Be careful with this.
|
||||
*/
|
||||
const KeyParameter* data() const { return data_.data(); }
|
||||
|
||||
/**
|
||||
* Sorts the set
|
||||
*/
|
||||
void Sort();
|
||||
|
||||
/**
|
||||
* Sorts the set and removes duplicates (inadvertently duplicating tags is easy to do with the
|
||||
* AuthorizationSetBuilder).
|
||||
*/
|
||||
void Deduplicate();
|
||||
|
||||
/**
|
||||
* Adds all elements from \p set that are not already present in this AuthorizationSet. As a
|
||||
* side-effect, if \p set is not null this AuthorizationSet will end up sorted.
|
||||
*/
|
||||
void Union(const AuthorizationSet& set);
|
||||
|
||||
/**
|
||||
* Removes all elements in \p set from this AuthorizationSet.
|
||||
*/
|
||||
void Subtract(const AuthorizationSet& set);
|
||||
|
||||
/**
|
||||
* Returns the offset of the next entry that matches \p tag, starting from the element after \p
|
||||
* begin. If not found, returns -1.
|
||||
*/
|
||||
int find(Tag tag, int begin = -1) const;
|
||||
|
||||
/**
|
||||
* Removes the entry at the specified index. Returns true if successful, false if the index was
|
||||
* out of bounds.
|
||||
*/
|
||||
bool erase(int index);
|
||||
|
||||
/**
|
||||
* Returns iterator (pointer) to beginning of elems array, to enable STL-style iteration
|
||||
*/
|
||||
std::vector<KeyParameter>::const_iterator begin() const { return data_.begin(); }
|
||||
|
||||
/**
|
||||
* Returns iterator (pointer) one past end of elems array, to enable STL-style iteration
|
||||
*/
|
||||
std::vector<KeyParameter>::const_iterator end() const { return data_.end(); }
|
||||
|
||||
/**
|
||||
* Modifies this Authorization set such that it only keeps the entries for which doKeep
|
||||
* returns true.
|
||||
*/
|
||||
void Filter(std::function<bool(const KeyParameter&)> doKeep);
|
||||
/**
|
||||
* Returns the nth element of the set.
|
||||
* Like for std::vector::operator[] there is no range check performed. Use of out of range
|
||||
* indices is undefined.
|
||||
*/
|
||||
KeyParameter& operator[](int n);
|
||||
|
||||
/**
|
||||
* Returns the nth element of the set.
|
||||
* Like for std::vector::operator[] there is no range check performed. Use of out of range
|
||||
* indices is undefined.
|
||||
*/
|
||||
const KeyParameter& operator[](int n) const;
|
||||
|
||||
/**
|
||||
* Returns true if the set contains at least one instance of \p tag
|
||||
*/
|
||||
bool Contains(Tag tag) const { return find(tag) != -1; }
|
||||
|
||||
template <TagType tag_type, Tag tag, typename ValueT>
|
||||
bool Contains(TypedTag<tag_type, tag> ttag, const ValueT& value) const {
|
||||
for (const auto& param : data_) {
|
||||
auto entry = authorizationValue(ttag, param);
|
||||
if (entry.isOk() && static_cast<ValueT>(entry.value()) == value) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Returns the number of \p tag entries.
|
||||
*/
|
||||
size_t GetTagCount(Tag tag) const;
|
||||
|
||||
template <typename T>
|
||||
inline NullOr<const typename TypedTag2ValueType<T>::type&> GetTagValue(T tag) const {
|
||||
auto entry = GetEntry(tag);
|
||||
if (entry.isOk()) return authorizationValue(tag, entry.value());
|
||||
return {};
|
||||
}
|
||||
|
||||
void push_back(const KeyParameter& param) { data_.push_back(param); }
|
||||
void push_back(KeyParameter&& param) { data_.push_back(std::move(param)); }
|
||||
void push_back(const AuthorizationSet& set) {
|
||||
for (auto& entry : set) {
|
||||
push_back(entry);
|
||||
}
|
||||
}
|
||||
void push_back(AuthorizationSet&& set) {
|
||||
std::move(set.begin(), set.end(), std::back_inserter(*this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Append the tag and enumerated value to the set.
|
||||
* "val" may be exactly one parameter unless a boolean parameter is added.
|
||||
* In this case "val" is omitted. This condition is checked at compile time by Authorization()
|
||||
*/
|
||||
template <typename TypedTagT, typename... Value>
|
||||
void push_back(TypedTagT tag, Value&&... val) {
|
||||
push_back(Authorization(tag, std::forward<Value>(val)...));
|
||||
}
|
||||
|
||||
template <typename Iterator>
|
||||
void append(Iterator begin, Iterator end) {
|
||||
while (begin != end) {
|
||||
push_back(*begin);
|
||||
++begin;
|
||||
}
|
||||
}
|
||||
|
||||
vector<KeyParameter> vector_data() const {
|
||||
vector<KeyParameter> result(begin(), end());
|
||||
return result;
|
||||
}
|
||||
|
||||
void Serialize(std::ostream* out) const;
|
||||
void Deserialize(std::istream* in);
|
||||
|
||||
private:
|
||||
NullOr<const KeyParameter&> GetEntry(Tag tag) const;
|
||||
|
||||
std::vector<KeyParameter> data_;
|
||||
};
|
||||
|
||||
class AuthorizationSetBuilder : public AuthorizationSet {
|
||||
public:
|
||||
template <typename TagType, typename... ValueType>
|
||||
AuthorizationSetBuilder& Authorization(TagType ttag, ValueType&&... value) {
|
||||
push_back(ttag, std::forward<ValueType>(value)...);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <Tag tag>
|
||||
AuthorizationSetBuilder& Authorization(TypedTag<TagType::BYTES, tag> ttag, const uint8_t* data,
|
||||
size_t data_length) {
|
||||
vector<uint8_t> new_blob(data, data + data_length);
|
||||
push_back(ttag, new_blob);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <Tag tag>
|
||||
AuthorizationSetBuilder& Authorization(TypedTag<TagType::BYTES, tag> ttag, const char* data,
|
||||
size_t data_length) {
|
||||
return Authorization(ttag, reinterpret_cast<const uint8_t*>(data), data_length);
|
||||
}
|
||||
|
||||
template <Tag tag>
|
||||
AuthorizationSetBuilder& Authorization(TypedTag<TagType::BYTES, tag> ttag, char* data,
|
||||
size_t data_length) {
|
||||
return Authorization(ttag, reinterpret_cast<const uint8_t*>(data), data_length);
|
||||
}
|
||||
|
||||
template <Tag tag, size_t size>
|
||||
AuthorizationSetBuilder& Authorization(TypedTag<TagType::BYTES, tag> ttag,
|
||||
const char (&data)[size]) {
|
||||
return Authorization(ttag, reinterpret_cast<const uint8_t*>(&data[0]),
|
||||
size - 1); // drop the terminating '\0'
|
||||
}
|
||||
|
||||
AuthorizationSetBuilder& Authorizations(const AuthorizationSet& set) {
|
||||
for (const auto& entry : set) {
|
||||
push_back(entry);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
AuthorizationSetBuilder& RsaKey(uint32_t key_size, uint64_t public_exponent);
|
||||
AuthorizationSetBuilder& EcdsaKey(uint32_t key_size);
|
||||
AuthorizationSetBuilder& EcdsaKey(EcCurve curve);
|
||||
AuthorizationSetBuilder& AesKey(uint32_t key_size);
|
||||
AuthorizationSetBuilder& TripleDesKey(uint32_t key_size);
|
||||
AuthorizationSetBuilder& HmacKey(uint32_t key_size);
|
||||
|
||||
AuthorizationSetBuilder& RsaSigningKey(uint32_t key_size, uint64_t public_exponent);
|
||||
AuthorizationSetBuilder& RsaEncryptionKey(uint32_t key_size, uint64_t public_exponent);
|
||||
AuthorizationSetBuilder& EcdsaSigningKey(uint32_t key_size);
|
||||
AuthorizationSetBuilder& EcdsaSigningKey(EcCurve curve);
|
||||
AuthorizationSetBuilder& AesEncryptionKey(uint32_t key_size);
|
||||
AuthorizationSetBuilder& TripleDesEncryptionKey(uint32_t key_size);
|
||||
|
||||
AuthorizationSetBuilder& SigningKey();
|
||||
AuthorizationSetBuilder& EncryptionKey();
|
||||
|
||||
AuthorizationSetBuilder& NoDigestOrPadding();
|
||||
|
||||
AuthorizationSetBuilder& EcbMode();
|
||||
AuthorizationSetBuilder& GcmModeMinMacLen(uint32_t minMacLength);
|
||||
AuthorizationSetBuilder& GcmModeMacLen(uint32_t macLength);
|
||||
|
||||
AuthorizationSetBuilder& BlockMode(std::initializer_list<BlockMode> blockModes);
|
||||
AuthorizationSetBuilder& Digest(std::vector<Digest> digests);
|
||||
AuthorizationSetBuilder& Padding(std::initializer_list<PaddingMode> paddings);
|
||||
|
||||
template <typename... T>
|
||||
AuthorizationSetBuilder& BlockMode(T&&... a) {
|
||||
return BlockMode({std::forward<T>(a)...});
|
||||
}
|
||||
template <typename... T>
|
||||
AuthorizationSetBuilder& Digest(T&&... a) {
|
||||
return Digest({std::forward<T>(a)...});
|
||||
}
|
||||
template <typename... T>
|
||||
AuthorizationSetBuilder& Padding(T&&... a) {
|
||||
return Padding({std::forward<T>(a)...});
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace keymint
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
||||
#endif // SYSTEM_SECURITY_KEYSTORE_KM4_AUTHORIZATION_SET_H_
|
||||
108
keymint/support/include/keymintSupport/key_param_output.h
Normal file
108
keymint/support/include/keymintSupport/key_param_output.h
Normal file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.
|
||||
*/
|
||||
|
||||
#ifndef HARDWARE_INTERFACES_KEYMINT_SUPPORT_INCLUDE_KEY_PARAM_OUTPUT_H_
|
||||
#define HARDWARE_INTERFACES_KEYMINT_SUPPORT_INCLUDE_KEY_PARAM_OUTPUT_H_
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
#include "keymint_tags.h"
|
||||
|
||||
#include <android/hardware/keymint/Algorithm.h>
|
||||
#include <android/hardware/keymint/BlockMode.h>
|
||||
#include <android/hardware/keymint/Digest.h>
|
||||
#include <android/hardware/keymint/EcCurve.h>
|
||||
#include <android/hardware/keymint/ErrorCode.h>
|
||||
#include <android/hardware/keymint/HardwareAuthenticatorType.h>
|
||||
#include <android/hardware/keymint/KeyCharacteristics.h>
|
||||
#include <android/hardware/keymint/KeyOrigin.h>
|
||||
#include <android/hardware/keymint/KeyParameter.h>
|
||||
#include <android/hardware/keymint/KeyPurpose.h>
|
||||
#include <android/hardware/keymint/PaddingMode.h>
|
||||
#include <android/hardware/keymint/SecurityLevel.h>
|
||||
#include <android/hardware/keymint/Tag.h>
|
||||
#include <android/hardware/keymint/TagType.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace keymint {
|
||||
|
||||
using namespace ::android::hardware::keymint;
|
||||
|
||||
inline ::std::ostream& operator<<(::std::ostream& os, Algorithm value) {
|
||||
return os << toString(value);
|
||||
}
|
||||
|
||||
inline ::std::ostream& operator<<(::std::ostream& os, BlockMode value) {
|
||||
return os << toString(value);
|
||||
}
|
||||
|
||||
inline ::std::ostream& operator<<(::std::ostream& os, Digest value) {
|
||||
return os << toString(value);
|
||||
}
|
||||
|
||||
inline ::std::ostream& operator<<(::std::ostream& os, EcCurve value) {
|
||||
return os << toString(value);
|
||||
}
|
||||
|
||||
inline ::std::ostream& operator<<(::std::ostream& os, ErrorCode value) {
|
||||
return os << toString(value);
|
||||
}
|
||||
|
||||
inline ::std::ostream& operator<<(::std::ostream& os, KeyOrigin value) {
|
||||
return os << toString(value);
|
||||
}
|
||||
|
||||
inline ::std::ostream& operator<<(::std::ostream& os, PaddingMode value) {
|
||||
return os << toString(value);
|
||||
}
|
||||
|
||||
inline ::std::ostream& operator<<(::std::ostream& os, SecurityLevel value) {
|
||||
return os << toString(value);
|
||||
}
|
||||
|
||||
template <typename ValueT>
|
||||
::std::ostream& operator<<(::std::ostream& os, const NullOr<ValueT>& value) {
|
||||
if (!value.isOk()) {
|
||||
os << "(value not present)";
|
||||
} else {
|
||||
os << value.value();
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
::std::ostream& operator<<(::std::ostream& os, const ::std::vector<KeyParameter>& set);
|
||||
::std::ostream& operator<<(::std::ostream& os, const KeyParameter& param);
|
||||
|
||||
inline ::std::ostream& operator<<(::std::ostream& os, const KeyCharacteristics& value) {
|
||||
return os << "SW: " << value.softwareEnforced << ::std::endl
|
||||
<< "HW: " << value.hardwareEnforced << ::std::endl;
|
||||
}
|
||||
|
||||
inline ::std::ostream& operator<<(::std::ostream& os, KeyPurpose value) {
|
||||
return os << toString(value);
|
||||
}
|
||||
|
||||
inline ::std::ostream& operator<<(::std::ostream& os, Tag tag) {
|
||||
return os << toString(tag);
|
||||
}
|
||||
|
||||
} // namespace keymint
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
||||
#endif // HARDWARE_INTERFACES_KEYMINT_SUPPORT_INCLUDE_KEY_PARAM_OUTPUT_H_
|
||||
414
keymint/support/include/keymintSupport/keymint_tags.h
Normal file
414
keymint/support/include/keymintSupport/keymint_tags.h
Normal file
@@ -0,0 +1,414 @@
|
||||
/*
|
||||
* Copyright (C) 2019 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.
|
||||
*/
|
||||
|
||||
#ifndef HARDWARE_INTERFACES_KEYMINT_SUPPORT_INCLUDE_KEYMINT_TAGS_H_
|
||||
#define HARDWARE_INTERFACES_KEYMINT_SUPPORT_INCLUDE_KEYMINT_TAGS_H_
|
||||
|
||||
#include <android/hardware/keymint/Algorithm.h>
|
||||
#include <android/hardware/keymint/BlockMode.h>
|
||||
#include <android/hardware/keymint/Digest.h>
|
||||
#include <android/hardware/keymint/EcCurve.h>
|
||||
#include <android/hardware/keymint/HardwareAuthenticatorType.h>
|
||||
#include <android/hardware/keymint/KeyOrigin.h>
|
||||
#include <android/hardware/keymint/KeyParameter.h>
|
||||
#include <android/hardware/keymint/KeyPurpose.h>
|
||||
#include <android/hardware/keymint/PaddingMode.h>
|
||||
#include <android/hardware/keymint/SecurityLevel.h>
|
||||
#include <android/hardware/keymint/Tag.h>
|
||||
#include <android/hardware/keymint/TagType.h>
|
||||
|
||||
namespace android::hardware::keymint {
|
||||
|
||||
using android::hardware::keymint::KeyParameter;
|
||||
using android::hardware::keymint::Tag;
|
||||
using android::hardware::keymint::TagType;
|
||||
|
||||
// The following create the numeric values that KM_TAG_PADDING and KM_TAG_DIGEST used to have. We
|
||||
// need these old values to be able to support old keys that use them.
|
||||
// TODO(seleneh) we should delete this code when we stop supporting keymaster1
|
||||
// and deletes it.
|
||||
static const int32_t KM_TAG_DIGEST_OLD = static_cast<int32_t>(TagType::ENUM) | 5;
|
||||
static const int32_t KM_TAG_PADDING_OLD = static_cast<int32_t>(TagType::ENUM) | 7;
|
||||
|
||||
constexpr TagType typeFromTag(Tag tag) {
|
||||
return static_cast<TagType>(static_cast<uint32_t>(tag) & static_cast<uint32_t>(0xf0000000));
|
||||
}
|
||||
|
||||
/**
|
||||
* TypedTag is a templatized version of Tag, which provides compile-time checking of
|
||||
* keymint tag types. Instances are convertible to Tag, so they can be used wherever
|
||||
* Tag is expected, and because they encode the tag type it's possible to create
|
||||
* function overloads that only operate on tags with a particular type.
|
||||
*/
|
||||
template <TagType tag_type, Tag tag>
|
||||
struct TypedTag {
|
||||
inline TypedTag() {
|
||||
// Ensure that it's impossible to create a TypedTag instance whose 'tag' doesn't have type
|
||||
// 'tag_type'. Attempting to instantiate a tag with the wrong type will result in a compile
|
||||
// error (no match for template specialization StaticAssert<false>), with no run-time cost.
|
||||
static_assert(typeFromTag(tag) == tag_type, "mismatch between tag and tag_type");
|
||||
}
|
||||
operator Tag() const { return tag; }
|
||||
int32_t maskedTag() { return static_cast<uint32_t>(tag) & 0x0FFFFFFF; }
|
||||
};
|
||||
|
||||
template <Tag tag>
|
||||
struct Tag2TypedTag {
|
||||
typedef TypedTag<typeFromTag(tag), tag> type;
|
||||
};
|
||||
|
||||
#define DECLARE_TYPED_TAG(name) \
|
||||
typedef typename Tag2TypedTag<Tag::name>::type TAG_##name##_t; \
|
||||
static TAG_##name##_t TAG_##name;
|
||||
|
||||
DECLARE_TYPED_TAG(ACTIVE_DATETIME);
|
||||
DECLARE_TYPED_TAG(ALGORITHM);
|
||||
DECLARE_TYPED_TAG(ALLOW_WHILE_ON_BODY);
|
||||
DECLARE_TYPED_TAG(APPLICATION_DATA);
|
||||
DECLARE_TYPED_TAG(APPLICATION_ID);
|
||||
DECLARE_TYPED_TAG(ASSOCIATED_DATA);
|
||||
DECLARE_TYPED_TAG(ATTESTATION_APPLICATION_ID);
|
||||
DECLARE_TYPED_TAG(ATTESTATION_CHALLENGE);
|
||||
DECLARE_TYPED_TAG(ATTESTATION_ID_BRAND);
|
||||
DECLARE_TYPED_TAG(ATTESTATION_ID_DEVICE);
|
||||
DECLARE_TYPED_TAG(ATTESTATION_ID_PRODUCT);
|
||||
DECLARE_TYPED_TAG(ATTESTATION_ID_MANUFACTURER);
|
||||
DECLARE_TYPED_TAG(ATTESTATION_ID_MODEL);
|
||||
DECLARE_TYPED_TAG(AUTH_TIMEOUT);
|
||||
DECLARE_TYPED_TAG(BLOCK_MODE);
|
||||
DECLARE_TYPED_TAG(BOOTLOADER_ONLY);
|
||||
DECLARE_TYPED_TAG(BOOT_PATCHLEVEL);
|
||||
DECLARE_TYPED_TAG(CALLER_NONCE);
|
||||
DECLARE_TYPED_TAG(CONFIRMATION_TOKEN);
|
||||
DECLARE_TYPED_TAG(CREATION_DATETIME);
|
||||
DECLARE_TYPED_TAG(DEVICE_UNIQUE_ATTESTATION);
|
||||
DECLARE_TYPED_TAG(DIGEST);
|
||||
DECLARE_TYPED_TAG(EARLY_BOOT_ONLY);
|
||||
DECLARE_TYPED_TAG(EC_CURVE);
|
||||
DECLARE_TYPED_TAG(HARDWARE_TYPE);
|
||||
DECLARE_TYPED_TAG(IDENTITY_CREDENTIAL_KEY);
|
||||
DECLARE_TYPED_TAG(INCLUDE_UNIQUE_ID);
|
||||
DECLARE_TYPED_TAG(INVALID);
|
||||
DECLARE_TYPED_TAG(KEY_SIZE);
|
||||
DECLARE_TYPED_TAG(MAC_LENGTH);
|
||||
DECLARE_TYPED_TAG(MAX_USES_PER_BOOT);
|
||||
DECLARE_TYPED_TAG(MIN_MAC_LENGTH);
|
||||
DECLARE_TYPED_TAG(MIN_SECONDS_BETWEEN_OPS);
|
||||
DECLARE_TYPED_TAG(NONCE);
|
||||
DECLARE_TYPED_TAG(NO_AUTH_REQUIRED);
|
||||
DECLARE_TYPED_TAG(ORIGIN);
|
||||
DECLARE_TYPED_TAG(ORIGINATION_EXPIRE_DATETIME);
|
||||
DECLARE_TYPED_TAG(OS_PATCHLEVEL);
|
||||
DECLARE_TYPED_TAG(OS_VERSION);
|
||||
DECLARE_TYPED_TAG(PADDING);
|
||||
DECLARE_TYPED_TAG(PURPOSE);
|
||||
DECLARE_TYPED_TAG(RESET_SINCE_ID_ROTATION);
|
||||
DECLARE_TYPED_TAG(ROLLBACK_RESISTANCE);
|
||||
DECLARE_TYPED_TAG(ROOT_OF_TRUST);
|
||||
DECLARE_TYPED_TAG(RSA_PUBLIC_EXPONENT);
|
||||
DECLARE_TYPED_TAG(STORAGE_KEY);
|
||||
DECLARE_TYPED_TAG(TRUSTED_CONFIRMATION_REQUIRED);
|
||||
DECLARE_TYPED_TAG(TRUSTED_USER_PRESENCE_REQUIRED);
|
||||
DECLARE_TYPED_TAG(UNIQUE_ID);
|
||||
DECLARE_TYPED_TAG(UNLOCKED_DEVICE_REQUIRED);
|
||||
DECLARE_TYPED_TAG(USAGE_EXPIRE_DATETIME);
|
||||
DECLARE_TYPED_TAG(USER_AUTH_TYPE);
|
||||
DECLARE_TYPED_TAG(USER_ID);
|
||||
DECLARE_TYPED_TAG(USER_SECURE_ID);
|
||||
DECLARE_TYPED_TAG(VENDOR_PATCHLEVEL);
|
||||
|
||||
template <typename... Elems>
|
||||
struct MetaList {};
|
||||
|
||||
using all_tags_t = MetaList<
|
||||
TAG_INVALID_t, TAG_KEY_SIZE_t, TAG_MAC_LENGTH_t, TAG_CALLER_NONCE_t, TAG_MIN_MAC_LENGTH_t,
|
||||
TAG_RSA_PUBLIC_EXPONENT_t, TAG_INCLUDE_UNIQUE_ID_t, TAG_ACTIVE_DATETIME_t,
|
||||
TAG_ORIGINATION_EXPIRE_DATETIME_t, TAG_USAGE_EXPIRE_DATETIME_t,
|
||||
TAG_MIN_SECONDS_BETWEEN_OPS_t, TAG_MAX_USES_PER_BOOT_t, TAG_USER_ID_t, TAG_USER_SECURE_ID_t,
|
||||
TAG_NO_AUTH_REQUIRED_t, TAG_AUTH_TIMEOUT_t, TAG_ALLOW_WHILE_ON_BODY_t,
|
||||
TAG_UNLOCKED_DEVICE_REQUIRED_t, TAG_APPLICATION_ID_t, TAG_APPLICATION_DATA_t,
|
||||
TAG_CREATION_DATETIME_t, TAG_ROLLBACK_RESISTANCE_t, TAG_HARDWARE_TYPE_t,
|
||||
TAG_ROOT_OF_TRUST_t, TAG_ASSOCIATED_DATA_t, TAG_NONCE_t, TAG_BOOTLOADER_ONLY_t,
|
||||
TAG_OS_VERSION_t, TAG_OS_PATCHLEVEL_t, TAG_UNIQUE_ID_t, TAG_ATTESTATION_CHALLENGE_t,
|
||||
TAG_ATTESTATION_APPLICATION_ID_t, TAG_ATTESTATION_ID_BRAND_t, TAG_ATTESTATION_ID_DEVICE_t,
|
||||
TAG_ATTESTATION_ID_PRODUCT_t, TAG_ATTESTATION_ID_MANUFACTURER_t, TAG_ATTESTATION_ID_MODEL_t,
|
||||
TAG_RESET_SINCE_ID_ROTATION_t, TAG_PURPOSE_t, TAG_ALGORITHM_t, TAG_BLOCK_MODE_t,
|
||||
TAG_DIGEST_t, TAG_PADDING_t, TAG_ORIGIN_t, TAG_USER_AUTH_TYPE_t, TAG_EC_CURVE_t,
|
||||
TAG_BOOT_PATCHLEVEL_t, TAG_VENDOR_PATCHLEVEL_t, TAG_TRUSTED_CONFIRMATION_REQUIRED_t,
|
||||
TAG_TRUSTED_USER_PRESENCE_REQUIRED_t>;
|
||||
|
||||
template <typename TypedTagType>
|
||||
struct TypedTag2ValueType;
|
||||
|
||||
#define MAKE_TAG_VALUE_ACCESSOR(tag_type, field_name) \
|
||||
template <Tag tag> \
|
||||
struct TypedTag2ValueType<TypedTag<tag_type, tag>> { \
|
||||
typedef decltype(static_cast<KeyParameter*>(nullptr)->field_name) type; \
|
||||
}; \
|
||||
template <Tag tag> \
|
||||
inline auto accessTagValue(TypedTag<tag_type, tag>, const KeyParameter& param) \
|
||||
->const decltype(param.field_name)& { \
|
||||
return param.field_name; \
|
||||
} \
|
||||
template <Tag tag> \
|
||||
inline auto accessTagValue(TypedTag<tag_type, tag>, KeyParameter& param) \
|
||||
->decltype(param.field_name)& { \
|
||||
return param.field_name; \
|
||||
}
|
||||
|
||||
MAKE_TAG_VALUE_ACCESSOR(TagType::ULONG, longInteger)
|
||||
MAKE_TAG_VALUE_ACCESSOR(TagType::ULONG_REP, longInteger)
|
||||
MAKE_TAG_VALUE_ACCESSOR(TagType::DATE, longInteger)
|
||||
MAKE_TAG_VALUE_ACCESSOR(TagType::UINT, integer)
|
||||
MAKE_TAG_VALUE_ACCESSOR(TagType::UINT_REP, integer)
|
||||
MAKE_TAG_VALUE_ACCESSOR(TagType::BOOL, boolValue)
|
||||
MAKE_TAG_VALUE_ACCESSOR(TagType::BYTES, blob)
|
||||
MAKE_TAG_VALUE_ACCESSOR(TagType::BIGNUM, blob)
|
||||
|
||||
// TODO(seleneh) change these MAKE_TAG_ENUM_VALUE_ACCESSOR back to the 2 parameter
|
||||
// version when aidl supports union
|
||||
#define MAKE_TAG_ENUM_VALUE_ACCESSOR(typed_tag, field_name, field_type) \
|
||||
template <> \
|
||||
struct TypedTag2ValueType<decltype(typed_tag)> { \
|
||||
typedef field_type type; \
|
||||
}; \
|
||||
inline auto accessTagValue(decltype(typed_tag), const KeyParameter& param) \
|
||||
->const field_type& { \
|
||||
return *reinterpret_cast<const field_type*>(¶m.field_name); \
|
||||
} \
|
||||
inline auto accessTagValue(decltype(typed_tag), KeyParameter& param)->field_type& { \
|
||||
return *reinterpret_cast<field_type*>(¶m.field_name); \
|
||||
}
|
||||
|
||||
MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_ALGORITHM, integer, Algorithm)
|
||||
MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_BLOCK_MODE, integer, BlockMode)
|
||||
MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_DIGEST, integer, Digest)
|
||||
MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_EC_CURVE, integer, EcCurve)
|
||||
MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_ORIGIN, integer, KeyOrigin)
|
||||
MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_PADDING, integer, PaddingMode)
|
||||
MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_PURPOSE, integer, KeyPurpose)
|
||||
MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_USER_AUTH_TYPE, integer, HardwareAuthenticatorType)
|
||||
MAKE_TAG_ENUM_VALUE_ACCESSOR(TAG_HARDWARE_TYPE, integer, SecurityLevel)
|
||||
|
||||
template <TagType tag_type, Tag tag, typename ValueT>
|
||||
inline KeyParameter makeKeyParameter(TypedTag<tag_type, tag> ttag, ValueT&& value) {
|
||||
KeyParameter param;
|
||||
param.tag = tag;
|
||||
param.longInteger = 0;
|
||||
accessTagValue(ttag, param) = std::forward<ValueT>(value);
|
||||
return param;
|
||||
}
|
||||
|
||||
// the boolean case
|
||||
template <Tag tag>
|
||||
inline KeyParameter makeKeyParameter(TypedTag<TagType::BOOL, tag>) {
|
||||
KeyParameter param;
|
||||
param.tag = tag;
|
||||
param.boolValue = true;
|
||||
return param;
|
||||
}
|
||||
|
||||
template <typename... Pack>
|
||||
struct FirstOrNoneHelper;
|
||||
template <typename First>
|
||||
struct FirstOrNoneHelper<First> {
|
||||
typedef First type;
|
||||
};
|
||||
template <>
|
||||
struct FirstOrNoneHelper<> {
|
||||
struct type {};
|
||||
};
|
||||
|
||||
template <typename... Pack>
|
||||
using FirstOrNone = typename FirstOrNoneHelper<Pack...>::type;
|
||||
|
||||
template <TagType tag_type, Tag tag, typename... Args>
|
||||
inline KeyParameter Authorization(TypedTag<tag_type, tag> ttag, Args&&... args) {
|
||||
static_assert(tag_type != TagType::BOOL || (sizeof...(args) == 0),
|
||||
"TagType::BOOL Authorizations do not take parameters. Presence is truth.");
|
||||
static_assert(tag_type == TagType::BOOL || (sizeof...(args) == 1),
|
||||
"Authorization other then TagType::BOOL take exactly one parameter.");
|
||||
static_assert(
|
||||
tag_type == TagType::BOOL ||
|
||||
std::is_convertible<
|
||||
std::remove_cv_t<std::remove_reference_t<FirstOrNone<Args...>>>,
|
||||
typename TypedTag2ValueType<TypedTag<tag_type, tag>>::type>::value,
|
||||
"Invalid argument type for given tag.");
|
||||
|
||||
return makeKeyParameter(ttag, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
/**
|
||||
* This class wraps a (mostly return) value and stores whether or not the wrapped value is valid out
|
||||
* of band. Note that if the wrapped value is a reference it is unsafe to access the value if
|
||||
* !isOk(). If the wrapped type is a pointer or value and !isOk(), it is still safe to access the
|
||||
* wrapped value. In this case the pointer will be NULL though, and the value will be default
|
||||
* constructed.
|
||||
*
|
||||
* TODO(seleneh) replace this with std::optional.
|
||||
*/
|
||||
template <typename ValueT>
|
||||
class NullOr {
|
||||
using internal_t = std::conditional_t<std::is_lvalue_reference<ValueT>::value,
|
||||
std::remove_reference_t<ValueT>*, ValueT>;
|
||||
|
||||
struct pointer_initializer {
|
||||
static std::nullptr_t init() { return nullptr; }
|
||||
};
|
||||
struct value_initializer {
|
||||
static ValueT init() { return ValueT(); }
|
||||
};
|
||||
struct value_pointer_deref_t {
|
||||
static ValueT& deref(ValueT& v) { return v; }
|
||||
};
|
||||
struct reference_deref_t {
|
||||
static auto& deref(internal_t v) { return *v; }
|
||||
};
|
||||
using initializer_t = std::conditional_t<std::is_lvalue_reference<ValueT>::value ||
|
||||
std::is_pointer<ValueT>::value,
|
||||
pointer_initializer, value_initializer>;
|
||||
using deref_t = std::conditional_t<std::is_lvalue_reference<ValueT>::value, reference_deref_t,
|
||||
value_pointer_deref_t>;
|
||||
|
||||
public:
|
||||
NullOr() : value_(initializer_t::init()), null_(true) {}
|
||||
template <typename T>
|
||||
NullOr(T&& value, typename std::enable_if<
|
||||
!std::is_lvalue_reference<ValueT>::value &&
|
||||
std::is_same<std::decay_t<ValueT>, std::decay_t<T>>::value,
|
||||
int>::type = 0)
|
||||
: value_(std::forward<ValueT>(value)), null_(false) {}
|
||||
template <typename T>
|
||||
NullOr(T& value, typename std::enable_if<
|
||||
std::is_lvalue_reference<ValueT>::value &&
|
||||
std::is_same<std::decay_t<ValueT>, std::decay_t<T>>::value,
|
||||
int>::type = 0)
|
||||
: value_(&value), null_(false) {}
|
||||
|
||||
bool isOk() const { return !null_; }
|
||||
|
||||
const ValueT& value() const& { return deref_t::deref(value_); }
|
||||
ValueT& value() & { return deref_t::deref(value_); }
|
||||
ValueT&& value() && { return std::move(deref_t::deref(value_)); }
|
||||
|
||||
private:
|
||||
internal_t value_;
|
||||
bool null_;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
std::remove_reference_t<T> NullOrOr(T&& v) {
|
||||
if (v.isOk()) return v;
|
||||
return {};
|
||||
}
|
||||
|
||||
template <typename Head, typename... Tail>
|
||||
std::remove_reference_t<Head> NullOrOr(Head&& head, Tail&&... tail) {
|
||||
if (head.isOk()) return head;
|
||||
return NullOrOr(std::forward<Tail>(tail)...);
|
||||
}
|
||||
|
||||
template <typename Default, typename Wrapped>
|
||||
std::remove_reference_t<Wrapped> defaultOr(NullOr<Wrapped>&& optional, Default&& def) {
|
||||
static_assert(std::is_convertible<std::remove_reference_t<Default>,
|
||||
std::remove_reference_t<Wrapped>>::value,
|
||||
"Type of default value must match the type wrapped by NullOr");
|
||||
if (optional.isOk()) return optional.value();
|
||||
return def;
|
||||
}
|
||||
|
||||
template <TagType tag_type, Tag tag>
|
||||
inline NullOr<const typename TypedTag2ValueType<TypedTag<tag_type, tag>>::type&> authorizationValue(
|
||||
TypedTag<tag_type, tag> ttag, const KeyParameter& param) {
|
||||
if (tag != param.tag) return {};
|
||||
return accessTagValue(ttag, param);
|
||||
}
|
||||
|
||||
} // namespace android::hardware::keymint
|
||||
|
||||
namespace std {
|
||||
|
||||
using namespace android::hardware::keymint;
|
||||
|
||||
// Aidl generates KeyParameter operator<, >, ==, != for cpp translation but not ndk
|
||||
// translations. So we cannot straight forward overload these operators.
|
||||
// However we need our custom comparison for KeyParameters. So we will
|
||||
// overload std::less, equal_to instead.
|
||||
template <>
|
||||
struct std::less<KeyParameter> {
|
||||
bool operator()(const KeyParameter& a, const KeyParameter& b) const {
|
||||
if (a.tag != b.tag) return a.tag < b.tag;
|
||||
int retval;
|
||||
switch (typeFromTag(a.tag)) {
|
||||
case TagType::INVALID:
|
||||
case TagType::BOOL:
|
||||
return false;
|
||||
case TagType::ENUM:
|
||||
case TagType::ENUM_REP:
|
||||
case TagType::UINT:
|
||||
case TagType::UINT_REP:
|
||||
return a.integer < b.integer;
|
||||
case TagType::ULONG:
|
||||
case TagType::ULONG_REP:
|
||||
case TagType::DATE:
|
||||
return a.longInteger < b.longInteger;
|
||||
case TagType::BIGNUM:
|
||||
case TagType::BYTES:
|
||||
// Handle the empty cases.
|
||||
if (a.blob.size() == 0) return b.blob.size() != 0;
|
||||
if (b.blob.size() == 0) return false;
|
||||
retval = memcmp(&a.blob[0], &b.blob[0], std::min(a.blob.size(), b.blob.size()));
|
||||
// if one is the prefix of the other the longer wins
|
||||
if (retval == 0) return a.blob.size() < b.blob.size();
|
||||
// Otherwise a is less if a is less.
|
||||
else
|
||||
return retval < 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct std::equal_to<KeyParameter> {
|
||||
bool operator()(const KeyParameter& a, const KeyParameter& b) const {
|
||||
if (a.tag != b.tag) {
|
||||
return false;
|
||||
}
|
||||
switch (typeFromTag(a.tag)) {
|
||||
case TagType::INVALID:
|
||||
case TagType::BOOL:
|
||||
return true;
|
||||
case TagType::ENUM:
|
||||
case TagType::ENUM_REP:
|
||||
case TagType::UINT:
|
||||
case TagType::UINT_REP:
|
||||
return a.integer == b.integer;
|
||||
case TagType::ULONG:
|
||||
case TagType::ULONG_REP:
|
||||
case TagType::DATE:
|
||||
return a.longInteger == b.longInteger;
|
||||
case TagType::BIGNUM:
|
||||
case TagType::BYTES:
|
||||
if (a.blob.size() != b.blob.size()) return false;
|
||||
return a.blob.size() == 0 || memcmp(&a.blob[0], &b.blob[0], a.blob.size()) == 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
|
||||
#endif // HARDWARE_INTERFACES_KEYMINT_SUPPORT_INCLUDE_KEYMINT_TAGS_H_
|
||||
51
keymint/support/include/keymintSupport/keymint_utils.h
Normal file
51
keymint/support/include/keymintSupport/keymint_utils.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef HARDWARE_INTERFACES_KEYMINT_10_SUPPORT_KEYMINT_UTILS_H_
|
||||
#define HARDWARE_INTERFACES_KEYMINT_10_SUPPORT_KEYMINT_UTILS_H_
|
||||
|
||||
#include <android/hardware/keymint/HardwareAuthToken.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace keymint {
|
||||
|
||||
using std::vector;
|
||||
|
||||
inline static std::vector<uint8_t> blob2vector(const uint8_t* data, const size_t length) {
|
||||
std::vector<uint8_t> result(data, data + length);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline static std::vector<uint8_t> blob2vector(const std::string& value) {
|
||||
vector<uint8_t> result(reinterpret_cast<const uint8_t*>(value.data()),
|
||||
reinterpret_cast<const uint8_t*>(value.data()) + value.size());
|
||||
return result;
|
||||
}
|
||||
|
||||
HardwareAuthToken vector2AuthToken(const vector<uint8_t>& buffer);
|
||||
vector<uint8_t> authToken2vector(const HardwareAuthToken& token);
|
||||
|
||||
uint32_t getOsVersion();
|
||||
uint32_t getOsPatchlevel();
|
||||
|
||||
} // namespace keymint
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
||||
#endif // HARDWARE_INTERFACES_KEYMINT_10_SUPPORT_KEYMINT_UTILS_H_
|
||||
63
keymint/support/include/keymintSupport/openssl_utils.h
Normal file
63
keymint/support/include/keymintSupport/openssl_utils.h
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2017 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.
|
||||
*/
|
||||
|
||||
#ifndef HARDWARE_INTERFACES_KEYMINT_1_0_SUPPORT_OPENSSL_UTILS_H_
|
||||
#define HARDWARE_INTERFACES_KEYMINT_1_0_SUPPORT_OPENSSL_UTILS_H_
|
||||
|
||||
#include <android/hardware/keymint/Digest.h>
|
||||
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
template <typename T, void (*F)(T*)>
|
||||
struct UniquePtrDeleter {
|
||||
void operator()(T* p) const { F(p); }
|
||||
};
|
||||
|
||||
typedef UniquePtrDeleter<EVP_PKEY, EVP_PKEY_free> EVP_PKEY_Delete;
|
||||
|
||||
#define MAKE_OPENSSL_PTR_TYPE(type) \
|
||||
typedef std::unique_ptr<type, UniquePtrDeleter<type, type##_free>> type##_Ptr;
|
||||
|
||||
MAKE_OPENSSL_PTR_TYPE(ASN1_OBJECT)
|
||||
MAKE_OPENSSL_PTR_TYPE(EVP_PKEY)
|
||||
MAKE_OPENSSL_PTR_TYPE(RSA)
|
||||
MAKE_OPENSSL_PTR_TYPE(X509)
|
||||
MAKE_OPENSSL_PTR_TYPE(BN_CTX)
|
||||
|
||||
typedef std::unique_ptr<BIGNUM, UniquePtrDeleter<BIGNUM, BN_free>> BIGNUM_Ptr;
|
||||
|
||||
inline const EVP_MD* openssl_digest(android::hardware::keymint::Digest digest) {
|
||||
switch (digest) {
|
||||
case android::hardware::keymint::Digest::NONE:
|
||||
return nullptr;
|
||||
case android::hardware::keymint::Digest::MD5:
|
||||
return EVP_md5();
|
||||
case android::hardware::keymint::Digest::SHA1:
|
||||
return EVP_sha1();
|
||||
case android::hardware::keymint::Digest::SHA_2_224:
|
||||
return EVP_sha224();
|
||||
case android::hardware::keymint::Digest::SHA_2_256:
|
||||
return EVP_sha256();
|
||||
case android::hardware::keymint::Digest::SHA_2_384:
|
||||
return EVP_sha384();
|
||||
case android::hardware::keymint::Digest::SHA_2_512:
|
||||
return EVP_sha512();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#endif // HARDWARE_INTERFACES_KEYMINT_1_0_SUPPORT_OPENSSL_UTILS_H_
|
||||
76
keymint/support/key_param_output.cpp
Normal file
76
keymint/support/key_param_output.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.
|
||||
*/
|
||||
|
||||
#include <keymintSupport/key_param_output.h>
|
||||
|
||||
#include <keymintSupport/keymint_tags.h>
|
||||
|
||||
#include <iomanip>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace keymint {
|
||||
|
||||
using ::std::endl;
|
||||
using ::std::ostream;
|
||||
|
||||
ostream& operator<<(ostream& os, const ::std::vector<KeyParameter>& set) {
|
||||
if (set.size() == 0) {
|
||||
os << "(Empty)" << endl;
|
||||
} else {
|
||||
os << "\n";
|
||||
for (const auto& elem : set) os << elem << endl;
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
// TODO(seleneh) update this to a parsing that looks at each tags individually
|
||||
// such as ALGORITHM BLOCK_MODE when aidl union support is added.
|
||||
ostream& operator<<(ostream& os, const KeyParameter& param) {
|
||||
os << param.tag << ": ";
|
||||
switch (typeFromTag(param.tag)) {
|
||||
case TagType::INVALID:
|
||||
return os << " Invalid";
|
||||
case TagType::ENUM_REP:
|
||||
case TagType::ENUM:
|
||||
case TagType::UINT_REP:
|
||||
case TagType::UINT:
|
||||
return os << param.integer;
|
||||
case TagType::ULONG_REP:
|
||||
case TagType::ULONG:
|
||||
case TagType::DATE:
|
||||
return os << param.longInteger;
|
||||
case TagType::BOOL:
|
||||
return os << "true";
|
||||
case TagType::BIGNUM:
|
||||
os << " Bignum: ";
|
||||
for (size_t i = 0; i < param.blob.size(); ++i) {
|
||||
os << std::hex << ::std::setw(2) << static_cast<int>(param.blob[i]) << ::std::dec;
|
||||
}
|
||||
return os;
|
||||
case TagType::BYTES:
|
||||
os << " Bytes: ";
|
||||
for (size_t i = 0; i < param.blob.size(); ++i) {
|
||||
os << ::std::hex << ::std::setw(2) << static_cast<int>(param.blob[i]) << ::std::dec;
|
||||
}
|
||||
return os;
|
||||
}
|
||||
return os << "UNKNOWN TAG TYPE!";
|
||||
}
|
||||
|
||||
} // namespace keymint
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
114
keymint/support/keymint_utils.cpp
Normal file
114
keymint/support/keymint_utils.cpp
Normal file
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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.
|
||||
*/
|
||||
|
||||
#include <regex.h>
|
||||
|
||||
#include <android-base/properties.h>
|
||||
#include <hardware/hw_auth_token.h>
|
||||
#include <keymintSupport/keymint_utils.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
|
||||
namespace android::hardware::keymint {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr char kPlatformVersionProp[] = "ro.build.version.release";
|
||||
constexpr char kPlatformVersionRegex[] = "^([0-9]{1,2})(\\.([0-9]{1,2}))?(\\.([0-9]{1,2}))?";
|
||||
constexpr size_t kMajorVersionMatch = 1;
|
||||
constexpr size_t kMinorVersionMatch = 3;
|
||||
constexpr size_t kSubminorVersionMatch = 5;
|
||||
constexpr size_t kPlatformVersionMatchCount = kSubminorVersionMatch + 1;
|
||||
|
||||
constexpr char kPlatformPatchlevelProp[] = "ro.build.version.security_patch";
|
||||
constexpr char kPlatformPatchlevelRegex[] = "^([0-9]{4})-([0-9]{2})-[0-9]{2}$";
|
||||
constexpr size_t kYearMatch = 1;
|
||||
constexpr size_t kMonthMatch = 2;
|
||||
constexpr size_t kPlatformPatchlevelMatchCount = kMonthMatch + 1;
|
||||
|
||||
uint32_t match_to_uint32(const char* expression, const regmatch_t& match) {
|
||||
if (match.rm_so == -1) return 0;
|
||||
|
||||
size_t len = match.rm_eo - match.rm_so;
|
||||
std::string s(expression + match.rm_so, len);
|
||||
return std::stoul(s);
|
||||
}
|
||||
|
||||
std::string wait_and_get_property(const char* prop) {
|
||||
std::string prop_value;
|
||||
while (!::android::base::WaitForPropertyCreation(prop))
|
||||
;
|
||||
prop_value = ::android::base::GetProperty(prop, "" /* default */);
|
||||
return prop_value;
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
uint32_t getOsVersion(const char* version_str) {
|
||||
regex_t regex;
|
||||
if (regcomp(®ex, kPlatformVersionRegex, REG_EXTENDED)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
regmatch_t matches[kPlatformVersionMatchCount];
|
||||
int not_match =
|
||||
regexec(®ex, version_str, kPlatformVersionMatchCount, matches, 0 /* flags */);
|
||||
regfree(®ex);
|
||||
if (not_match) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t major = match_to_uint32(version_str, matches[kMajorVersionMatch]);
|
||||
uint32_t minor = match_to_uint32(version_str, matches[kMinorVersionMatch]);
|
||||
uint32_t subminor = match_to_uint32(version_str, matches[kSubminorVersionMatch]);
|
||||
|
||||
return (major * 100 + minor) * 100 + subminor;
|
||||
}
|
||||
|
||||
uint32_t getOsVersion() {
|
||||
std::string version = wait_and_get_property(kPlatformVersionProp);
|
||||
return getOsVersion(version.c_str());
|
||||
}
|
||||
|
||||
uint32_t getOsPatchlevel(const char* patchlevel_str) {
|
||||
regex_t regex;
|
||||
if (regcomp(®ex, kPlatformPatchlevelRegex, REG_EXTENDED) != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
regmatch_t matches[kPlatformPatchlevelMatchCount];
|
||||
int not_match =
|
||||
regexec(®ex, patchlevel_str, kPlatformPatchlevelMatchCount, matches, 0 /* flags */);
|
||||
regfree(®ex);
|
||||
if (not_match) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t year = match_to_uint32(patchlevel_str, matches[kYearMatch]);
|
||||
uint32_t month = match_to_uint32(patchlevel_str, matches[kMonthMatch]);
|
||||
|
||||
if (month < 1 || month > 12) {
|
||||
return 0;
|
||||
}
|
||||
return year * 100 + month;
|
||||
}
|
||||
|
||||
uint32_t getOsPatchlevel() {
|
||||
std::string patchlevel = wait_and_get_property(kPlatformPatchlevelProp);
|
||||
return getOsPatchlevel(patchlevel.c_str());
|
||||
}
|
||||
|
||||
} // namespace android::hardware::keymint
|
||||
Reference in New Issue
Block a user