文档搜索 > AES256Documentation======

AES256Documentation======

AES256 Documentation
====================

This is an implementation of the AES256 cipher in C++,
supporting a number of block chaining modes. The code
is intended for inclusion as source code into other
programs (but it could, with a bit of reorganization,
also made into a library).

Before you read any further please note:

I AM NOT A PROFESSIONAL CRYPTOGRAPHER BUT A
MERE AMATEUR IN THIS FIELD. THIS CODE HASN'T
BEEN VETTED BY ANY EXPERTS. SHOULD YOU INTEND
TO USE THE SUPPLIED CODE IN ANY SECURITY-SENSI-
TIVE SOFTWARE IT'S YOUR RESPONSIBILITY TO CARE-
FULLY CHECK THAT IT BEHAVES AS EXPECTED.

Beside the 'AES256' class for (byte-oriented) encryption
and decryption of messages with a set of different block
chaining modes, it contains other components. The most
important is an implementation of "basic AES256", which
only deals with single 16 byte wide blocks at a time.
This is derived from a C implementation by Ilya O. Levin,
with contributions by Hal Finney, which can be downloaded
from

http://www.literatecode.com/aes256

Beside that there is a pseudo-random number generator,
which also uses the basic AES256 code. The other files
are helper classes and other utility headers and programs
for testing the class with the available NIST ("National
Institute of Standards and Technology") test data sets.

If the following text seems to be mostly gibberish to you
you may find some more general information in the file
'Intro.txt' where I try to answer a number of questions
I had to figure out for myself when I started this project.


1) Status of the code

The code hasn't been tested extensively. My short tests
indicate that it works correctly with the data supplied
in the NIST "Advanced Encryption Standard Algorithm
Validation Suite" (AESAVS) for KAT ("Known Answer Tests"),
MMT ("Multi-block Message Tests" and MCT ("Monte Carlo
Tests". The test files can be downloaded from

http://csrc.nist.gov/groups/STM/cavp/documents/aes/KAT_AES.zip
http://csrc.nist.gov/groups/STM/cavp/documents/aes/aesmmt.zip
http://csrc.nist.gov/groups/STM/cavp/documents/aes/aesmct.zip

This may not be confused with any "official" validation
- which can't be done by the original author anyway!

The code has not been vetted in any way by others yet,
especially not by any experts in cryptography. No
attempts have been made to address potential security
issues like side-channel attacks.

The code also has not been optimized for speed. Instead I
have tried to only use portable C++ and to make it easy
to understand and thus modify (e.g. most people probably
won't need all the different chaining modes or other
features, so they're supposed to be easy to remove).

Currently the following block chaining modes are
supported

a) Electronic Codebook (ECB)
b) Cipher Block Chaining (CBC)
c) Propagating Cipher Block Chaining (PCBC)
d) Cipher Feedback 128 (CFB-128) (often just called CFB)
e) Cipher Feedback 8 (CFB-8)
f) Output Feedback (OFB)
g) Counter (CTR)

The following padding modes are supported

a) PKCS5/PKCS7
b) ISO/IEC 7816-4
c) ANSI X9.23
d) all unused bytes set to 0


2) The 'AES256' class

The file 'AES256.cpp' and the corresponding header file,
'AES256.hpp" contain the code for encrypting and decrypting
messages, either passed (and returned) as std::string objects
or by writing to a std::istream and reading from a std::ostream.

2a) Constructors

There are two constructors for an 'AES256' object:

AES256(std::string const & key,
std::string const & seed,
AES256::Chaining_Mode chaining_mode = AES256::CBC,
AES256::Padding_Mode padding_mode = AES256::ISO7816_4);

and

AES256(std::string const & key,
AES256::Chaining_Mode chaining_mode = AES256::CBC,
AES256::Padding_Mode padding_mode = AES256::ISO7816_4);

Both require an (at least) 32 byte long key (as a std::string)
and have two optional arguments, the block chaining mode to
use and the padding mode (if applicable for the chaining
mode selected).

The following values can be used for the block chaining modes:

a) AES256::ECB
b) AES256::CBC
c) AES256::PCBC
d) AES256::CFB or AES56::CFB128
e) AES256::CFB8
f) AES256::OFB
g) AES256::CTR

If the corresponding argument is not supplied AES256::CBC is
used per default.

The values for the padding modes are

a) AES256::PKCS7
a) AES256::ANSIX9_23
a) AES256::ISO7816_4
a) AES256::ALL_NULL

In PKCS7 padding mode all the unused bytes of a block are set
to the number of unused bytes. In ANSIX9_23 mode all unused
bytes are set to 0 except the very last one, which contains
the number of unused bytes. For ISO7816_4 the first unused
byte in the block is set to 0x80, all remaining ones to 0.
With ALL_NULL all the unused bytes are set to 0 (this mode
is unsuitable for transmitting binary data!).

