📄 rvdesencryption.c
字号:
thisPtr->encrypt = (direction == RV_DESENCRYPTION_DIRECTION_ENCRYPT);
rvDesEncryptionExpandKey(key, thisPtr->key);
rvDesEncryptionGenerateKeySet(thisPtr->key, thisPtr->keySet, thisPtr->encrypt);
rvDesEncryptionScrunch(iv, thisPtr->iv);
rvDesEncryptionReset(thisPtr);
}
/*$
{function scope="protected":
{name: rvDesEncryptionProcess }
{class: RvDesEncryption }
{include: rvdesencryption.h}
{description:
{p: This method process the input buffer based on how the RvDesEncryption
object was initialized.}
}
{proto:void rvDesEncryptionProcess(RvDesEncryption* thisPtr, const RvUint8* input, RvUint8* output, RvUint32 length);}
{params:
{param: {n: thisPtr} {d:The RvDesEncryption object to perform the processing.}}
{param: {n: input} {d:The input buffer.}}
{param: {n: output} {d:The output buffer. This can be the same buffer as the input buffer.}}
{param: {n: length} {d:The size of the buffers in bytes.}}
}
}
$*/
void rvDesEncryptionProcess(RvDesEncryption *thisPtr, const RvUint8 *input,
RvUint8 *output, RvUint32 length)
{
rvDesEncryptionFunction(input, output, length, thisPtr->mode,
thisPtr->prevBlock,thisPtr->keySet, thisPtr->encrypt);
}
/*$
{function scope="protected":
{name: rvDesEncryptionReset }
{class: RvDesEncryption }
{include: rvdesencryption.h}
{description:
{p: This method reinitalizes the algorithm based on the previous
initialization call.}
}
{proto:void rvDesEncryptionReset(RvDesEncryption* thisPtr);}
{params:
{param: {n: thisPtr} {d:The RvDesEncryption object to reset.}}
}
}
$*/
void rvDesEncryptionReset(RvDesEncryption *thisPtr)
{
thisPtr->prevBlock[0] = thisPtr->iv[0];
thisPtr->prevBlock[1] = thisPtr->iv[1];
}
/***********************************************************************
* Private method definitions
***********************************************************************/
static void rvDesEncryptionFunction(const RvUint8 *input,
RvUint8 *output,
RvUint32 length,
RvUint8 mode,
RvUint32 prevBlock[2],
const RvUint32 keys[32],
RvBool encrypt)
{
static const RvUint8 bytesPerBlock = 8;
RvUint32 fval;
RvUint32 work;
RvUint32 right;
RvUint32 left;
int round;
RvUint32 i;
RvUint32 inputBlock[2];
RvUint32 outputBlock[2];
RvUint32 blocks = length/bytesPerBlock;
const RvUint32 *currentKeyPtr;
for(i = 0; i < blocks; i++)
{
/* Copy the 8 input bytes into a block of 2 longwords */
/* TBD: Is his necessary? will simple casting do after correcting for endian ? */
rvDesEncryptionScrunch(input, inputBlock); /* Unwind function to optimize */
input += bytesPerBlock;
if(mode == RV_DESENCRYPTION_MODE_CBC)
{
if(encrypt)
{
/* In CBC Mode encryption the previous block is XORed with */
/* the current before the block is encrypted. */
inputBlock[0] ^= prevBlock[0];
inputBlock[1] ^= prevBlock[1];
}
}
/* Split the block into the left and right half */
left = inputBlock[0];
right = inputBlock[1];
/* Perform the intitial permutation */
work = ((left >> 4) ^ right) & 0x0F0F0F0FL;
right ^= work;
left ^= (work << 4);
work = ((left >> 16) ^ right) & 0x0000FFFFL;
right ^= work;
left ^= (work << 16);
work = ((right >> 2) ^ left) & 0x33333333L;
left ^= work;
right ^= (work << 2);
work = ((right >> 8) ^ left) & 0x00FF00FFL;
left ^= work;
right ^= (work << 8);
right = ((right << 1) | ((right >> 31) & 1L)) & 0xFFFFFFFFL;
work = ((left ^ right) & 0xAAAAAAAAL);
left ^= work;
right ^= work;
left = ((left << 1) | ((left >> 31) & 1L)) & 0xFFFFFFFFL;
/* Set the current key to the first key */
currentKeyPtr = keys;
/* Perform the rounds in pairs */
for(round = 0; round < 8; round++)
{
/* perform round on right half */
work = (right << 28) | (right >> 4);
work ^= *currentKeyPtr++;
fval = SP7[ work & 0x3FL];
fval |= SP5[(work >> 8) & 0x3FL];
fval |= SP3[(work >> 16) & 0x3FL];
fval |= SP1[(work >> 24) & 0x3FL];
work = right ^ *currentKeyPtr++;
fval |= SP8[ work & 0x3FL];
fval |= SP6[(work >> 8) & 0x3FL];
fval |= SP4[(work >> 16) & 0x3FL];
fval |= SP2[(work >> 24) & 0x3FL];
left ^= fval;
/* perform round on left half */
work = (left << 28) | (left >> 4);
work ^= *currentKeyPtr++;
fval = SP7[ work & 0x3FL];
fval |= SP5[(work >> 8) & 0x3FL];
fval |= SP3[(work >> 16) & 0x3FL];
fval |= SP1[(work >> 24) & 0x3FL];
work = left ^ *currentKeyPtr++;
fval |= SP8[ work & 0x3FL];
fval |= SP6[(work >> 8) & 0x3FL];
fval |= SP4[(work >> 16) & 0x3FL];
fval |= SP2[(work >> 24) & 0x3FL];
right ^= fval;
}
/* Perform the inverse of the intitial permutation */
right = (right << 31) | (right >> 1);
work = (left ^ right) & 0xAAAAAAAAL;
left ^= work;
right ^= work;
left = (left << 31) | (left >> 1);
work = ((left >> 8) ^ right) & 0x00FF00FFL;
right ^= work;
left ^= (work << 8);
work = ((left >> 2) ^ right) & 0x33333333L;
right ^= work;
left ^= (work << 2);
work = ((right >> 16) ^ left) & 0x0000FFFFL;
left ^= work;
right ^= (work << 16);
work = ((right >> 4) ^ left) & 0x0F0F0F0FL;
left ^= work;
right ^= (work << 4);
/* Recombine the block's left and right half */
outputBlock[0] = right;
outputBlock[1] = left;
if(mode == RV_DESENCRYPTION_MODE_CBC)
{
if(encrypt)
{
prevBlock[0] = outputBlock[0];
prevBlock[1] = outputBlock[1];
}
else
{
outputBlock[0] ^= prevBlock[0];
outputBlock[1] ^= prevBlock[1];
prevBlock[0] = inputBlock[0];
prevBlock[1] = inputBlock[1];
}
}
rvDesEncryptionUnscrunch(outputBlock, output); /* Unwind function to optimize */
output += bytesPerBlock;
}
}
static void rvDesEncryptionGenerateKeySet(const RvUint8 key[8], RvUint32 keys[32], RvBool encrypt)
{
RvUint32 i,j,l,m,n;
RvUint8 pc1m[56];
RvUint8 pcr[56];
RvUint32 rawKeys[32];
for(j = 0; j < 56; j++)
{
l = keyPermutation[j];
m = l & 07;
pc1m[j] = (key[l >> 3] & bytebit[m]) ? 1 : 0;
}
for(i = 0; i < 16; i++)
{
if(!encrypt)
m = (15-i) << 1;
else
m = i << 1;
n = m + 1;
rawKeys[m] = rawKeys[n] = 0L;
for(j = 0; j < 28; j++)
{
l = j + keyRotation[i];
if(l < 28)
pcr[j] = pc1m[l];
else
pcr[j] = pc1m[l-28];
}
for(j = 28; j < 56; j++)
{
l = j + keyRotation[i];
if(l < 56)
pcr[j] = pc1m[l];
else
pcr[j] = pc1m[l-28];
}
for(j = 0; j < 24; j++)
{
if(pcr[compressionPermutation[j]])
rawKeys[m] |= bigbyte[j];
if(pcr[compressionPermutation[j+24]])
rawKeys[n] |= bigbyte[j];
}
}
rvDesEncryptionCookKeys(rawKeys, keys);
}
static void rvDesEncryptionCookKeys( const RvUint32 rawKeys[32], RvUint32 cookedKeys[32])
{
const RvUint32 *rawKey1 = rawKeys;
const RvUint32 *rawKey0;
RvUint32 *cookedKeys0 = cookedKeys;
RvUint32 i;
for(i = 0; i < 16; i++)
{
rawKey0 = rawKey1++;
*cookedKeys0 = (*rawKey0 & 0x00FC0000L) << 6;
*cookedKeys0 |= (*rawKey0 & 0x00000FC0L) << 10;
*cookedKeys0 |= (*rawKey1 & 0x00FC0000L) >> 10;
*cookedKeys0++ |= (*rawKey1 & 0x00000FC0L) >> 6;
*cookedKeys0 = (*rawKey0 & 0x0003F000L) << 12;
*cookedKeys0 |= (*rawKey0 & 0x0000003FL) << 16;
*cookedKeys0 |= (*rawKey1 & 0x0003F000L) >> 4;
*cookedKeys0++ |= (*rawKey1 & 0x0000003FL);
rawKey1++;
}
}
static void rvDesEncryptionScrunch(const RvUint8 outof[8], RvUint32 into[2])
{
*into = (*outof++ & 0xFFL) << 24;
*into |= (*outof++ & 0xFFL) << 16;
*into |= (*outof++ & 0xFFL) << 8;
*into++ |= (*outof++ & 0xFFL);
*into = (*outof++ & 0xFFL) << 24;
*into |= (*outof++ & 0xFFL) << 16;
*into |= (*outof++ & 0xFFL) << 8;
*into |= (*outof & 0xFFL);
}
static void rvDesEncryptionUnscrunch(const RvUint32 outof[2], RvUint8 into[8])
{
*into++ = (*outof >> 24) & 0xFFL;
*into++ = (*outof >> 16) & 0xFFL;
*into++ = (*outof >> 8) & 0xFFL;
*into++ = (*outof++ ) & 0xFFL;
*into++ = (*outof >> 24) & 0xFFL;
*into++ = (*outof >> 16) & 0xFFL;
*into++ = (*outof >> 8) & 0xFFL;
*into = (*outof ) & 0xFFL;
}
/*$
{function scope="private":
{name: rvDesEncryptionExpandKey }
{class: RvDesEncryption }
{include: rvdesencryption.h}
{description:
{p: Expands a 56 bit key into a 64 bit key by esxpanding it into
8 octets with an odd parity bit in the most significant position. }
}
{proto: void rvDesEncryptionExpandKey(const RvUint8 key[7], RvUint8 expandedKey[8]);}
{params:
{param: {n:key} {d:The 56 bit key.}}
{param: {n:expandedKey} {d:The expanded 64 bit key.}}
}
}
$*/
void rvDesEncryptionExpandKey(const RvUint8 key[7], RvUint8 expandedKey[8])
{
static const RvUint8 byte1[8] = { 0, 1, 2, 3, 4, 5, 6, 6};
static const RvUint8 shift1[8] = { 0, 1, 2, 3, 4, 5, 6, 1};
static const RvUint8 byte2[8] = { 0, 0, 1, 2, 3, 4, 5, 6};
static const RvUint8 shift2[8] = { 0, 7, 6, 5, 4, 3, 2, 1};
static const RvUint8 mask2[8] = {0x00,0x01,0x03,0x07,0x0F,0x1F,0x3F,0x7F};
int i;
int j;
int parity;
/* Expand key to set msb in the byte to be an odd parity bit. */
for(i = 0; i < 8; i++)
{
if(byte1[i] == byte2[i])
expandedKey[i] = (key[byte2[i]] >> shift2[i]) & 0x7F;
else
expandedKey[i] = (((key[byte2[i]] >> shift2[i]) & mask2[i])+
(key[byte1[i]] << shift1[i])) & 0x7F;
/* Add odd parity bit to msb */
parity = 0;
for(j = 0; j < 8; j++)
parity += ((expandedKey[i] >> j) & 0x01);
if((parity%2) == 0)
expandedKey[i] += 0x80;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -