📄 ctx_aes.c
字号:
/****************************************************************************
* *
* cryptlib AES Encryption Routines *
* Copyright Peter Gutmann 2000-2007 *
* *
****************************************************************************/
#if defined( INC_ALL )
#include "crypt.h"
#include "context.h"
#include "aes.h"
#include "aesopt.h"
#else
#include "crypt.h"
#include "context/context.h"
#include "crypt/aes.h"
#include "crypt/aesopt.h"
#endif /* Compiler-specific includes */
/* The AES code separates encryption and decryption to make it easier to
do encrypt-only or decrypt-only apps, however since we don't know
what the user will choose to do we have to do both key schedules (this
is a relatively minor overhead compared to en/decryption, so it's not a
big problem).
When building with VC++, the asm code used is aescrypt2.asm, built with
'yasm -Xvc -D ASMV2 -f win32 aescrypt2.asm', which provides the best
performance by using asm for the en/decrypt functions and C for the
key schedule */
#ifdef USE_AES
/* The size of an AES key and block and a keyscheduled AES key */
#define AES_KEYSIZE 32
#define AES_BLOCKSIZE 16
#define AES_EXPANDED_KEYSIZE sizeof( AES_CTX )
/* The scheduled AES key and key schedule control and function return
codes */
#define AES_EKEY aes_encrypt_ctx
#define AES_DKEY aes_decrypt_ctx
#define AES_2KEY AES_CTX
/* The following macros are from the AES implementation, and aren't cryptlib
code.
Assign memory for AES contexts in 'UNIT_SIZE' blocks of bytes with two
such blocks in cryptlib's AES context (one encryption and one decryption).
The cryptlib key schedule is then two AES contexts plus an extra UNIT_SIZE
block to allow for alignment adjustment by up to 'UNIT_SIZE' - 1 bytes to
align each of the internal AES contexts on UNIT_SIZE boundaries */
#define UNIT_SIZE 16
/* The size of the AES context rounded up (if necessary) to a multiple 16 bytes */
#define BYTE_SIZE( x ) ( UNIT_SIZE * ( ( sizeof( x ) + UNIT_SIZE - 1 ) / UNIT_SIZE ) )
/* The size of the cryptlib AES context plus UNIT_SIZE bytes for possible upward
alignment to a UNIT_SIZE byte boundary */
#define KS_SIZE ( BYTE_SIZE( AES_EKEY ) + BYTE_SIZE( AES_DKEY ) + UNIT_SIZE )
/* The base address for the cryptlib AES context */
#define KS_BASE(x) ( ( unsigned char * )( ( ( AES_CTX * ) x )->ksch ) )
/* The AES encrypt context address rounded up (if necessary) to a 16 byte boundary */
#define EKEY( x ) ( ( AES_EKEY * ) ALIGN_CEIL( KS_BASE( x ), UNIT_SIZE ) )
/* The AES decrypt context address rounded up (if necessary) to a 16 byte boundary */
#define DKEY( x ) ( ( AES_DKEY * ) ALIGN_CEIL( KS_BASE( x ) + BYTE_SIZE( AES_EKEY ), UNIT_SIZE ) )
/* A type to hold the cryptlib AES context */
typedef unsigned long _unit;
typedef struct {
_unit ksch[ ( KS_SIZE + sizeof( _unit ) - 1 ) / sizeof( _unit ) ];
} AES_CTX;
#define ENC_KEY( x ) EKEY( ( x )->key )
#define DEC_KEY( x ) DKEY( ( x )->key )
/****************************************************************************
* *
* AES Self-test Routines *
* *
****************************************************************************/
/* AES FIPS test vectors */
/* The data structure for the ( key, plaintext, ciphertext ) triplets */
typedef struct {
const int keySize;
const BYTE key[ AES_KEYSIZE + 8 ];
const BYTE plaintext[ AES_BLOCKSIZE + 8 ];
const BYTE ciphertext[ AES_BLOCKSIZE + 8 ];
} AES_TEST;
static const AES_TEST FAR_BSS testAES[] = {
{ 16,
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F },
{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF },
{ 0x69, 0xC4, 0xE0, 0xD8, 0x6A, 0x7B, 0x04, 0x30,
0xD8, 0xCD, 0xB7, 0x80, 0x70, 0xB4, 0xC5, 0x5A } },
{ 24,
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 },
{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF },
{ 0xDD, 0xA9, 0x7C, 0xA4, 0x86, 0x4C, 0xDF, 0xE0,
0x6E, 0xAF, 0x70, 0xA0, 0xEC, 0x0D, 0x71, 0x91 } },
{ 32,
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF },
{ 0x8E, 0xA2, 0xB7, 0xCA, 0x51, 0x67, 0x45, 0xBF,
0xEA, 0xFC, 0x49, 0x90, 0x4B, 0x49, 0x60, 0x89 } }
};
#if 0
/* Test the AES code against the test vectors from the AES FIPS */
static void printVector( const char *description, const BYTE *data,
const int length )
{
int i;
printf( "%s = ", description );
for( i = 0; i < length; i++ )
printf( "%02x", data[ i ] );
putchar( '\n' );
}
static int updateKey( BYTE *key, const int keySize,
CONTEXT_INFO *contextInfo,
const CAPABILITY_INFO *capabilityInfo,
const BYTE *newKey1, const BYTE *newKey2 )
{
BYTE keyData[ AES_KEYSIZE + 8 ];
int i;
switch( keySize )
{
case 16:
memcpy( keyData, newKey2, keySize );
break;
case 24:
memcpy( keyData, newKey1 + 8, keySize );
memcpy( keyData + 8, newKey2, AES_BLOCKSIZE );
case 32:
memcpy( keyData, newKey1, AES_BLOCKSIZE );
memcpy( keyData + 16, newKey2, AES_BLOCKSIZE );
}
for( i = 0; i < keySize; i++ )
key[ i ] ^= keyData[ i ];
return( capabilityInfo->initKeyFunction( contextInfo, key,
keySize ) );
}
static int mct( CONTEXT_INFO *contextInfo,
const CAPABILITY_INFO *capabilityInfo,
const BYTE *initialKey, const int keySize,
const BYTE *initialIV, const BYTE *initialPT )
{
BYTE key[ AES_KEYSIZE + 8 ], iv[ AES_KEYSIZE + 8 ];
BYTE temp[ AES_BLOCKSIZE + 8 ];
int i;
memcpy( key, initialKey, keySize );
if( iv != NULL )
memcpy( iv, initialIV, AES_BLOCKSIZE );
memcpy( temp, initialPT, AES_BLOCKSIZE );
for( i = 0; i < 100; i++ )
{
BYTE prevTemp[ AES_BLOCKSIZE + 8 ];
int j, status;
status = capabilityInfo->initKeyFunction( contextInfo, key,
keySize );
if( cryptStatusError( status ) )
return( status );
printVector( "Key", key, keySize );
if( iv != NULL )
printVector( "IV", iv, AES_BLOCKSIZE );
printVector( "Plaintext", temp, AES_BLOCKSIZE );
if( iv != NULL )
memcpy( contextInfo->ctxConv->currentIV, iv, AES_BLOCKSIZE );
for( j = 0; j < 1000; j++ )
{
/* memcpy( prevTemp, temp, AES_BLOCKSIZE ); */
if( iv != NULL && j == 0 )
{
status = capabilityInfo->encryptCBCFunction( contextInfo, temp,
AES_BLOCKSIZE );
memcpy( prevTemp, temp, AES_BLOCKSIZE );
memcpy( temp, iv, AES_BLOCKSIZE );
}
else
{
status = capabilityInfo->encryptFunction( contextInfo, temp,
AES_BLOCKSIZE );
if( iv != NULL )
{
BYTE tmpTemp[ AES_BLOCKSIZE + 8 ];
memcpy( tmpTemp, temp, AES_BLOCKSIZE );
memcpy( temp, prevTemp, AES_BLOCKSIZE );
memcpy( prevTemp, tmpTemp, AES_BLOCKSIZE );
}
}
if( cryptStatusError( status ) )
return( status );
}
printVector( "Ciphertext", temp, AES_BLOCKSIZE );
putchar( '\n' );
status = updateKey( key, keySize, contextInfo, capabilityInfo,
prevTemp, temp );
if( cryptStatusError( status ) )
return( status );
}
return( CRYPT_OK );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -