public int processPacket(byte[] in,int inOff,int inLen,byte[] output,int outOff) throws IllegalStateException, InvalidCipherTextException, DataLengthException {
  if (keyParam == null) {
    throw new IllegalStateException("CCM cipher unitialized.");
  }
  int n=nonce.length;
  int q=15 - n;
  if (q < 4) {
    int limitLen=1 << (8 * q);
    if (inLen >= limitLen) {
      throw new IllegalStateException("CCM packet too large for choice of q.");
    }
  }
  byte[] iv=new byte[blockSize];
  iv[0]=(byte)((q - 1) & 0x7);
  System.arraycopy(nonce,0,iv,1,nonce.length);
  BlockCipher ctrCipher=new SICBlockCipher(cipher);
  ctrCipher.init(forEncryption,new ParametersWithIV(keyParam,iv));
  int outputLen;
  int inIndex=inOff;
  int outIndex=outOff;
  if (forEncryption) {
    outputLen=inLen + macSize;
    if (output.length < (outputLen + outOff)) {
      throw new OutputLengthException("Output buffer too short.");
    }
    calculateMac(in,inOff,inLen,macBlock);
    ctrCipher.processBlock(macBlock,0,macBlock,0);
    while (inIndex < (inOff + inLen - blockSize)) {
      ctrCipher.processBlock(in,inIndex,output,outIndex);
      outIndex+=blockSize;
      inIndex+=blockSize;
    }
    byte[] block=new byte[blockSize];
    System.arraycopy(in,inIndex,block,0,inLen + inOff - inIndex);
    ctrCipher.processBlock(block,0,block,0);
    System.arraycopy(block,0,output,outIndex,inLen + inOff - inIndex);
    System.arraycopy(macBlock,0,output,outOff + inLen,macSize);
  }
 else {
    if (inLen < macSize) {
      throw new InvalidCipherTextException("data too short");
    }
    outputLen=inLen - macSize;
    if (output.length < (outputLen + outOff)) {
      throw new OutputLengthException("Output buffer too short.");
    }
    System.arraycopy(in,inOff + outputLen,macBlock,0,macSize);
    ctrCipher.processBlock(macBlock,0,macBlock,0);
    for (int i=macSize; i != macBlock.length; i++) {
      macBlock[i]=0;
    }
    while (inIndex < (inOff + outputLen - blockSize)) {
      ctrCipher.processBlock(in,inIndex,output,outIndex);
      outIndex+=blockSize;
      inIndex+=blockSize;
    }
    byte[] block=new byte[blockSize];
    System.arraycopy(in,inIndex,block,0,outputLen - (inIndex - inOff));
    ctrCipher.processBlock(block,0,block,0);
    System.arraycopy(block,0,output,outIndex,outputLen - (inIndex - inOff));
    byte[] calculatedMacBlock=new byte[blockSize];
    calculateMac(output,outOff,outputLen,calculatedMacBlock);
    if (!Arrays.constantTimeAreEqual(macBlock,calculatedMacBlock)) {
      throw new InvalidCipherTextException("mac check in CCM failed");
    }
  }
  return outputLen;
}

public int processPacket ( byte [ ] in , int inOff , int inLen , byte [ ] output , int outOff ) throws IllegalStateException , InvalidCipherTextException , DataLengthException { if ( keyParam == null ) { throw new IllegalStateException ( "CCM cipher unitialized." ) ; } int n = nonce . length ; int q = 15 - n ; if ( q < 4 ) { int limitLen = 1 << ( 8 * q ) ; if ( inLen >= limitLen ) { throw new IllegalStateException ( "CCM packet too large for choice of q." ) ; } } byte [ ] iv = new byte [ blockSize ] ; iv [ 0 ] = ( byte ) ( ( q - 1 ) & 0x7 ) ; System . arraycopy ( nonce , 0 , iv , 1 , nonce . length ) ; BlockCipher ctrCipher = new SICBlockCipher ( cipher ) ; ctrCipher . init ( forEncryption , new ParametersWithIV ( keyParam , iv ) ) ; int outputLen ; int inIndex = inOff ; int outIndex = outOff ; if ( forEncryption ) { outputLen = inLen + macSize ; if ( output . length < ( outputLen + outOff ) ) { throw new OutputLengthException ( "Output buffer too short." ) ; } calculateMac ( in , inOff , inLen , macBlock ) ; ctrCipher . processBlock ( macBlock , 0 , macBlock , 0 ) ; while ( inIndex < ( inOff + inLen - blockSize ) ) { ctrCipher . processBlock ( in , inIndex , output , outIndex ) ; outIndex += blockSize ; inIndex += blockSize ; } byte [ ] block = new byte [ blockSize ] ; System . arraycopy ( in , inIndex , block , 0 , inLen + inOff - inIndex ) ; ctrCipher . processBlock ( block , 0 , block , 0 ) ; System . arraycopy ( block , 0 , output , outIndex , inLen + inOff - inIndex ) ; System . arraycopy ( macBlock , 0 , output , outOff + inLen , macSize ) ; } else { if ( inLen < macSize ) { throw new InvalidCipherTextException ( "data too short" ) ; } outputLen = inLen - macSize ; if ( output . length < ( outputLen + outOff ) ) { throw new OutputLengthException ( "Output buffer too short." ) ; } System . arraycopy ( in , inOff + outputLen , macBlock , 0 , macSize ) ; ctrCipher . processBlock ( macBlock , 0 , macBlock , 0 ) ; for ( int i = macSize ; i != macBlock . length ; i ++ ) { macBlock [ i ] = 0 ; } while ( inIndex < ( inOff + outputLen - blockSize ) ) { ctrCipher . processBlock ( in , inIndex , output , outIndex ) ; outIndex += blockSize ; inIndex += blockSize ; } byte [ ] block = new byte [ blockSize ] ; System . arraycopy ( in , inIndex , block , 0 , outputLen - ( inIndex - inOff ) ) ; ctrCipher . processBlock ( block , 0 , block , 0 ) ; System . arraycopy ( block , 0 , output , outIndex , outputLen - ( inIndex - inOff ) ) ; byte [ ] calculatedMacBlock = new byte [ blockSize ] ; calculateMac ( output , outOff , outputLen , calculatedMacBlock ) ; if ( ! Arrays . constantTimeAreEqual ( macBlock , calculatedMacBlock ) ) { throw new InvalidCipherTextException ( "mac check in CCM failed" ) ; } } return outputLen ; }
process a packet of data for either ccm decryption or encryption .
