AES-OFB is the Output Feedback mode of AES, which turns the block cipher into a stream cipher by encrypting an IV over and over and XORing the results with the data. OFB stands for Output Feedback and is defined in NIST SP 800-38A. It needs no padding, so ciphertext is exactly as long as the plaintext, and it gives no integrity protection.
OFB feeds the cipher's own output back into its input. The first input block is the IV. Each output block is the AES encryption of the previous output block, and every output block is XORed with one block of plaintext. A short final block simply uses the leftmost bytes of the last output block. Decryption runs the identical steps, because XOR undoes itself. Only the AES encrypt direction is ever used.
The first output block is plain AES of the IV, which is also what AES-CFB uses for its first block. The script below confirms the keystream chain, then flips one ciphertext bit.
import warnings; warnings.simplefilter("ignore")
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
key = bytes(range(16))
iv = bytes(range(16))
ofb = lambda: Cipher(algorithms.AES(key), modes.OFB(iv))
ecb = Cipher(algorithms.AES(key), modes.ECB()).encryptor()
o1 = ecb.update(iv)
o2 = ecb.update(o1)
ks = ofb().encryptor().update(bytes(32))
print("O1", ks[:16].hex(), ks[:16] == o1)
print("O2", ks[16:].hex(), ks[16:] == o2)
msg = b"pay 100 to bob. pay 100 to eve. end"
c = bytearray(ofb().encryptor().update(msg))
c[4] ^= ord("1") ^ ord("9")
print(ofb().decryptor().update(bytes(c)).decode())
O1 0a940bb5416ef045f1c39458c653ea5a True
O2 aee71ea541d7ae4beb60becc593fb663 True
pay 900 to bob. pay 100 to eve. end
Encrypting the five bytes "hello" with this key and IV gave 62f167d92e, and openssl enc -aes-128-ofb and Node's aes-128-ofb printed the same bytes.
Two messages encrypted with the same key and IV share one keystream, so XORing the two ciphertexts yields the XOR of the plaintexts. With an all-zero IV, "attack at dawn" and "retreat at six" gave 13110013060a5441155444121e16, exactly the XOR of the two plaintexts. SP 800-38A says every message under a key needs its own IV.
No. A flipped ciphertext bit flips only the same plaintext bit, and later blocks are unaffected, according to SP 800-38A Appendix D. The flip side is that an attacker can change chosen bits, as the "bob" example shows. A bit error in the IV, however, corrupts every block.