Sì, questo è spiegabile dal modo in cui funzionano queste modalità.
Nota: l'input della modalità deve essere un multiplo del blocco. (Ecco perché questo può essere inferiore a 128-bit per un codice a 128 bit)
Ora osserva come funziona CBC:
NewBlock(LastCiphertextBlock,PlaintextBlock):=Encrypt(LastCiphertextBlock XOR PlaintextBlock)
Come puoi vedere, questo può solo crittografare un multiplo del blocco effettivo del codice.
Ora vediamo come funziona OFB:
NewBlock(State,Plaintext):=State=Encrypt(State);return State XOR Plaintext
Quindi in pratica stai crittografando alcuni stati ripetutamente e usi questo stato come pad per crittografare il testo in chiaro. Quindi stai convertendo il tuo blockcipher in un streamcipher. Dato che l'applicazione può ora memorizzare lo stato e generare solo nuovi stati come ogni vecchio bit è stato utilizzato, è possibile crittografare le dimensioni arbitrarie dei dati.
Ora esaminiamo il CTR:
NewBlock(Counter,Plaintext):=Counter++;return Encrypt(Counter) XOR Plaintext
Come vedi questa è la stessa logica di OFB, tu generi il pad usando uno stato (il contatore). Poiché è possibile memorizzare questo pad fino a quando non è necessario il prossimo pad-block, è possibile crittografare i dati bit per bit.
Infine esaminiamo il CFB (n bit):
NewBlock(LastCipherTextBlock,Plaintext):=Plaintext XOR Encrypt(LastCipherTextBlock)
Quindi di nuovo stai convertendo in un codice di flusso, ma questa volta prendi il blocco di testo cifrato precedente (che è noto), lo cripto e lo fai XOR rispetto al testo in chiaro. Poiché è possibile memorizzare nuovamente il pad e non eseguire operazioni di blocco sul testo in chiaro, è possibile utilizzare dimensioni in testo normale arbitrarie.