Code Monkey home page Code Monkey logo

aes's Introduction

An AES (Rijndael) Implementation in C/C++ (as specified in FIPS-197)

Change (26/09/2018)

  1. Changes to test programs to allow them to be built on Linux/GCC (with thanks to Michael Mohr).

  2. Rationalisation of the defines DLL_IMPORT, DYNAMIC_DLL and USE_DLL in the test code - now DLL_IMPORT and DLL_DYNAMIC_LOAD

  3. Update the test_avs test to allow the testing of static, DLL and dynamically loaded DLL libraries.

Change (21/05/2018)

  1. Properly dectect presence of AESNI when using GCC (my thanks to Peter Gutmann for this fix)

Changes (6/12/2016)

  1. Changed function definition of has_aes_ni() to has_aes_ni(void), suggested by Peter Gutmann

  2. Changed the default location for the vsyasm assembler to: C:\Program Files\yasm

Changes (27/09/2015)

  1. Added automatic dynamic table initialisation (my thanks to Henrik S. Gaßmann who proposed this addition).

Changes (09/09/2014)

  1. Added the ability to use Intel's hardware support for AES with GCC on Windows and Linux

Changes (01/09/2014)

  1. Clarify some user choices in the file aes_amd64.asm

  2. Change the detection of the x86 and x86_64 processors in aesopt.h to allow assembler code use with GCC

Changes (14/11/2013)

  1. Added the ability to use Intel's hardware support for AES on Windows using Microsoft Visual Studio.

  2. Added the include 'stdint.h' and used the uintt instead of the old uintt (e.g. uint_32t is now uint32_t).

  3. Added a missing .text directive in aes_x86_v2.asm that caused runtime errors in one build configuration.

Changes (16/04/2007)

These changes remove errors in the VC++ build files and add some improvements in file naming consitency and portability. There are no changes to overcome reported bugs in the code.

  1. gen_tabs() has been renamed to aes_init() to better decribe its function to those not familiar with AES internals.

  2. via_ace.h has been renamed to aes_via_ace.h.

  3. Minor changes have been made to aestab.h and aestab.c to enable all the code to be compiled in either C or C++.

  4. The code for detecting memory alignment in aesmdoes.c has been simplified and a new routine has been added:

    aes_test_alignment_detection()
    

    to check that the aligment test is likely to be correct.

  5. The addition of support for Structured Exception Handling (SEH) to YASM (well done Peter and Michael!) has allowed the AMD64 x64 assembler code to be changed to comply with SEH requriements.

  6. Corrections to build files (for win32 debug build).

Overview

This code implements AES for both 32 and 64 bit systems with optional assembler support for x86 and AMD64/EM64T (but optimised for AMD64).

The basic AES source code files are as follows:

aes.h the header file needed to use AES in C aescpp.h the header file required with to use AES in C++ aesopt.h the header file for setting options (and some common code) aestab.h the header file for the AES table declaration aescrypt.c the main C source code file for encryption and decryption aeskey.c the main C source code file for the key schedule aestab.c the main file for the AES tables brg_types.h a header defining some standard types and DLL defines brg_endian.h a header containing code to detect or define endianness aes_x86_v1.asm x86 assembler (YASM) alternative to aescrypt.c using large tables aes_x86_v2.asm x86 assembler (YASM) alternative to aescrypt.c using compressed tables aes_amd64.asm AMD64 assembler (YASM) alternative to aescrypt.c using compressed tables

In addition AES modes are implemented in the files:

aes_modes.c AES modes with optional support for VIA ACE detection and use aes_via_ace.h the header file for VIA ACE support

and Intel hardware support for AES (AES_NI) is implemented in the files

aes_ni.h defines for AES_NI implementation aes_ni.c the AES_NI implementation

Other associated files for testing and support are:

aesaux.h header for auxilliary routines for testsing aesaux.c auxilliary routines for testsingt aestst.h header file for setting the testing environment rdtsc.h a header file that provides access to the Time Stamp Counter aestst.c a simple test program for quick tests of the AES code aesgav.c a program to generate and verify the test vector files aesrav.c a program to verify output against the test vector files aestmr.c a program to time the code on x86 systems modetest.c a program to test the AES modes support vbxam.doc a demonstration of AES DLL use from Visual Basic in Microsoft Word vb.txt Visual Basic code from the above example (win32 only) aesxam.c an example of AES use tablegen.c a program to generate a simplified 'aestab.c' file for use with compilers that find aestab.c too complex yasm.rules the YASM build rules file for Microsoft Visual Studio 2005 via_ace.txt describes support for the VIA ACE cryptography engine aes.txt this file

Building The AES Libraries

A. Versions

The code can be used to build static and dynamic libraries, each in five versions:

Key scheduling code in C, encrypt/decrypt in:

C           C source code                        (win32 and x64)
ASM_X86_V1C large table x86 assembler code       (win32)
ASM_X86_V2C compressed table x86 assembler code  (win32)
ASM_AMD64   compressed table x64 assembler code  (x64)

Key scheduling and encrypt/decrypt code in assembler:

ASM_X86_V2  compressed table x86 assembler       (win32)

