diff options
Diffstat (limited to 'ready_se/google/keymint/KM300/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMPoolManager.java')
-rw-r--r-- | ready_se/google/keymint/KM300/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMPoolManager.java | 657 |
1 files changed, 657 insertions, 0 deletions
diff --git a/ready_se/google/keymint/KM300/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMPoolManager.java b/ready_se/google/keymint/KM300/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMPoolManager.java new file mode 100644 index 0000000..9bc258c --- /dev/null +++ b/ready_se/google/keymint/KM300/Applet/AndroidSEProviderLib/src/com/android/javacard/seprovider/KMPoolManager.java @@ -0,0 +1,657 @@ +/* + * 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.seprovider; + +import javacard.framework.JCSystem; +import javacard.security.AESKey; +import javacard.security.CryptoException; +import javacard.security.DESKey; +import javacard.security.ECPrivateKey; +import javacard.security.ECPublicKey; +import javacard.security.HMACKey; +import javacard.security.KeyAgreement; +import javacard.security.KeyBuilder; +import javacard.security.KeyPair; +import javacard.security.Signature; +import javacardx.crypto.AEADCipher; +import javacardx.crypto.Cipher; + +/** + * This class creates and manages all the cipher, signer, key agreement, operation and trusted + * confirmation pool instances. Each cipher or signer pool can hold a maximum of 4 instances per + * algorithm; however, only one instance of each algorithm is created initially and if required more + * instances are created dynamically. A maximum of four operations can be performed simultaneously. + * Upon reaching the maximum limit of 4, further operations or crypto instances will throw a + * TOO_MANY_OPERATIONS error. TrustedConfirmation pool is to support any operation which has the + * TRUSTED_CONFIRMATION tag in its key parameters. + */ +public class KMPoolManager { + + public static final byte MAX_OPERATION_INSTANCES = 4; + private static final byte HMAC_MAX_OPERATION_INSTANCES = 8; + public static final byte AES_128 = 0x04; + public static final byte AES_256 = 0x05; + // Resource type constants + public static final byte RESOURCE_TYPE_CRYPTO = 0x00; + public static final byte RESOURCE_TYPE_KEY = 0x01; + // static final variables + // -------------------------------------------------------------- + // P-256 Curve Parameters + static byte[] secp256r1_P; + static byte[] secp256r1_A; + + static byte[] secp256r1_B; + static byte[] secp256r1_S; + + // Uncompressed form + static byte[] secp256r1_UCG; + static byte[] secp256r1_N; + static final byte secp256r1_H = 1; + // -------------------------------------------------------------- + + // Cipher pool + private Object[] cipherPool; + // Signature pool + private Object[] signerPool; + // Keyagreement pool + private Object[] keyAgreementPool; + // KMOperationImpl pool + private Object[] operationPool; + // Hmac signer pool which is used to support TRUSTED_CONFIRMATION_REQUIRED tag. + private Object[] hmacSignOperationPool; + + private Object[] keysPool; + // RKP uses AESGCM and HMAC in generateCSR flow. + KMOperation rkpOPeration; + Signature rkpEc; + KMKeyObject rkpEcKey; + + final byte[] KEY_ALGS = { + AES_128, AES_256, KMType.DES, KMType.RSA, KMType.EC, KMType.HMAC, + }; + + final byte[] CIPHER_ALGS = { + Cipher.ALG_AES_BLOCK_128_CBC_NOPAD, + Cipher.ALG_AES_BLOCK_128_ECB_NOPAD, + Cipher.ALG_DES_CBC_NOPAD, + Cipher.ALG_DES_ECB_NOPAD, + Cipher.ALG_AES_CTR, + Cipher.ALG_RSA_PKCS1, + KMRsaOAEPEncoding.ALG_RSA_PKCS1_OAEP_SHA256_MGF1_SHA1, + KMRsaOAEPEncoding.ALG_RSA_PKCS1_OAEP_SHA256_MGF1_SHA256, + Cipher.ALG_RSA_NOPAD, + AEADCipher.ALG_AES_GCM + }; + + final byte[] SIG_ALGS = { + Signature.ALG_RSA_SHA_256_PKCS1, + Signature.ALG_RSA_SHA_256_PKCS1_PSS, + Signature.ALG_ECDSA_SHA_256, + Signature.ALG_HMAC_SHA_256, + KMRsa2048NoDigestSignature.ALG_RSA_SIGN_NOPAD, + KMRsa2048NoDigestSignature.ALG_RSA_PKCS1_NODIGEST, + KMEcdsa256NoDigestSignature.ALG_ECDSA_NODIGEST + }; + + final byte[] KEY_AGREE_ALGS = {KeyAgreement.ALG_EC_SVDP_DH_PLAIN}; + + private static KMPoolManager poolManager; + + public static KMPoolManager getInstance() { + if (poolManager == null) { + poolManager = new KMPoolManager(); + } + return poolManager; + } + + public static void initStatics() { + secp256r1_P = + new byte[] { + (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, + (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, + (byte) 0xFF, (byte) 0xFF + }; + + secp256r1_A = + new byte[] { + (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, + (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, + (byte) 0xFF, (byte) 0xFC + }; + + secp256r1_B = + new byte[] { + (byte) 0x5A, (byte) 0xC6, (byte) 0x35, (byte) 0xD8, (byte) 0xAA, (byte) 0x3A, + (byte) 0x93, (byte) 0xE7, (byte) 0xB3, (byte) 0xEB, (byte) 0xBD, (byte) 0x55, + (byte) 0x76, (byte) 0x98, (byte) 0x86, (byte) 0xBC, (byte) 0x65, (byte) 0x1D, + (byte) 0x06, (byte) 0xB0, (byte) 0xCC, (byte) 0x53, (byte) 0xB0, (byte) 0xF6, + (byte) 0x3B, (byte) 0xCE, (byte) 0x3C, (byte) 0x3E, (byte) 0x27, (byte) 0xD2, + (byte) 0x60, (byte) 0x4B + }; + + secp256r1_S = + new byte[] { + (byte) 0xC4, (byte) 0x9D, (byte) 0x36, (byte) 0x08, (byte) 0x86, (byte) 0xE7, + (byte) 0x04, (byte) 0x93, (byte) 0x6A, (byte) 0x66, (byte) 0x78, (byte) 0xE1, + (byte) 0x13, (byte) 0x9D, (byte) 0x26, (byte) 0xB7, (byte) 0x81, (byte) 0x9F, + (byte) 0x7E, (byte) 0x90 + }; + + // Uncompressed form + secp256r1_UCG = + new byte[] { + (byte) 0x04, (byte) 0x6B, (byte) 0x17, (byte) 0xD1, (byte) 0xF2, (byte) 0xE1, + (byte) 0x2C, (byte) 0x42, (byte) 0x47, (byte) 0xF8, (byte) 0xBC, (byte) 0xE6, + (byte) 0xE5, (byte) 0x63, (byte) 0xA4, (byte) 0x40, (byte) 0xF2, (byte) 0x77, + (byte) 0x03, (byte) 0x7D, (byte) 0x81, (byte) 0x2D, (byte) 0xEB, (byte) 0x33, + (byte) 0xA0, (byte) 0xF4, (byte) 0xA1, (byte) 0x39, (byte) 0x45, (byte) 0xD8, + (byte) 0x98, (byte) 0xC2, (byte) 0x96, (byte) 0x4F, (byte) 0xE3, (byte) 0x42, + (byte) 0xE2, (byte) 0xFE, (byte) 0x1A, (byte) 0x7F, (byte) 0x9B, (byte) 0x8E, + (byte) 0xE7, (byte) 0xEB, (byte) 0x4A, (byte) 0x7C, (byte) 0x0F, (byte) 0x9E, + (byte) 0x16, (byte) 0x2B, (byte) 0xCE, (byte) 0x33, (byte) 0x57, (byte) 0x6B, + (byte) 0x31, (byte) 0x5E, (byte) 0xCE, (byte) 0xCB, (byte) 0xB6, (byte) 0x40, + (byte) 0x68, (byte) 0x37, (byte) 0xBF, (byte) 0x51, (byte) 0xF5 + }; + + secp256r1_N = + new byte[] { + (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0x00, (byte) 0x00, + (byte) 0x00, (byte) 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, + (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xBC, (byte) 0xE6, + (byte) 0xFA, (byte) 0xAD, (byte) 0xA7, (byte) 0x17, (byte) 0x9E, (byte) 0x84, + (byte) 0xF3, (byte) 0xB9, (byte) 0xCA, (byte) 0xC2, (byte) 0xFC, (byte) 0x63, + (byte) 0x25, (byte) 0x51 + }; + } + + private KMPoolManager() { + initStatics(); + cipherPool = new Object[(short) (CIPHER_ALGS.length * MAX_OPERATION_INSTANCES)]; + // Extra 4 algorithms are used to support TRUSTED_CONFIRMATION_REQUIRED feature. + signerPool = + new Object[(short) ((SIG_ALGS.length * MAX_OPERATION_INSTANCES) + MAX_OPERATION_INSTANCES)]; + keyAgreementPool = new Object[(short) (KEY_AGREE_ALGS.length * MAX_OPERATION_INSTANCES)]; + + keysPool = + new Object[(short) ((KEY_ALGS.length * MAX_OPERATION_INSTANCES) + MAX_OPERATION_INSTANCES)]; + 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(); + rkpEc = Signature.getInstance(Signature.ALG_ECDSA_SHA_256, false); + rkpEcKey = createKeyObjectInstance(KMType.EC); + } + + private void initializeKeysPool() { + for (short index = 0; index < KEY_ALGS.length; index++) { + keysPool[index] = createKeyObjectInstance(KEY_ALGS[index]); + } + } + + private void initializeOperationPool() { + for (short index = 0; index < MAX_OPERATION_INSTANCES; index++) { + operationPool[index] = new KMOperationImpl(); + } + } + + private void initializeHmacSignOperationPool() { + for (short index = 0; index < MAX_OPERATION_INSTANCES; index++) { + hmacSignOperationPool[index] = new KMOperationImpl(); + } + } + + // Create a signature instance of each algorithm once. + private void initializeSignerPool() { + short index; + for (index = 0; index < SIG_ALGS.length; index++) { + signerPool[index] = getSignatureInstance(SIG_ALGS[index]); + } + + // Allocate extra 4 HMAC signer instances required for trusted confirmation + for (short len = (short) (index + 4); index < len; index++) { + signerPool[index] = getSignatureInstance(Signature.ALG_HMAC_SHA_256); + } + } + + // Create a cipher instance of each algorithm once. + private void initializeCipherPool() { + for (short index = 0; index < CIPHER_ALGS.length; index++) { + cipherPool[index] = getCipherInstance(CIPHER_ALGS[index]); + } + } + + private void initializeKeyAgreementPool() { + for (short index = 0; index < KEY_AGREE_ALGS.length; index++) { + keyAgreementPool[index] = getKeyAgreementInstance(KEY_AGREE_ALGS[index]); + } + } + + private Object[] getCryptoPoolInstance(short purpose) { + switch (purpose) { + case KMType.AGREE_KEY: + return keyAgreementPool; + + case KMType.ENCRYPT: + case KMType.DECRYPT: + return cipherPool; + + case KMType.SIGN: + case KMType.VERIFY: + return signerPool; + + default: + KMException.throwIt(KMError.UNSUPPORTED_PURPOSE); + } + return null; + } + + private Object createInstance(short purpose, short alg) { + switch (purpose) { + case KMType.AGREE_KEY: + return getKeyAgreementInstance((byte) alg); + + case KMType.ENCRYPT: + case KMType.DECRYPT: + return getCipherInstance((byte) alg); + + case KMType.SIGN: + case KMType.VERIFY: + return getSignatureInstance((byte) alg); + + default: + KMException.throwIt(KMError.UNSUPPORTED_PURPOSE); + } + return null; + } + + private KeyAgreement getKeyAgreementInstance(byte alg) { + return KeyAgreement.getInstance(alg, false); + } + + private Signature getSignatureInstance(byte alg) { + if (KMRsa2048NoDigestSignature.ALG_RSA_SIGN_NOPAD == alg + || KMRsa2048NoDigestSignature.ALG_RSA_PKCS1_NODIGEST == alg) { + return new KMRsa2048NoDigestSignature(alg); + } else if (KMEcdsa256NoDigestSignature.ALG_ECDSA_NODIGEST == alg) { + return new KMEcdsa256NoDigestSignature(alg); + } else { + return Signature.getInstance(alg, false); + } + } + + private KMKeyObject createKeyObjectInstance(byte alg) { + Object keyObject = null; + switch (alg) { + case AES_128: + keyObject = + (AESKey) + KeyBuilder.buildKey( + KeyBuilder.TYPE_AES_TRANSIENT_RESET, KeyBuilder.LENGTH_AES_128, false); + break; + case AES_256: + keyObject = + (AESKey) + KeyBuilder.buildKey( + KeyBuilder.TYPE_AES_TRANSIENT_RESET, KeyBuilder.LENGTH_AES_256, false); + break; + case KMType.DES: + keyObject = + (DESKey) + KeyBuilder.buildKey( + KeyBuilder.TYPE_DES_TRANSIENT_RESET, KeyBuilder.LENGTH_DES3_3KEY, false); + break; + case KMType.RSA: + keyObject = new KeyPair(KeyPair.ALG_RSA, KeyBuilder.LENGTH_RSA_2048); + break; + case KMType.EC: + keyObject = new KeyPair(KeyPair.ALG_EC_FP, KeyBuilder.LENGTH_EC_FP_256); + initECKey((KeyPair) keyObject); + break; + case KMType.HMAC: + keyObject = + (HMACKey) KeyBuilder.buildKey(KeyBuilder.TYPE_HMAC_TRANSIENT_RESET, (short) 512, false); + break; + default: + KMException.throwIt(KMError.UNSUPPORTED_ALGORITHM); + } + KMKeyObject ptr = new KMKeyObject(); + ptr.algorithm = alg; + ptr.keyObjectInst = keyObject; + return ptr; + } + + private Cipher getCipherInstance(byte alg) { + if ((KMRsaOAEPEncoding.ALG_RSA_PKCS1_OAEP_SHA256_MGF1_SHA1 == alg) + || (KMRsaOAEPEncoding.ALG_RSA_PKCS1_OAEP_SHA256_MGF1_SHA256 == alg)) { + return new KMRsaOAEPEncoding(alg); + } else { + return Cipher.getInstance(alg, false); + } + } + + /** + * Returns the first available resource from operation pool. + * + * @return instance of the available resource or null if no resource is available. + */ + public KMOperation getResourceFromOperationPool(boolean isTrustedConfOpr) { + short index = 0; + KMOperationImpl impl; + Object[] oprPool; + if (isTrustedConfOpr) { + oprPool = hmacSignOperationPool; + } else { + oprPool = operationPool; + } + while (index < oprPool.length) { + impl = (KMOperationImpl) oprPool[index]; + // Mode is always set. so compare using mode value. + if (impl.getPurpose() == KMType.INVALID_VALUE) { + return impl; + } + index++; + } + return null; + } + + private byte getAlgorithm(short purpose, Object object) { + switch (purpose) { + case KMType.AGREE_KEY: + return ((KeyAgreement) object).getAlgorithm(); + + case KMType.ENCRYPT: + case KMType.DECRYPT: + return ((Cipher) object).getAlgorithm(); + + case KMType.SIGN: + case KMType.VERIFY: + return ((Signature) object).getAlgorithm(); + + default: + KMException.throwIt(KMError.UNSUPPORTED_PURPOSE); + } + return 0; + } + + private boolean isResourceBusy(Object obj, byte resourceType) { + short index = 0; + while (index < MAX_OPERATION_INSTANCES) { + if (((KMOperationImpl) operationPool[index]).isResourceMatches(obj, resourceType) + || ((KMOperationImpl) hmacSignOperationPool[index]) + .isResourceMatches(obj, resourceType)) { + return true; + } + index++; + } + return false; + } + + private void setObject(short purpose, KMOperation operation, Object obj) { + switch (purpose) { + case KMType.AGREE_KEY: + ((KMOperationImpl) operation).setKeyAgreement((KeyAgreement) obj); + break; + case KMType.ENCRYPT: + case KMType.DECRYPT: + ((KMOperationImpl) operation).setCipher((Cipher) obj); + break; + case KMType.SIGN: + case KMType.VERIFY: + ((KMOperationImpl) operation).setSignature((Signature) obj); + break; + default: + KMException.throwIt(KMError.UNSUPPORTED_PURPOSE); + } + } + + private void reserveOperation( + KMOperation operation, + short purpose, + short strongboxAlgType, + short padding, + short blockMode, + short macLength, + Object obj, + KMKeyObject keyObject) { + ((KMOperationImpl) operation).setPurpose(purpose); + ((KMOperationImpl) operation).setAlgorithmType(strongboxAlgType); + ((KMOperationImpl) operation).setPaddingAlgorithm(padding); + ((KMOperationImpl) operation).setBlockMode(blockMode); + ((KMOperationImpl) operation).setMacLength(macLength); + ((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 Signature.ALG_ECDSA_SHA_256: + cryptoObj = rkpEc; + keyObject = rkpEcKey; + 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, + short padding, + short blockMode, + short macLength, + short secretLength, + boolean isTrustedConfOpr) { + KMOperation operation; + // Throw exception if no resource from operation pool is available. + if (null == (operation = getResourceFromOperationPool(isTrustedConfOpr))) { + KMException.throwIt(KMError.TOO_MANY_OPERATIONS); + } + // Get one of the pool instances (cipher / signer / keyAgreement) based on purpose. + Object[] pool = getCryptoPoolInstance(purpose); + short index = 0; + short usageCount = 0; + short maxOperations = MAX_OPERATION_INSTANCES; + if (Signature.ALG_HMAC_SHA_256 == alg) { + maxOperations = HMAC_MAX_OPERATION_INSTANCES; + } + + KMKeyObject keyObject = getKeyObjectFromPool(alg, secretLength, maxOperations); + while (index < pool.length) { + if (usageCount >= maxOperations) { + KMException.throwIt(KMError.TOO_MANY_OPERATIONS); + } + if (pool[index] == null) { + // Create one of the instance (Cipher / Signer / KeyAgreement] based on purpose. + Object cipherObject = createInstance(purpose, alg); + JCSystem.beginTransaction(); + pool[index] = cipherObject; + JCSystem.commitTransaction(); + reserveOperation( + operation, + purpose, + strongboxAlgType, + padding, + blockMode, + macLength, + pool[index], + keyObject); + break; + } + if (alg == getAlgorithm(purpose, pool[index])) { + // Check if the crypto instance is not busy and free to use. + if (!isResourceBusy(pool[index], RESOURCE_TYPE_CRYPTO)) { + reserveOperation( + operation, + purpose, + strongboxAlgType, + padding, + blockMode, + macLength, + pool[index], + keyObject); + break; + } + usageCount++; + } + index++; + } + return operation; + } + + public KMKeyObject getKeyObjectFromPool(short alg, short secretLength, short maxOperations) { + KMKeyObject keyObject = null; + byte algo = mapAlgorithm(alg, secretLength); + short index = 0; + short usageCount = 0; + while (index < keysPool.length) { + if (usageCount >= maxOperations) { + KMException.throwIt(KMError.TOO_MANY_OPERATIONS); + } + if (keysPool[index] == null) { + keyObject = createKeyObjectInstance(algo); + JCSystem.beginTransaction(); + keysPool[index] = keyObject; + JCSystem.commitTransaction(); + break; + } + keyObject = (KMKeyObject) keysPool[index]; + if (algo == keyObject.algorithm) { + // Check if the Object instance is not busy and free to use. + if (!isResourceBusy(keyObject, RESOURCE_TYPE_KEY)) { + break; + } + usageCount++; + } + index++; + } + return keyObject; + } + + private byte mapAlgorithm(short alg, short secretLength) { + byte algo = 0; + switch (alg) { + case Cipher.ALG_AES_BLOCK_128_CBC_NOPAD: + case Cipher.ALG_AES_BLOCK_128_ECB_NOPAD: + case Cipher.ALG_AES_CTR: + case AEADCipher.ALG_AES_GCM: + if (secretLength == 16) { + algo = AES_128; + } else if (secretLength == 32) { + algo = AES_256; + } else { + CryptoException.throwIt(CryptoException.ILLEGAL_VALUE); + } + break; + case Cipher.ALG_DES_CBC_NOPAD: + case Cipher.ALG_DES_ECB_NOPAD: + algo = KMType.DES; + break; + case Cipher.ALG_RSA_PKCS1: + case KMRsaOAEPEncoding.ALG_RSA_PKCS1_OAEP_SHA256_MGF1_SHA1: + case KMRsaOAEPEncoding.ALG_RSA_PKCS1_OAEP_SHA256_MGF1_SHA256: + case Cipher.ALG_RSA_NOPAD: + case Signature.ALG_RSA_SHA_256_PKCS1: + case Signature.ALG_RSA_SHA_256_PKCS1_PSS: + case KMRsa2048NoDigestSignature.ALG_RSA_SIGN_NOPAD: + case KMRsa2048NoDigestSignature.ALG_RSA_PKCS1_NODIGEST: + algo = KMType.RSA; + break; + case Signature.ALG_ECDSA_SHA_256: + case KMEcdsa256NoDigestSignature.ALG_ECDSA_NODIGEST: + case KeyAgreement.ALG_EC_SVDP_DH_PLAIN: + algo = KMType.EC; + break; + case Signature.ALG_HMAC_SHA_256: + algo = KMType.HMAC; + break; + default: + KMException.throwIt(KMError.UNSUPPORTED_ALGORITHM); + } + return algo; + } + + public void initECKey(KeyPair ecKeyPair) { + ECPrivateKey privKey = (ECPrivateKey) ecKeyPair.getPrivate(); + ECPublicKey pubkey = (ECPublicKey) ecKeyPair.getPublic(); + pubkey.setFieldFP(secp256r1_P, (short) 0, (short) secp256r1_P.length); + pubkey.setA(secp256r1_A, (short) 0, (short) secp256r1_A.length); + pubkey.setB(secp256r1_B, (short) 0, (short) secp256r1_B.length); + pubkey.setG(secp256r1_UCG, (short) 0, (short) secp256r1_UCG.length); + pubkey.setK(secp256r1_H); + pubkey.setR(secp256r1_N, (short) 0, (short) secp256r1_N.length); + + privKey.setFieldFP(secp256r1_P, (short) 0, (short) secp256r1_P.length); + privKey.setA(secp256r1_A, (short) 0, (short) secp256r1_A.length); + privKey.setB(secp256r1_B, (short) 0, (short) secp256r1_B.length); + privKey.setG(secp256r1_UCG, (short) 0, (short) secp256r1_UCG.length); + privKey.setK(secp256r1_H); + privKey.setR(secp256r1_N, (short) 0, (short) secp256r1_N.length); + } + + public void powerReset() { + short index = 0; + while (index < operationPool.length) { + ((KMOperationImpl) operationPool[index]).abort(); + ((KMOperationImpl) hmacSignOperationPool[index]).abort(); + index++; + } + // release rkp operation + rkpOPeration.abort(); + } +} |