javacard.security.KeyBuilder Java Examples

The following examples show how to use javacard.security.KeyBuilder. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: CardEdge.java    From SatochipApplet with GNU Affero General Public License v3.0 7 votes vote down vote up
/**
 * Retrieves the Key object to be used w/ the specified key number, key type
 * (KEY_XX) and size. If exists, check it has the proper key type If not,
 * creates it.
 * 
 * @return Retrieved Key object or throws SW_UNATUTHORIZED,
 *         SW_OPERATION_NOT_ALLOWED
 */
private Key getKey(byte key_nb, byte key_type, short key_size) {
	
	if (eckeys[key_nb] == null) {
		// We have to create the Key
		eckeys[key_nb] = KeyBuilder.buildKey(key_type, key_size, false);
	} else {
		// Key already exists: check size & type
		/*
		 * TODO: As an option, we could just discard and recreate if not of
		 * the correct type, but creates trash objects
		 */
		if ((eckeys[key_nb].getSize() != key_size) || (eckeys[key_nb].getType() != key_type))
			ISOException.throwIt(SW_OPERATION_NOT_ALLOWED);
	}
	return eckeys[key_nb];
}
 
Example #2
Source File: SigMsgRecApplet.java    From JCMathLib with MIT License 6 votes vote down vote up
/**
 * Only this class's install method should create the applet object.
 */
protected SigMsgRecApplet(byte[] bArray, short bOffset, byte bLength){       
    byte aidLen = bArray[bOffset];
    if (aidLen== (byte)0){
        //System.out.println("using dfault");
        register();
    } else {
        //System.out.println("using provided");
        register(bArray, (short)(bOffset+1), aidLen);
    }                    
    pubKey = (RSAPublicKey)KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_PUBLIC,KeyBuilder.LENGTH_RSA_512,false);
    privKey = (RSAPrivateKey)KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_PRIVATE,KeyBuilder.LENGTH_RSA_512,false);
    privKey.setExponent(RSA_PRIV_KEY_EXP,(short)0,(short)RSA_PRIV_KEY_EXP.length);
    privKey.setModulus(RSA_PUB_PRIV_KEY_MOD,(short)0,(short)RSA_PUB_PRIV_KEY_MOD.length);
    pubKey.setExponent(RSA_PUB_KEY_EXP,(short)0,(short)RSA_PUB_KEY_EXP.length);
    pubKey.setModulus(RSA_PUB_PRIV_KEY_MOD,(short)0,(short)RSA_PUB_PRIV_KEY_MOD.length);
    sigBuff = JCSystem.makeTransientByteArray((short)(SIG_LENGTH+2),JCSystem.CLEAR_ON_DESELECT);
    sig = (SignatureMessageRecovery)Signature.getInstance(Signature.ALG_RSA_SHA_ISO9796_MR,false);
    recState = (byte)0;
}
 
Example #3
Source File: OpenPGPSecureMessaging.java    From javacard-openpgpcard with GNU General Public License v2.0 6 votes vote down vote up
/**
 * Construct a new secure messaging wrapper.
 */
public OpenPGPSecureMessaging() {
    ssc = JCSystem.makeTransientByteArray(SSC_SIZE, 
            JCSystem.CLEAR_ON_DESELECT);
    tmp = JCSystem.makeTransientByteArray(TMP_SIZE, 
            JCSystem.CLEAR_ON_DESELECT);
    signer = Signature.getInstance(
            Signature.ALG_DES_MAC8_ISO9797_1_M2_ALG3, false);
    verifier = Signature.getInstance(
            Signature.ALG_DES_MAC8_ISO9797_1_M2_ALG3, false);
    cipher = Cipher.getInstance(
            Cipher.ALG_DES_CBC_ISO9797_M2, false);
    decipher = Cipher.getInstance(
            Cipher.ALG_DES_CBC_ISO9797_M2, false);
    
    keyMAC = (DESKey) KeyBuilder.buildKey(
            KeyBuilder.TYPE_DES_TRANSIENT_DESELECT, 
            KeyBuilder.LENGTH_DES3_2KEY, false);
    keyENC = (DESKey) KeyBuilder.buildKey(
            KeyBuilder.TYPE_DES_TRANSIENT_DESELECT, 
            KeyBuilder.LENGTH_DES3_2KEY, false);
    
    ssc_set = JCSystem.makeTransientBooleanArray((short)1, JCSystem.CLEAR_ON_DESELECT);
    ssc_set[0] = false;
}
 
Example #4
Source File: PinTests.java    From GidsApplet with GNU General Public License v3.0 6 votes vote down vote up
@Test
public void authenticateGeneralReplayAttack() {
    byte[] challenge, challengeresponse = new byte[8];
    byte[] key = DatatypeConverter.parseHexBinary("010203040506070801020304050607080102030405060708");
    Cipher cipherDES = Cipher.getInstance(Cipher.ALG_DES_CBC_NOPAD, false);
    DESKey deskey = (DESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_DES, KeyBuilder.LENGTH_DES3_3KEY, false);
    deskey.setKey(key, (short) 0);

    // select admin key
    execute("00 22 81 A4 03 83 01 80");
    // get a challenge
    ResponseAPDU response = execute("00 87 00 00 04 7C 02 81 00 00");
    if (!Arrays.equals(Arrays.copyOfRange(response.getBytes(), 0, 4), new byte[] {0x7C,0x0A,(byte) 0x81,0x08})) {
        fail("not a challenge:" + DatatypeConverter.printHexBinary(response.getBytes()));
    }
    // compute the response
    challenge = Arrays.copyOfRange(response.getBytes(), 4, 12);
    //solve challenge
    cipherDES.init(deskey, Cipher.MODE_ENCRYPT);
    cipherDES.doFinal(challenge, (short) 0, (short)8, challengeresponse, (short) 0);
    // send the response
    execute("00 87 00 00 0C 7C 0A 82 08" + DatatypeConverter.printHexBinary(challengeresponse), 0x9000);
    execute("00 87 00 00 0C 7C 0A 82 08" + DatatypeConverter.printHexBinary(challengeresponse), 0x6985);
}
 