The C version can be compiled for Win32 or x64 whereas the x86 and x64 assembler versions are for Win32 and x64 respectively.

If Intel's hardware support for AES (AES_NI) is available, it can be used with either the C or the ASM_AMD64 version. If ASM_AMD64 is to be used, it is important that the define USE_INTEL_AES_IF_PRESENT in asm_amd64.asm is set to the same value as it has in aesopt.h

B. YASM

If you wish to use the x86 assembler files you will also need the YASM open source x86 assembler (r1331 or later) for Windows which can be obtained from:

http://www.tortall.net/projects/yasm/

This assembler (vsyasm.exe) should be placed in the directory:

C:\Program Files\yasm

C. Configuration

The following configurations are available as projects for Visual Studio but the following descriptions should allow them to be built in other x86 environments

lib_generic_c       Win32 and x64
    headers:        aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs.h
	                (+ aes_ni.h for AES_NI)
    C source:       aescrypt.c, aeskey.c, aestab.c, aes_modes.c
	                (+ aes_ni.c for AES_NI)
    defines

dll_generic_c       Win32 and x64
    headers:        aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs.h
	                (+ aes_ni.h for AES_NI)
    C source:       aescrypt.c, aeskey.c, aestab.c, aes_modes.c
	                (+ aes_ni.c for AES_NI)
    defines         DLL_EXPORT

lib_asm_x86_v1c     Win32
    headers:        aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs.h
    C source:       aeskey.c, aestab.c, aes_modes.c
    x86 assembler:  aes_x86_v1.asm
    defines         ASM_X86_V1C (set for C and assembler files)

dll_asm_x86_v1c     Win32
    headers:        aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs.h
    C source:       aeskey.c, aestab.c, aes_modes.c
    x86 assembler:  aes_x86_v1.asm
    defines         DLL_EXPORT, ASM_X86_V1C (set for C and assembler files)

lib_asm_x86_v2c     Win32
    headers:        aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs.h
    C source:       aeskey.c, aestab.c, aes_modes.c
    x86 assembler:  aes_x86_v2.asm
    defines         ASM_X86_V2C (set for C and assembler files)

dll_asm_x86_v2c     Win32
    headers:        aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs.h
    C source:       aeskey.c, aestab.c, aes_modes.c
    x86 assembler:  aes_x86_v1.asm
    defines         DLL_EXPORT, ASM_X86_V2C (set for C and assembler files)

lib_asm_x86_v2      Win32
    headers:        aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs.h
    C source:       aes_modes.c
    x86 assembler:  aes_x86_v1.asm
    defines         ASM_X86_V2 (set for C and assembler files)

dll_asm_x86_v2      Win32
    headers:        aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs.h
    C source:       aes_modes.c
    x86 assembler:  aes_x86_v1.asm
    defines         DLL_EXPORT, ASM_AMD64_C (set for C and assembler files)

lib_asm_amd64_c     x64
    headers:        aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs.h
	                (+ aes_ni.h for AES_NI)
    C source:       aes_modes.c (+ aes_ni.c for AES_NI)
    x86 assembler:  aes_amd64.asm
    defines         ASM_AMD64_C (set for C and assembler files)

dll_asm_amd64_c     x64
    headers:        aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs.h
	                (+ aes_ni.h for AES_NI)
    C source:       aes_modes.c (+ aes_ni.c for AES_NI)
    x86 assembler:  aes_amd64.asm
    defines         DLL_EXPORT, ASM_AMD64_C (set for C and assembler files)

Notes:

ASM_X86_V1C is defined if using the version 1 assembler code (aescrypt1.asm). The defines in the assember file must match those in aes.h and aesopt.h). Also remember to include/exclude the right assembler and C files in the build to avoid undefined or multiply defined symbols - include aes_x86_v1.asm and exclude aescrypt.c

ASM_X86_V2 is defined if using the version 2 assembler code (aes_x86_v2.asm). This version provides a full, self contained assembler version and does not use any C source code files except for the mutiple block encryption modes that are provided by aes_modes.c. The define ASM_X86_V2 must be set on the YASM command line (or in aes_x86_v2.asm) to use this version and all C files except aec_modes.c and, for the DLL build, aestab.c must be excluded from the build.

ASM_X86_V2C is defined when using the version 2 assembler code (aes_x86_v2.asm) with faster key scheduling provided by the in C code (the options in the assember file must match those in aes.h and aesopt.h). In this case aeskey.c and aestab.c are needed with aes_x86_v2.asm and the define ASM_X86_V2C must be set for both the C files and for aes_x86_v2.asm in the build commands(or in aesopt.h and aes_x86_v2.asm). Include aes_x86_v2.asm, aeskey.c and aestab.c, exclude aescrypt.c for this option.

ASM_AMD64_C is defined when using the AMD64 assembly code because the C key scheduling is used in this case.

DLL_EXPORT must be defined to generate the DLL version of the code and to run tests on it

DLL_IMPORT must be defined to use the DLL version of the code in an application program

Directories the paths for the various directories for test vector input and output have to be set in aestst.h

VIA ACE see the via_ace.txt for this item

Static The static libraries are named: Libraries aes_lib_generic_c.lib aes_lib_asm_x86_v1c.lib aes_lib_asm_x86_v2.lib aes_lib_asm_x86_v2c.lib aes_lib_asm_amd64_c.lib

        and placed in one of the the directories:

            lib\win32\release\
            lib\win32\debug\
            lib\x64\release\
            lib\x64\debug\

        in the aes root directory depending on the platform(win32 or
        x64) and the build (release or debug). After any of these is
        built it is then copied into the aes\lib directory, which is
		the library location that is subsequently used for testing. 
		Hence testing is always for the last static library built.

Dynamic These libraries are named: Libraries aes_lib_generic_c.dll aes_lib_asm_x86_v1c.dll aes_lib_asm_x86_v2.dll aes_lib_asm_x86_v2c.dll aes_lib_asm_amd64_c.dll

        and placed in one of the the directories:

            dll\win32\release\
            dll\win32\debug\
            dll\x64\release\
            dll\x64\debug\

        in the aes root directory depending on the platform(win32 or
        x64) and the build (release or debug).  Each DLL library:

            aes_<ext>.dll

        has three associated files:

            aes_dll_<ext>.lib   the library file for implicit linking
            aes_dll_<ext>.exp   the exports file
            aes_dll_<ext>.pdb   the symbol file

        After any DLL is built it and its three related files are then
        copied to the aes\dll directory, which is the library location
		used in subsequent testing.  Hence testing is always for the 
		last DLL built.

D. Testing

These tests require that the test vector files are placed in the 'testvals' subdirectory. If the AES Algorithm Validation Suite tests are used then the *.fax files need to be put in the 'testvals\fax' subdirectory. This is covered in more detail below.

The projects test_lib and time_lib are used to test and time the last static library built. They use the files:

test_lib:       Win32 (x64 for the C and AMD64 versions)
    headers:    aes.h, aescpp.h, brg_types.h, aesaux.h and aestst.h
    C source:   aesaux.c, aesrav.c
    defines:

time_lib:       Win32 (x64 for the C and AMD64 versions)
    headers:    aes.h, aescpp.h, brg_types.h, aesaux.h, aestst.h and rdtsc.h
    C source:   aesaux.c, aestmr.c
    defines:

The projects test_dll and time_dll are used to test and time the last DLL built. These use the files:

test_dll:       Win32 (x64 for the C and AMD64 versions)
    headers:    aes.h, aescpp.h, brg_types.h, aesaux.h and aestst.h
    C source:   aesaux.c, aesrav.c
    defines:    DLL_IMPORT

time_dll:       Win32 (x64 for the C and AMD64 versions)
    headers:    aes.h, aescpp.h, brg_types.h, aesaux.h aestst.h and rdtsc.h
    C source:   aesaux.c, aestmr.c
    defines:    DLL_IMPORT

and default to linkingto with the AES DLL using dynamic (run-time) linking. Implicit linking can be used by adding the lib file associated with the AES DLL (in the aes\dll sub-directory) to the build (under project Properties|Linker in Visual Studio) and removing the DLL_DYNAMIC_LOAD define (under project Properties|C/C++|Preprocessor).

0 Link is linked into this project and the symbol DLL_DYNAMIC_LOAD is left undefined, then implicit linking will be used

The above tests take command line arguments that determine which test are run as follows:

test_lib /t:[knec] /k:[468]
test_dll /t:[knec] /k:[468]

where the symbols in square brackets can be used in any combination (without the brackets) and have the following meanings:

    /t:[knec]   selects which tests are used
    /k:[468]    selects the key lengths used
    /c          compares output with reference (see later)

    k: generate ECB Known Answer Test files
    n: generate ECB Known Answer Test files (new)
    e: generate ECB Monte Carlo Test files
    c: generate CBC Monte Carlo Test files

and the characters giving the lengths are digits representing the key lengths in 32-bit units (4, 6, 8 for lengths of 128, 192 or 256 bits respectively).

The project test_modes tests the AES modes. It uses the files:

test_modes:     Win32 or x64
    headers:    aes.h, aescpp.h, brg_types.h, aesaux,h and aestst.h
    C source:   aesaux.c, modetest.c
    defines:    none for static library test, DLL_IMPORT for DLL test

which again links to the last library built.

E. Other Applications

These are:

gen_tests       builds the test_vector files. The commad line is
                    gen_tests /t:knec /k:468 /c
                as described earlier
                
test_aes_avs    run the AES Algorithm Validation Suite tests for
                ECB, CBC, CFB and OFB modes

gen_tables      builds a simple version of aes_tab.c (in aestab2.c)
                for compilers that cannot handle the normal version
aes_example     provides an example of AES use

These applications are linked to the last static library built or, if DLL_IMPORT is defined during compilation, to the last DLL built.

F. Use of the VIA ACE Cryptography Engine (x86 only)

The use of the code with the VIA ACE cryptography engine in described in the file via_ace.txt. In outline aes_modes.c is used and USE_VIA_ACE_IF_PRESENT is defined either in section 2 of aesopt.h or as a compilation option in Visual Studio. If in addition ASSUME_VIA_ACE_PRESENT is also defined then all normal AES code will be removed if not needed to support VIA ACE use. If VIA ACE support is needed and AES assembler is being used only the ASM_X86_V1C and ASM_X86_V2C versions should be used since ASM_X86_V2 and ASM_AMD64 do not support the VIA ACE engine.

