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

📄 pgpipsecesp.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*____________________________________________________________________________
	Copyright (C) 1998 Network Associates, Inc.
	All rights reserved.

	$Id: pgpIPsecESP.c,v 1.47.4.1 1999/06/17 15:28:47 dgal Exp $
____________________________________________________________________________*/

#ifndef USERLAND_TEST
#define USERLAND_TEST	0
#endif

#if USERLAND_TEST

#define DBG_FUNC(x)
#define DBG_ENTER()
#define DBG_PRINT(x)
#define DBG_LEAVE(x)

#else

#if PGP_WIN32

#include "vpn.h"
#include "vpndbg.h"
#include "ipdef.h"

#elif PGP_MACINTOSH

#define DBG_FUNC(x)
#define DBG_ENTER()
#define DBG_PRINT(x)
#define DBG_LEAVE(x)

#endif

#endif

#include "pgpIPsecESP.h"
#include "pgpIPheader.h"
#include "pgpIPsecErrors.h"
#include "pgpIPsecContextPriv.h"
#include "pgpHMAC.h"
#include "pgpEndianConversion.h"
#include "pgpMem.h"

#define ESP_PROTOCOL	50
#define ESP_HEADERSIZE	8

#define ESPHDR_SPI			0
#define ESPHDR_SEQNUMBER	4
#define ESPHDR_DATA			8

#define MAXHASHSIZE	32
#define TRUNCATED_HASH_SIZE	12

#define MAX_SLOP_BLOCK	16
#define MAX_PADDING		24

static PGPByte nullIV[] = {0,0,0,0,0,0,0,0};


PGPError pgpIPsecESPGetSPI(PGPIPsecBuffer *inPacket, PGPUInt32 *spi)
{
	PGPUInt32 espIndex;
	PGPIPsecBuffer tempPacket;
	PGPByte data[ESP_HEADERSIZE];
	PGPError err = kPGPError_NoErr;

	*spi = 0;
	
	tempPacket.data = data;
	tempPacket.dataSize = 0;
	tempPacket.allocatedSize = ESP_HEADERSIZE;
	tempPacket.next = NULL;

	err = pgpFindProtocolHeader(inPacket, ESP_PROTOCOL, &espIndex);

	if (IsntPGPError(err))
	{
		PGPCopyIPsecBuffer(NULL, inPacket, espIndex, &tempPacket, 0, 
			ESP_HEADERSIZE, ESP_HEADERSIZE);

		*spi = PGPEndianToUInt32(kPGPNetworkByteOrder, &(data[ESPHDR_SPI]));
	}

	return err;
}