Example #5
Source File: GidsBaseTestClass.java    From GidsApplet with GNU General Public License v3.0 6 votes vote down vote up
protected void authenticateGeneral(byte[] key, boolean successexpected) {
    byte[] challenge, challengeresponse = new byte[8];
    Cipher cipherDES = Cipher.getInstance(Cipher.ALG_DES_CBC_NOPAD, false);
    DESKey deskey = (DESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_DES, KeyBuilder.LENGTH_DES3_3KEY, false);
    deskey.setKey(key, (short) 0);

    // select admin key
    execute("00 22 81 A4 03 83 01 80");
    // get a challenge
    ResponseAPDU response = execute("00 87 00 00 04 7C 02 81 00 00");
    if (!Arrays.equals(Arrays.copyOfRange(response.getBytes(), 0, 4), new byte[] {0x7C,0x0A,(byte) 0x81,0x08})) {
        fail("not a challenge:" + DatatypeConverter.printHexBinary(response.getBytes()));
    }
    // compute the response
    challenge = Arrays.copyOfRange(response.getBytes(), 4, 12);
    //solve challenge
    cipherDES.init(deskey, Cipher.MODE_ENCRYPT);
    cipherDES.doFinal(challenge, (short) 0, (short)8, challengeresponse, (short) 0);
    // send the response
    execute("00 87 00 00 0C 7C 0A 82 08" + DatatypeConverter.printHexBinary(challengeresponse), (successexpected?0x9000: 0x6982));
}
 
Example #6
Source File: JCardSIMProprietaryAPI.java    From ledger-javacard with GNU Affero General Public License v3.0 6 votes vote down vote up
@Override
public boolean getUncompressedPublicPoint(byte[] privateKey,
		short privateKeyOffset, byte[] publicPoint, short publicPointOffset) {
	if ((privateKey != null) && (keyAgreement != null)) {
		try {
			if (ecAlgorithm != KeyBuilder.TYPE_EC_FP_PRIVATE) {
				Secp256k1.setCommonCurveParameters(this.privateKey);
			}
			this.privateKey.setS(privateKey, privateKeyOffset, (short)32);
			keyAgreement.init(this.privateKey);
			keyAgreement.generateSecret(Secp256k1.SECP256K1_G, (short)0, (short)Secp256k1.SECP256K1_G.length, publicPoint, publicPointOffset);
			return true;
		}
		catch(Exception e) {
			return false;
		}
	}
	else {		
		return false;
	}
}
 
Example #7
Source File: IsoApplet.java    From IsoApplet with GNU General Public License v3.0 6 votes vote down vote up
/**
 * \brief Get the field length of an EC FP key using the amount of bytes
 * 			of a parameter (e.g. the prime).
 *
 * \return The bit length of the field.
 *
 * \throw ISOException SC_FUNC_NOT_SUPPORTED.
 */
private short getEcFpFieldLength(short bytes) {
    switch(bytes) {
    case 24:
        return KeyBuilder.LENGTH_EC_FP_192;
    case 28:
        return LENGTH_EC_FP_224;
    case 32:
        return LENGTH_EC_FP_256;
    case 40:
        return LENGTH_EC_FP_320;
    case 48:
        return LENGTH_EC_FP_384;
    case 64:
        return LENGTH_EC_FP_512;
    case 66:
        return LENGTH_EC_FP_521;
    default:
        ISOException.throwIt(ISO7816.SW_FUNC_NOT_SUPPORTED);
        return 0;
    }
}
 
Example #8
Source File: FIDOCCImplementation.java    From CCU2F with Apache License 2.0 5 votes vote down vote up
public FIDOCCImplementation() {
	
	random = RandomData.getInstance(RandomData.ALG_SECURE_RANDOM);
	
    scratch = JCSystem.makeTransientByteArray((short)128, JCSystem.CLEAR_ON_DESELECT);
    //seed = new byte[64];
    
    keyPair = new KeyPair(
        (ECPublicKey)KeyBuilder.buildKey(KeyBuilder.TYPE_EC_FP_PUBLIC, KeyBuilder.LENGTH_EC_FP_256, false),
        (ECPrivateKey)KeyBuilder.buildKey(KeyBuilder.TYPE_EC_FP_PRIVATE, KeyBuilder.LENGTH_EC_FP_256, false));
    Secp256r1.setCommonCurveParameters((ECKey)keyPair.getPrivate());
    Secp256r1.setCommonCurveParameters((ECKey)keyPair.getPublic());
            
    // Initialize the unique seed for DRNG function 
    //random.generateData(seed, (short)0, (short)64);
    
    // Initialize the unique seed for DRNG function       
    drngSeed1 = (AESKey)KeyBuilderX.buildKey(KeyBuilderX.TYPE_AES_STATIC, KeyBuilder.LENGTH_AES_256, false);
    drngSeed2 = (AESKey)KeyBuilderX.buildKey(KeyBuilderX.TYPE_AES_STATIC, KeyBuilder.LENGTH_AES_256, false);
    random.generateData(scratch, (short)0, (short)32);
    drngSeed1.setKey(scratch, (short)0);
    random.generateData(scratch, (short)0, (short)32);
    drngSeed2.setKey(scratch, (short)0);
 
    sha256 = MessageDigest.getInstance(MessageDigest.ALG_SHA_256, false);
            
    // Initialize the unique keys for MAC function
    macKey1 = (AESKey)KeyBuilderX.buildKey(KeyBuilderX.TYPE_AES_STATIC, KeyBuilder.LENGTH_AES_128, false);
    macKey2 = (AESKey)KeyBuilderX.buildKey(KeyBuilderX.TYPE_AES_STATIC, KeyBuilder.LENGTH_AES_128, false);
    random.generateData(scratch, (short)0, (short)16);
    macKey1.setKey(scratch, (short)0);
    random.generateData(scratch, (short)0, (short)16);
    macKey2.setKey(scratch, (short)0);
    
    // Initialize ecMultiplier 
    ecMultiplyHelper = KeyAgreementX.getInstance(KeyAgreementX.ALG_EC_SVDP_DH_PLAIN_XY, false);
}
 
Example #9
Source File: PinTests.java    From GidsApplet with GNU General Public License v3.0 5 votes vote down vote up
@Test
public void authenticateMutualReplayAttack() {
    byte[] key = DatatypeConverter.parseHexBinary("010203040506070801020304050607080102030405060708");
    byte[] myChallenge= new byte [16], globalchallenge = new byte[40], challengeresponse = new byte[40];
    byte[] challenge;
    Cipher cipherDES = Cipher.getInstance(Cipher.ALG_DES_CBC_NOPAD, false);
    DESKey deskey = (DESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_DES, KeyBuilder.LENGTH_DES3_3KEY, false);
    deskey.setKey(key, (short) 0);
    RandomData randomData = RandomData.getInstance(RandomData.ALG_SECURE_RANDOM);
    randomData.generateData(myChallenge, (short) 0, (short) myChallenge.length);
    // select admin key
    execute("00 22 81 A4 03 83 01 80");
    // get a challenge
    ResponseAPDU response = execute("00 87 00 00 14 7C 12 81 10" + DatatypeConverter.printHexBinary(myChallenge) + "00");
    if (!Arrays.equals(Arrays.copyOfRange(response.getBytes(), 0, 4), new byte[] {0x7C,0x12,(byte) 0x81,0x10})) {
        fail("not a challenge:" + DatatypeConverter.printHexBinary(response.getBytes()));
    }
    // compute the response
    challenge = Arrays.copyOfRange(response.getBytes(), 4, 20);
    //solve challenge
    //R2
    System.arraycopy(challenge, 0, globalchallenge, 0, 16);
    //R1
    System.arraycopy(myChallenge, 0, globalchallenge, 16, 16);
    // keep Z1 random
    globalchallenge[(short)39] = (byte) 0x80;
    cipherDES.init(deskey, Cipher.MODE_ENCRYPT);
    cipherDES.doFinal(globalchallenge, (short) 0, (short)40, challengeresponse, (short) 0);
    // send the response
    execute("00 87 00 00 2C 7C 2A 82 28" + DatatypeConverter.printHexBinary(challengeresponse), 0x9000);
    execute("00 87 00 00 2C 7C 2A 82 28" + DatatypeConverter.printHexBinary(challengeresponse), 0x6985);
}
 
Example #10
Source File: STPayW.java    From CardExamples with The Unlicense 5 votes vote down vote up
/**
 * Creates Java Card applet object.
 * 
 * @param array
 *            the byte array containing the AID bytes
 * @param offset
 *            the start of AID bytes in array
 * @param length
 *            the length of the AID bytes in array
 */
private STPayW(byte[] array, short offset, byte length) {
    this.udk = (DESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_DES, KeyBuilder.LENGTH_DES3_2KEY, false);

    this.udkMsd = (DESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_DES, KeyBuilder.LENGTH_DES3_2KEY, false);

    this.tempKey = (DESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_DES_TRANSIENT_DESELECT, KeyBuilder.LENGTH_DES3_2KEY, false);

    this.gpState = GPSystem.APPLICATION_SELECTABLE;

    this.accountParamsStatic = new AccountParamsStatic();

    // Build Static Account Parameters.
    // NOTE: This is a kludge to retrieve AID. This would not work with real Java Card.
    byte[] aidBuffer = new byte[16];
    byte aidLength = JCSystem.getAID().getBytes(aidBuffer, (short) 0);
    this.accountParamsStatic.setAid(aidBuffer, (short) 0, aidLength);

    this.sequenceCounter = (short) 0;

    try {
        setStatePerso();
    }
    catch (IOException e) {
    }

    // Register instance AID.
    register(array, (short) (offset + (byte) 1), array[offset]);
}
 
Example #11
Source File: LedgerWalletApplet.java    From ledger-javacard with GNU Affero General Public License v3.0 5 votes vote down vote up
public LedgerWalletApplet(byte[] parameters, short parametersOffset, byte parametersLength) {
    BCDUtils.init();
    TC.init();
    Crypto.init();
    Transaction.init();
    Bip32Cache.init();
    Keycard.init();
    limits = new byte[LIMIT_LAST];
    scratch256 = JCSystem.makeTransientByteArray((short)256, JCSystem.CLEAR_ON_DESELECT);
    transactionPin = new OwnerPIN(TRANSACTION_PIN_ATTEMPTS, TRANSACTION_PIN_SIZE);
    walletPin = new OwnerPIN(WALLET_PIN_ATTEMPTS, WALLET_PIN_SIZE);
    secondaryPin = new OwnerPIN(SECONDARY_PIN_ATTEMPTS, SECONDARY_PIN_SIZE);
    masterDerived = new byte[64];
    chipKey = (DESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_DES, KeyBuilder.LENGTH_DES3_2KEY, false);
    trustedInputKey = (DESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_DES, KeyBuilder.LENGTH_DES3_2KEY, false);
    developerKey = (DESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_DES, KeyBuilder.LENGTH_DES3_2KEY, false);
    try {
        pairingKey = (AESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_AES, KeyBuilder.LENGTH_AES_256, false);
    }
    catch(Exception e) {
    }
    reset();
    if (parametersLength != 0) {
        attestationPrivate = (ECPrivateKey)KeyBuilder.buildKey(KeyBuilder.TYPE_EC_FP_PRIVATE, KeyBuilder.LENGTH_EC_FP_256, false);
        attestationPublic = new byte[65];
        Secp256k1.setCommonCurveParameters(attestationPrivate);
        attestationPrivate.setS(parameters, parametersOffset, (short)32);
        parametersOffset += (short)32;
        attestationSignature = new byte[parameters[(short)(parametersOffset + 1)] + 2];
        Util.arrayCopy(parameters, parametersOffset, attestationSignature, (short)0, (short)attestationSignature.length);
    }
}
 
Example #12
Source File: CardEdge.java    From SatochipApplet with GNU Affero General Public License v3.0 5 votes vote down vote up
/**
 * This function allows to set the 2FA key and enable 2FA.
 * Once activated, 2FA can only be deactivated when the seed is reset.
 *  
 *  ins: 0x79
 *  p1: 0x00
 *  p2: 0x00
 *  data: [hmacsha1_key(20b) | amount_limit(8b)]
 *  return: (none)
 */