G. The AES Test Vector Files

These files fall in the following groups (where is a two digit number):

  1. ecbvk.txt ECB vectors with variable key
  2. ecbvt.txt ECB vectors with variable text
  3. ecbnk.txt new ECB vectors with variable key
  4. ecbnt.txt new ECB vectors with variable text
  5. ecbme.txt ECB monte carlo encryption test vectors
  6. ecbmd.txt ECB monte carlo decryption test vectors
  7. cbcme.txt CBC monte carlo encryption test vectors
  8. cbcmd.txt CBC monte carlo decryption test vectors

The first digit of the numeric suffix on the filename gives the block size in 32 bit units and the second numeric digit gives the key size. For example, the file ecbvk44.txt provides the test vectors for ECB encryption with a 128 bit block size and a 128 bit key size. The test routines expect to find these files in the 'testvals' subdirectory within the aes root directory. The 'outvals' subdirectory is used for outputs that are compared with the files in 'testvals'. Note that the monte carlo test vectors are the result of applying AES iteratively 10000 times, not just once.

The AES Algorithm Validation Suite tests can be run for ECB, CBC, CFB and OFB modes (CFB1 and CFB8 are not implemented). The test routine uses the *.fax test files, which should be placed in the 'testvals\fax' subdirectory.

H. The Basic AES Calling Interface

The basic AES code keeps its state in a context, there being different contexts for encryption and decryption:

aes_encrypt_ctx
aes_decrypt_ctx

The AES code is initialised with the call

aes_init(void)

although this is only essential if the option to generate the AES tables at run-time has been set in the options (i.e.fixed tables are not being used).

The AES encryption key is set by one of the calls:

aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1])
aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1])
aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1])

or by:

aes_encrypt_key(const unsigned char *key, int key_len, 
                                            aes_encrypt_ctx cx[1])

where the key length is set by 'key_len', which can be the length in bits or bytes.

Similarly, the AES decryption key is set by one of:

aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1])
aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1])
aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1])

or by:

aes_decrypt_key(const unsigned char *key, int key_len, 
                                            aes_decrypt_ctx cx[1])

Encryption and decryption for a single 16 byte block is then achieved using:

aes_encrypt(const unsigned char *in, unsigned char *out, 
                                        const aes_encrypt_ctx cx[1])
aes_decrypt(const unsigned char *in, unsigned char *out, 
                                        const aes_decrypt_ctx cx[1])

The above subroutines return a value of EXIT_SUCCESS or EXIT_FAILURE depending on whether the operation succeeded or failed.

I. The Calling Interface for the AES Modes

The subroutines for the AES modes, ECB, CBC, CFB, OFB and CTR, each process blocks of variable length and can also be called several times to complete single mode operations incrementally on long messages (or those messages, not all of which are available at the same time). The calls:

aes_ecb_encrypt(const unsigned char *ibuf, unsigned char *obuf,
                int len, const aes_encrypt_ctx cx[1])

aes_ecb_decrypt(const unsigned char *ibuf, unsigned char *obuf,
                int len, const aes_decrypt_ctx cx[1])

for ECB operations and those for CBC:

aes_cbc_encrypt(const unsigned char *ibuf, unsigned char *obuf,
                int len, unsigned char *iv, const aes_encrypt_ctx cx[1])

aes_cbc_decrypt(const unsigned char *ibuf, unsigned char *obuf,
                int len, unsigned char *iv, const aes_decrypt_ctx cx[1])

can only process blocks whose lengths are multiples of 16 bytes but the calls for CFB, OFB and CTR mode operations:

aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf,
                int len, unsigned char *iv, aes_encrypt_ctx cx[1])

aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf,
                int len, unsigned char *iv, aes_encrypt_ctx cx[1])

aes_ofb_encrypt(const unsigned char *ibuf, unsigned char *obuf,
                int len, unsigned char *iv, aes_encrypt_ctx cx[1])

aes_ofb_decrypt(const unsigned char *ibuf, unsigned char *obuf,
                int len, unsigned char *iv, aes_encrypt_ctx cx[1])

aes_ctr_encrypt(const unsigned char *ibuf, unsigned char *obuf,
        int len, unsigned char *cbuf, cbuf_inc ctr_inc, aes_encrypt_ctx cx[1])

aes_ctr_decrypt(const unsigned char *ibuf, unsigned char *obuf,
        int len, unsigned char *cbuf, cbuf_inc ctr_inc, aes_encrypt_ctx cx[1])

can process blocks of any length. Note also that CFB, OFB and CTR mode calls only use AES encryption contexts even during decryption operations.

The calls CTR mode operations use a buffer (cbuf) which holds the counter value together with a function parameter:

void cbuf_inc(unsigned char *cbuf);

that is ued to update the counter value after each 16 byte AES operation. The counter buffer is updated appropriately to allow for incremental operations.

