## self implement
```java=
package PRLab ;
import javacard.framework.*;
import javacard.security.*;
public class HMAC
{
private final short BLOCK_SIZE = (short)64;
private byte[] prk;
private byte[] msg;
private MessageDigest sha256 = MessageDigest.getInstance(MessageDigest.ALG_SHA_256, false);
private byte[] ikeypad = new byte[BLOCK_SIZE];
private byte[] okeypad = new byte[BLOCK_SIZE];
HMAC(byte[] input_key){
if(input_key.length <= BLOCK_SIZE){
prk = new byte[input_key.length];
Util.arrayCopy(input_key, (short)0, prk, (short)0, (short)input_key.length);
}else{
prk = new byte[32];
sha256.doFinal(input_key, (short)0, (short)input_key.length, prk, (short)0);
}
for(short i = 0; i<prk.length; i++){
ikeypad[i] = (byte)(prk[i]^0x36);
okeypad[i] = (byte)(prk[i]^0x5c);
}
// The Util.arrayFill() have a strange bug that will left some bytes would not be filled.
Util.arrayFillNonAtomic(ikeypad, (short)prk.length, (short)(ikeypad.length-prk.length), (byte)0x36);
Util.arrayFillNonAtomic(okeypad, (short)prk.length, (short)(okeypad.length-prk.length), (byte)0x5c);
}
public void update(byte[] newMsg){
if(msg == null){
msg = new byte[newMsg.length];
Util.arrayCopy(newMsg, (short)0, msg, (short)0, (short)newMsg.length);
return;
}
byte[] temp = new byte[msg.length + newMsg.length];
concat(msg, newMsg, temp);
msg = temp;
JCSystem.requestObjectDeletion();
}
public void doFinal(byte[] output, short offset){
sha256.update(ikeypad, (short)0, (short)ikeypad.length);
sha256.doFinal(msg, (short)0, (short)msg.length, output, (short)0);
sha256.update(okeypad, (short)0, (short)okeypad.length);
sha256.doFinal(output, (short)0, (short)32, output, (short)0);
}
private void concat(byte[] a, byte[] b, byte[] output){
Util.arrayCopy(a, (short)0, output, (short)0, (short)a.length);
Util.arrayCopy(b, (short)0, output, (short)a.length, (short)b.length);
}
}
```
## javacard api
J3R180 not support..... orz
```java=
HMACKey hmacKey = (HMACKey)KeyBuilder.buildKey(
KeyBuilder.ALG_TYPE_HMAC,
JCSystem.MEMORY_TYPE_TRANSIENT_DESELECT,
KeyBuilder.LENGTH_HMAC_SHA_256_BLOCK_64,
false
);
hmacKey.setKey(new byte[]{'P','A','S','S','W','O','R','D',}, (short)0, (short)8);
Signature hmac = Signature.getInstance(Signature.ALG_HMAC_SHA_256, false);
hmac.init(hmacKey, Signature.MODE_SIGN);
hmac.sign(new byte[]{'j','o','s','h',}, (short)0, (short)4, apdu.getBuffer(), (short)0);
apdu.setOutgoingAndSend((short)0, (short)32);
// 3A 91 62 FE EF 7B 24 F0 92 07 DC 8E CA 56 4B 7E 69 8D E3 18 94 C9 84 5A 86 EA 52 86 95 75 03 9B
```