package generated.javacard.mondex.purse;

import javacard.framework.*;
import javacardx.crypto.Cipher;

public class EncDataSymm extends EncData {

	public EncDataSymm() {
		encrypted = new byte[Store.MAXENCRYPTLENGTHSYMM];
		c = Cipher.getInstance(Cipher.ALG_DES_CBC_NOPAD, false);
		tmparray = new byte[Store.MAXENCRYPTLENGTHSYMM];
	}

	public byte getCode() {
		return Code.ENCDATASYMM;
	}

	public boolean isEncDataSymm() {
		return true;
	}

	// ********************************************************
	public static EncDataSymm encrypt(Symmkey key, PlainData d) {
		return Store.newEncDataSymm().instEncrypt(key, d);
	}

	private EncDataSymm instEncrypt(Symmkey key, PlainData d) {
		plainDataType = d.getCode();
		Util.arrayFillNonAtomic(tmparray, (short) 0, (short) tmparray.length,
				(byte) 0x0);
		Coding.getInstance().encode(d, tmparray);
		plainlength = Coding.getInstance().getEncodingLength();
		enclength = plainlength % 8 == 0
				? plainlength
				: (short) (8 + plainlength - plainlength % 8);
		c.init(key.toAPIKey(), Cipher.MODE_ENCRYPT);
		c.doFinal(tmparray, (short) 0, enclength, encrypted, (short) 0);
		return this;
	}
	// ********************************************************
	private boolean check() {
		if (!(0 < plainlength && plainlength <= enclength && enclength <= encrypted.length))
			return false;
		return enclength % 8 == 0;
	}

	public static PlainData decrypt(Symmkey key, EncDataSymm e) {
		return e.decrypt(key);
	}

	private PlainData decrypt(Symmkey key) {
		if (!check())
			stop();
		c.init(key.toAPIKey(), Cipher.MODE_DECRYPT);
		c.doFinal(encrypted, (short) 0, enclength, tmparray, (short) 0);
		return Coding.getInstance().decodePlainData(tmparray, plainDataType);
	}

	private void stop() {
		ISOException.throwIt(ISO7816.SW_CONDITIONS_NOT_SATISFIED);
	}

}