private short set2FAKey(APDU apdu, byte[] buffer){
	// check that PIN[0] has been entered previously
	if (!pins[0].isValidated())
		ISOException.throwIt(SW_UNAUTHORIZED);
	// cannot modify an existing 2FA!
	if (needs_2FA)
		ISOException.throwIt(SW_2FA_INITIALIZED_KEY);
	
	//check input length
	short bytesLeft = Util.makeShort((byte) 0x00, buffer[ISO7816.OFFSET_LC]);
	if (bytesLeft < (short)(20+8))
		ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
	
	if (!done_once_2FA){
		data2FA= new byte[OFFSET_2FA_SIZE];
		randomData = RandomData.getInstance(RandomData.ALG_SECURE_RANDOM);
        aes128_cbc= Cipher.getInstance(Cipher.ALG_AES_BLOCK_128_CBC_NOPAD, false);
        key_2FA= (AESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_AES, KeyBuilder.LENGTH_AES_128, false);
        done_once_2FA= true;
	}
	
	short offset= ISO7816.OFFSET_CDATA;
	Util.arrayCopyNonAtomic(buffer, offset, data2FA, OFFSET_2FA_HMACKEY, (short)20); 
	offset+=(short)20;
	Util.arrayCopyNonAtomic(buffer, offset, data2FA, OFFSET_2FA_LIMIT, (short)8); 
	offset+=(short)8;
	// hmac derivation for id_2FA & key_2FA
	HmacSha160.computeHmacSha160(data2FA, OFFSET_2FA_HMACKEY, (short)20, CST_2FA, (short)0, (short)6, data2FA, OFFSET_2FA_ID);
       HmacSha160.computeHmacSha160(data2FA, OFFSET_2FA_HMACKEY, (short)20, CST_2FA, (short)6, (short)7, recvBuffer, (short)0);
       key_2FA.setKey(recvBuffer,(short)0); // AES-128: 16-bytes key!!
       needs_2FA= true;	
       
       return (short)0;
}
 
Example #13
Source File: PayPass.java    From CardExamples with The Unlicense 4 votes vote down vote up
public PayPass(byte[] bArray, short bOffset, byte bLength) {
    if (bLength != 27)
        ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
    // transaction starts
    JCSystem.beginTransaction();

    // set up and initialize all the DES encryption/descrytion ciphers used in the app
    DESKEY_KD_PERSO_L_EN = (DESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_DES, KeyBuilder.LENGTH_DES, false);
    DESKEY_KD_PERSO_R_DE = (DESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_DES, KeyBuilder.LENGTH_DES, false);
    DESKEY_KD_PERSO_L_DE = (DESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_DES, KeyBuilder.LENGTH_DES, false);
    DESKEY_KD_PERSO_R_EN = (DESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_DES, KeyBuilder.LENGTH_DES, false);
    CIPHER_KD_PERSO_L_EN = Cipher.getInstance(Cipher.ALG_DES_ECB_NOPAD, false);
    CIPHER_KD_PERSO_R_DE = Cipher.getInstance(Cipher.ALG_DES_ECB_NOPAD, false);
    CIPHER_KD_PERSO_L_DE = Cipher.getInstance(Cipher.ALG_DES_ECB_NOPAD, false);
    CIPHER_KD_PERSO_R_EN = Cipher.getInstance(Cipher.ALG_DES_ECB_NOPAD, false);

    // transaction ends
    JCSystem.commitTransaction();

    // define RAM buffers for faster operation
    CVC3_DATA = JCSystem.makeTransientByteArray((short) 16, JCSystem.CLEAR_ON_DESELECT);
    CMD_BUF = JCSystem.makeTransientByteArray((short) 261, JCSystem.CLEAR_ON_DESELECT);
    MAC = JCSystem.makeTransientByteArray((short) 8, JCSystem.CLEAR_ON_DESELECT);

    // on initialize the current state is not_alive
    state = not_alive;

    PROFILE = new Profile();

    // testing area
    // pre-personalization data
    // issuer supply
    PROFILE.VER_KMC = (byte) 0x01;  // MC version
    PROFILE.VER_KMC = bArray[bOffset];  // MC version
    PROFILE.KMC_ID[0] = (byte) 0x54;  // key id
    PROFILE.KMC_ID[1] = (byte) 0x13;
    PROFILE.KMC_ID[2] = (byte) 0x12;
    PROFILE.KMC_ID[3] = (byte) 0xFF;
    PROFILE.KMC_ID[4] = (byte) 0xFF;
    PROFILE.KMC_ID[5] = (byte) 0xFF;
    Util.arrayCopyNonAtomic(bArray, (short) (bOffset + 1), PROFILE.KMC_ID, (short) 0, (short) 6);
    PROFILE.KD_PERSO[0] = (byte) 0xA8;  // personalization key
    PROFILE.KD_PERSO[1] = (byte) 0x6A;
    PROFILE.KD_PERSO[2] = (byte) 0x3D;
    PROFILE.KD_PERSO[3] = (byte) 0x06;
    PROFILE.KD_PERSO[4] = (byte) 0xCA;
    PROFILE.KD_PERSO[5] = (byte) 0xE7;
    PROFILE.KD_PERSO[6] = (byte) 0x04;
    PROFILE.KD_PERSO[7] = (byte) 0x6A;
    PROFILE.KD_PERSO[8] = (byte) 0x10;
    PROFILE.KD_PERSO[9] = (byte) 0x63;
    PROFILE.KD_PERSO[10] = (byte) 0x58;
    PROFILE.KD_PERSO[11] = (byte) 0xD5;
    PROFILE.KD_PERSO[12] = (byte) 0xB8;
    PROFILE.KD_PERSO[13] = (byte) 0x23;
    PROFILE.KD_PERSO[14] = (byte) 0x9C;
    PROFILE.KD_PERSO[15] = (byte) 0xBE;
    Util.arrayCopyNonAtomic(bArray, (short) (bOffset + 7), PROFILE.KD_PERSO, (short) 0, (short) 16);
    PROFILE.CSN[0] = (byte) 0x89;
    PROFILE.CSN[1] = (byte) 0xAA;
    PROFILE.CSN[2] = (byte) 0x7F;
    PROFILE.CSN[3] = (byte) 0x00;
    Util.arrayCopyNonAtomic(bArray, (short) (bOffset + 23), PROFILE.CSN, (short) 0, (short) 4);
    // end issuer supply

    // profile can now be considered in personalization state
    PROFILE.STATE = PERSO;
}
 