PGPError pgpIPsecEncrypt(PGPIPsecContextRef ipsec, PGPUInt32 maxBufferSize,
			PGPIPsecBuffer *ipPacketIn, PGPBoolean tunnelMode, 
			PGPUInt32 gatewayIP, PGPCipherAlgorithm cipher, 
			const PGPByte *cryptKey, PGPByte *iv, PGPHashAlgorithm hash,
			PGPByte *authKey, PGPUInt32 spi, PGPUInt32 sequenceNumber, 
			PGPIPsecBuffer *ipPacketOut)
{
	PGPUInt32 espIndex;
	PGPUInt32 index;
	PGPUInt32 padStart;
	PGPUInt16 packetSize;
	PGPUInt32 inputStart;
	PGPUInt32 inDataIndex;
	PGPUInt32 outDataIndex;
	PGPUInt32 inSlopIndex;
	PGPUInt32 outSlopIndex;
	PGPUInt32 chunkSize;
	PGPSize total;
	PGPSize prevTotal;
	PGPByte nextHeader;
	PGPByte padLength;
	PGPSize keySize;
	PGPSize encryptSize;
	PGPSize blockSize;
	PGPSize inputSize;
	PGPByte hashSize;
	PGPByte authKeySize;
	PGPByte inSlopBlock[MAX_SLOP_BLOCK];
	PGPByte outSlopBlock[MAX_SLOP_BLOCK];
	PGPByte padding[MAX_PADDING];
	PGPByte authBuffer[MAXHASHSIZE];
	PGPByte headerData[ESP_HEADERSIZE + MAXHASHSIZE];
	PGPByte *inSlopPtr = NULL;
	PGPByte *outSlopPtr = NULL;
	PGPIPsecBuffer tempBuffer;
	PGPIPsecBuffer *inPtr = NULL;
	PGPIPsecBuffer *outPtr = NULL;
	PGPMemoryMgrRef memoryMgr = NULL;
	PGPHMACContextRef hmacRef = NULL;
	PGPSymmetricCipherContextRef cipherRef = NULL;
	PGPCBCContextRef cbcRef = NULL;
	PGPError err = kPGPError_NoErr;

	DBG_FUNC("pgpIPsecEncrypt")

	DBG_ENTER();

	if (IsNull(ipsec)) {
		DBG_PRINT(("!!!!! pgpIPsecEncrypt error: %d !!!!!!!!!!!\n", kPGPError_BadParams););
		DBG_LEAVE(kPGPError_BadParams);
		return kPGPError_BadParams;
	}
	
	memoryMgr = ipsec->memory;
	
	packetSize = pgpGetPacketSize(ipPacketIn);
	
	if (((PGPUInt32)(packetSize + 32) < maxBufferSize) || 
		(maxBufferSize == 0))
	{
		if (ipPacketOut->allocatedSize < (PGPUInt32) (packetSize + 32))
		{
			if (IsntNull(ipPacketOut->data))
				PGPFreeData(ipPacketOut->data);
			
			ipPacketOut->data = (PGPByte *) PGPNewData(memoryMgr,
												packetSize + 32,
												kPGPMemoryMgrFlags_Clear);
			
			ipPacketOut->allocatedSize = packetSize + 32;
			if (maxBufferSize == 0)
				maxBufferSize = packetSize + 32;
		}
	}
	else
	{
		if (ipPacketOut->allocatedSize < maxBufferSize)
		{
			if (IsntNull(ipPacketOut->data))
				PGPFreeData(ipPacketOut->data);
			
			ipPacketOut->data = (PGPByte *) PGPNewData(memoryMgr,
												maxBufferSize,
												kPGPMemoryMgrFlags_Clear);
			
			ipPacketOut->allocatedSize = maxBufferSize;
		}
	}
	
	if (IsNull(ipPacketOut->data))
		err = kPGPError_OutOfMemory;

	switch (cipher)
	{
	case kPGPCipherAlgorithm_CAST5:
		keySize = 16;
		blockSize = 8;
		err = PGPNewSymmetricCipherContext(memoryMgr, 
				kPGPCipherAlgorithm_CAST5, 16, &cipherRef);

		if (IsntPGPError(err))
			err = PGPNewCBCContext(cipherRef, &cbcRef);
		break;

	case kPGPCipherAlgorithm_3DES:
		keySize = 24;
		blockSize = 8;
		err = PGPNewSymmetricCipherContext(memoryMgr, 
				kPGPCipherAlgorithm_3DES, 24, &cipherRef);

		if (IsntPGPError(err))
			err = PGPNewCBCContext(cipherRef, &cbcRef);
		break;

	case kPGPCipherAlgorithm_None:
		keySize = 0;
		blockSize = 0;
		break;

	default:
		err = kPGPError_BadCipherNumber;
		break;
	};

	if (IsntPGPError(err)) 
	{
		pgpGetIPHeaderNextProtocol(ipPacketIn, tunnelMode, &nextHeader);

		espIndex = pgpGetIPHeaderLength(ipPacketIn);
		err = pgpAddProtocolToIPHeader(ipPacketIn, ESP_PROTOCOL, ipPacketOut);

		if (tunnelMode)
			packetSize += espIndex;
	}

	if (IsntPGPError(err))
	{
		if ((maxBufferSize > 0) && 
			(maxBufferSize <= (espIndex + ESP_HEADERSIZE + blockSize)))
			err = kPGPError_BufferTooSmall;

		encryptSize = packetSize - espIndex;

		if (tunnelMode)
			inputStart = 0;
		else
			inputStart = espIndex;

		inputSize = encryptSize;
		outDataIndex = espIndex + ESPHDR_DATA + blockSize;
	}

	if (cipher != kPGPCipherAlgorithm_None)
	{
		if (IsntPGPError(err))
		{
			if (IsntNull(iv))
				err = PGPInitCBC(cbcRef, cryptKey, iv);
			else
				err = PGPInitCBC(cbcRef, cryptKey, nullIV);
		}
		
		if (IsntPGPError(err))
		{
			inPtr = ipPacketIn;
			outPtr = ipPacketOut;
			total = inPtr->dataSize;
			prevTotal = 0;
			inSlopIndex = 0;
			outSlopIndex = 0;
			
			while ((total < inputStart) && IsntNull(inPtr->next))
			{
				prevTotal = total;
				inPtr = inPtr->next;
				total += inPtr->dataSize;
			}
			
			inDataIndex = inputStart - prevTotal;
			
			if (total < inputStart)
				err = kPGPError_BufferTooSmall;
		}
		
		while (IsntPGPError(err) && (inputSize >= blockSize) &&
			IsntNull(inPtr))
		{
			inSlopIndex = 0;
			outSlopIndex = 0;
			
			if (((inPtr->dataSize - inDataIndex) >= blockSize) &&
				((outPtr->allocatedSize - outDataIndex) >= blockSize))
			{
				if ((inPtr->dataSize - inDataIndex) <= 
					(outPtr->allocatedSize - outDataIndex))
				{
					chunkSize = (inPtr->dataSize - inDataIndex) -
								((inPtr->dataSize - inDataIndex) % blockSize);
				}
				else
				{
					chunkSize = (outPtr->allocatedSize - outDataIndex) -
								((outPtr->allocatedSize - outDataIndex) % 
									blockSize);
				}
				
				err = PGPCBCEncrypt(cbcRef, &(inPtr->data[inDataIndex]), 
						chunkSize, &(outPtr->data[outDataIndex]));
				
				outDataIndex += chunkSize;
				inDataIndex += chunkSize;
				inputSize -= chunkSize;

				if (inDataIndex == inPtr->dataSize)
				{
					inPtr = inPtr->next;
					inDataIndex = 0;
				}

				if (outDataIndex == outPtr->allocatedSize)
				{
					outPtr->dataSize = outPtr->allocatedSize;
					outPtr = outPtr->next;
					outDataIndex = 0;
				}
			}
			else
			{
				if ((inPtr->dataSize - inDataIndex) < blockSize)
				{
					inSlopPtr = inSlopBlock;
					
					while ((inputSize >= (blockSize - inSlopIndex) ) && 
							(inSlopIndex < blockSize) && IsntNull(inPtr))
					{
						total = inPtr->dataSize - inDataIndex;
						if (total > (blockSize - inSlopIndex))
							total = blockSize - inSlopIndex;
						
						pgpCopyMemory(&(inPtr->data[inDataIndex]),
							&(inSlopBlock[inSlopIndex]), total);
						
						inSlopIndex += total;
						inDataIndex += total;
						inputSize -= total;
						
						if (inDataIndex == inPtr->dataSize)
						{
							inPtr = inPtr->next;
							inDataIndex = 0;
						}
					}
				}
				else
				{
					inSlopPtr = &(inPtr->data[inDataIndex]);
					inSlopIndex = blockSize;
					inDataIndex += blockSize;
					inputSize -= blockSize;
				}
				
				if ((outPtr->allocatedSize - outDataIndex) < blockSize)
				{
					err = PGPExpandIPsecBuffer(memoryMgr, outPtr, 
							maxBufferSize, blockSize + outDataIndex);
					
					if ((outPtr->allocatedSize - outDataIndex) < blockSize)
						outSlopPtr = outSlopBlock;
					else
						outSlopPtr = &(outPtr->data[outDataIndex]);
				}
				else
					outSlopPtr = &(outPtr->data[outDataIndex]);
				
				if (IsntPGPError(err) && (inSlopIndex == blockSize))
				{
					inSlopIndex = 0;
					err = PGPCBCEncrypt(cbcRef, inSlopPtr, blockSize, 
							outSlopPtr);
					
					if (IsntPGPError(err) && (outSlopPtr == outSlopBlock))
					{
						outSlopIndex = outPtr->allocatedSize - outDataIndex;
						
						pgpCopyMemory(outSlopBlock, 
							&(outPtr->data[outDataIndex]), outSlopIndex);
						
						outPtr->dataSize = outPtr->allocatedSize;
						outPtr = outPtr->next;
						
						pgpCopyMemory(&(outSlopBlock[outSlopIndex]),
							outPtr->data, blockSize - outSlopIndex);
						
						outDataIndex = blockSize - outSlopIndex;
					}
					else
						outDataIndex += blockSize;
				}
			}
		}
		
		if (IsntPGPError(err))
		{
			if (inputSize)
			{
				if ((inPtr->dataSize - inDataIndex) < inputSize)
				{
					pgpCopyMemory(&(inPtr->data[inDataIndex]),
						&(inSlopBlock[inSlopIndex]), 
						inPtr->dataSize - inDataIndex);

					inSlopIndex += inPtr->dataSize - inDataIndex;
					inputSize -= inPtr->dataSize - inDataIndex;
					inPtr = inPtr->next;

					pgpCopyMemory(inPtr->data, &(inSlopBlock[inSlopIndex]), 
						inputSize);
				}
				else
					pgpCopyMemory(&(inPtr->data[inDataIndex]),
						&(inSlopBlock[inSlopIndex]), inputSize);
				
				inSlopIndex += inputSize;
			}
			
			if ((outPtr->allocatedSize - outDataIndex) < blockSize)
			{
				err = PGPExpandIPsecBuffer(memoryMgr, outPtr, 
						maxBufferSize, blockSize + outDataIndex);
					
				if ((outPtr->allocatedSize - outDataIndex) < blockSize)
					outSlopPtr = outSlopBlock;
				else
					outSlopPtr = &(outPtr->data[outDataIndex]);
			}
			else
				outSlopPtr = &(outPtr->data[outDataIndex]);
				
			if (inSlopIndex < 7)
			{
				padLength = blockSize - inSlopIndex - 2;
				
				if (padLength)
					for (index=0; index<padLength; index++)
						inSlopBlock[index+inSlopIndex] = index + 1;
					
					inSlopBlock[inSlopIndex + padLength] = padLength;
					inSlopBlock[inSlopIndex + padLength + 1] = nextHeader;
					
					err = PGPCBCEncrypt(cbcRef, inSlopBlock, blockSize, 
							outSlopPtr);
					
					if (IsntPGPError(err) && (outSlopPtr == outSlopBlock))
					{
						outSlopIndex = outPtr->allocatedSize - outDataIndex;
						
						pgpCopyMemory(outSlopBlock, 
							&(outPtr->data[outDataIndex]), outSlopIndex);
						
						outPtr->dataSize = outPtr->allocatedSize;
						outPtr = outPtr->next;
						
						pgpCopyMemory(&(outSlopBlock[outSlopIndex]),
							outPtr->data, blockSize - outSlopIndex);
						
						outDataIndex = blockSize - outSlopIndex;
					}
					else
						outDataIndex += blockSize;
			}
			else
			{
				inSlopBlock[7] = 1;
				err = PGPCBCEncrypt(cbcRef, inSlopBlock, blockSize, 
						outSlopPtr);
				
				if (IsntPGPError(err) && (outSlopPtr == outSlopBlock))
				{
					outSlopIndex = outPtr->allocatedSize - outDataIndex;
					
					pgpCopyMemory(outSlopBlock, 
						&(outPtr->data[outDataIndex]), outSlopIndex);
					
					outPtr->dataSize = outPtr->allocatedSize;
					outPtr = outPtr->next;
					
					pgpCopyMemory(&(outSlopBlock[outSlopIndex]),
						outPtr->data, blockSize - outSlopIndex);
					
					outDataIndex = blockSize - outSlopIndex;
				}
				else
					outDataIndex += blockSize;
				
				if ((outPtr->allocatedSize - outDataIndex) < blockSize)
				{
					err = PGPExpandIPsecBuffer(memoryMgr, outPtr, 
							maxBufferSize, blockSize + outDataIndex);
					
					if ((outPtr->allocatedSize - outDataIndex) < blockSize)
						outSlopPtr = outSlopBlock;
					else
						outSlopPtr = &(outPtr->data[outDataIndex]);
				}
				else
					outSlopPtr = &(outPtr->data[outDataIndex]);
				
				if (IsntPGPError(err))
				{
					for (index=0; index<6; index++)
						inSlopBlock[index] = index + 2;
					
					padLength = 7;
					inSlopBlock[6] = padLength;
					inSlopBlock[7] = nextHeader;
					
					err = PGPCBCEncrypt(cbcRef, inSlopBlock, blockSize, 
							outSlopPtr);
				}
				
				if (IsntPGPError(err) && (outSlopPtr == outSlopBlock))
				{
					outSlopIndex = outPtr->allocatedSize - outDataIndex;
					
					pgpCopyMemory(outSlopBlock, 
						&(outPtr->data[outDataIndex]), outSlopIndex);
					
					outPtr->dataSize = outPtr->allocatedSize;
					outPtr = outPtr->next;
					
					pgpCopyMemory(&(outSlopBlock[outSlopIndex]),
						outPtr->data, blockSize - outSlopIndex);
					
					outDataIndex = blockSize - outSlopIndex;
				}
				else
					outDataIndex += blockSize;
			}
		}

		if (IsntPGPError(err))
		{
			packetSize += padLength + 2 + ESP_HEADERSIZE + blockSize;
			outPtr->dataSize = outDataIndex;
		}
	}
	else
	{
		if (tunnelMode)
			PGPCopyIPsecBuffer(memoryMgr, ipPacketIn, 0, ipPacketOut, 
				espIndex + ESP_HEADERSIZE + blockSize, packetSize - espIndex,
				maxBufferSize);
		else
			PGPCopyIPsecBuffer(memoryMgr, ipPacketIn, espIndex, ipPacketOut, 
				espIndex + ESP_HEADERSIZE + blockSize, packetSize - espIndex,
				maxBufferSize);
		
		padStart = espIndex + ESPHDR_DATA + blockSize + encryptSize;

		if (blockSize > 0)
		{
			padLength = blockSize - ((encryptSize + 2) % blockSize);
			if (padLength == 8)
				padLength = 0;
		}
		else
		{
			padLength = 4 - ((encryptSize + 2) % 4);
			if (padLength == 4)
				padLength = 0;
		}
		
		if (padLength)
		{
			for (index=0; index<padLength; index++)
				padding[index] = index + 1;
		}
		
		padding[padLength] = padLength;
		padding[padLength + 1] = nextHeader;

		tempBuffer.data = padding;
		tempBuffer.dataSize = padLength + 2;
		tempBuffer.allocatedSize = padLength + 2;
		tempBuffer.next = NULL;

		PGPCopyIPsecBuffer(memoryMgr, &tempBuffer, 0, ipPacketOut, padStart, 
			padLength + 2, maxBufferSize);

		packetSize += padLength + 2 + ESP_HEADERSIZE + blockSize;
	}

	if (IsntPGPError(err))
	{
		tempBuffer.data = headerData;
		tempBuffer.dataSize = ESP_HEADERSIZE + blockSize;
		tempBuffer.allocatedSize = ESP_HEADERSIZE + blockSize;
		tempBuffer.next = NULL;

		PGPUInt32ToEndian(spi, kPGPNetworkByteOrder, 
			&(headerData[ESPHDR_SPI]));
		PGPUInt32ToEndian(sequenceNumber, kPGPNetworkByteOrder, 
			&(headerData[ESPHDR_SEQNUMBER]));

		if (IsntNull(iv))
		{
			pgpCopyMemory(iv, &(headerData[ESPHDR_DATA]), blockSize);

			if (IsntNull(outSlopPtr))
				pgpCopyMemory(outSlopPtr, iv, blockSize);
		}
		else
			pgpCopyMemory(nullIV, &(headerData[ESPHDR_DATA]), blockSize);
			
		PGPCopyIPsecBuffer(memoryMgr, &tempBuffer, 0, ipPacketOut, espIndex, 
			ESP_HEADERSIZE + blockSize, ESP_HEADERSIZE + blockSize);

		err = pgpAddProtocolToIPHeader(ipPacketIn, ESP_PROTOCOL, 
				ipPacketOut);

		if (tunnelMode)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -