Skip to content

Commit ade6e7e

Browse files
authored
Merge pull request #122 from subrahmanyaman/rkp_dedicated_operation
Rkp dedicated operation - Reserver a sepate operation slot for RKP as compared to all other Keymint supported operations.
2 parents f4eb552 + c95a39d commit ade6e7e

File tree

5 files changed

+140
-23
lines changed

5 files changed

+140
-23
lines changed

Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMAndroidSEProvider.java

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -583,11 +583,16 @@ private byte mapCipherAlg(byte alg, byte padding, byte blockmode, byte digest) {
583583

584584
public KMOperation createSymmetricCipher(short alg, short purpose, short macLength,
585585
short blockMode, short padding, byte[] secret, short secretStart,
586-
short secretLength, byte[] ivBuffer, short ivStart, short ivLength) {
587-
588-
short cipherAlg = mapCipherAlg((byte) alg, (byte) padding, (byte) blockMode, (byte) 0);
589-
KMOperation operation =
590-
poolMgr.getOperationImpl(purpose, cipherAlg, alg, padding, blockMode, macLength, secretLength, false);
586+
short secretLength, byte[] ivBuffer, short ivStart, short ivLength,
587+
boolean isRkp) {
588+
589+
short cipherAlg = mapCipherAlg((byte) alg, (byte) padding, (byte) blockMode, (byte) 0);
590+
KMOperation operation = null;
591+
if (isRkp) {
592+
operation = poolMgr.getRKpOperation(purpose, cipherAlg, alg, padding, blockMode, macLength);
593+
} else {
594+
operation = poolMgr.getOperationImpl(purpose, cipherAlg, alg, padding, blockMode, macLength, secretLength, false);
595+
}
591596
// Get the KeyObject from the operation and update the key with the secret key material.
592597
KMKeyObject keyObj = operation.getKeyObject();
593598
Key key = (Key)keyObj.getKeyObjectInstance();
@@ -608,13 +613,18 @@ public KMOperation createSymmetricCipher(short alg, short purpose, short macLeng
608613
}
609614

610615
public KMOperation createHmacSignerVerifier(short purpose, short digest,
611-
byte[] secret, short secretStart, short secretLength) {
616+
byte[] secret, short secretStart, short secretLength, boolean isRkp) {
617+
KMOperation operation = null;
612618
if (digest != KMType.SHA2_256) {
613619
CryptoException.throwIt(CryptoException.ILLEGAL_VALUE);
614620
}
615-
KMOperation operation =
616-
poolMgr.getOperationImpl(purpose, Signature.ALG_HMAC_SHA_256,
621+
if (isRkp) {
622+
operation = poolMgr.getRKpOperation(purpose, Signature.ALG_HMAC_SHA_256, KMType.HMAC,
623+
KMType.INVALID_VALUE, KMType.INVALID_VALUE, KMType.INVALID_VALUE);
624+
} else {
625+
operation = poolMgr.getOperationImpl(purpose, Signature.ALG_HMAC_SHA_256,
617626
KMType.HMAC, KMType.INVALID_VALUE, KMType.INVALID_VALUE, KMType.INVALID_VALUE, (short)0, false);
627+
}
618628
// Get the KeyObject from the operation and update the key with the secret key material.
619629
KMKeyObject keyObj = operation.getKeyObject();
620630
HMACKey key = (HMACKey)keyObj.getKeyObjectInstance();
@@ -632,13 +642,36 @@ private KMOperation createHmacSignerVerifier(short purpose, short digest, HMACKe
632642
KMType.HMAC, KMType.INVALID_VALUE, KMType.INVALID_VALUE, KMType.INVALID_VALUE, (short)0, isTrustedConf);
633643
// Get the KeyObject from the operation and update the key with the secret key material.
634644
KMKeyObject keyObj = operation.getKeyObject();
635-
HMACKey key = (HMACKey)keyObj.getKeyObject();
645+
HMACKey key = (HMACKey)keyObj.getKeyObjectInstance();
636646
short len = hmacKey.getKey(tmpArray, (short) 0);
637647
key.setKey(tmpArray, (short) 0, len);
638648
((KMOperationImpl) operation).init(key, digest, null, (short) 0, (short) 0);
639649
return operation;
640650
}
641651

652+
@Override
653+
public KMOperation getRkpOperation(byte purpose, byte alg,
654+
byte digest, byte padding, byte blockMode, byte[] keyBuf, short keyStart,
655+
short keyLength, byte[] ivBuf, short ivStart, short ivLength,
656+
short macLength) {
657+
KMOperation opr = null;
658+
switch (alg) {
659+
case KMType.AES:
660+
// Convert macLength to bytes
661+
macLength = (short) (macLength / 8);
662+
opr = createSymmetricCipher(alg, purpose, macLength, blockMode, padding, keyBuf, keyStart, keyLength, ivBuf,
663+
ivStart, ivLength, true/* isRKP */);
664+
break;
665+
case KMType.HMAC:
666+
opr = createHmacSignerVerifier(purpose, digest, keyBuf, keyStart, keyLength, true/* isRKP */);
667+
break;
668+
default:
669+
CryptoException.throwIt(CryptoException.NO_SUCH_ALGORITHM);
670+
break;
671+
}
672+
return opr;
673+
}
674+
642675
@Override
643676
public KMOperation initSymmetricOperation(byte purpose, byte alg,
644677
byte digest, byte padding, byte blockMode, byte[] keyBuf, short keyStart,
@@ -651,10 +684,10 @@ public KMOperation initSymmetricOperation(byte purpose, byte alg,
651684
// Convert macLength to bytes
652685
macLength = (short) (macLength / 8);
653686
opr = createSymmetricCipher(alg, purpose, macLength, blockMode, padding, keyBuf, keyStart,
654-
keyLength, ivBuf, ivStart, ivLength);
687+
keyLength, ivBuf, ivStart, ivLength, false/* isRKP */);
655688
break;
656689
case KMType.HMAC:
657-
opr = createHmacSignerVerifier(purpose, digest, keyBuf, keyStart, keyLength);
690+
opr = createHmacSignerVerifier(purpose, digest, keyBuf, keyStart, keyLength, false/* isRKP */);
658691
break;
659692
default:
660693
CryptoException.throwIt(CryptoException.NO_SUCH_ALGORITHM);

Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMPoolManager.java

Lines changed: 59 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
import javacard.security.KeyAgreement;
2525
import javacard.security.KeyBuilder;
2626
import javacard.security.KeyPair;
27-
import javacard.security.SecretKey;
2827
import javacard.security.Signature;
2928
import javacardx.crypto.AEADCipher;
3029
import javacardx.crypto.Cipher;
@@ -68,15 +67,21 @@ public class KMPoolManager {
6867
private Object[] hmacSignOperationPool;
6968

7069
private Object[] keysPool;
70+
// RKP uses AESGCM and HMAC in generateCSR flow.
71+
KMOperation rkpOPeration;
72+
Cipher rkpAesGcm;
73+
Signature rkpHmac;
74+
KMKeyObject rkpHmacKey;
75+
KMKeyObject rkpAesKey;
7176

7277
final byte[] KEY_ALGS = {
7378
AES_128,
7479
AES_256,
75-
KMType.DES,
76-
KMType.RSA,
77-
KMType.EC,
78-
KMType.HMAC,
79-
};
80+
KMType.DES,
81+
KMType.RSA,
82+
KMType.EC,
83+
KMType.HMAC,
84+
};
8085

8186
final byte[] CIPHER_ALGS = {
8287
Cipher.ALG_AES_BLOCK_128_CBC_NOPAD,
@@ -186,17 +191,27 @@ private KMPoolManager() {
186191
keyAgreementPool = new Object[(short) (KEY_AGREE_ALGS.length * 4)];
187192

188193
keysPool = new Object[(short) ((KEY_ALGS.length * 4) + 4)];
189-
operationPool = new Object[4];
190-
hmacSignOperationPool = new Object[4];
194+
operationPool = new Object[MAX_OPERATION_INSTANCES];
195+
hmacSignOperationPool = new Object[MAX_OPERATION_INSTANCES];
191196
/* Initialize pools */
192197
initializeOperationPool();
193198
initializeHmacSignOperationPool();
194199
initializeSignerPool();
195200
initializeCipherPool();
196201
initializeKeyAgreementPool();
197202
initializeKeysPool();
203+
// Initialize the Crypto and Key objects required for RKP flow.
204+
initializeRKpObjects();
198205

199206
}
207+
208+
private void initializeRKpObjects() {
209+
rkpOPeration = new KMOperationImpl();
210+
rkpAesGcm = Cipher.getInstance(AEADCipher.ALG_AES_GCM, false);
211+
rkpHmac = Signature.getInstance(Signature.ALG_HMAC_SHA_256, false);
212+
rkpAesKey = createKeyObjectInstance(AES_256);
213+
rkpHmacKey = createKeyObjectInstance(KMType.HMAC);
214+
}
200215

201216
private void initializeKeysPool() {
202217
short index = 0;
@@ -229,6 +244,12 @@ private void initializeSignerPool() {
229244
signerPool[index] = getSignatureInstance(SIG_ALGS[index]);
230245
index++;
231246
}
247+
// Allocate extra 4 HMAC signer instances required for trusted confirmation
248+
short len = (short) (index + 4);
249+
while (index < len) {
250+
signerPool[index] = getSignatureInstance(Signature.ALG_HMAC_SHA_256);
251+
index++;
252+
}
232253
}
233254

234255
//Create a cipher instance of each algorithm once.
@@ -428,6 +449,34 @@ private void reserveOperation(KMOperation operation, short purpose, short strong
428449
((KMOperationImpl) operation).setKeyObject(keyObject);
429450
setObject(purpose, operation, obj);
430451
}
452+
453+
public KMOperation getRKpOperation(short purpose, short alg, short strongboxAlgType,
454+
short padding, short blockMode, short macLength) {
455+
if (((KMOperationImpl) rkpOPeration).getPurpose() != KMType.INVALID_VALUE) {
456+
// Should not come here.
457+
KMException.throwIt(KMError.UNKNOWN_ERROR);
458+
}
459+
Object cryptoObj = null;
460+
KMKeyObject keyObject = null;
461+
462+
switch (alg) {
463+
case AEADCipher.ALG_AES_GCM:
464+
cryptoObj = rkpAesGcm;
465+
keyObject = rkpAesKey;
466+
break;
467+
case Signature.ALG_HMAC_SHA_256:
468+
cryptoObj = rkpHmac;
469+
keyObject = rkpHmacKey;
470+
break;
471+
default:
472+
// Should not come here.
473+
KMException.throwIt(KMError.UNSUPPORTED_ALGORITHM);
474+
break;
475+
}
476+
reserveOperation(rkpOPeration, purpose, strongboxAlgType, padding, blockMode, macLength,
477+
cryptoObj, keyObject);
478+
return rkpOPeration;
479+
}
431480

432481

433482
public KMOperation getOperationImpl(short purpose, short alg, short strongboxAlgType,
@@ -573,6 +622,8 @@ public void powerReset() {
573622
((KMOperationImpl) hmacSignOperationPool[index]).abort();
574623
index++;
575624
}
625+
// release rkp operation
626+
rkpOPeration.abort();
576627
}
577628

578629
}

Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMSEProvider.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,39 @@ KMOperation initSymmetricOperation(
540540
short ivLength,
541541
short macLength);
542542

543+
/**
544+
* This function creates an Operation instance only for RKP module.
545+
*
546+
* @param purpose is KMType.ENCRYPT or KMType.DECRYPT for AES and DES algorithm. It will be
547+
* KMType.SIGN and KMType.VERIFY for HMAC algorithm
548+
* @param alg is KMType.HMAC, KMType.AES or KMType.DES.
549+
* @param digest is KMType.SHA2_256 in case of HMAC else it will be KMType.DIGEST_NONE.
550+
* @param padding is KMType.PADDING_NONE or KMType.PKCS7 (in case of AES and DES).
551+
* @param blockMode is KMType.CTR, KMType.GCM. KMType.CBC or KMType.ECB for AES or DES else it is
552+
* 0.
553+
* @param keyBuf is aes, des or hmac key buffer.
554+
* @param keyStart is the start of the key buffer.
555+
* @param keyLength is the length of the key buffer.
556+
* @param ivBuf is the iv buffer (in case on AES and DES algorithm without ECB mode)
557+
* @param ivStart is the start of the iv buffer.
558+
* @param ivLength is the length of the iv buffer. It will be zero in case of HMAC and AES/DES
559+
* with ECB mode.
560+
* @param macLength is the mac length in case of signing operation for hmac algorithm.
561+
* @return KMOperation instance.
562+
*/
563+
KMOperation getRkpOperation(byte purpose,
564+
byte alg,
565+
byte digest,
566+
byte padding,
567+
byte blockMode,
568+
byte[] keyBuf,
569+
short keyStart,
570+
short keyLength,
571+
byte[] ivBuf,
572+
short ivStart,
573+
short ivLength,
574+
short macLength);
575+
543576
/**
544577
* This creates a persistent operation for signing, verify, encryption and decryption using RSA
545578
* and EC algorithms when keymaster hal's beginOperation function is executed. For RSA the public

Applet/src/com/android/javacard/keymaster/KMKeymintDataStore.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -570,7 +570,7 @@ public void createRkpMacKey(byte[] keydata, short offset, short length) {
570570
}
571571
}
572572

573-
public KMRkpMacKey getRkpMacacKey() {
573+
public KMRkpMacKey getRkpMacKey() {
574574
return rkpMacKey;
575575
}
576576

Applet/src/com/android/javacard/keymaster/RemotelyProvisionedComponentDevice.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1093,7 +1093,7 @@ private short generateEphemeralEcKey(byte[] scratchPad) {
10931093
private void initHmacOperation() {
10941094
short dataEntryIndex = getEntry(EPHEMERAL_MAC_KEY);
10951095
operation[0] =
1096-
seProvider.initSymmetricOperation(
1096+
seProvider.getRkpOperation(
10971097
KMType.SIGN,
10981098
KMType.HMAC,
10991099
KMType.SHA2_256,
@@ -1134,7 +1134,7 @@ private void initAesGcmOperation(byte[] scratchPad, short nonce) {
11341134
);
11351135
// Initialize the Cipher object.
11361136
operation[0] =
1137-
seProvider.initSymmetricOperation(
1137+
seProvider.getRkpOperation(
11381138
KMType.ENCRYPT,
11391139
KMType.AES,
11401140
(byte) 0,
@@ -1470,7 +1470,7 @@ private short rkpHmacSign(boolean testMode, byte[] data, short dataStart, short
14701470
KMByteBlob.cast(macKey).getStartOff(), MAC_KEY_SIZE, (byte) 0);
14711471
result = seProvider.hmacSign(KMByteBlob.cast(macKey).getBuffer(), KMByteBlob.cast(macKey).getStartOff(), MAC_KEY_SIZE, data, dataStart, dataLength, signature, signatureStart);
14721472
} else {
1473-
result = seProvider.hmacSign(storeDataInst.getRkpMacacKey(), data, dataStart, dataLength, signature, signatureStart);
1473+
result = seProvider.hmacSign(storeDataInst.getRkpMacKey(), data, dataStart, dataLength, signature, signatureStart);
14741474
}
14751475
return result;
14761476
}

0 commit comments

Comments
 (0)