public static void Process(IBlockCipher cipher, MemoryStream data, int off, int len, byte[] iv, IBlockCipher f8Cipher) { F8Context f8ctx = new F8Context(); /* * Get memory for the derived IV (IV') */ f8ctx.ivAccent = new byte[BLKLEN]; /* * Use the derived IV encryption setup to encrypt the original IV to produce IV'. */ f8Cipher.ProcessBlock(iv, 0, f8ctx.ivAccent, 0); f8ctx.J = 0; // initialize the counter f8ctx.S = new byte[BLKLEN]; // get the key stream buffer Arrays.Fill(f8ctx.S, (byte)0); int inLen = len; while (inLen >= BLKLEN) { ProcessBlock(cipher, f8ctx, data, off, data, off, BLKLEN); inLen -= BLKLEN; off += BLKLEN; } if (inLen > 0) { ProcessBlock(cipher, f8ctx, data, off, data, off, inLen); } }
/** * Encrypt / Decrypt a block using F8 Mode AES algorithm, read len bytes * data from in at inOff and write the output into out at outOff * * @param f8ctx * F8 encryption context * @param in * byte array holding the data to be processed * @param inOff * start offset of the data to be processed inside in array * @param out * byte array that will hold the processed data * @param outOff * start offset of output data in out * @param len * length of the input data */ public static void ProcessBlock(IBlockCipher cipher, F8Context f8ctx, MemoryStream _in, int inOff, MemoryStream _out, int outOff, int len) { /* * XOR the previous key stream with IV' * ( S(-1) xor IV' ) */ for (int i = 0; i < BLKLEN; i++) { f8ctx.S[i] ^= f8ctx.ivAccent[i]; } /* * Now XOR (S(n-1) xor IV') with the current counter, then increment * the counter */ f8ctx.S[12] ^= (byte)(f8ctx.J >> 24); f8ctx.S[13] ^= (byte)(f8ctx.J >> 16); f8ctx.S[14] ^= (byte)(f8ctx.J >> 8); f8ctx.S[15] ^= (byte)(f8ctx.J); f8ctx.J++; /* * Now compute the new key stream using AES encrypt */ cipher.ProcessBlock(f8ctx.S, 0, f8ctx.S, 0); /* * As the last step XOR the plain text with the key stream to produce * the cipher text. */ for (int i = 0; i < len; i++) { _in.Position = inOff + i; var inByte = _in.ReadByte(); _out.Position = outOff + i; _out.WriteByte((byte)(inByte ^ f8ctx.S[i])); } }