Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rkp dedicated operation #122

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 @@ -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