📄 cast.c
字号:
#include "bc_types.h"#include "bc_cast.h"#include "bc_casti.h"/**********************************************************************
*
* Useful definitions
*
**********************************************************************/#define ROL( X, n ) ( ( ( X ) << ( n ) ) | ( ( X ) >> ( 32 - ( n ) ) ) )/* Macroses to transform array of 4 bytes to 32-bit dwords
* (and reverse) without depending on the Little-Endian or
* Big-Endian processor's architecture
*/#define BYTES_TO_DWORD(b,d) (d =((DWORD)(*((b)++)))<<24, \ d|=((DWORD)(*((b)++)))<<16, \ d|=((DWORD)(*((b)++)))<<8, \ d|=((DWORD)(*((b)++))))#define DWORD_TO_4BYTES(d,b) (*((b)++)=(BYTE)(((d)>>24)&0xff), \ *((b)++)=(BYTE)(((d)>>16)&0xff), \ *((b)++)=(BYTE)(((d)>> 8)&0xff), \ *((b)++)=(BYTE)(((d) )&0xff))/**********************************************************************
*
* CAST core implementation
*
**********************************************************************//*
* PRE_SUBKEY, FIND_SUBKEY and FIND_SUBKEYS macroses help to clarify the * procedures of the subkeys generation.
*
* PRE_SUBKEY macros helps to calculate temporary variables for subkeys
* generation
*/#define PRE_SUBKEY( Result, Parameter, S, I0, I1, I2, I3, I4) \ ( Result = Parameter ^ cast_Sbox[ 4 ][ I0 ] ^ \ cast_Sbox[ 5 ][ I1 ] ^ \ cast_Sbox[ 6 ][ I2 ] ^ \ cast_Sbox[ 7 ][ I3 ] ^ \ cast_Sbox[ S ][ I4 ] )#define FIND_SUBKEY( Subkey, S, I0, I1, I2, I3, I4) \ Subkey = cast_Sbox[ 4 ][ I0 ] ^ \ cast_Sbox[ 5 ][ I1 ] ^ \ cast_Sbox[ 6 ][ I2 ] ^ \ cast_Sbox[ 7 ][ I3 ] ^ \ cast_Sbox[ S ][ I4 ]#define FIND_SUBKEYS1( skIndex, bPtr ) \ FIND_SUBKEY( subKeys[skIndex ], 4, bPtr[0x8], bPtr[0x9], bPtr[0x7], bPtr[0x6], bPtr[0x2] ); \ FIND_SUBKEY( subKeys[skIndex+1], 5, bPtr[0xA], bPtr[0xB], bPtr[0x5], bPtr[0x4], bPtr[0x6] ); \ FIND_SUBKEY( subKeys[skIndex+2], 6, bPtr[0xC], bPtr[0xD], bPtr[0x3], bPtr[0x2], bPtr[0x9] ); \ FIND_SUBKEY( subKeys[skIndex+3], 7, bPtr[0xE], bPtr[0xF], bPtr[0x1], bPtr[0x0], bPtr[0xC] )#define FIND_SUBKEYS2( skIndex, bPtr ) \ FIND_SUBKEY( subKeys[skIndex ], 4, bPtr[0x3], bPtr[0x2], bPtr[0xC], bPtr[0xD], bPtr[0x8] ); \ FIND_SUBKEY( subKeys[skIndex+1], 5, bPtr[0x1], bPtr[0x0], bPtr[0xE], bPtr[0xF], bPtr[0xD] ); \ FIND_SUBKEY( subKeys[skIndex+2], 6, bPtr[0x7], bPtr[0x6], bPtr[0x8], bPtr[0x9], bPtr[0x3] ); \ FIND_SUBKEY( subKeys[skIndex+3], 7, bPtr[0x5], bPtr[0x4], bPtr[0xA], bPtr[0xB], bPtr[0x7] )#define FIND_SUBKEYS3( skIndex, bPtr ) \ FIND_SUBKEY( subKeys[skIndex ], 4, bPtr[0x3], bPtr[0x2], bPtr[0xC], bPtr[0xD], bPtr[0x9] ); \ FIND_SUBKEY( subKeys[skIndex+1], 5, bPtr[0x1], bPtr[0x0], bPtr[0xE], bPtr[0xF], bPtr[0xC] ); \ FIND_SUBKEY( subKeys[skIndex+2], 6, bPtr[0x7], bPtr[0x6], bPtr[0x8], bPtr[0x9], bPtr[0x2] ); \ FIND_SUBKEY( subKeys[skIndex+3], 7, bPtr[0x5], bPtr[0x4], bPtr[0xA], bPtr[0xB], bPtr[0x6] )#define FIND_SUBKEYS4( skIndex, bPtr ) \ FIND_SUBKEY( subKeys[skIndex ], 4, bPtr[0x8], bPtr[0x9], bPtr[0x7], bPtr[0x6], bPtr[0x3] ); \ FIND_SUBKEY( subKeys[skIndex+1], 5, bPtr[0xA], bPtr[0xB], bPtr[0x5], bPtr[0x4], bPtr[0x7] ); \ FIND_SUBKEY( subKeys[skIndex+2], 6, bPtr[0xC], bPtr[0xD], bPtr[0x3], bPtr[0x2], bPtr[0x8] ); \ FIND_SUBKEY( subKeys[skIndex+3], 7, bPtr[0xE], bPtr[0xF], bPtr[0x1], bPtr[0x0], bPtr[0xD] )/* One round of CAST encryption. There are 3 types of calculations
* depending on the round number:
* - Rounds 1, 4, 7, 10, 13, and 16 use f function Type 1.
* - Rounds 2, 5, 8, 11, and 14 use f function Type 2.
* - Rounds 3, 6, 9, 12, and 15 use f function Type 3.
*/#define ROUND_TYPE1(Left, Right, Ks, Num, Tmp ) \ Tmp = ROL((Ks[Num] + Right), (Ks[Num+16])); \ Left ^= ((cast_Sbox[ 0 ][ (Tmp>>24)&0xff ] ^ \ cast_Sbox[ 1 ][ (Tmp>>16)&0xff ]) - \ cast_Sbox[ 2 ][ (Tmp>>8 )&0xff ]) + \ cast_Sbox[ 3 ][ (Tmp )&0xff ]#define ROUND_TYPE2(Left, Right, Ks, Num, Tmp ) \ Tmp = ROL((Ks[Num] ^ Right), (Ks[Num+16])); \ Left ^= ((cast_Sbox[ 0 ][ (Tmp>>24)&0xff ] - \ cast_Sbox[ 1 ][ (Tmp>>16)&0xff ]) + \ cast_Sbox[ 2 ][ (Tmp>>8 )&0xff ]) ^ \ cast_Sbox[ 3 ][ (Tmp )&0xff ]#define ROUND_TYPE3(Left, Right, Ks, Num, Tmp ) \ Tmp = ROL((Ks[Num] - Right), (Ks[Num+16])); \ Left ^= ((cast_Sbox[ 0 ][ (Tmp>>24)&0xff ] + \ cast_Sbox[ 1 ][ (Tmp>>16)&0xff ]) ^ \ cast_Sbox[ 2 ][ (Tmp>>8 )&0xff ]) - \ cast_Sbox[ 3 ][ (Tmp )&0xff ]/**********************************************************************
*
* KeyExtend() calculates extended key from a given key
*
**********************************************************************/BOOLKeyExtend( BYTE *KeySource, // 8-bit uchars DWORD *KeyDestination ) // 32-bit dwords{ /* keyByteStream and key32bStream arrays are used to avoid big-endian and
little-endian problems */ BYTE keyByteStream[CAST_MAXIMUM_KEYSIZE_BYTES], *keyBytePtr, *kb, tmpByteStream[CAST_MAXIMUM_KEYSIZE_BYTES], *tmpBytePtr, *tb; DWORD key32bStream[CAST_MAXIMUM_KEYSIZE_DWORD], tmp32bStream[CAST_MAXIMUM_KEYSIZE_DWORD]; CastData *castData; BYTE *key; DWORD *subKeys; DWORD i, subKeyNum; /* Get addresses of an encryption key and an extended key
that will be calculated from the encryption key */ key = KeySource; castData = (CastData *)KeyDestination; subKeys = castData->subKeys; for ( i=0; i<CAST_MAXIMUM_KEYSIZE_BYTES; i++ ) keyByteStream[i] = key[i]; /* Depending on the keyData->keySize value we will make
12 or 16 rounds in the encrypt/decrypt operations
We use maximum possible key (more than MIN_KEYSIZE_FOR_16_ROUNDS)
*/ castData->make16rounds = TRUE; /* Calculating of the CAST subkeys */ kb = keyByteStream; tb = tmpByteStream; keyBytePtr = keyByteStream; tmpBytePtr = tmpByteStream; for ( i=0; i<CAST_MAXIMUM_KEYSIZE_DWORD; i++ ) { BYTES_TO_DWORD( keyBytePtr, key32bStream[i] ); } subKeyNum = 0; for ( i=0; i<2; i++ ) { /* Define 0-3 subkeys (16-19 on the second round) */ keyBytePtr = keyByteStream; tmpBytePtr = tmpByteStream; PRE_SUBKEY( tmp32bStream[0],key32bStream[0],6,kb[0xD],kb[0xF],kb[0xC],kb[0xE],kb[0x8]); DWORD_TO_4BYTES(tmp32bStream[0], tmpBytePtr); PRE_SUBKEY( tmp32bStream[1],key32bStream[2],7,tb[0x0],tb[0x2],tb[0x1],tb[0x3],kb[0xA]); DWORD_TO_4BYTES(tmp32bStream[1], tmpBytePtr); PRE_SUBKEY( tmp32bStream[2],key32bStream[3],4,tb[0x7],tb[0x6],tb[0x5],tb[0x4],kb[0x9]); DWORD_TO_4BYTES(tmp32bStream[2], tmpBytePtr); PRE_SUBKEY( tmp32bStream[3],key32bStream[1],5,tb[0xA],tb[0x9],tb[0xB],tb[0x8],kb[0xB]); DWORD_TO_4BYTES(tmp32bStream[3], tmpBytePtr); FIND_SUBKEYS1(subKeyNum, tb); subKeyNum += 4; /* Define 4-7 subkeys (20-23 on the second round) */ keyBytePtr = keyByteStream; tmpBytePtr = tmpByteStream; PRE_SUBKEY( key32bStream[0],tmp32bStream[2],6,tb[0x5],tb[0x7],tb[0x4],tb[0x6],tb[0x0]); DWORD_TO_4BYTES(key32bStream[0], keyBytePtr); PRE_SUBKEY( key32bStream[1],tmp32bStream[0],7,kb[0x0],kb[0x2],kb[0x1],kb[0x3],tb[0x2]); DWORD_TO_4BYTES(key32bStream[1], keyBytePtr); PRE_SUBKEY( key32bStream[2],tmp32bStream[1],4,kb[0x7],kb[0x6],kb[0x5],kb[0x4],tb[0x1]); DWORD_TO_4BYTES(key32bStream[2], keyBytePtr); PRE_SUBKEY( key32bStream[3],tmp32bStream[3],5,kb[0xA],kb[0x9],kb[0xB],kb[0x8],tb[0x3]); DWORD_TO_4BYTES(key32bStream[3], keyBytePtr); FIND_SUBKEYS2(subKeyNum, kb); subKeyNum += 4; /* Define 8-11 subkeys (24-27 on the second round) */ keyBytePtr = keyByteStream; tmpBytePtr = tmpByteStream; PRE_SUBKEY( tmp32bStream[0],key32bStream[0],6,kb[0xD],kb[0xF],kb[0xC],kb[0xE],kb[0x8]); DWORD_TO_4BYTES(tmp32bStream[0], tmpBytePtr); PRE_SUBKEY( tmp32bStream[1],key32bStream[2],7,tb[0x0],tb[0x2],tb[0x1],tb[0x3],kb[0xA]); DWORD_TO_4BYTES(tmp32bStream[1], tmpBytePtr); PRE_SUBKEY( tmp32bStream[2],key32bStream[3],4,tb[0x7],tb[0x6],tb[0x5],tb[0x4],kb[0x9]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -