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 @@ -100,7 +100,7 @@ public class KMAttestationCertImpl implements KMAttestationCert {
private static final byte keyUsageCertSign = (byte) 0x04; // 5th- bit

private static final byte KEYMASTER_VERSION = 100;
private static final byte ATTESTATION_VERSION = 3;
private static final byte ATTESTATION_VERSION = 100;
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 @@ -138,7 +138,8 @@ public class KMAttestationCertImpl implements KMAttestationCert {
private static short serialNum;

private static byte certMode;
private static short certAttestKey ;
private static short certAttestKeySecret;
private static short certAttestKeyRsaPubModulus;
private static boolean certRsaSign;
private static final byte SERIAL_NUM_MAX_LEN = 20;
private static final byte SUBJECT_NAME_MAX_LEN = 32;
Expand Down Expand Up @@ -186,7 +187,7 @@ private static void init() {
deviceLocked = 0;
signPriv = 0;
certMode = KMType.NO_CERT;
certAttestKey = KMType.INVALID_VALUE;
certAttestKeySecret = KMType.INVALID_VALUE;
certRsaSign = true;
issuer = KMType.INVALID_VALUE;
subjectName = KMType.INVALID_VALUE;
Expand Down Expand Up @@ -234,7 +235,6 @@ public KMAttestationCert notAfter(short usageExpiryTimeObj, boolean derEncoded,
if (usageExpiryTimeObj != KMType.INVALID_VALUE) {
// compare if the expiry time is greater then 2051 then use generalized
// time format else use utc time format.
usageExpiryTimeObj = KMIntegerTag.cast(usageExpiryTimeObj).getValue();
short tmpVar = KMInteger.uint_64(KMUtils.firstJan2051, (short) 0);
if (KMInteger.compare(usageExpiryTimeObj, tmpVar) >= 0) {
usageExpiryTimeObj = KMUtils.convertToDate(usageExpiryTimeObj, scratchPad,
Expand Down Expand Up @@ -514,14 +514,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 Expand Up @@ -862,8 +864,8 @@ public short getCertLength() {
return certLength;
}

@Override
public void build(byte[] attBuf, short attStart, short attLength, boolean rsaSign, boolean fakeCert) {

public void build(short attSecret, short attMod, boolean rsaSign, boolean fakeCert) {
stackPtr = (short)(bufStart + bufLength);
short last = stackPtr;
short sigLen = 0;
Expand Down Expand Up @@ -891,18 +893,18 @@ else if (rsaSign) {
tbsStart = stackPtr;
tbsLength = (short) (tbsLength - tbsStart);
KMJCardSimulator provider = KMJCardSimulator.getInstance();
if(attBuf != null){
if(attSecret != KMType.INVALID_VALUE){
// Sign with the attestation key
// The pubKey is the modulus.
if (rsaSign) {
sigLen = provider
.rsaSign256Pkcs1(
attBuf,
attStart,
attLength,
KMByteBlob.cast(pubKey).getBuffer(),
KMByteBlob.cast(pubKey).getStartOff(),
KMByteBlob.cast(pubKey).length(),
KMByteBlob.cast(attSecret).getBuffer(),
KMByteBlob.cast(attSecret).getStartOff(),
KMByteBlob.cast(attSecret).length(),
KMByteBlob.cast(attMod).getBuffer(),
KMByteBlob.cast(attMod).getStartOff(),
KMByteBlob.cast(attMod).length(),
stack,
tbsStart,
tbsLength,
Expand All @@ -912,9 +914,9 @@ else if (rsaSign) {
} else {
sigLen = provider
.ecSign256(
attBuf,
attStart,
attLength,
KMByteBlob.cast(attSecret).getBuffer(),
KMByteBlob.cast(attSecret).getStartOff(),
KMByteBlob.cast(attSecret).length(),
stack,
tbsStart,
tbsLength,
Expand All @@ -941,11 +943,9 @@ else if (rsaSign) {
@Override
public void build() {
if(certMode == KMType.FAKE_CERT) {
build(null, (short) 0, (short) 0, true, true);
build(KMType.INVALID_VALUE, KMType.INVALID_VALUE, true, true);
}else {
build(KMByteBlob.cast(certAttestKey).getBuffer(),
KMByteBlob.cast(certAttestKey).getStartOff(),
KMByteBlob.cast(certAttestKey).length(), certRsaSign, false);
build(certAttestKeySecret, certAttestKeyRsaPubModulus, certRsaSign, false);
}
}

Expand Down Expand Up @@ -1024,10 +1024,20 @@ public boolean subjectName(short sub){
}

@Override
public KMAttestationCert attestKey(short attestKey, boolean rsaSign, byte mode){
public KMAttestationCert ecAttestKey(short attestKey, byte mode){
certMode = mode;
certAttestKeySecret = attestKey;
certAttestKeyRsaPubModulus = KMType.INVALID_VALUE;
certRsaSign = false;
return this;
}

@Override
public KMAttestationCert rsaAttestKey(short attestPrivExp, short attestMod, byte mode){
certMode = mode;
certAttestKey = attestKey;
certRsaSign = rsaSign;
certAttestKeySecret = attestPrivExp;
certAttestKeyRsaPubModulus = attestMod;
certRsaSign = true;
return this;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright(C) 2021 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" (short)0IS,
* 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 com.android.javacard.keymaster;
import javacard.security.ECPrivateKey;
import javacard.security.ECPublicKey;
import javacard.security.KeyPair;

public class KMECDeviceUniqueKey implements KMDeviceUniqueKey {

private KeyPair ecKeyPair;

@Override
public short getPublicKey(byte[] buf, short offset) {
ECPublicKey publicKey = getPublicKey();
return publicKey.getW(buf, offset);
}

public KMECDeviceUniqueKey(KeyPair ecPair) {
ecKeyPair = ecPair;
}

public void setS(byte[] buffer, short offset, short length) {
ECPrivateKey ecPriv = (ECPrivateKey) ecKeyPair.getPrivate();
ecPriv.setS(buffer, offset, length);
}

public void setW(byte[] buffer, short offset, short length) {
ECPublicKey ecPublicKey = (ECPublicKey) ecKeyPair.getPublic();
ecPublicKey.setW(buffer, offset, length);
}

public ECPrivateKey getPrivateKey() {
return (ECPrivateKey) ecKeyPair.getPrivate();
}

public ECPublicKey getPublicKey() {
return (ECPublicKey) ecKeyPair.getPublic();
}

}
Loading