package hwb1; import javacard.framework.*; //import javacardx.annotations.*; import javacard.security.*; import javacardx.crypto.*; public class Applet1 extends Applet { AESKey crypt_key; AESKey mac_key; byte crypt_key_bytes[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}; byte mac_key_bytes[] = {15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0}; Cipher crypt; Signature mac; public static void install(byte[] bArray, short bOffset, byte bLength) { new Applet1(bArray, bOffset, bLength); } protected Applet1(byte[] bArray, short bOffset, byte bLength) { crypt_key = (AESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_AES, KeyBuilder.LENGTH_AES_128, false); crypt_key.setKey(crypt_key_bytes, (short)0); crypt = Cipher.getInstance(Cipher.ALG_AES_BLOCK_128_CBC_NOPAD, false); mac_key = (AESKey) KeyBuilder.buildKey(KeyBuilder.TYPE_AES, KeyBuilder.LENGTH_AES_128, false); mac_key.setKey(mac_key_bytes, (short)0); mac = Signature.getInstance(Cipher.ALG_AES_MAC_128_NOPAD, false); register(); } private void encrypt(APDU apdu) { byte[] buf = apdu.getBuffer(); short inLen = apdu.setIncomingAndReceive(); if (inLen > 64 || (ilen % 16) != 0) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); byte[] outBuf = new byte[64]; byte[] macBuf = new byte[16]; crypt.init(crypt_key, Cipher.MODE_ENCRYPT); crypt.doFinal(buf, ISO7816.OFFSET_CDATA, inLen, outBuf, (short) 0); mac.init(mac_key, Signature.MODE_SIGN); mac.sign(outBuf, (short) 0, (short) inLen, macBuf, (short) 0); Util.arrayCopyNonAtomic(outBuf, (short) 0, buf, (short) 0, inLen); Util.arrayCopyNonAtomic(macBuf, (short) 0, buf, inLen, (short) 16); apdu.setOutgoingAndSend((short) 0, (short) (inLen + 16)); } private void decrypt(APDU apdu) { byte[] buf = apdu.getBuffer(); short inLen = apdu.setIncomingAndReceive(); // 64 encrypted + 16 signature if (inLen != 80) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); short cryptDataLen = (short) (inLen - (short) 16); byte[] cryptBuf = new byte[64]; mac.init(mac_key, Signature.MODE_VERIFY); boolean isValidMac = mac.verify(buf, (short) 0, cryptDataLen, buf, cryptDataLen, (short) 16); if (!isValidMac) { ISOException.throwIt(ISO7816.SW_WRONG_DATA); } crypt.init(crypt_key, Cipher.MODE_DECRYPT); crypt.doFinal(buf, (short) 0, cryptDataLen, cryptBuf, (short) 0); Util.arrayCopyNonAtomic(cryptBuf, (short) 0, buf, (short) 0, cryptDataLen); apdu.setOutgoingAndSend((short) 0, cryptDataLen); } public void process(APDU apdu) { byte [] buf = apdu.getBuffer(); if (buf[ISO7816.OFFSET_CLA] != 0x00) { ISOException.throwIt(ISO7816.SW_CLA_NOT_SUPPORTED); } byte ins = buf[ISO7816.OFFSET_INS]; switch(ins) { case 0x42: encrypt(apdu); ISOException.throwIt(ISO7816.SW_NO_ERROR); case 0x44: decrypt(apdu); ISOException.throwIt(ISO7816.SW_NO_ERROR); } ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED); } }