Example #14
Source File: Bignat_Helper.java    From JCMathLib with MIT License 4 votes vote down vote up
void initialize(short modRSAEngineMaxBits, short multRSAEngineMaxBits) {
    MODULO_RSA_ENGINE_MAX_LENGTH_BITS = modRSAEngineMaxBits;
    MULT_RSA_ENGINE_MAX_LENGTH_BITS = multRSAEngineMaxBits;
    
    fnc_deep_resize_tmp = rm.helper_BN_array1;
    fnc_mult_resultArray1 = rm.helper_BN_array1;
    fnc_mult_resultArray2 = rm.helper_BN_array2;

    fnc_same_value_array1 = rm.helper_BN_array1;
    fnc_same_value_hash = rm.helper_BN_array2;
    
    fnc_shift_bytes_right_tmp = rm.helper_BN_array1;
    
    // BN below are just reassigned allocated helper_BN_? so that same helper_BN_? is not used in parallel (checked by lock() unlock())
    fnc_mod_add_tmp = rm.helper_BN_A;

    fnc_mod_sub_tmpThis = rm.helper_BN_A;
    fnc_mod_sub_tmp = rm.helper_BN_B;
    fnc_mod_sub_tmpOther = rm.helper_BN_C;

    fnc_mult_mod_tmpThis = rm.helper_BN_A;
    fnc_mult_mod_tmp_mod = rm.helper_BN_B;
    fnc_mult_mod_tmp_x = rm.helper_BN_C;

    fnc_exponentiation_tmp = rm.helper_BN_A;
    fnc_exponentiation_i = rm.helper_BN_B;

    fnc_mod_minus_2 = rm.helper_BN_B;

    fnc_negate_tmp = rm.helper_BN_B;

    fnc_sqrt_S = rm.helper_BN_A;
    fnc_sqrt_exp = rm.helper_BN_A;
    fnc_sqrt_p_1 = rm.helper_BN_B;
    fnc_sqrt_Q = rm.helper_BN_C;
    fnc_sqrt_tmp = rm.helper_BN_D;
    fnc_sqrt_z = rm.helper_BN_E;

    fnc_mod_mult_tmpThis = rm.helper_BN_E; // mod_mult is called from  fnc_sqrt => requires helper_BN_E not being locked in fnc_sqrt when mod_mult is called

    fnc_divide_tmpThis = rm.helper_BN_E; // divide is called from  fnc_sqrt => requires helper_BN_E not being locked  in fnc_sqrt when divide is called

    fnc_mod_exp_modBN = rm.helper_BN_F;  // mod_exp is called from  fnc_sqrt => requires helper_BN_F not being locked  in fnc_sqrt when mod_exp is called

    fnc_int_add_tmpMag = rm.helper_BN_A;
    fnc_int_multiply_mod = rm.helper_BN_A;
    fnc_int_multiply_tmpThis = rm.helper_BN_B;
    fnc_int_divide_tmpThis = rm.helper_BN_A;        
    
    
    // Allocate BN constants always in EEPROM (only reading)
    ONE = new Bignat((short) 1, JCSystem.MEMORY_TYPE_PERSISTENT, this);
    ONE.one();
    TWO = new Bignat((short) 1, JCSystem.MEMORY_TYPE_PERSISTENT, this);
    TWO.two();
    THREE = new Bignat((short) 1, JCSystem.MEMORY_TYPE_PERSISTENT, this);
    THREE.three();

    tmp_array_short = rm.memAlloc.allocateByteArray((short) 2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // only 2b RAM for faster add(short)
    fnc_NmodE_cipher = Cipher.getInstance(Cipher.ALG_RSA_NOPAD, false);
    fnc_NmodE_pubKey = (RSAPublicKey) KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_PUBLIC, MODULO_RSA_ENGINE_MAX_LENGTH_BITS, false);

    // Speedup for fast multiplication
    fnc_mult_keypair = new KeyPair(KeyPair.ALG_RSA_CRT, MULT_RSA_ENGINE_MAX_LENGTH_BITS);
    fnc_mult_keypair.genKeyPair();
    fnc_mult_pubkey_pow2 = (RSAPublicKey) fnc_mult_keypair.getPublic();
    //mult_privkey_pow2 = (RSAPrivateCrtKey) mult_keypair.getPrivate();
    fnc_mult_pubkey_pow2.setExponent(CONST_TWO, (short) 0, (short) CONST_TWO.length);
    fnc_mult_cipher = Cipher.getInstance(Cipher.ALG_RSA_NOPAD, false);

    hashEngine = rm.hashEngine;

    FLAG_FAST_MULT_VIA_RSA = false; // set true only if succesfully allocated and tested below
    try { // Subsequent code may fail on some real (e.g., Infineon CJTOP80K) cards - catch exception
        fnc_mult_cipher.init(fnc_mult_pubkey_pow2, Cipher.MODE_ENCRYPT);
        // Try operation - if doesn't work, exception SW_CANTALLOCATE_BIGNAT is emitted
        Util.arrayFillNonAtomic(fnc_mult_resultArray1, (short) 0, (short) fnc_mult_resultArray1.length, (byte) 6);
        fnc_mult_cipher.doFinal(fnc_mult_resultArray1, (short) 0, (short) fnc_mult_resultArray1.length, fnc_mult_resultArray1, (short) 0);
        FLAG_FAST_MULT_VIA_RSA = true;
    } catch (Exception ignored) {
    } // discard exception                
}
 
