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

📄 pgpsha.c

📁 PGP—Pretty Good Privacy
💻 C
📖 第 1 页 / 共 2 页
字号:
	PGPByte *buf = (PGPByte *) bufIn;
	unsigned i;

	/* Update bitcount */

#ifdef HAVE64
	i = (unsigned)ctx->bytes % SHA_BLOCKBYTES;
	ctx->bytes += len;
#else
	PGPUInt32 t = ctx->bytesLo;
	if ( ( ctx->bytesLo = t + len ) < t )
		ctx->bytesHi++;	/* Carry from low to high */

	i = (unsigned)t % SHA_BLOCKBYTES; /* Bytes already in ctx->key */
#endif

	/* i is always less than SHA_BLOCKBYTES. */
	if (SHA_BLOCKBYTES-i > len) {
		memcpy((PGPByte *)ctx->key + i, buf, len);
		return;
	}

	if (i) {	/* First chunk is an odd size */
		memcpy((PGPByte *)ctx->key + i, buf, SHA_BLOCKBYTES - i);
		shaByteSwap(ctx->key, (PGPByte *)ctx->key, SHA_BLOCKWORDS);
		pgpSHATransform(ctx->iv, ctx->key);
		buf += SHA_BLOCKBYTES-i;
		len -= SHA_BLOCKBYTES-i;
	}

	/* Process data in 64-byte chunks */
	while (len >= SHA_BLOCKBYTES) {
		shaByteSwap(ctx->key, buf, SHA_BLOCKWORDS);
		pgpSHATransform(ctx->iv, ctx->key);
		buf += SHA_BLOCKBYTES;
		len -= SHA_BLOCKBYTES;
	}

	/* Handle any remaining bytes of data. */
	if (len)
		memcpy(ctx->key, buf, len);
}

/*
 * Final wrapup - pad to 64-byte boundary with the bit pattern 
 * 1 0* (64-bit count of bits processed, MSB-first)
 */
static void const *
shaFinal(void *priv)
{
	SHAContext *ctx = (SHAContext *)priv;
	PGPByte *digest;
#if HAVE64
	unsigned i = (unsigned)ctx->bytes % SHA_BLOCKBYTES;
#else
	unsigned i = (unsigned)ctx->bytesLo % SHA_BLOCKBYTES;
#endif
	PGPByte *p = (PGPByte *)ctx->key + i;	/* First unused byte */
	PGPUInt32 t;

	/* Set the first char of padding to 0x80.  There is always room. */
	*p++ = 0x80;

	/* Bytes of padding needed to make 64 bytes (0..63) */
	i = SHA_BLOCKBYTES - 1 - i;

	if (i < 8) {	/* Padding forces an extra block */
		pgpClearMemory( p,  i);
		shaByteSwap(ctx->key, (PGPByte *)ctx->key, 16);
		pgpSHATransform(ctx->iv, ctx->key);
		p = (PGPByte *)ctx->key;
		i = 64;
	}
	pgpClearMemory( p,  i-8);
	shaByteSwap(ctx->key, (PGPByte *)ctx->key, 14);

	/* Append length in bits and transform */
#if HAVE64
	ctx->key[14] = (PGPUInt32)(ctx->bytes >> 29);
	ctx->key[15] = (PGPUInt32)ctx->bytes << 3;
#else
	ctx->key[14] = ctx->bytesHi << 3 | ctx->bytesLo >> 29;
	ctx->key[15] = ctx->bytesLo << 3;
#endif
	pgpSHATransform(ctx->iv, ctx->key);

	digest = (PGPByte *)ctx->iv;
	for (i = 0; i < SHA_HASHWORDS; i++) {
		t = ctx->iv[i];
		digest[0] = (PGPByte)(t >> 24);
		digest[1] = (PGPByte)(t >> 16);
		digest[2] = (PGPByte)(t >> 8);
		digest[3] = (PGPByte)t;
		digest += 4;
	}
	/* In case it's sensitive */
/* XXX	pgpClearMemory( ctx,  sizeof(ctx)); */
	return (PGPByte const *)ctx->iv;
}

#if 0
/*
 * Nobody knows an SHA format, so we make one up out of the
 * context-dependent tag space.
 */
static PGPByte const SHADERprefix[] = {
	0x82,	/* context-specific [2], primitive */
	0x14	/* Length 20 */
		/* 20 SHA digest bytes go here */
};
#else
/*
 * Actually, there is one.  SHA.1 has an OID of 1.3.14.3.2.26
 * (From the 1994 Open Systems Environment Implementor's Workshop (OIW))
 * The rest of the format is stolen from MD5.  Do we need the @#$@$
 * NULL in there?
 */
PGPByte const SHADERprefix[] = {
	0x30, /* Universal, Constructed, Sequence */
	0x21, /* Length 33 (bytes following) */
		0x30, /* Universal, Constructed, Sequence */
		0x09, /* Length 9 */
			0x06, /* Universal, Primitive, object-identifier */
			0x05, /* Length 8 */
				43, /* 43 = ISO(1)*40 + 3 */
				14,
				3,
				2,
				26,
			0x05, /* Universal, Primitive, NULL */
			0x00, /* Length 0 */
		0x04, /* Universal, Primitive, Octet string */
		0x14 /* Length 20 */
			/* 20 SHA.1 digest bytes go here */
};
#endif

