Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ public class KMAttestationCertImpl implements KMAttestationCert {
private static final byte keyUsageKeyEncipher = (byte) 0x20; // 2nd- bit
private static final byte keyUsageDataEncipher = (byte) 0x10; // 3rd- bit

private static final byte KEYMASTER_VERSION = 4;
private static final byte ATTESTATION_VERSION = 3;
private static final byte KEYMASTER_VERSION = 41;
private static final byte ATTESTATION_VERSION = 4;
private static final byte[] pubExponent = {0x01, 0x00, 0x01};
private static final byte SERIAL_NUM = (byte) 0x01;
private static final byte X509_VERSION = (byte) 0x02;
Expand Down Expand Up @@ -462,14 +462,16 @@ private static void pushHWParams() {
// Below are the allowed hardwareEnforced Authorization tags inside the attestation certificate's extension.
short[] tagIds = {
KMType.BOOT_PATCH_LEVEL, KMType.VENDOR_PATCH_LEVEL,
KMType.ATTESTATION_ID_MODEL, KMType.ATTESTATION_ID_MANUFACTURER,
KMType.ATTESTATION_ID_MEID, KMType.ATTESTATION_ID_IMEI,
KMType.ATTESTATION_ID_SERIAL, KMType.ATTESTATION_ID_PRODUCT,
KMType.ATTESTATION_ID_DEVICE, KMType.ATTESTATION_ID_BRAND,
KMType.OS_PATCH_LEVEL, KMType.OS_VERSION, KMType.ROOT_OF_TRUST,
KMType.ORIGIN, KMType.APPLICATION_ID,
KMType.TRUSTED_CONFIRMATION_REQUIRED,
KMType.TRUSTED_USER_PRESENCE_REQUIRED, KMType.ALLOW_WHILE_ON_BODY,
KMType.AUTH_TIMEOUT, KMType.USER_AUTH_TYPE, KMType.NO_AUTH_REQUIRED,
KMType.ROLLBACK_RESISTANCE, KMType.RSA_PUBLIC_EXPONENT,
KMType.ECCURVE, KMType.PADDING, KMType.DIGEST, KMType.KEYSIZE,
KMType.ALGORITHM, KMType.PURPOSE};
KMType.ORIGIN, KMType.AUTH_TIMEOUT, KMType.USER_AUTH_TYPE,
KMType.NO_AUTH_REQUIRED, KMType.USER_SECURE_ID,
KMType.RSA_PUBLIC_EXPONENT, KMType.ECCURVE, KMType.MIN_MAC_LENGTH,
KMType.CALLER_NONCE, KMType.PADDING, KMType.DIGEST, KMType.BLOCK_MODE,
KMType.KEYSIZE, KMType.ALGORITHM, KMType.PURPOSE};

byte index = 0;
do {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ public class KMAttestationCertImpl implements KMAttestationCert {
private static final byte keyUsageKeyEncipher = (byte) 0x20; // 2nd- bit
private static final byte keyUsageDataEncipher = (byte) 0x10; // 3rd- bit

private static final byte KEYMASTER_VERSION = 4;
private static final byte ATTESTATION_VERSION = 3;
private static final byte KEYMASTER_VERSION = 41;
private static final byte ATTESTATION_VERSION = 4;
private static final byte[] pubExponent = {0x01, 0x00, 0x01};
private static final byte SERIAL_NUM = (byte) 0x01;
private static final byte X509_VERSION = (byte) 0x02;
Expand Down Expand Up @@ -456,14 +456,16 @@ private static void pushHWParams() {
// Below are the allowed hardwareEnforced Authorization tags inside the attestation certificate's extension.
short[] tagIds = {
KMType.BOOT_PATCH_LEVEL, KMType.VENDOR_PATCH_LEVEL,
KMType.ATTESTATION_ID_MODEL, KMType.ATTESTATION_ID_MANUFACTURER,
KMType.ATTESTATION_ID_MEID, KMType.ATTESTATION_ID_IMEI,
KMType.ATTESTATION_ID_SERIAL, KMType.ATTESTATION_ID_PRODUCT,
KMType.ATTESTATION_ID_DEVICE, KMType.ATTESTATION_ID_BRAND,
KMType.OS_PATCH_LEVEL, KMType.OS_VERSION, KMType.ROOT_OF_TRUST,
KMType.ORIGIN, KMType.APPLICATION_ID,
KMType.TRUSTED_CONFIRMATION_REQUIRED,
KMType.TRUSTED_USER_PRESENCE_REQUIRED, KMType.ALLOW_WHILE_ON_BODY,
KMType.AUTH_TIMEOUT, KMType.USER_AUTH_TYPE, KMType.NO_AUTH_REQUIRED,
KMType.ROLLBACK_RESISTANCE, KMType.RSA_PUBLIC_EXPONENT,
KMType.ECCURVE, KMType.PADDING, KMType.DIGEST, KMType.KEYSIZE,
KMType.ALGORITHM, KMType.PURPOSE};
KMType.ORIGIN, KMType.AUTH_TIMEOUT, KMType.USER_AUTH_TYPE,
KMType.NO_AUTH_REQUIRED, KMType.USER_SECURE_ID,
KMType.RSA_PUBLIC_EXPONENT, KMType.ECCURVE, KMType.MIN_MAC_LENGTH,
KMType.CALLER_NONCE, KMType.PADDING, KMType.DIGEST, KMType.BLOCK_MODE,
KMType.KEYSIZE, KMType.ALGORITHM, KMType.PURPOSE};

byte index = 0;
do {
Expand Down
47 changes: 43 additions & 4 deletions Applet/src/com/android/javacard/keymaster/KMKeymasterApplet.java
Original file line number Diff line number Diff line change
Expand Up @@ -1442,6 +1442,8 @@ private void processAttestKeyCmd(APDU apdu) {
rsaCert = false;
}
KMAttestationCert cert = seProvider.getAttestationCert(rsaCert);
// Validate and add attestation ids.
addAttestationIds(cert);
// Save attestation application id - must be present.
tmpVariables[0] =
KMKeyParameters.findTag(
Expand Down Expand Up @@ -1485,7 +1487,6 @@ private void processAttestKeyCmd(APDU apdu) {
KMKeyParameters.findTag(KMType.DATE_TAG, KMType.USAGE_EXPIRE_DATETIME, data[SW_PARAMETERS]);
cert.notAfter(tmpVariables[2], repository.getCertExpiryTime(), scratchPad, (short) 0);

addAttestationIds(cert);
addTags(KMKeyCharacteristics.cast(data[KEY_CHARACTERISTICS]).getHardwareEnforced(), true, cert);
addTags(
KMKeyCharacteristics.cast(data[KEY_CHARACTERISTICS]).getSoftwareEnforced(), false, cert);
Expand All @@ -1512,7 +1513,25 @@ private void processAttestKeyCmd(APDU apdu) {
sendOutgoing(apdu);
}

private boolean isEmpty(byte[] buf, short offset, short len) {
boolean empty = true;
short index = 0;
while (index < len) {
if (buf[index] != 0) {
empty = false;
break;
}
index++;
}
return empty;
}

// --------------------------------
// Only add the Attestation ids which are requested in the attestation parameters.
// If the requested attestation ids are not provisioned or deleted then
// throw CANNOT_ATTEST_IDS error. If there is mismatch in the attestation
// id values of both the requested parameters and the provisioned parameters
// then throw INVALID_TAG error.
private void addAttestationIds(KMAttestationCert cert) {
final short[] attTags =
new short[]{
Expand All @@ -1527,10 +1546,30 @@ private void addAttestationIds(KMAttestationCert cert) {
};
byte index = 0;
short attIdTag;
short attIdTagValue;
short storedAttId;
while (index < (short) attTags.length) {
attIdTag = repository.getAttId(mapToAttId(attTags[index]));
if (attIdTag != 0) {
attIdTag = KMByteTag.instance(attTags[index], attIdTag);
attIdTag = KMKeyParameters.findTag(KMType.BYTES_TAG, attTags[index], data[KEY_PARAMETERS]);
if (attIdTag != KMType.INVALID_VALUE) {
attIdTagValue = KMByteTag.cast(attIdTag).getValue();
storedAttId = repository.getAttId(mapToAttId(attTags[index]));
// Return CANNOT_ATTEST_IDS if Attestation IDs are not provisioned or
// Attestation IDs are deleted.
if (storedAttId == 0 ||
isEmpty(KMByteBlob.cast(storedAttId).getBuffer(),
KMByteBlob.cast(storedAttId).getStartOff(),
KMByteBlob.cast(storedAttId).length())) {
KMException.throwIt(KMError.CANNOT_ATTEST_IDS);
}
// Return INVALID_TAG if Attestation IDs does not match.
if ((KMByteBlob.cast(storedAttId).length() != KMByteBlob.cast(attIdTagValue).length()) ||
(0 != Util.arrayCompare(KMByteBlob.cast(storedAttId).getBuffer(),
KMByteBlob.cast(storedAttId).getStartOff(),
KMByteBlob.cast(attIdTagValue).getBuffer(),
KMByteBlob.cast(attIdTagValue).getStartOff(),
KMByteBlob.cast(storedAttId).length()))) {
KMException.throwIt(KMError.INVALID_TAG);
}
cert.extensionTag(attIdTag, true);
}
index++;
Expand Down
12 changes: 7 additions & 5 deletions ProvisioningTool/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ This tool can be built along with aosp build. It has dependency on
[libjc_provision](Android.bp).

#### Sample resources for quick testing
A sample json file is located in this directory with name [sample_json.txt](sample_json.txt)
for your reference. Also the required certificates and keys can be found
in [test_resources](test_resources) directory. Copy the certificates and the key into the
emulator/device filesystem in their respective paths mentioned in the
sample_json.txt.
Two sample json files are located in this directory with names
[sample_json_cf.txt](sample_json_cf.txt) and and [sample_json_gf.txt](sample_json_gf.txt)
for your reference. Use sample_json_cf.txt for cuttlefish target and use
sample_json_gf.txt for goldfish target. Also the required certificates and
keys can be found in [test_resources](test_resources) directory. Copy the
certificates and the key into the emulator/device filesystem in their respective
paths mentioned in the sample json file.

#### Usage
<pre>
Expand Down
26 changes: 26 additions & 0 deletions ProvisioningTool/sample_json_cf.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"attest_ids": {
"brand": "generic",
"device": "vsoc_x86_64",
"product": "aosp_cf_x86_64_phone",
"serial": "",
"imei": "000000000000000",
"meid": "000000000000000",
"manufacturer": "Google",
"model": "Cuttlefish x86_64 phone"
},
"shared_secret": "0000000000000000000000000000000000000000000000000000000000000000",
"set_boot_params": {
"boot_patch_level": 0,
"verified_boot_key": "0000000000000000000000000000000000000000000000000000000000000000",
"verified_boot_key_hash": "0000000000000000000000000000000000000000000000000000000000000000",
"boot_state": 2,
"device_locked": 1
},
"attest_key": "/data/vendor/batch_key.der",
"attest_cert_chain": [
"/data/vendor/batch_cert.der",
"/data/vendor/intermediate_cert.der",
"/data/vendor/ca_cert.der"
]
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
{
"attest_ids": {
"brand": "Google",
"device": "Pixel 3A",
"product": "Pixel",
"serial": "UGYJFDjFeRuBEH",
"imei": "987080543071019",
"meid": "27863510227963",
"manufacturer": "Foxconn",
"model": "HD1121"
"brand": "Android",
"device": "generic_x86_64",
"product": "aosp_x86_64",
"serial": "",
"imei": "000000000000000",
"meid": "000000000000000",
"manufacturer": "unknown",
"model": "AOSP on x86_64"
},
"shared_secret": "0000000000000000000000000000000000000000000000000000000000000000",
"set_boot_params": {
"boot_patch_level": 0,
"verified_boot_key": "0000000000000000000000000000000000000000000000000000000000000000",
"verified_boot_key_hash": "0000000000000000000000000000000000000000000000000000000000000000",
"boot_state": 2,
"device_locked": 0
"device_locked": 1
},
"attest_key": "/data/vendor/batch_key.der",
"attest_cert_chain": [
Expand Down