Example #15
Source File: STPayP.java    From CardExamples with The Unlicense 4 votes vote down vote up
/**
 * Creates Java Card applet object.
 * 
 * @param array
 *            the byte array containing the AID bytes
 * @param offset
 *            the start of AID bytes in array
 * @param length
 *            the length of the AID bytes in array
 */
private STPayP(byte[] array, short offset, byte length) {
    /*** Start allocate memory when applet is instantiated. ***/
    this.records = new Records(Constants.MAX_SFI_RECORDS);

    this.persistentByteBuffer = new byte[Constants.SIZE_PBB];
    this.personalizedPersistentByteBuffer = new byte[Constants.SIZE_PPBB];

    this.transientByteBuffer = JCSystem.makeTransientByteArray(Constants.SIZE_TBB, JCSystem.CLEAR_ON_DESELECT);

    // NOTE: 'keyEncryption' parameter not used.
    this.mkAC = (DESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_DES, KeyBuilder.LENGTH_DES3_2KEY, false);
    this.mkIDN = (DESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_DES, KeyBuilder.LENGTH_DES3_2KEY, false);
    /*** End allocate memory when applet is instantiated. ***/

    /*** Allocate memory when personalized. ***/
    this.selectResponse = null;
    this.cardLayoutDescriptionPart1 = null;
    this.cardLayoutDescriptionPart2 = null;
    this.cardLayoutDescriptionPart3 = null;

    this.gpState = GPSystem.APPLICATION_SELECTABLE;

    /*** Start initialize variables specific to MPP Remote-SE Lite. ***/
    this.cardProfile = new CardProfile();

    // Build Card Profile.
    // NOTE: This is a kludge to retrieve AID. This would not work with real Java Card.
    byte aidLength = JCSystem.getAID().getBytes(this.transientByteBuffer, (short) 0);
    this.cardProfile.setAid(this.transientByteBuffer, (short) 0, aidLength);

    this.cardProfileHash = new byte[32];

    // Initialize and seed random.
    this.random = RandomData.getInstance(RandomData.ALG_PSEUDO_RANDOM);
    byte[] seed = DataUtil.stringToCompressedByteArray(String.valueOf(Calendar.getInstance().getTimeInMillis()));
    this.random.setSeed(seed, (short) 0, (short) seed.length);

    // Initialize Mobile Key.
    this.dataEncryption = new DataEncryption();
    if (!this.dataEncryption.initMobileKey()) {
        System.out.println("Error: M_Key not initialized.");
    }

    this.sha256 = MessageDigest.getInstance(MessageDigest.ALG_SHA_256, false);
    /*** End initialize variables specific to MPP Remote-SE Lite. ***/

    // Register instance AID.
    register(array, (short) (offset + (byte) 1), array[offset]);
}
 
Example #16
Source File: Keycard.java    From ledger-javacard with GNU Affero General Public License v3.0 4 votes vote down vote up
public static void init() {
    issuerKeycard = (DESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_DES, KeyBuilder.LENGTH_DES3_2KEY, false);
    userKeycard = (DESKey)KeyBuilder.buildKey(KeyBuilder.TYPE_DES, KeyBuilder.LENGTH_DES3_2KEY, false);
    pairingData = JCSystem.makeTransientByteArray((byte)(PAIRING_DATA_SIZE + 1), JCSystem.CLEAR_ON_DESELECT);
    challenge = JCSystem.makeTransientByteArray((byte)4, JCSystem.CLEAR_ON_DESELECT);
}
 
Example #17
Source File: CardEdge.java    From SatochipApplet with GNU Affero General Public License v3.0 4 votes vote down vote up
/**
   * This function signs a given transaction hash with a std or the last extended key
   * If 2FA is enabled, a HMAC must be provided as an additional security layer. 
* 
   * ins: 0x7A
* p1: key number or 0xFF for the last derived Bip32 extended key  
* p2: 0x00
* data: [hash(32b) | option: 2FA-flag(2b)|hmac(20b)]
* 
* return: [sig ]
* 
   */
  private short SignTransactionHash(APDU apdu, byte[] buffer){
  	
  	// check that PIN[0] has been entered previously
if (!pins[0].isValidated())
	ISOException.throwIt(SW_UNAUTHORIZED);

  	byte key_nb = buffer[ISO7816.OFFSET_P1];
if ( (key_nb!=(byte)0xFF) && ((key_nb < 0) || (key_nb >= MAX_NUM_KEYS)) )
	ISOException.throwIt(SW_INCORRECT_P1);

  	short bytesLeft = Util.makeShort((byte) 0x00, buffer[ISO7816.OFFSET_LC]);
if (bytesLeft<MessageDigest.LENGTH_SHA_256)
	ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
  	
  	// check whether the seed is initialized
if (key_nb==(byte)0xFF && !bip32_seeded)
	ISOException.throwIt(SW_BIP32_UNINITIALIZED_SEED);
  	
// check 2FA if required
if(needs_2FA){
	// check data length
	if (bytesLeft<MessageDigest.LENGTH_SHA_256+MessageDigest.LENGTH_SHA+(short)2)
		ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
	// check flag for 2fa_hmac_chalresp
	short hmac_flags= Util.getShort(buffer, (short)(ISO7816.OFFSET_CDATA+32));
	if (hmac_flags!=HMAC_CHALRESP_2FA)
		ISOException.throwIt(SW_INCORRECT_ALG);
	// hmac of 64-bytes msg: ( 32bytes tx_hash | 32bytes 0xCC-padding)
	Util.arrayCopyNonAtomic(buffer, (short)ISO7816.OFFSET_CDATA, recvBuffer, (short)0, (short)32);
	Util.arrayFillNonAtomic(recvBuffer, (short)32, (short)32, (byte)0xCC);
	HmacSha160.computeHmacSha160(data2FA, OFFSET_2FA_HMACKEY, (short)20, recvBuffer, (short)0, (short)64, recvBuffer, (short)64);
	if (Util.arrayCompare(buffer, (short)(ISO7816.OFFSET_CDATA+32+2), recvBuffer, (short)64, (short)20)!=0)
		ISOException.throwIt(SW_SIGNATURE_INVALID);
}

// hash+sign singlehash
  	if (key_nb==(byte)0xFF)
  		sigECDSA.init(bip32_extendedkey, Signature.MODE_SIGN);
  	else{
  		Key key= eckeys[key_nb];
  		// check type and size
  		if ((key == null) || !key.isInitialized())
  			ISOException.throwIt(SW_INCORRECT_P1);
  		if (key.getType() != KeyBuilder.TYPE_EC_FP_PRIVATE)
  			ISOException.throwIt(SW_INCORRECT_ALG);		
  		if (key.getSize()!= LENGTH_EC_FP_256)
  			ISOException.throwIt(SW_INCORRECT_ALG);
  		sigECDSA.init(key, Signature.MODE_SIGN);
  	}
      short sign_size= sigECDSA.signPreComputedHash(buffer, ISO7816.OFFSET_CDATA, MessageDigest.LENGTH_SHA_256, buffer, (short)0);
      return sign_size;
  }
 