Please note the following IMPORTANT points about the AES mode subroutines:

1. All modes are reset when a new AES key is set.

2. Incremental calls to the different modes cannot 
   be mixed. If a change of mode is needed a new 
   key must be set or a reset must be issued (see 
   below).
   
3. For modes with IVs, the IV value is an input AND
   an output since it is updated after each call to 
   the value needed for any subsequent incremental
   call(s). If the mode is reset, the IV hence has
   to be set (or reset) as well.
   
4. ECB operations must be multiples of 16 bytes
   but do not need to be reset for new operations.
   
5. CBC operations must also be multiples of 16 
   bytes and are reset for a new operation by 
   setting the IV.
   
6. CFB, OFB and CTR mode must be reset by setting 
   a new IV value AND by calling:
   
       aes_mode_reset(aes_encrypt_ctx cx[1])
       
   For CTR mode the cbuf value also has to be reset.
   
7. CFB, OFB and CTR modes only use AES encryption 
   operations and contexts and do not need AES
   decryption operations.
   
8. AES keys remain valid across resets and changes
   of mode (but encryption and decryption keys must 
   both be set if they are needed).  

Brian Gladman 26/09/2018

aes's People

Contributors

arahaan avatar briangladman avatar coeur avatar mikejonesguy avatar rupan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

aes's Issues

Password verification value

Hi,
I have encrypted a file using Winzip with AES-128 encryption. The password i applied is "12345678".
The SALT value stored in the encrypted zip archive is 8 bytes i.e. [0xa4 0x94 0x72 0xce 0x84 0x16 0x84 0x05].

Now i tried using the following:

    fcrypt_ctx ctx;
int mode = 1;
unsigned char pwd[8] = {'1','2','3','4','5','6','7','8'};
    unsigned char salt[8] = {0xa4,0x94,0x72,0xce,0x84,0x16,0x84,0x05};
unsigned char pwd_ver[2] = { 0 };

       fcrypt_init(mode,pwd,8,salt,pwd_ver,&ctx);
       printf("Password Verifier : 0x%02x 0x%02x\n",pwd_ver[0],pwd_ver[1]);

The output i.e. "Password verification value" comes out to be [0XEA,0X43] which is not the same Password verification value i extracted from the ZIP archive [0X97,0XB1] using the same SALT and PASSWORD.
The fileenc header and source are attached herewith.
filenc.zip

Not able find function

Where can I find aes_encrypt function? I am using aes for file encryption, specifically the aesxam file.

Authentication code value

The Password Verification value comes out to be correct once i replaced the previous SHA1 with the new one as we discussed in the previous thread i.e. https://github.com/BrianGladman/aes/issues/38
, but the Authentication Code for an encrypted data comes out to be different.

I have made an archive (using WinZip) with an encryption method AES-128. The actual data size is 5 bytes and the compressed+encrypted data size is of 7 bytes length i.e.
Actual data ASCII bytes = { t e x t 1 }
Encrypted data = {0xd4, 0xbb, 0xbf, 0xdb, 0xf6, 0x16, 0x50}

The Salt value is
{0xa4, 0x94, 0x72, 0xce, 0x84, 0x16, 0x84, 0x05}

I have encrypted the archive with a password "12345678"

After using your implementation, the Password Verification value comes out to be correct i.e. {0x97 0xB1} but the Authentication Code generated from your implementation doesn't match the Authentication Code value of Zip archive.

Here is how i am generating the Authentication Code

fcrypt_init(mode,Password,8,salt,pwd_ver,&ctx);
fcrypt_decrypt(Encrypted_Data_bytes, Encrypted_Data_Size, &ctx);
fcrypt_end(mac,&ctx);
I assume the mac contains the Authentication code.

Authentication code generated from your implementation
{0xe6, 0x52, 0xb1, 0x91, 0xa1, 0xdc, 0x65, 0xa7, 0x31, 0x81}

Authentication Code extracted from the Zip archive is
{0xc2, 0x36, 0xec, 0x48, 0xb8, 0xb2, 0x04, 0xcc, 0xb7, 0xf4}

Here is the zip archive
NewZip_aes128_12345678.zip

I hope GCC isn't messing with your implementation.

AES NI question

Hi Brian,
The aes_CBC_encrypt and aes_CBC_decrypt routines in aes_ni.c take in a "key" and a "number_of_rounds" rather than the ctx. Can these routines be changed to take in the ctx, like the CBC routines in aes_modes.c?
I'm passing "ctx->ks" for the key and "ctx->inf.b[0] >> 4" for the number_of_rounds. Is that correct?
If so, the aes_CBC_encrypt routine passes my verification tests, however the aes_CBC_decrypt routine does not. I think the problem is the index needs to decrement rather than increment, at aes_ni.c, lines 495-496, as follows -
data = _mm_xor_si128(last_in, ((__m128i*)key)[number_of_rounds]);
for(j = number_of_rounds -1; j >= 1; j--)
with this change the aes_CBC_decrypt routine did pass my verification tests.
Please advise. Thanks.

sequence-point warning with gcc -Wall

Building with gcc version 7.5.0 or 9.3.0 and the -Wall flag, I see several warnings of the form:

