Commit 26dcbb64 authored by Dmitry Baryshkov's avatar Dmitry Baryshkov Committed by Niels Möller

Add CFB block mode support

Signed-off-by: Dmitry Baryshkov's avatarDmitry Eremin-Solenikov <dbaryshkov@gmail.com>
parent e8cc2b0e
......@@ -91,7 +91,7 @@ nettle_SOURCES = aes-decrypt-internal.c aes-decrypt.c \
camellia256-set-decrypt-key.c \
camellia256-meta.c \
cast128.c cast128-meta.c cbc.c \
ccm.c ccm-aes128.c ccm-aes192.c ccm-aes256.c \
ccm.c ccm-aes128.c ccm-aes192.c ccm-aes256.c cfb.c \
chacha-crypt.c chacha-core-internal.c \
chacha-poly1305.c chacha-poly1305-meta.c \
chacha-set-key.c chacha-set-nonce.c \
......@@ -188,7 +188,7 @@ OPT_SOURCES = fat-x86_64.c fat-arm.c mini-gmp.c
HEADERS = aes.h arcfour.h arctwo.h asn1.h blowfish.h \
base16.h base64.h bignum.h buffer.h camellia.h cast128.h \
cbc.h ccm.h chacha.h chacha-poly1305.h ctr.h \
cbc.h ccm.h cfb.h chacha.h chacha-poly1305.h ctr.h \
curve25519.h des.h des-compat.h dsa.h dsa-compat.h eax.h \
ecc-curve.h ecc.h ecdsa.h eddsa.h \
gcm.h gosthash94.h hmac.h \
......
/* cfb.c
Cipher feedback mode.
Copyright (C) 2015 Dmitry Eremin-Solenikov
Copyright (C) 2001, 2011 Niels Möller
This file is part of GNU Nettle.
GNU Nettle is free software: you can redistribute it and/or
modify it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
or both in parallel, as here.
GNU Nettle is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received copies of the GNU General Public License and
the GNU Lesser General Public License along with this program. If
not, see http://www.gnu.org/licenses/.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "cfb.h"
#include "memxor.h"
#include "nettle-internal.h"
void
cfb_encrypt(const void *ctx, nettle_cipher_func *f,
size_t block_size, uint8_t *iv,
size_t length, uint8_t *dst,
const uint8_t *src)
{
uint8_t *p;
TMP_DECL(buffer, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE);
TMP_ALLOC(buffer, block_size);
if (src != dst)
{
for (p = iv; length >= block_size; p = dst, dst += block_size, src += block_size, length -= block_size)
{
f(ctx, block_size, dst, p);
memxor(dst, src, block_size);
}
}
else
{
for (p = iv; length >= block_size; p = dst, dst += block_size, src += block_size, length -= block_size)
{
f(ctx, block_size, buffer, p);
memxor(dst, buffer, block_size);
}
}
if (p != iv)
memcpy(iv, p, block_size);
if (length)
{
f(ctx, block_size, buffer, iv);
memxor3(dst, buffer, src, length);
/* We do not care about updating IV here. This is the last call in
* message sequence and one has to set IV afterwards anyway */
}
}
/* Don't allocate any more space than this on the stack */
#define CFB_BUFFER_LIMIT 512
void
cfb_decrypt(const void *ctx, nettle_cipher_func *f,
size_t block_size, uint8_t *iv,
size_t length, uint8_t *dst,
const uint8_t *src)
{
if (src != dst)
{
size_t left = length % block_size;
length -= left;
if (length > 0)
{
/* Decrypt in ECB mode */
f(ctx, block_size, dst, iv);
f(ctx, length - block_size, dst + block_size, src);
memcpy(iv, src + length - block_size, block_size);
memxor(dst, src, length);
}
if (left > 0)
{
TMP_DECL(buffer, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE);
TMP_ALLOC(buffer, block_size);
f(ctx, block_size, buffer, iv);
memxor3(dst + length, src + length, buffer, left);
}
}
else
{
/* For in-place CFB, we decrypt into a temporary buffer of size
* at most CFB_BUFFER_LIMIT, and process that amount of data at
* a time. */
/* NOTE: We assume that block_size <= CFB_BUFFER_LIMIT */
TMP_DECL(buffer, uint8_t, CFB_BUFFER_LIMIT);
TMP_DECL(initial_iv, uint8_t, NETTLE_MAX_CIPHER_BLOCK_SIZE);
size_t buffer_size;
size_t left;
buffer_size = CFB_BUFFER_LIMIT - (CFB_BUFFER_LIMIT % block_size);
TMP_ALLOC(buffer, buffer_size);
TMP_ALLOC(initial_iv, block_size);
left = length % block_size;
length -= left;
while (length > 0)
{
size_t part = length > buffer_size ? buffer_size : length;
/* length is greater that zero and is divided by block_size, so it is
* not less than block_size. So does part */
f(ctx, block_size, buffer, iv);
f(ctx, part - block_size, buffer + block_size, src);
memcpy(iv, src + part - block_size, block_size);
memxor(dst, buffer, part);
length -= part;
src += part;
dst += part;
}
if (left > 0)
{
f(ctx, block_size, buffer, iv);
memxor(dst, buffer, left);
}
}
}
/* cfb.h
Cipher feedback mode.
Copyright (C) 2015 Dmitry Eremin-Solenikov
Copyright (C) 2001 Niels Möller
This file is part of GNU Nettle.
GNU Nettle is free software: you can redistribute it and/or
modify it under the terms of either:
* the GNU Lesser General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your
option) any later version.
or
* the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your
option) any later version.
or both in parallel, as here.
GNU Nettle is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received copies of the GNU General Public License and
the GNU Lesser General Public License along with this program. If
not, see http://www.gnu.org/licenses/.
*/
#ifndef NETTLE_CFB_H_INCLUDED
#define NETTLE_CFB_H_INCLUDED
#include "nettle-types.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Name mangling */
#define cfb_encrypt nettle_cfb_encrypt
#define cfb_decrypt nettle_cfb_decrypt
void
cfb_encrypt(const void *ctx, nettle_cipher_func *f,
size_t block_size, uint8_t *iv,
size_t length, uint8_t *dst,
const uint8_t *src);
void
cfb_decrypt(const void *ctx, nettle_cipher_func *f,
size_t block_size, uint8_t *iv,
size_t length, uint8_t *dst,
const uint8_t *src);
#define CFB_CTX(type, size) \
{ type ctx; uint8_t iv[size]; }
#define CFB_SET_IV(ctx, data) \
memcpy((ctx)->iv, (data), sizeof((ctx)->iv))
/* NOTE: Avoid using NULL, as we don't include anything defining it. */
#define CFB_ENCRYPT(self, f, length, dst, src) \
(0 ? ((f)(&(self)->ctx, ~(size_t) 0, \
(uint8_t *) 0, (const uint8_t *) 0)) \
: cfb_encrypt((void *) &(self)->ctx, \
(nettle_cipher_func *) (f), \
sizeof((self)->iv), (self)->iv, \
(length), (dst), (src)))
#define CFB_DECRYPT(self, f, length, dst, src) \
(0 ? ((f)(&(self)->ctx, ~(size_t) 0, \
(uint8_t *) 0, (const uint8_t *) 0)) \
: cfb_decrypt((void *) &(self)->ctx, \
(nettle_cipher_func *) (f), \
sizeof((self)->iv), (self)->iv, \
(length), (dst), (src)))
#ifdef __cplusplus
}
#endif
#endif /* NETTLE_CFB_H_INCLUDED */
......@@ -93,6 +93,7 @@ Cipher modes
* CBC::
* CTR::
* CFB::
* GCM::
* CCM::
......@@ -1884,21 +1885,23 @@ a message that is larger than the cipher's block size. As explained in
processing them independently with the block cipher (Electronic Code
Book mode, @acronym{ECB}), leaks information.
Besides @acronym{ECB}, Nettle provides a two other modes of operation:
Cipher Block Chaining (@acronym{CBC}), Counter mode (@acronym{CTR}), and
a couple of @acronym{AEAD} modes (@pxref{Authenticated encryption}).
@acronym{CBC} is widely used, but there are a few subtle issues of
information leakage, see, e.g.,
Besides @acronym{ECB}, Nettle provides several other modes of operation:
Cipher Block Chaining (@acronym{CBC}), Counter mode (@acronym{CTR}), Cipher
Feedback (@acronym{CFB}) and a couple of @acronym{AEAD} modes
(@pxref{Authenticated encryption}). @acronym{CBC} is widely used, but
there are a few subtle issues of information leakage, see, e.g.,
@uref{http://www.kb.cert.org/vuls/id/958563, @acronym{SSH} @acronym{CBC}
vulnerability}. Today, @acronym{CTR} is usually preferred over @acronym{CBC}.
Modes like @acronym{CBC} and @acronym{CTR} provide @emph{no} message
authentication, and should always be used together with a @acronym{MAC}
(@pxref{Keyed hash functions}) or signature to authenticate the message.
Modes like @acronym{CBC}, @acronym{CTR} and @acronym{CFB} provide @emph{no}
message authentication, and should always be used together with a
@acronym{MAC} (@pxref{Keyed hash functions}) or signature to authenticate
the message.
@menu
* CBC::
* CTR::
* CFB::
@end menu
@node CBC, CTR, Cipher modes, Cipher modes
......@@ -1994,7 +1997,7 @@ These macros use some tricks to make the compiler display a warning if
the types of @var{f} and @var{ctx} don't match, e.g. if you try to use
an @code{struct aes_ctx} context with the @code{des_encrypt} function.
@node CTR, , CBC, Cipher modes
@node CTR, CFB, CBC, Cipher modes
@comment node-name, next, previous, up
@subsection Counter mode
......@@ -2070,6 +2073,91 @@ last three arguments define the source and destination area for the
operation.
@end deffn
@node CFB, , CTR, Cipher modes
@comment node-name, next, previous, up
@subsection Cipher Feedback mode
@cindex Cipher Feedback Mode
@cindex CFB Mode
Cipher Feedback mode (@acronym{CFB}) being a close relative to both
@acronym{CBC} mode and @acronym{CTR} mode borrows some characteristics
from stream ciphers.
The message is divided into @code{n} blocks @code{M_1},@dots{}
@code{M_n}, where @code{M_n} is of size @code{m} which may be smaller
than the block size. Except for the last block, all the message blocks
must be of size equal to the cipher's block size.
If @code{E_k} is the encryption function of a block cipher, @code{IV} is
the initialization vector, then the @code{n} plaintext blocks are
transformed into @code{n} ciphertext blocks @code{C_1},@dots{}
@code{C_n} as follows:
@example
C_1 = E_k(IV) XOR M_1
C_2 = E_k(C_1) XOR M_2
@dots{}
C_(n-1) = E_k(C_(n - 2)) XOR M_(n-1)
C_n = E_k(C_(n - 1)) [1..m] XOR M_n
@end example
Nettle's includes two functions for applying a block cipher in Cipher
Feedback (@acronym{CFB}) mode, one for encryption and one for
decryption. These functions uses @code{void *} to pass cipher contexts
around.
@deftypefun {void} cfb_encrypt (const void *@var{ctx}, nettle_cipher_func *@var{f}, size_t @var{block_size}, uint8_t *@var{iv}, size_t @var{length}, uint8_t *@var{dst}, const uint8_t *@var{src})
@deftypefunx {void} cfb_decrypt (const void *@var{ctx}, nettle_cipher_func *@var{f}, size_t @var{block_size}, uint8_t *@var{iv}, size_t @var{length}, uint8_t *@var{dst}, const uint8_t *@var{src})
Applies the encryption or decryption function @var{f} in @acronym{CFB}
mode. The final ciphertext block processed is copied into @var{iv}
before returning, so that a large message can be processed by a sequence
of calls to @code{cfb_encrypt}. Note that for @acronym{CFB} mode
internally uses encryption only function and hence @var{f} should always
be the encryption function for the underlying block cipher.
When a message is encrypted using a sequence of calls to
@code{cfb_encrypt}, all but the last call @emph{must} use a length that
is a multiple of the block size.
@end deftypefun
Like for @acronym{CBC}, there are also a couple of helper macros.
@deffn Macro CFB_CTX (@var{context_type}, @var{block_size})
Expands to
@example
@{
context_type ctx;
uint8_t iv[block_size];
@}
@end example
@end deffn
@deffn Macro CFB_SET_IV(@var{ctx}, @var{iv})
First argument is a pointer to a context struct as defined by
@code{CFB_CTX}, and the second is a pointer to an initialization vector
that is copied into that context.
@end deffn
@deffn Macro CFB_ENCRYPT (@var{ctx}, @var{f}, @var{length}, @var{dst}, @var{src})
A simpler way to invoke @code{cfb_encrypt}. The first argument is a
pointer to a context struct as defined by @code{CFB_CTX}, and the second
argument is an encryption function following Nettle's conventions. The
last three arguments define the source and destination area for the
operation.
@end deffn
@deffn Macro CFB_DECRYPT (@var{ctx}, @var{f}, @var{length}, @var{dst}, @var{src})
A simpler way to invoke @code{cfb_decrypt}. The first argument is a
pointer to a context struct as defined by @code{CFB_CTX}, and the second
argument is an encryption function following Nettle's conventions. The
last three arguments define the source and destination area for the
operation.
@end deffn
@node Authenticated encryption, Keyed hash functions, Cipher modes, Reference
@comment node-name, next, previous, up
......
......@@ -12,6 +12,7 @@
/cast128-test
/cbc-test
/ccm-test
/cfb-test
/chacha-poly1305-test
/chacha-test
/ctr-test
......
......@@ -115,6 +115,9 @@ knuth-lfib-test$(EXEEXT): knuth-lfib-test.$(OBJEXT)
cbc-test$(EXEEXT): cbc-test.$(OBJEXT)
$(LINK) cbc-test.$(OBJEXT) $(TEST_OBJS) -o cbc-test$(EXEEXT)
cfb-test$(EXEEXT): cfb-test.$(OBJEXT)
$(LINK) cfb-test.$(OBJEXT) $(TEST_OBJS) -o cfb-test$(EXEEXT)
ctr-test$(EXEEXT): ctr-test.$(OBJEXT)
$(LINK) ctr-test.$(OBJEXT) $(TEST_OBJS) -o ctr-test$(EXEEXT)
......
......@@ -25,7 +25,7 @@ TS_NETTLE_SOURCES = aes-test.c arcfour-test.c arctwo-test.c \
sha3-384-test.c sha3-512-test.c \
serpent-test.c twofish-test.c version-test.c \
knuth-lfib-test.c \
cbc-test.c ctr-test.c gcm-test.c eax-test.c ccm-test.c \
cbc-test.c cfb-test.c ctr-test.c gcm-test.c eax-test.c ccm-test.c \
poly1305-test.c chacha-poly1305-test.c \
hmac-test.c umac-test.c \
meta-hash-test.c meta-cipher-test.c\
......
#include "testutils.h"
#include "aes.h"
#include "cfb.h"
#include "knuth-lfib.h"
/* Test with more data and inplace decryption, to check that the
* cfb_decrypt buffering works. */
#define CFB_BULK_DATA 10000
static void
test_cfb_bulk(void)
{
struct knuth_lfib_ctx random;
uint8_t clear[CFB_BULK_DATA];
uint8_t cipher[CFB_BULK_DATA + 1];
const uint8_t *key = H("966c7bf00bebe6dc 8abd37912384958a"
"743008105a08657d dcaad4128eee38b3");
const uint8_t *start_iv = H("11adbff119749103 207619cfa0e8d13a");
const uint8_t *end_iv = H("1fd0a9189b8480b7 b06a2b36ef5943ba");
struct CFB_CTX(struct aes_ctx, AES_BLOCK_SIZE) aes;
knuth_lfib_init(&random, CFB_BULK_DATA);
knuth_lfib_random(&random, CFB_BULK_DATA, clear);
/* Byte that should not be overwritten */
cipher[CFB_BULK_DATA] = 17;
aes_set_encrypt_key(&aes.ctx, 32, key);
CFB_SET_IV(&aes, start_iv);
CFB_ENCRYPT(&aes, aes_encrypt, CFB_BULK_DATA, cipher, clear);
ASSERT(cipher[CFB_BULK_DATA] == 17);
if (verbose)
{
printf("IV after bulk encryption: ");
print_hex(AES_BLOCK_SIZE, aes.iv);
printf("\n");
}
ASSERT(MEMEQ(AES_BLOCK_SIZE, aes.iv, end_iv));
/* Decrypt, in place */
aes_set_encrypt_key(&aes.ctx, 32, key);
CFB_SET_IV(&aes, start_iv);
CFB_DECRYPT(&aes, aes_encrypt, CFB_BULK_DATA, cipher, cipher);
ASSERT(cipher[CFB_BULK_DATA] == 17);
if (verbose)
{
printf("IV after bulk decryption: ");
print_hex(AES_BLOCK_SIZE, aes.iv);
printf("\n");
}
ASSERT (MEMEQ(AES_BLOCK_SIZE, aes.iv, end_iv));
ASSERT (MEMEQ(CFB_BULK_DATA, clear, cipher));
}
void
test_main(void)
{
/* From NIST spec 800-38a on AES modes.
*
* F.3 CFB Example Vectors
* F.3.13 CFB128-AES128.Encrypt
*/
/* Intermediate values, blocks input to AES:
*
* 000102030405060708090a0b0c0d0e0f
* 3b3fd92eb72dad20333449f8e83cfb4a
* c8a64537a0b3a93fcde3cdad9f1ce58b
* 26751f67a3cbb140b1808cf187a4f4df
*/
test_cipher_cfb(&nettle_aes128,
SHEX("2b7e151628aed2a6abf7158809cf4f3c"),
SHEX("6bc1bee22e409f96e93d7e117393172a"
"ae2d8a571e03ac9c9eb76fac45af8e51"
"30c81c46a35ce411e5fbc1191a0a52ef"
"f69f2445df4f9b17ad2b417be66c3710"),
SHEX("3b3fd92eb72dad20333449f8e83cfb4a"
"c8a64537a0b3a93fcde3cdad9f1ce58b"
"26751f67a3cbb140b1808cf187a4f4df"
"c04b05357c5d1c0eeac4c66f9ff7f2e6"),
SHEX("000102030405060708090a0b0c0d0e0f"));
/* F.3.15 CFB128-AES192.Encrypt */
/* Intermediate values, blocks input to AES:
*
* 000102030405060708090a0b0c0d0e0f
* cdc80d6fddf18cab34c25909c99a4174
* 67ce7f7f81173621961a2b70171d3d7a
* 2e1e8a1dd59b88b1c8e60fed1efac4c9
*/
test_cipher_cfb(&nettle_aes192,
SHEX("8e73b0f7da0e6452c810f32b809079e5"
"62f8ead2522c6b7b"),
SHEX("6bc1bee22e409f96e93d7e117393172a"
"ae2d8a571e03ac9c9eb76fac45af8e51"
"30c81c46a35ce411e5fbc1191a0a52ef"
"f69f2445df4f9b17ad2b417be66c3710"),
SHEX("cdc80d6fddf18cab34c25909c99a4174"
"67ce7f7f81173621961a2b70171d3d7a"
"2e1e8a1dd59b88b1c8e60fed1efac4c9"
"c05f9f9ca9834fa042ae8fba584b09ff"),
SHEX("000102030405060708090a0b0c0d0e0f"));
/* F.3.17 CFB128-AES256.Encrypt */
/* Intermediate values, blcoks input to AES:
*
* 000102030405060708090a0b0c0d0e0f
* dc7e84bfda79164b7ecd8486985d3860
* 39ffed143b28b1c832113c6331e5407b
* df10132415e54b92a13ed0a8267ae2f9
*/
test_cipher_cfb(&nettle_aes256,
SHEX("603deb1015ca71be2b73aef0857d7781"
"1f352c073b6108d72d9810a30914dff4"),
SHEX("6bc1bee22e409f96e93d7e117393172a"
"ae2d8a571e03ac9c9eb76fac45af8e51"
"30c81c46a35ce411e5fbc1191a0a52ef"
"f69f2445df4f9b17ad2b417be66c3710"),
SHEX("dc7e84bfda79164b7ecd8486985d3860"
"39ffed143b28b1c832113c6331e5407b"
"df10132415e54b92a13ed0a8267ae2f9"
"75a385741ab9cef82031623d55b1e471"),
SHEX("000102030405060708090a0b0c0d0e0f"));
test_cfb_bulk();
}
/*
F.3.13 CFB128-AES128.Encrypt
Key 2b7e151628aed2a6abf7158809cf4f3c
IV 000102030405060708090a0b0c0d0e0f
Segment #1
Input Block 000102030405060708090a0b0c0d0e0f
Output Block 50fe67cc996d32b6da0937e99bafec60
Plaintext 6bc1bee22e409f96e93d7e117393172a
Ciphertext 3b3fd92eb72dad20333449f8e83cfb4a
Segment #2
Input Block 3b3fd92eb72dad20333449f8e83cfb4a
Output Block 668bcf60beb005a35354a201dab36bda
Plaintext ae2d8a571e03ac9c9eb76fac45af8e51
Ciphertext c8a64537a0b3a93fcde3cdad9f1ce58b
Segment #3
Input Block c8a64537a0b3a93fcde3cdad9f1ce58b
Output Block 16bd032100975551547b4de89daea630
Plaintext 30c81c46a35ce411e5fbc1191a0a52ef
Ciphertext 26751f67a3cbb140b1808cf187a4f4df
Segment #4
Input Block 26751f67a3cbb140b1808cf187a4f4df
Output Block 36d42170a312871947ef8714799bc5f6
Plaintext f69f2445df4f9b17ad2b417be66c3710
Ciphertext c04b05357c5d1c0eeac4c66f9ff7f2e6
F.3.14 CFB128-AES128.Decrypt
Key 2b7e151628aed2a6abf7158809cf4f3c
IV 000102030405060708090a0b0c0d0e0f
Segment #1
Input Block 000102030405060708090a0b0c0d0e0f
Output Block 50fe67cc996d32b6da0937e99bafec60
Ciphertext 3b3fd92eb72dad20333449f8e83cfb4a
Plaintext 6bc1bee22e409f96e93d7e117393172a
Segment #2
Input Block 3b3fd92eb72dad20333449f8e83cfb4a
Output Block 668bcf60beb005a35354a201dab36bda
Ciphertext c8a64537a0b3a93fcde3cdad9f1ce58b
Plaintext ae2d8a571e03ac9c9eb76fac45af8e51
Segment #3
Input Block c8a64537a0b3a93fcde3cdad9f1ce58b
Output Block 16bd032100975551547b4de89daea630
Ciphertext 26751f67a3cbb140b1808cf187a4f4df
Plaintext 30c81c46a35ce411e5fbc1191a0a52ef
Segment #4
Input Block 26751f67a3cbb140b1808cf187a4f4df
Output Block 36d42170a312871947ef8714799bc5f6
Ciphertext c04b05357c5d1c0eeac4c66f9ff7f2e6
Plaintext f69f2445df4f9b17ad2b417be66c3710
F.3.15 CFB128-AES192.Encrypt
Key 8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b
000102030405060708090a0b0c0d0e0f
Segment #1
50
IV
Input Block 000102030405060708090a0b0c0d0e0f
Output Block a609b38df3b1133dddff2718ba09565e
Plaintext 6bc1bee22e409f96e93d7e117393172a
Ciphertext cdc80d6fddf18cab34c25909c99a4174
Segment #2
Input Block cdc80d6fddf18cab34c25909c99a4174
Output Block c9e3f5289f149abd08ad44dc52b2b32b
Plaintext ae2d8a571e03ac9c9eb76fac45af8e51
Ciphertext 67ce7f7f81173621961a2b70171d3d7a
Segment #3
Input Block 67ce7f7f81173621961a2b70171d3d7a
Output Block 1ed6965b76c76ca02d1dcef404f09626
Plaintext 30c81c46a35ce411e5fbc1191a0a52ef
Ciphertext 2e1e8a1dd59b88b1c8e60fed1efac4c9
Segment #4
Input Block 2e1e8a1dd59b88b1c8e60fed1efac4c9
Output Block 36c0bbd976ccd4b7ef85cec1be273eef
Plaintext f69f2445df4f9b17ad2b417be66c3710
Ciphertext c05f9f9ca9834fa042ae8fba584b09ff
F.3.16 CFB128-AES192.Decrypt
Key 8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b
IV 000102030405060708090a0b0c0d0e0f
Segment #1
Input Block 000102030405060708090a0b0c0d0e0f
Output Block a609b38df3b1133dddff2718ba09565e
Ciphertext cdc80d6fddf18cab34c25909c99a4174
Plaintext 6bc1bee22e409f96e93d7e117393172a
Segment #2
Input Block cdc80d6fddf18cab34c25909c99a4174
Output Block c9e3f5289f149abd08ad44dc52b2b32b
Ciphertext 67ce7f7f81173621961a2b70171d3d7a
Plaintext ae2d8a571e03ac9c9eb76fac45af8e51
Segment #3
Input Block 67ce7f7f81173621961a2b70171d3d7a
Output Block 1ed6965b76c76ca02d1dcef404f09626
Ciphertext 2e1e8a1dd59b88b1c8e60fed1efac4c9
Plaintext 30c81c46a35ce411e5fbc1191a0a52ef
Segment #4
Input Block 2e1e8a1dd59b88b1c8e60fed1efac4c9
Output Block 36c0bbd976ccd4b7ef85cec1be273eef
Ciphertext c05f9f9ca9834fa042ae8fba584b09ff
Plaintext f69f2445df4f9b17ad2b417be66c3710
F.3.17 CFB128-AES256.Encrypt
Key 603deb1015ca71be2b73aef0857d7781
1f352c073b6108d72d9810a30914dff4
IV 000102030405060708090a0b0c0d0e0f
Segment #1
Input Block 000102030405060708090a0b0c0d0e0f
Output Block b7bf3a5df43989dd97f0fa97ebce2f4a
Plaintext 6bc1bee22e409f96e93d7e117393172a
Ciphertext dc7e84bfda79164b7ecd8486985d3860
Segment #2
Input Block dc7e84bfda79164b7ecd8486985d3860
Output Block 97d26743252b1d54aca653cf744ace2a
Plaintext ae2d8a571e03ac9c9eb76fac45af8e51
Ciphertext 39ffed143b28b1c832113c6331e5407b
Segment #3
Input Block 39ffed143b28b1c832113c6331e5407b
Output Block efd80f62b6b9af8344c511b13c70b016
Plaintext 30c81c46a35ce411e5fbc1191a0a52ef
Ciphertext df10132415e54b92a13ed0a8267ae2f9
Segment #4
Input Block df10132415e54b92a13ed0a8267ae2f9
Output Block 833ca131c5f655ef8d1a2346b3ddd361
Plaintext f69f2445df4f9b17ad2b417be66c3710
Ciphertext 75a385741ab9cef82031623d55b1e471
F.3.18 CFB128-AES256.Decrypt
Key 603deb1015ca71be2b73aef0857d7781
1f352c073b6108d72d9810a30914dff4
IV 000102030405060708090a0b0c0d0e0f
Segment #1
Input Block 000102030405060708090a0b0c0d0e0f
Output Block b7bf3a5df43989dd97f0fa97ebce2f4a
Ciphertext dc7e84bfda79164b7ecd8486985d3860
Plaintext 6bc1bee22e409f96e93d7e117393172a
Segment #2
Input Block dc7e84bfda79164b7ecd8486985d3860
Output Block 97d26743252b1d54aca653cf744ace2a
Ciphertext 39ffed143b28b1c832113c6331e5407b
Plaintext ae2d8a571e03ac9c9eb76fac45af8e51
Segment #3