Example #18
Source File: CardEdge.java    From SatochipApplet with GNU Affero General Public License v3.0 4 votes vote down vote up
/**
   * This function signs the current hash transaction with a std or the last extended key
   * The hash provided in the APDU is compared to the version stored inside the chip.
* Depending of the total amount in the transaction and the predefined limit, 
* a HMAC must be provided as an additional security layer. 
* 
   * ins: 0x6F
* p1: key number or 0xFF for the last derived Bip32 extended key  
* p2: 0x00
* data: [hash(32b) | option: 2FA-flag(2b)|hmac(20b)]
* 
* return: [sig ]
*
   */
  private short SignTransaction(APDU apdu, byte[] buffer){
// check that PIN[0] has been entered previously
if (!pins[0].isValidated())
	ISOException.throwIt(SW_UNAUTHORIZED);

  	byte key_nb = buffer[ISO7816.OFFSET_P1];
if ( (key_nb!=(byte)0xFF) && ((key_nb < 0) || (key_nb >= MAX_NUM_KEYS)) )
	ISOException.throwIt(SW_INCORRECT_P1);

  	short bytesLeft = Util.makeShort((byte) 0x00, buffer[ISO7816.OFFSET_LC]);
if (bytesLeft<MessageDigest.LENGTH_SHA_256)
	ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
  	
  	// check whether the seed is initialized
if (key_nb==(byte)0xFF && !bip32_seeded)
	ISOException.throwIt(SW_BIP32_UNINITIALIZED_SEED);

// check doublehash value in buffer with cached singlehash value
sha256.reset();
sha256.doFinal(transactionData, OFFSET_TRANSACTION_HASH, MessageDigest.LENGTH_SHA_256, recvBuffer, (short)0);
if ((byte)0 != Util.arrayCompare(buffer, ISO7816.OFFSET_CDATA, recvBuffer, (short)0, MessageDigest.LENGTH_SHA_256))
	ISOException.throwIt(SW_INCORRECT_TXHASH);

// check challenge-response answer if necessary
if(needs_2FA){
	if(	Biginteger.lessThan(data2FA, OFFSET_2FA_LIMIT, transactionData, OFFSET_TRANSACTION_AMOUNT, (short)8)){
		if (bytesLeft<MessageDigest.LENGTH_SHA_256+MessageDigest.LENGTH_SHA+(short)2)
			ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
		// check flag for 2fa_hmac_chalresp
		short hmac_flags= Util.getShort(buffer, (short)(ISO7816.OFFSET_CDATA+32));
		if (hmac_flags!=HMAC_CHALRESP_2FA)
			ISOException.throwIt(SW_INCORRECT_ALG);
		// hmac of 64-bytes msg: (doublesha256(raw_tx) | 32bytes zero-padding)
		Util.arrayFillNonAtomic(recvBuffer, (short)32, (short)32, (byte)0x00);
		HmacSha160.computeHmacSha160(data2FA, OFFSET_2FA_HMACKEY, (short)20, recvBuffer, (short)0, (short)64, recvBuffer, (short)64);
		if (Util.arrayCompare(buffer, (short)(ISO7816.OFFSET_CDATA+32+2), recvBuffer, (short)64, (short)20)!=0)
			ISOException.throwIt(SW_SIGNATURE_INVALID);
		// reset total amount
		Util.arrayFillNonAtomic(transactionData, OFFSET_TRANSACTION_TOTAL, (short)8, (byte)0x00);
	}
	else{					
		//update total amount
		Util.arrayCopyNonAtomic(transactionData, OFFSET_TRANSACTION_AMOUNT, transactionData, OFFSET_TRANSACTION_TOTAL, (short)8);
	}
}

// hash+sign singlehash
  	if (key_nb==(byte)0xFF)
  		sigECDSA.init(bip32_extendedkey, Signature.MODE_SIGN);
  	else{
  		Key key= eckeys[key_nb];
  		// check type and size
  		if ((key == null) || !key.isInitialized())
  			ISOException.throwIt(SW_INCORRECT_P1);
  		if (key.getType() != KeyBuilder.TYPE_EC_FP_PRIVATE)
  			ISOException.throwIt(SW_INCORRECT_ALG);		
  		if (key.getSize()!= LENGTH_EC_FP_256)
  			ISOException.throwIt(SW_INCORRECT_ALG);
  		sigECDSA.init(key, Signature.MODE_SIGN);
  	}
      short sign_size= sigECDSA.sign(transactionData, OFFSET_TRANSACTION_HASH, (short)32, buffer, (short)0);
      return sign_size;
  }
 
Example #19
Source File: CardEdge.java    From SatochipApplet with GNU Affero General Public License v3.0 4 votes vote down vote up
/** 
 * This function returns the public key associated with a particular private key stored 
 * in the applet. The exact key blob contents depend on the key�s algorithm and type. 
 * 
 * ins: 0x35
 * p1: private key number (0x00-0x0F)
 * p2: 0x00
 * data: none 
 * return(SECP256K1): [coordx_size(2b) | pubkey_coordx | sig_size(2b) | sig]
 */