aeskey.c: In function ‘aes_decrypt_key192’:
aeskey.c:407:34: warning: operation on ‘ss[4]’ may be undefined [-Wsequence-point]
     cx->ks[v(48,(4))] = ff(ss[4] = word_in(key, 4));
aesopt.h:363:25: note: in definition of macro ‘to_byte’
 #  define to_byte(x)  ((x) & 0xff)
                         ^
aesopt.h:737:12: note: in expansion of macro ‘bval’
   ^ tab[2][bval(vf(x,2,c),rf(2,c))] \
            ^~~~
aesopt.h:737:17: note: in expansion of macro ‘vf1’
   ^ tab[2][bval(vf(x,2,c),rf(2,c))] \
                 ^~
aesopt.h:759:29: note: in expansion of macro ‘four_tables’
 #  define inv_mcol(x)       four_tables(x,t_use(i,m),vf1,rf1,0)
                             ^~~~~~~~~~~
aeskey.c:242:17: note: in expansion of macro ‘inv_mcol’
 #define ff(x)   inv_mcol(x)
                 ^~~~~~~~
aeskey.c:407:25: note: in expansion of macro ‘ff’
     cx->ks[v(48,(4))] = ff(ss[4] = word_in(key, 4));
                         ^~

four_tables() uses its first argument four times, so using it with a side-effecting expression may be the source of the complaint.

Block size modify

Hey Brian,

I think that I can not change the block size.

aes/aes_modes.c
aes_ecb_decrypt
aes_cbc_encrypt

int nb = len >> 4;
I think this is wrong.

int nb = len / AES_BLOCK_SIZE;
I think this is correct.

There are other places that are hard-coded in 16.

Thanks heaps,

Tomoaki

Macro redefinition warnings

AES_ENCRYPT and AES_DECRYPT macros are redefined when including both https://github.com/BrianGladman/aes and https://github.com/openssl/openssl.

Cocoapods recommandation:

Can I workaround ‘Duplicate Symbol’ errors with static libraries?
[...]
in general, the vendor should really prefix any dependencies it includes, so you don’t need to deal with it. When this happens, please contact the vendor and ask them to fix it on their side.

So my request is: can you prefix AES_ENCRYPT and AES_DECRYPT macros please?

related: openssl/openssl#4441

IS_ENCRYPTION_CTX() appears not to work with aes_ni

This is from code inspection, so apologies if I've read something wrong.

Per the comments, IS_ENCRYPTION_CTX() and IS_DECRYPTION_CTX() are intended to be useful to some category of callers. aeskey.c sets the corresponding bit in cx->inf.b[2] where it calls MARK_AS_ENCRYPTION_CTX() and MARK_AS_DECRYPTION_CTX().

If USE_VIA_ACE_IF_PRESENT is defined, the public API for key schedules lives in aes_ni.c. The aeskey.c functions are bypassed completely unless has_aes_ni() returns false. The aes_ni.c functions don't appear to touch cx->inf.b[2] (they only use ctx->inf.b[0]).

Also, from reading the code I think the caller is responsible for initializing cx->inf.b[2] to zero (perhaps by zeroing the whole context), as the macros used by aeskey.c modify that byte rather than initialize it. I don't see any documentation of that.

aes code, library not found

hi, i am working on aes code in VS2015 provided here, but its showing this error:
Severity Code Description Project File Line Source
Error LNK1104 cannot open file 'D:\FYP\AES-master\lib\Win32\Debug\lib_asm_amd64_c.lib'

when I open the folder D:\FYP\AES-master\lib\Win32\Debug, it is empty. where will i find this library lib_asm_amd64_c ? please help ASAP

aes.h: #include <stdlib.h>

Похоже, строку 27 можно закомментировать. Понял, когда обнаружил, что эта строка вызывает конфликт в одном UEFI проекте.

FIPS tested

Hi

I wanted to know whether your AES code is FIPS tested?
Thanks a lot, seems you did amazing job BTW!

archive downloads / TrueCrypt code

I am working on CipherShed, a fork of TrueCrypt. Our goal is to re-license under an OSI approved license (likely BSD or Apache).

The manual indicates you contributed (maybe they just copied your source) some of the code. I tried to download older copies of your crypto libraries, but could only find the current ones.

Do you have archive of you libraries that you may share?

Need minimal modules

The documentation is not clear for minimal libraries.
For example, I only need AES or RSA but I have to import the complete library set into my project which makes the binary quite heavy.

Any minimal module available or compilation of minimal features for these two available?

need cplusplus code

I want to c++ code,how can I get that. I have got the aescpp.h ,but I can not use it. My English is not very well ,sorry . Thank you !

decryption provides invalid / corrupt bytes.

On pycrypto and pycryptodome you can get away with base64 on the data and then encrypt. It seems that the data from base64 does not work right after encrypting (trying to decrypt provides invalid bytes)

bytearray(b'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')

It also seems to avoid the error from this base64 stuff I have to do an while not loop to check if it is / 16 to get an even number and if not append an null byte on the end.

Also it seems that doing this right after zlib also results in zlib error -3

Documentation

