Skip to content

Commit

Permalink
Merge pull request #122 from subrahmanyaman/rkp_dedicated_operation
Browse files Browse the repository at this point in the history
Rkp dedicated operation - Reserver a sepate operation slot for RKP as compared to all other Keymint supported operations.
  • Loading branch information
mdwivedi authored Apr 29, 2022
2 parents f4eb552 + c95a39d commit ade6e7e
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -583,11 +583,16 @@ private byte mapCipherAlg(byte alg, byte padding, byte blockmode, byte digest) {

public KMOperation createSymmetricCipher(short alg, short purpose, short macLength,
short blockMode, short padding, byte[] secret, short secretStart,
short secretLength, byte[] ivBuffer, short ivStart, short ivLength) {

short cipherAlg = mapCipherAlg((byte) alg, (byte) padding, (byte) blockMode, (byte) 0);
KMOperation operation =
poolMgr.getOperationImpl(purpose, cipherAlg, alg, padding, blockMode, macLength, secretLength, false);
short secretLength, byte[] ivBuffer, short ivStart, short ivLength,
boolean isRkp) {

short cipherAlg = mapCipherAlg((byte) alg, (byte) padding, (byte) blockMode, (byte) 0);
KMOperation operation = null;
if (isRkp) {
operation = poolMgr.getRKpOperation(purpose, cipherAlg, alg, padding, blockMode, macLength);
} else {
operation = poolMgr.getOperationImpl(purpose, cipherAlg, alg, padding, blockMode, macLength, secretLength, false);
}
// Get the KeyObject from the operation and update the key with the secret key material.
KMKeyObject keyObj = operation.getKeyObject();
Key key = (Key)keyObj.getKeyObjectInstance();
Expand All @@ -608,13 +613,18 @@ public KMOperation createSymmetricCipher(short alg, short purpose, short macLeng
}

public KMOperation createHmacSignerVerifier(short purpose, short digest,
byte[] secret, short secretStart, short secretLength) {
byte[] secret, short secretStart, short secretLength, boolean isRkp) {
KMOperation operation = null;
if (digest != KMType.SHA2_256) {
CryptoException.throwIt(CryptoException.ILLEGAL_VALUE);
}
KMOperation operation =
poolMgr.getOperationImpl(purpose, Signature.ALG_HMAC_SHA_256,
if (isRkp) {
operation = poolMgr.getRKpOperation(purpose, Signature.ALG_HMAC_SHA_256, KMType.HMAC,
KMType.INVALID_VALUE, KMType.INVALID_VALUE, KMType.INVALID_VALUE);
} else {
operation = poolMgr.getOperationImpl(purpose, Signature.ALG_HMAC_SHA_256,
KMType.HMAC, KMType.INVALID_VALUE, KMType.INVALID_VALUE, KMType.INVALID_VALUE, (short)0, false);
}
// Get the KeyObject from the operation and update the key with the secret key material.
KMKeyObject keyObj = operation.getKeyObject();
HMACKey key = (HMACKey)keyObj.getKeyObjectInstance();
Expand All @@ -632,13 +642,36 @@ private KMOperation createHmacSignerVerifier(short purpose, short digest, HMACKe
KMType.HMAC, KMType.INVALID_VALUE, KMType.INVALID_VALUE, KMType.INVALID_VALUE, (short)0, isTrustedConf);
// Get the KeyObject from the operation and update the key with the secret key material.
KMKeyObject keyObj = operation.getKeyObject();
HMACKey key = (HMACKey)keyObj.getKeyObject();
HMACKey key = (HMACKey)keyObj.getKeyObjectInstance();
short len = hmacKey.getKey(tmpArray, (short) 0);
key.setKey(tmpArray, (short) 0, len);
((KMOperationImpl) operation).init(key, digest, null, (short) 0, (short) 0);
return operation;
}

@Override
public KMOperation getRkpOperation(byte purpose, byte alg,
byte digest, byte padding, byte blockMode, byte[] keyBuf, short keyStart,
short keyLength, byte[] ivBuf, short ivStart, short ivLength,
short macLength) {
KMOperation opr = null;
switch (alg) {
case KMType.AES:
// Convert macLength to bytes
macLength = (short) (macLength / 8);
opr = createSymmetricCipher(alg, purpose, macLength, blockMode, padding, keyBuf, keyStart, keyLength, ivBuf,
ivStart, ivLength, true/* isRKP */);
break;
case KMType.HMAC:
opr = createHmacSignerVerifier(purpose, digest, keyBuf, keyStart, keyLength, true/* isRKP */);
break;
default:
CryptoException.throwIt(CryptoException.NO_SUCH_ALGORITHM);
break;
}
return opr;
}

@Override
public KMOperation initSymmetricOperation(byte purpose, byte alg,
byte digest, byte padding, byte blockMode, byte[] keyBuf, short keyStart,
Expand All @@ -651,10 +684,10 @@ public KMOperation initSymmetricOperation(byte purpose, byte alg,
// Convert macLength to bytes
macLength = (short) (macLength / 8);
opr = createSymmetricCipher(alg, purpose, macLength, blockMode, padding, keyBuf, keyStart,
keyLength, ivBuf, ivStart, ivLength);
keyLength, ivBuf, ivStart, ivLength, false/* isRKP */);
break;
case KMType.HMAC:
opr = createHmacSignerVerifier(purpose, digest, keyBuf, keyStart, keyLength);
opr = createHmacSignerVerifier(purpose, digest, keyBuf, keyStart, keyLength, false/* isRKP */);
break;
default:
CryptoException.throwIt(CryptoException.NO_SUCH_ALGORITHM);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import javacard.security.KeyAgreement;
import javacard.security.KeyBuilder;
import javacard.security.KeyPair;
import javacard.security.SecretKey;
import javacard.security.Signature;
import javacardx.crypto.AEADCipher;
import javacardx.crypto.Cipher;
Expand Down Expand Up @@ -68,15 +67,21 @@ public class KMPoolManager {
private Object[] hmacSignOperationPool;

private Object[] keysPool;
// RKP uses AESGCM and HMAC in generateCSR flow.
KMOperation rkpOPeration;
Cipher rkpAesGcm;
Signature rkpHmac;
KMKeyObject rkpHmacKey;
KMKeyObject rkpAesKey;

final byte[] KEY_ALGS = {
AES_128,
AES_256,
KMType.DES,
KMType.RSA,
KMType.EC,
KMType.HMAC,
};
KMType.DES,
KMType.RSA,
KMType.EC,
KMType.HMAC,
};

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

keysPool = new Object[(short) ((KEY_ALGS.length * 4) + 4)];
operationPool = new Object[4];
hmacSignOperationPool = new Object[4];
operationPool = new Object[MAX_OPERATION_INSTANCES];
hmacSignOperationPool = new Object[MAX_OPERATION_INSTANCES];
/* Initialize pools */
initializeOperationPool();
initializeHmacSignOperationPool();
initializeSignerPool();
initializeCipherPool();
initializeKeyAgreementPool();
initializeKeysPool();
// Initialize the Crypto and Key objects required for RKP flow.
initializeRKpObjects();

}

private void initializeRKpObjects() {
rkpOPeration = new KMOperationImpl();
rkpAesGcm = Cipher.getInstance(AEADCipher.ALG_AES_GCM, false);
rkpHmac = Signature.getInstance(Signature.ALG_HMAC_SHA_256, false);
rkpAesKey = createKeyObjectInstance(AES_256);
rkpHmacKey = createKeyObjectInstance(KMType.HMAC);
}

private void initializeKeysPool() {
short index = 0;
Expand Down Expand Up @@ -229,6 +244,12 @@ private void initializeSignerPool() {
signerPool[index] = getSignatureInstance(SIG_ALGS[index]);
index++;
}
// Allocate extra 4 HMAC signer instances required for trusted confirmation
short len = (short) (index + 4);
while (index < len) {
signerPool[index] = getSignatureInstance(Signature.ALG_HMAC_SHA_256);
index++;
}
}

//Create a cipher instance of each algorithm once.
Expand Down Expand Up @@ -428,6 +449,34 @@ private void reserveOperation(KMOperation operation, short purpose, short strong
((KMOperationImpl) operation).setKeyObject(keyObject);
setObject(purpose, operation, obj);
}

public KMOperation getRKpOperation(short purpose, short alg, short strongboxAlgType,
short padding, short blockMode, short macLength) {
if (((KMOperationImpl) rkpOPeration).getPurpose() != KMType.INVALID_VALUE) {
// Should not come here.
KMException.throwIt(KMError.UNKNOWN_ERROR);
}
Object cryptoObj = null;
KMKeyObject keyObject = null;

switch (alg) {
case AEADCipher.ALG_AES_GCM:
cryptoObj = rkpAesGcm;
keyObject = rkpAesKey;
break;
case Signature.ALG_HMAC_SHA_256:
cryptoObj = rkpHmac;
keyObject = rkpHmacKey;
break;
default:
// Should not come here.
KMException.throwIt(KMError.UNSUPPORTED_ALGORITHM);
break;
}
reserveOperation(rkpOPeration, purpose, strongboxAlgType, padding, blockMode, macLength,
cryptoObj, keyObject);
return rkpOPeration;
}


public KMOperation getOperationImpl(short purpose, short alg, short strongboxAlgType,
Expand Down Expand Up @@ -573,6 +622,8 @@ public void powerReset() {
((KMOperationImpl) hmacSignOperationPool[index]).abort();
index++;
}
// release rkp operation
rkpOPeration.abort();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,39 @@ KMOperation initSymmetricOperation(
short ivLength,
short macLength);

/**
* This function creates an Operation instance only for RKP module.
*
* @param purpose is KMType.ENCRYPT or KMType.DECRYPT for AES and DES algorithm. It will be
* KMType.SIGN and KMType.VERIFY for HMAC algorithm
* @param alg is KMType.HMAC, KMType.AES or KMType.DES.
* @param digest is KMType.SHA2_256 in case of HMAC else it will be KMType.DIGEST_NONE.
* @param padding is KMType.PADDING_NONE or KMType.PKCS7 (in case of AES and DES).
* @param blockMode is KMType.CTR, KMType.GCM. KMType.CBC or KMType.ECB for AES or DES else it is
* 0.
* @param keyBuf is aes, des or hmac key buffer.
* @param keyStart is the start of the key buffer.
* @param keyLength is the length of the key buffer.
* @param ivBuf is the iv buffer (in case on AES and DES algorithm without ECB mode)
* @param ivStart is the start of the iv buffer.
* @param ivLength is the length of the iv buffer. It will be zero in case of HMAC and AES/DES
* with ECB mode.
* @param macLength is the mac length in case of signing operation for hmac algorithm.
* @return KMOperation instance.
*/
KMOperation getRkpOperation(byte purpose,
byte alg,
byte digest,
byte padding,
byte blockMode,
byte[] keyBuf,
short keyStart,
short keyLength,
byte[] ivBuf,
short ivStart,
short ivLength,
short macLength);

/**
* This creates a persistent operation for signing, verify, encryption and decryption using RSA
* and EC algorithms when keymaster hal's beginOperation function is executed. For RSA the public
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -570,7 +570,7 @@ public void createRkpMacKey(byte[] keydata, short offset, short length) {
}
}

public KMRkpMacKey getRkpMacacKey() {
public KMRkpMacKey getRkpMacKey() {
return rkpMacKey;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1093,7 +1093,7 @@ private short generateEphemeralEcKey(byte[] scratchPad) {
private void initHmacOperation() {
short dataEntryIndex = getEntry(EPHEMERAL_MAC_KEY);
operation[0] =
seProvider.initSymmetricOperation(
seProvider.getRkpOperation(
KMType.SIGN,
KMType.HMAC,
KMType.SHA2_256,
Expand Down Expand Up @@ -1134,7 +1134,7 @@ private void initAesGcmOperation(byte[] scratchPad, short nonce) {
);
// Initialize the Cipher object.
operation[0] =
seProvider.initSymmetricOperation(
seProvider.getRkpOperation(
KMType.ENCRYPT,
KMType.AES,
(byte) 0,
Expand Down Expand Up @@ -1470,7 +1470,7 @@ private short rkpHmacSign(boolean testMode, byte[] data, short dataStart, short
KMByteBlob.cast(macKey).getStartOff(), MAC_KEY_SIZE, (byte) 0);
result = seProvider.hmacSign(KMByteBlob.cast(macKey).getBuffer(), KMByteBlob.cast(macKey).getStartOff(), MAC_KEY_SIZE, data, dataStart, dataLength, signature, signatureStart);
} else {
result = seProvider.hmacSign(storeDataInst.getRkpMacacKey(), data, dataStart, dataLength, signature, signatureStart);
result = seProvider.hmacSign(storeDataInst.getRkpMacKey(), data, dataStart, dataLength, signature, signatureStart);
}
return result;
}
Expand Down

0 comments on commit ade6e7e

Please sign in to comment.