⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rvdesencryption.c

📁 协议代码,主要用语Megaco 协议应用
💻 C
📖 第 1 页 / 共 2 页
字号:
    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 + -