FIT_hardware_security/lab01-03_java_card/Applet2.java

89 lines
3.1 KiB
Java

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);
}
}