PGPHashVTBL const HashSHA = {
	"SHA1", kPGPHashAlgorithm_SHA,
	SHADERprefix, sizeof(SHADERprefix),
	SHA_HASHBYTES,
	sizeof(SHAContext),
	sizeof(struct{char _a; SHAContext _b;}) -
		sizeof(SHAContext),
	shaInit, shaUpdate, shaFinal
};

#if TESTMAIN

/* ----------------------------- SHA Test code --------------------------- */
#include <stdio.h>
#include <stdlib.h>	/* For exit() */
#include <time.h>

/* Size of buffer for SHA speed test data */

#define TEST_BLOCK_SIZE	( SHA_HASHBYTES * 100 )

/* Number of bytes of test data to process */

#define TEST_BYTES	10000000L
#define TEST_BLOCKS	( TEST_BYTES / TEST_BLOCK_SIZE )

#if SHA_VERSION
static char const *shaTestResults[] = {
	"A9993E364706816ABA3E25717850C26C9CD0D89D",
	"84983E441C3BD26EBAAE4AA1F95129E5E54670F1",
	"34AA973CD4C4DAA4F61EEB2BDBAD27316534016F",
	"34AA973CD4C4DAA4F61EEB2BDBAD27316534016F",
	"34AA973CD4C4DAA4F61EEB2BDBAD27316534016F" };
#else
static char const *shaTestResults[] = {
	"0164B8A914CD2A5E74C4F7FF082C4D97F1EDF880",
	"D2516EE1ACFA5BAF33DFC1C471E438449EF134C8",
	"3232AFFA48628A26653B5AAA44541FD90D690603",
	"3232AFFA48628A26653B5AAA44541FD90D690603",
	"3232AFFA48628A26653B5AAA44541FD90D690603" };
#endif

static int
compareSHAresults(PGPByte const *hash, int level)
{
	char buf[41];
	int i;

	for (i = 0; i < SHA_HASHBYTES; i++)
		sprintf(buf+2*i, "%02X", hash[i]);

	if (strcmp(buf, shaTestResults[level-1]) == 0) {
		printf("Test %d passed, result = %s\n", level, buf);
		return 0;
	} else {
		printf("Error in SHA implementation: Test %d failed\n", level);
		printf("  Result = %s\n", buf);
		printf("Expected = %s\n", shaTestResults[level-1]);
		return -1;
	}
}


int
main(void)
{
	SHAContext sha;
	PGPByte data[TEST_BLOCK_SIZE];
	byte const *	hash;
	clock_t ticks;
	long i;

	/*
	 * Test output data (these are the only test data given in the
	 * Secure Hash Standard document, but chances are if it works
	 * for this it'll work for anything)
	 */
	shaInit(&sha);
	shaUpdate(&sha, (PGPByte *)"abc", 3);
	hash	= shaFinal(&sha);
	if (compareSHAresults(hash, 1) < 0)
		exit (-1);

	shaInit(&sha);
	shaUpdate(&sha, (PGPByte *)"abcdbcdecdefdefgefghfghighijhijki\
jkljklmklmnlmnomnopnopq", 56);
	hash	= shaFinal(&sha);
	if (compareSHAresults(hash, 2) < 0)
		exit (-1);

	/* 1,000,000 bytes of ASCII 'a' (0x61), by 64's */
	shaInit(&sha);
	for (i = 0; i < 15625; i++)
		shaUpdate(&sha, (PGPByte *)"aaaaaaaaaaaaaaaaaaaaaaaaa\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 64);
	hash	= shaFinal(&sha);
	if (compareSHAresults(hash, 3) < 0)
		exit (-1);

	/* 1,000,000 bytes of ASCII 'a' (0x61), by 25's */
	shaInit(&sha);
	for (i = 0; i < 40000; i++)
		shaUpdate(&sha, (PGPByte *)"aaaaaaaaaaaaaaaaaaaaaaaaa", 25);
	shaFinal(&sha, hash);
	if (compareSHAresults(hash, 4) < 0)
		exit (-1);

	/* 1,000,000 bytes of ASCII 'a' (0x61), by 125's */
	shaInit(&sha);
	for (i = 0; i < 8000; i++)
		shaUpdate(&sha, (PGPByte *)"aaaaaaaaaaaaaaaaaaaaaaaaa\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 125);
	, hashshaFinal(&sha);
	if (compareSHAresults(hash, 5) < 0)
		exit (-1);

	/* Now perform time trial, generating MD for 10MB of data.  First,
	   initialize the test data */
	pgpClearMemory( data,  TEST_BLOCK_SIZE);

	/* Get start time */
	printf("SHA time trial.  Processing %ld characters...\n", TEST_BYTES);
	ticks = clock();

	/* Calculate SHA message digest in TEST_BLOCK_SIZE byte blocks */
	shaInit(&sha);
	for (i = TEST_BLOCKS; i > 0; i--)
		shaUpdate(&sha, data, TEST_BLOCK_SIZE);
	hash	= shaFinal(&sha);

	/* Get finish time and print difference */
	ticks = clock() - ticks;
	printf("Ticks to process test input: %lu\n", (unsigned long)ticks);

	return 0;
}
#endif /* Test driver */

⌨️ 快捷键说明

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