The important difference between the two constructors is the
'seed' argument, which is missing in the second version. This
'seed' is used as the seed for a pseudo-random number generator,
which generates random initialization vectors (IVs). If the
version of the constructor with the 'seed' argument is used
for each encryption a new, randomly chosen IV is created and
used. It's probably a good idea to do this since one never
should use the same IV again for the same key. To make sure
the IV is as random as possible the seed should be picked to
be truly random (use the best source of randomness available
on your system).

If the second version of the constructor is used the random
generator is seeded with a default seed, which is the same
for each instance of the AES256 class. This is only useful
for testing, where reproducibility of results matters, but
can have devastating effects when used for security critical
applications (which then aren't secure anymore). If you use
the second version (without the 'seed' argument) anyway you
should manually set a different IV for each encryption you
do, using the 'set_IV()' method.

2b) 'set_IV()' method

void set_IV(std::string const & IV = std::string());


The 'set_IV()' method allows you to set a new initialization
vector at any time. When not called a different IV is chosen
randomly before each new encryption. If the 'set_IV()' method
has been called with an at least 16 byte long string as its
argument this value is used as the IV for the next encryption
(with the exception of the ECB chaining mode which doesn't use
an IV). During the encryption of each block of 16 bytes (or,
for CFB-8, each byte) the "IV" for the encryption of the next
block is generated. The resulting "IV" of encrypting the last
block of a message is then stored and used on the next call
of of the 'encrypt()' method (unless a different IV has been
set via 'set_IV()' in between). Also calls of the 'decrypt()'
method will modify the internal "IV" state in a similar way.
For a security critical application a new IV should be set via
the 'set_IV()' method before each call of 'encrypt()' (unless
IVs are set to be chosen at random automatically).

If 'set_IV()' has been called to set an IV you can switch
back to using randomly chosen IVs by calling it again with
an empty std::string (or no argument at all).

2c) 'get_IV()' method

std::string get_IV() const;

This method returns the current internal state of the "IV", i.e.
the value that will be used for the next encryption when random
selection of IVs is disabled and no call of the 'decrypt()'
method is done in between.

2d) The 'get_key()' methods

std::string get_key() const;

This method returns the key used for encryption.

2e) 'set_chaining_mode()' method

void set_chaining_mode(AES256::Chaining_Mode mode);

This method allows to switch between different chaining
modes. The argument can have the same values as already
described above in the documentation of the constructors.

2f) 'set_padding_mode()' method

void set_padding_mode(AES256::Padding_Mode mode);

This method allows to switch between the different padding
modes. The argument can have the same values as already
described above in the documentation of the constructors.
Note that only some of the block chaining modes (ECB, CBC
and PCBC) require padding, for all others this setting is
irrelevant.

2g) 'uses_padding()' method

bool uses_padding() const;

Returns if the currently selected block chaining mode uses
padding.

2h) 'encrypt()' methods

std::string encrypt(std::string const & in,
bool no_padding_block = false);

and

std::ostream & encrypt(std::istream & in,
std::ostream & out,
bool no_padding_block = false);

These methods are to be used for encrypting messages. The
first one expects the message as a std::string (as its
first argument) and returns the encrypted result as
another std::string. The second method tries to read the
message to be encrypted from a std::istream, supplied via
the first argument and writes the result to the std::ostream
from the second argument (which is also the return value).

Note that each message is prepended by a 16 byte wide block
containing the IV used in encrypting the message (if one was
used). Thus, except for ECB mode the result of calling the
'encrypt()' method will always be at least 16 bytes longer
than the input.

Beside, both methods accept a second/third, optional argument,
'no_padding_block'. If set it prevents the methods from writing
out a final full block of (encrypted) padding for block chaining
modes that require padding when the length of the message is an
integer multiple of 16. Per default such full padding blocks are
always written out since without them the receiver of the encrypted
message isn't able to determine were the message ends and padding
begins. But under certain circumstances (i.e. when it's known
in advance that messages always have lengths divisible by 16)
disabling the extra padding blocks can reduce the amount of data
to be transmitted.

2i) 'decrypt()' methods

std::string decrypt(std::string const & in,
bool no_padding_block = false);

and

std::ostream & decrypt(std::istream & in,
std::ostream & out,
bool no_padding_block = false);

Like their 'encrypt()' counterparts these methods work either
with std:strings or a std::istream and std::ostream pair and
decrypt a message.

Note that both methods expect the IV used for encrypting to to be
prepended to the encrypted message!

The second/third, optional argument, 'no_padding_block', allows
to instruct the methods not to expect a full (encrypted) block
of padding (for block chaining modes requiring padding) when the
plaintext messages has a length divisible by 16. This only makes
sense (in conjunction with chaining modes requiring padding) when
all messages exchanged have lengths that are multiples of 16 and
the sender and recipient have agreed in advance on dropping such
full padding blocks.


3) Other classes and files

3a) The 'AES256_Base' class

This class, implemented in the files 'AES256_Base.cpp' and
'AES256_Base.cpp' handles the basic, single 16 byte block
encryption and decryption. As pointed out above the code is
derived from C code written and distributed by Ilya O. Levin
et al.. Beside the constructor it contains mostly two methods,
one for encrypting and one for decrypting a block of 16 bytes.

