I am working on a project which involve AES256 OFB mode. Also, I am using the library from AES library from Brian Gladman. My question is: how can I generate keystreams? My understanding is that i have a initial vector to start with. We would encrypt the IV to get a keystream, then the keystream is encrypted again to generate a subsequent keystream, and so on. I have the following code, but I can't seem to get the correct keystream.
unsigned char szKey[32] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x45, 0x67, 0x89, 0xA8, 0xCD, 0xEF, 0x01, 0x23, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23, 0x45 };
unsigned char szIV[16] = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0x6f, 0xe2, 0x80, 0x2a, 0xa4, 0x03, 0x82, 0x8b };
unsigned char szKeystream1[16];
unsigned char szKeystream2[16];
aes_init();
aes_encrypt_ctx ctx[1];
aes_encrypt_key(szKey, 32, ctx);
aes_encrypt(szIV, szKeystream1, ctx); // generate the first keystream
aes_encrypt(szKeystream1, szKeystream2, ctx); // to generate the second keystream
Edit: turns out there is an typo in my key... 0xA8 should be 0xAB... sorry, and I appreciate you guys look into it
OFB works as follows:
First, you generate an IV of blocksize bytes.
Then, you encrypt this IV with the AES key.
The result of this encryption operation is used to encrypt the first plaintext block by XOR'ing it. Since XOR is a symmetric operation, the same procedure applies to decrypting the first ciphertext block to plaintext.
The result of this operation is furthermore encrypted again with the same AES key for encrypting the next plaintext block (or decrypting the next ciphertext block). This process is iterated until the whole data is encrypted (decrypted).
So yes, in your code here
aes_encrypt(szIV, szKeystream1, ctx); // generate the first keystream
aes_encrypt(szKeystream1, szKeystream2, ctx); // to generate the second keystream
you generate two blocks suitable for AES-ofb. What is still missing is the XOR operation with a plaintext block for encrypting (or a ciphertext block for decrypting). You can iterate the procedure for larger blocks of data.
char data[DATALEN];
aes_encrypt(szIV, szKeystream1, ctx); // generate the first xor block
for (int i = 0; i < DATALEN; i += AES_BLOCK_LENGTH) {
for (int j = 0; j < AES_BLOCK_LENGTH; j++) {
data[i+j] ^= szKeystream1[j];
}
aes_encrypt(szKeystream1, szKeystream2, ctx); // generate next block
memcpy(szKeystream1, szKeystream2, sizeof(szKeystream1);
}