List of usage examples for org.bouncycastle.crypto.engines AESEngine processBlock
public int processBlock(byte[] in, int inOff, byte[] out, int outOff)
From source file:io.warp10.script.lora.LORAENC.java
License:Apache License
@Override public Object apply(WarpScriptStack stack) throws WarpScriptException { Object top = stack.pop();//from ww w. ja v a2 s. c o m if (!(top instanceof String)) { throw new WarpScriptException(getName() + " expects a 128 bits hex encoded key on top of the stack."); } String keystr = top.toString(); if (keystr.length() != 32) { throw new WarpScriptException(getName() + " expects a 128 bits hex encoded key on top of the stack."); } top = stack.pop(); if (!(top instanceof Long)) { throw new WarpScriptException(getName() + " expects a sequence counter below the key."); } int sequenceCounter = ((Number) top).intValue(); top = stack.pop(); if (!(top instanceof Long)) { throw new WarpScriptException( getName() + " expects a direction (0 uplink or 1 downlink) below the sequence counter."); } int dir = ((Number) top).intValue(); if (0 != dir && 1 != dir) { throw new WarpScriptException( getName() + " expects a direction (0 uplink or 1 downlink) below the sequence counter."); } top = stack.pop(); if (!(top instanceof Long)) { throw new WarpScriptException(getName() + " expects a device address below the direction."); } int addr = ((Number) top).intValue(); String datastr = stack.pop().toString(); if (0 != datastr.length() % 2) { throw new WarpScriptException( getName() + " expects a hex encoded data frame with an even length of hex digits."); } byte[] data = Hex.decode(datastr); // // Compute MIC block B0 // byte[] ABlock = new byte[16]; ABlock[0] = 0x01; ABlock[5] = (byte) (dir & 0x1); ABlock[6] = (byte) (addr & 0xFF); ABlock[7] = (byte) ((addr >> 8) & 0xFF); ABlock[8] = (byte) ((addr >> 16) & 0xFF); ABlock[9] = (byte) ((addr >> 24) & 0xFF); ABlock[10] = (byte) ((sequenceCounter) & 0xFF); ABlock[11] = (byte) ((sequenceCounter >> 8) & 0xFF); ABlock[12] = (byte) ((sequenceCounter >> 16) & 0xFF); ABlock[13] = (byte) ((sequenceCounter >> 24) & 0xFF); int nblocks = data.length / 16 + (0 == data.length % 16 ? 0 : 1); AESEngine aes = new AESEngine(); KeyParameter key = new KeyParameter(Hex.decode(keystr)); aes.init(true, key); byte[] SBlock = new byte[16]; int offset = 0; for (int i = 0; i < nblocks; i++) { ABlock[15] = (byte) (i & 0xFF); aes.reset(); aes.processBlock(ABlock, 0, SBlock, 0); for (int k = 0; i < 16; i++) { if (offset + k < data.length) { data[offset + k] = (byte) (data[offset + k] ^ SBlock[k]); } } offset += 16; } stack.push(new String(Hex.encode(data), Charsets.US_ASCII)); return stack; }