private short getPublicKeyFromPrivate(APDU apdu, byte[] buffer) {
	// check that PIN[0] has been entered previously
	if (!pins[0].isValidated())
		ISOException.throwIt(SW_UNAUTHORIZED);
	
	if (buffer[ISO7816.OFFSET_P2] != (byte) 0x00)
		ISOException.throwIt(SW_INCORRECT_P2);
	
	byte key_nb = buffer[ISO7816.OFFSET_P1];
	if ((key_nb < 0) || (key_nb >= MAX_NUM_KEYS))
		ISOException.throwIt(SW_INCORRECT_P1);
	
	Key key = eckeys[key_nb];
	// check type and size
	if ((key == null) || !key.isInitialized())
		ISOException.throwIt(SW_INCORRECT_P1);
	if (key.getType() != KeyBuilder.TYPE_EC_FP_PRIVATE)
		ISOException.throwIt(SW_INCORRECT_ALG);		
	if (key.getSize()!= LENGTH_EC_FP_256)
		ISOException.throwIt(SW_INCORRECT_ALG);
	// check the curve param
	if(!Secp256k1.checkCurveParameters((ECPrivateKey)key, recvBuffer, (short)0))
		ISOException.throwIt(SW_INCORRECT_ALG);
			
	// compute the corresponding partial public key...
       keyAgreement.init((ECPrivateKey)key);
       short coordx_size=(short)32;
   	keyAgreement.generateSecret(Secp256k1.SECP256K1, Secp256k1.OFFSET_SECP256K1_G, (short) 65, buffer, (short)1); //pubkey in uncompressed form
    Util.setShort(buffer, (short)0, coordx_size);
       
       // sign fixed message
       sigECDSA.init(key, Signature.MODE_SIGN);
       short sign_size= sigECDSA.sign(buffer, (short)0, (short)(coordx_size+2), buffer, (short)(coordx_size+4));
       Util.setShort(buffer, (short)(coordx_size+2), sign_size);
       
       // return x-coordinate of public key+signature
       // the client can recover full public-key from the signature or
       // by guessing the compression value () and verifying the signature... 
       return (short)(2+coordx_size+2+sign_size);
}
 
Example #20
Source File: GidsBaseTestClass.java    From GidsApplet with GNU General Public License v3.0 4 votes vote down vote up
protected void authenticateMutual(byte[] key, boolean successexpected) {
    byte[] myChallenge= new byte [16], globalchallenge = new byte[40], challengeresponse = new byte[40];
    byte[] cardChallenge;
    Cipher cipherDES = Cipher.getInstance(Cipher.ALG_DES_CBC_NOPAD, false);
    DESKey deskey = (DESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_DES, KeyBuilder.LENGTH_DES3_3KEY, false);
    deskey.setKey(key, (short) 0);
    new Random().nextBytes(myChallenge);
    // select admin key
    execute("00 22 81 A4 03 83 01 80");
    // get a challenge
    ResponseAPDU response = execute("00 87 00 00 14 7C 12 81 10" + DatatypeConverter.printHexBinary(myChallenge) + "00");
    if (!Arrays.equals(Arrays.copyOfRange(response.getBytes(), 0, 4), new byte[] {0x7C,0x12,(byte) 0x81,0x10})) {
        fail("not a challenge:" + DatatypeConverter.printHexBinary(response.getBytes()));
    }
    // compute the response
    cardChallenge = Arrays.copyOfRange(response.getBytes(), 4, 20);
    //solve challenge
    //R2
    System.arraycopy(cardChallenge, 0, globalchallenge, 0, 16);
    //R1
    System.arraycopy(myChallenge, 0, globalchallenge, 16, 16);
    // keep Z1 random
    globalchallenge[(short)39] = (byte) 0x80;
    cipherDES.init(deskey, Cipher.MODE_ENCRYPT);
    cipherDES.doFinal(globalchallenge, (short) 0, (short)40, challengeresponse, (short) 0);
    // send the response
    String command = "00 87 00 00 2C 7C 2A 82 28" + DatatypeConverter.printHexBinary(challengeresponse);
    
    ResponseAPDU responseAPDU = execute(command, true);
    
    if (!successexpected)
    {
        if(responseAPDU.getSW() != 0x6982) {
            fail("expected: " + Integer.toHexString(0x6982) + " but was: " + Integer.toHexString(response.getSW()));
        }
        return;
    }
    if(responseAPDU.getSW() != 0x9000) {
        fail("expected: " + Integer.toHexString(0x9000) + " but was: " + Integer.toHexString(response.getSW()));
    }
    byte[] cardresponse = responseAPDU.getBytes();
    if (!Arrays.equals(Arrays.copyOfRange(cardresponse, 0, 4), new byte[] {0x7C,0x2A,(byte)0x82,0x28}))
    {
        fail("header verification failed");
    }
    byte[] decryptedCardResponse = new byte[40];
    cipherDES.init(deskey, Cipher.MODE_DECRYPT);
    cipherDES.doFinal(cardresponse, (short) 4, (short)40, decryptedCardResponse, (short) 0);
   
    
    if (!Arrays.equals(Arrays.copyOfRange(decryptedCardResponse, 0, 16), myChallenge)) {
        fail("R1 verification failed");
    }
    
    if (!Arrays.equals(Arrays.copyOfRange(decryptedCardResponse, 16, 32), cardChallenge)) {
        fail("R2 verification failed");
    }
    if (decryptedCardResponse[(short)39] != (byte) 0x80) {
        fail("padding failed");
    }
    
}
 
Example #21
Source File: SECP256k1.java    From status-keycard with Apache License 2.0 4 votes vote down vote up
/**
 * Allocates objects needed by this class. Must be invoked during the applet installation exactly 1 time.
 */
SECP256k1() {
  this.ecPointMultiplier = KeyAgreement.getInstance(ALG_EC_SVDP_DH_PLAIN_XY, false);
  this.tmpECPrivateKey = (ECPrivateKey) KeyBuilder.buildKey(KeyBuilder.TYPE_EC_FP_PRIVATE, SECP256K1_KEY_SIZE, false);
  setCurveParameters(tmpECPrivateKey);
}