Hello, I would love to use this in my project, but how does one get started?

What is the directory structure?
Which files do I need to embed and which ones don't I?

Fail to get data buffer on python 3.6

Not sure if it is my code or not but after needing to convert an str object to bytes to satisfy 1 Exception then his one shows up.

class AESCipher:
    def __init__(self, key): 
        self.key = hashlib.sha256(key.encode()).digest()

    def encrypt(self, raw):
        iv = bytearray(os.urandom(16))
        cipher = AES(mode='cbc', key=self.key, iv=iv)
        data = raw.encode('ascii')
        output = cipher.encrypt(data=data)
        return iv + output

    def decrypt(self, enc):
        iv = enc[:16]
        cipher = AES(mode='cbc', key=self.key, iv=iv)
        try:
            return cipher.decrypt(data=enc[16:]).decode('utf-8')
        except UnicodeDecodeError:
            return None

Edit: seems what I had to do was make the bytes object become an bytearray.

fcrypt migration guide?

An old version of this code was used to implement AES support in Winzip.
The implementations I know are reliant on the particularities of the codebase at the time.

Can you please provide a migration guide how one would switch from that code to the current one?

In particular, how does one get the password verification data with the modern code?

Here's a piece of code I'd like to see converted:

fcrypt_init(mode, password, length_of_password, salt, password_verification, context);
fcrypt_decrypt(buf, bufsize, context);
fcrypt_end(mac, context);

Thank you!

Contact

Hi Brian, I know this is not the appropriate place for this, but I wanted to ask you a question about some of your GSL Visual Studio project files but couldn't find your contact info anywhere.

I was wondering if you or the GSL team have any intention of integrating your build files into the GSL repository, making it easier for people to use GSL on windows?

Again, sorry about the location for this, but I saw no other way of contacting you.

Thanks.

How to compile this inside of an embedded python interpreter in MSVC under Windows?

It be nice if I could know how to compile the AES c extension for my python 3.6+ embedded interpreter to elimiate the need to ship with things like pycryptodome that wastes distribution space a ton.

I need to know this so I got more portibility in loading up encrypted python scripts, yes encrypted python script loading is possible with an import hook that I made for within zip files.

However it is a means of well (installing it) which the install function takes in an encrypted key for any encrypted python scripts (*.pye files).

And yes the *.pye format was made by me for users who want to ship secured python code within their applications that might cover things like security means or something (like hiding secured functions used in their code that should remain private and sensitive information).

aes_ni.c of nmoinvaz/minizip fails to compile on GCC 4.4.7

Please allow me to refer you to the issue I created in the minizip repository:
zlib-ng/minizip-ng#362

I already tried nmoinvaz's suggestions, tried to change the optimization level, but nothing of that helped. A simple cc fails on aes_ni.c:

[root@d50e2017a6ae minizip-1.2]# cc -c -O aes/aes_ni.c
cc: Internal error: Segmentation fault (program cc1)
Please submit a full bug report.
See <http://bugzilla.redhat.com/bugzilla> for instructions.

Do you have any idea what the problem might be?

Trouble with CFB and OFB with the C implementation

Hello, I can get the python CFB and OFB tests working with the aes_ni implementation, but somehow it fails with the C and amd64.asm implementation.