The AES256_Base class uses the S_Box class (for the Rijndael
S-box and its inverse). A note on compiling this part: per
default the Rijndael S-box tables are pre-set, static members
of the class. They are thus part of the executable program and
thus can be found by inspection of the (compiled and linked)
program. Some may object to this (since it may make it easier
to detect that the program uses AES-256). For those there is
a macro that when set avoids having these tables become part
of the executable: if the macro 'CALC_RIJNDAEL_SBOX' is defined
these tables only get generated when the first instance of the
'AES256_Base' class (and thus the 'S_Box' class) is used -
instead of putting the values into the executable. This is
probably only of interest for the truly paranoid and adds a
bit of extra code.

If minimizing the amount of memory used is of utmost importance
the macro 'ON_THE_FLY_RIJNDAEL_SBOX' can be set instead. This
results in no tables being used (which occupy 512 bytes) but
instead the values of the S-box (and its inverse) being com-
puted whenever needed. Note that this can add a lot of extra
computation time.


3b) The 'AS256_PRNG' class

This class, implemented in 'AS256_PRNG.cpp' and 'AS256_PRNG.hpp',
is a generator of pseudo-random numbers, based on the the AES256
cipher. It is used to provide random initialization vectors for
the 'AES256' class. Beside the constructor (which accepts a
seed which controls the sequence of the generated "random"
bytes) and a method for reseeding the generator it has three
methods for obtaining sets of bytes either as a std::string,
having them put into a user supplied buffer of unsigned chars
or into a 'Byte_Block' object (see below).


3c) The 'Byte_Block' class

The 'Byte_Block' template class, implemented in the file
'Byte_Block.hpp' is a helper class for dealing with the types
of (fixed sized) blocks of bytes used everywhere else. It is
basically an array of N (the template argument) bytes, with a
number of methods useful in the rest of the code. There are
several ways to construct an instance of the class (with
automated addition of padding when the data provided don't
suffice to fill N bytes), methods for accessing or modifying
them, increment, shift and XOR operators, implicit and explicit
conversion to and from other types and data structures.


3d) The 'nist_test.cpp' and 'nist_test_mct.cpp' files

These two files compile to programs that allow to test the
'AES256' class against the test data sets supplied by NIST
(see above in section 1 for the URLs at the time of writing).
The program generated from 'nist_test.cpp' allows to do tests
with the KAT and MTT files (for AES256 and the block chaining
modes supported). 'nist_test_mct.cpp' compiles to a program
for testing the MCT files. Both programs assume that the names
of the NIST supplied test files haven't been modified. They
either print out a success message or, on failure, how many
of the (supported) tests did fail.


4) Compiling

When compiling the code as part of your program the following
files will have to compiled with it:

a) AES256.cpp
b) AES256_Base.cpp
c) AES256_PRNG.cpp

These files require the header files

a) AES256.hpp
b) AES256_PRNG.hpp
c) AES256_Base.hpp
d) Byte_Block.hpp
e) Padding_Type.hpp

which, of course, need to be in places were the compiler can
find them.

The 'cpp' files all have some extra code for creating a number
of programs for doing very simple-minded tests. Which of these
(non-essential) parts of the files the compiler "sees" depends on
macros being defined. They are

a) 'TEST_AES256_STRING'
b) 'TEST_AES256_STREAM'
c) 'TEST_AES256_FILE'
d) 'TEST_AES256_RAND1'
e) 'TEST_AES256_RAND2'
f) 'TEST_AES256_BASE'
g) 'TEST_AES256_BASE_FIPS'

During a compilation only one of these macros may be defined. If
one of them is set an executable test program will be generated.
To find out what these test programs do (and for some examples
of how the functionality can be used) search for the macros in
the 'cpp' files. The 'Makefile' coming with the package creates
all of these "test programs" when executed. It also creates the
two programs for testing with the test suite files supplied by
NIST.


5) Testing with the NIST data sets for AES-256

If you have the NIST test data in a subdirectory named 'NIST
installed and have used the 'Makefile' coming with the package
to create all programs, you can do (assuming a bash-like shell)
e.g.

for i in NIST/KAT/*256.rsp; do ./nist_test $i; done
for i in NIST/MMT/*256.rsp; do ./nist_test $i; done
for i in NIST/MCT/*256.rsp; do ./nist_test_mct $i; done

to run the tests supplied by NIST. All of them should succeed
(except for the unsupported CFB1 mode) - or you've found a bug
and I'd be glad to know about it! Feel free to write to my email
given at the end.


6) License

This package is, in most parts, distributed under the terms and
conditions of the GPL3 (GNU General Public License, version 3).
Exceptions are the files 'AES256_Base.cpp' and 'AES256_Base.hpp'
- since they are derived work they're under the same license as
was chosen by the authors of the original work.


2018/01/03 Jens Thoms T?rring <jt@toerring.de>

设为首页 | 加入收藏 | 昂纲搜索

All Rights Reserved Powered by 文档下载网

Copyright © 2011
文档下载网内容来自网络,如有侵犯请和我们联系。tousu#anggang.com
返回顶部