I have a Dockerfile reproducing this (my CPU is 12th Gen Intel(R) Core(TM) i9-12900H, but I've reproduced this on a few other machines, and with gcc 9.3)

FROM gcc:13.2.0
RUN apt-get --allow-unauthenticated update && apt-get --allow-unauthenticated install -y python3-dev git yasm python3-psutil
RUN git clone https://github.com/BrianGladman/aes
WORKDIR /aes/python_binding
RUN git checkout 646c5d4

# This uses the aes_ni implementation
RUN gcc -fPIC -shared -I.. -O2 -Wall -g -I/usr/include/python3.11 -D__PROFILE_AES__ -march=skylake ../aes_ni.c ../aes_modes.c ../aescrypt.c ../aeskey.c ../aestab.c ./aesmodule.c -o aes.cpython-311-x86_64-linux-gnu.so
RUN python3 demo.py  # works
RUN python3 test_aes.py  # works

# This uses the amd64 asm implementation
RUN yasm -f elf64 -a x86 -D__GNUC__ ../aes_amd64.asm -o asm.o
RUN gcc -fPIC -shared -I.. -O2 -Wall -g -I/usr/include/python3.11 -D__PROFILE_AES__ -march=skylake -U__AES__ -DASM_AMD64_C ./asm.o ../aes_modes.c ../aescrypt.c ../aeskey.c ../aestab.c ./aesmodule.c -o aes.cpython-311-x86_64-linux-gnu.so
RUN python3 demo.py  # works
RUN python3 test_aes.py  # fails

# This uses the C implementation, and doesn't
RUN gcc -fPIC -shared -I.. -O2 -Wall -g -I/usr/include/python3.11 -D__PROFILE_AES__ -march=skylake -U__AES__ ../aes_ni.c ../aes_modes.c ../aescrypt.c ../aeskey.c ../aestab.c ./aesmodule.c -o aes.cpython-311-x86_64-linux-gnu.so
RUN python3 demo.py  # works
RUN python3 test_aes.py  # fails

Am I doing something wrongly?

Compiling without SHA2

It appears that hmac.h has problems compiling if SHA2 support is not necessary. There is a compiler error that SHA2_MAX_DIGEST_SIZE is not defined. Adding something like the following should fix it:

#if defined(SHA_224) || defined(SHA_256) || defined(SHA_384) || defined(SHA_512)
#define HMAC_MAX_OUTPUT_SIZE SHA2_MAX_DIGEST_SIZE
#define HMAC_MAX_BLOCK_SIZE SHA2_MAX_BLOCK_SIZE
#else 
#define HMAC_MAX_OUTPUT_SIZE SHA1_DIGEST_SIZE
#define HMAC_MAX_BLOCK_SIZE SHA1_BLOCK_SIZE
#endif

And hmac_ctx should use HMAC_MAX_BLOCK_SIZE instead of SHA2_MAX_BLOCK_SIZE.

Thanks!

makefile cmake build

Hello Brian,

Why your sources do not have makefile or cmake to build the code? It could be a project with cross-platform build.

Macro warning

Hello, I submitted this at https://github.com/nmoinvaz/minizip where aes code is used and was redirected here. I am building Linux 64 version and getting warnings about macros, but I got quite lost in the definitions and don't know what's the reason behind it:

/aes/aesopt.h:353:25: note: in definition of macro ‘to_byte’
# define to_byte(x) ((x) & 0xff)
^
/aes/aesopt.h:727:12: note: in expansion of macro ‘bval’
^ tab[2][bval(vf(x,2,c),rf(2,c))] \
^~~~
/aes/aesopt.h:727:17: note: in expansion of macro ‘vf1’
^ tab[2][bval(vf(x,2,c),rf(2,c))] \
^~
/aes/aesopt.h:749:29: note: in expansion of macro ‘four_tables’
# define inv_mcol(x) four_tables(x,t_use(i,m),vf1,rf1,0)
^~~~~~~~~~~
/aes/aeskey.c:232:17: note: in expansion of macro ‘inv_mcol’
#define ff(x) inv_mcol(x)
^~~~~~~~
/aes/aeskey.c:491:25: note: in expansion of macro ‘ff’
cx->ks[v(56,(7))] = ff(ss[7] = word_in(key, 7));
^~
/aes/aeskey.c:491:34: warning: operation on ‘ss[7]’ may be undefined [-Wsequence-point]
cx->ks[v(56,(7))] = ff(ss[7] = word_in(key, 7));

Your example can encrypt but not decrypt

Hey Brian,

I have tried to set up your example for aes encryption and decryption.
I got your example working and the encryption works but for some reason it errors out and stops the program from running when I try to decrypt?

Any ideas?

Thanks heaps,

Steph

OS X / IOS / Android support?

Dear Brian,

I see that you have (assembly) code for linux and Windows.
Do you also have code for OSX?

How does the performance of your aes code compare to e.g.
this code?

Thanks in advance for your answer

warning: "Function cannot return qualified void type 'volatile void'"

Xcode 8.3.3, using compiler default ([-std=gnu99]), is reporting me warnings for aes_via_ace.h:

Function cannot return qualified void type 'volatile void'

Stack Overflow got a specific question regarding volatile void in AES... with a direct link to aes_via_ace.h, and it says we should use __attribute__((noreturn)) void instead.

Yet, this step is only changing the warning to another one:

Function declared 'noreturn' should not return

The same StackOverflow thread is concerned that:

  • this code is insane
  • Declaring a function as doesn't return when it does return to convince the optimizer to do something specific is asking for trouble.
  • Extensive use of this technique is definitely discouraged. First, it depends on customization for each compiler. Second, it depends on those compilers not changing how they handle the 'no return' case. Third, it's potentially confusing to subsequent maintainers.

Finally, a comment reveals:

  • In later AES implementations, I haven't seen this sort of 'trick' used at all.

It was unspecified what are those later AES implementations. Could be any of those:

Would it be possible to get inspiration from those to get rid of the volatile void?

Key is bad (RFC2898 Password Based Key Derivation)

I have tried your implementation of RFC2898 (pwd2key.c) in order to verify the derive_key() function. In your implementation you had placed a test case to verify it and i had executed that. Unfortunately it shows that the "key is bad" which shows that there is something wrong in the derive_key() function.
The pwd2key.c file

pwd2key.txt

Here is the structure

strut.txt

main function

main.txt

Output

1

aescrypt.cu:115: undefined reference to `t_fn'

Hi !
I have used your created modules and it works just fine. I have used it along with some zlib modules as well. Now i am trying to add some cuda-kernels to it but i face a little problem which i am unable to identify the reason behind this.

In order to move gradually, at this point, i haven't embed any kernels. I have just replaced the .c extension to .cu in order to pass it to the nvcc compiler. The building process stuck with these two files (aescrypt.cu and aeskey.cu).
I have searched for these elements 't_fn' 't_fl' `t_rc' in your code but couldn't found it !

Here are the screenshots
1
2

Note: I haven't modified the above files, the files are as-it-is.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.