sha2.c

来自「非常好的dns解析软件」· C语言 代码 · 共 1,235 行 · 第 1/3 页

C
1,235
字号
/* Unrolled SHA-512 round macros: */#if BYTE_ORDER == LITTLE_ENDIAN#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h)	\	REVERSE64(*data++, W512[j]); \	T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \             K512[j] + W512[j]; \	(d) += T1, \	(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \	j++#else /* BYTE_ORDER == LITTLE_ENDIAN */#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h)	\	T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \             K512[j] + (W512[j] = *data++); \	(d) += T1; \	(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \	j++#endif /* BYTE_ORDER == LITTLE_ENDIAN */#define ROUND512(a,b,c,d,e,f,g,h)	\	s0 = W512[(j+1)&0x0f]; \	s0 = sigma0_512(s0); \	s1 = W512[(j+14)&0x0f]; \	s1 = sigma1_512(s1); \	T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \             (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \	(d) += T1; \	(h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \	j++void isc_sha512_transform(isc_sha512_t *context, const isc_uint64_t* data) {	isc_uint64_t	a, b, c, d, e, f, g, h, s0, s1;	isc_uint64_t	T1, *W512 = (isc_uint64_t*)context->buffer;	int		j;	/* Initialize registers with the prev. intermediate value */	a = context->state[0];	b = context->state[1];	c = context->state[2];	d = context->state[3];	e = context->state[4];	f = context->state[5];	g = context->state[6];	h = context->state[7];	j = 0;	do {		ROUND512_0_TO_15(a,b,c,d,e,f,g,h);		ROUND512_0_TO_15(h,a,b,c,d,e,f,g);		ROUND512_0_TO_15(g,h,a,b,c,d,e,f);		ROUND512_0_TO_15(f,g,h,a,b,c,d,e);		ROUND512_0_TO_15(e,f,g,h,a,b,c,d);		ROUND512_0_TO_15(d,e,f,g,h,a,b,c);		ROUND512_0_TO_15(c,d,e,f,g,h,a,b);		ROUND512_0_TO_15(b,c,d,e,f,g,h,a);	} while (j < 16);	/* Now for the remaining rounds up to 79: */	do {		ROUND512(a,b,c,d,e,f,g,h);		ROUND512(h,a,b,c,d,e,f,g);		ROUND512(g,h,a,b,c,d,e,f);		ROUND512(f,g,h,a,b,c,d,e);		ROUND512(e,f,g,h,a,b,c,d);		ROUND512(d,e,f,g,h,a,b,c);		ROUND512(c,d,e,f,g,h,a,b);		ROUND512(b,c,d,e,f,g,h,a);	} while (j < 80);	/* Compute the current intermediate hash value */	context->state[0] += a;	context->state[1] += b;	context->state[2] += c;	context->state[3] += d;	context->state[4] += e;	context->state[5] += f;	context->state[6] += g;	context->state[7] += h;	/* Clean up */	a = b = c = d = e = f = g = h = T1 = 0;}#else /* ISC_SHA2_UNROLL_TRANSFORM */voidisc_sha512_transform(isc_sha512_t *context, const isc_uint64_t* data) {	isc_uint64_t	a, b, c, d, e, f, g, h, s0, s1;	isc_uint64_t	T1, T2, *W512 = (isc_uint64_t*)context->buffer;	int		j;	/* Initialize registers with the prev. intermediate value */	a = context->state[0];	b = context->state[1];	c = context->state[2];	d = context->state[3];	e = context->state[4];	f = context->state[5];	g = context->state[6];	h = context->state[7];	j = 0;	do {#if BYTE_ORDER == LITTLE_ENDIAN		/* Convert TO host byte order */		REVERSE64(*data++, W512[j]);		/* Apply the SHA-512 compression function to update a..h */		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j];#else /* BYTE_ORDER == LITTLE_ENDIAN */		/* Apply the SHA-512 compression function to update a..h with copy */		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++);#endif /* BYTE_ORDER == LITTLE_ENDIAN */		T2 = Sigma0_512(a) + Maj(a, b, c);		h = g;		g = f;		f = e;		e = d + T1;		d = c;		c = b;		b = a;		a = T1 + T2;		j++;	} while (j < 16);	do {		/* Part of the message block expansion: */		s0 = W512[(j+1)&0x0f];		s0 = sigma0_512(s0);		s1 = W512[(j+14)&0x0f];		s1 =  sigma1_512(s1);		/* Apply the SHA-512 compression function to update a..h */		T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] +		     (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0);		T2 = Sigma0_512(a) + Maj(a, b, c);		h = g;		g = f;		f = e;		e = d + T1;		d = c;		c = b;		b = a;		a = T1 + T2;		j++;	} while (j < 80);	/* Compute the current intermediate hash value */	context->state[0] += a;	context->state[1] += b;	context->state[2] += c;	context->state[3] += d;	context->state[4] += e;	context->state[5] += f;	context->state[6] += g;	context->state[7] += h;	/* Clean up */	a = b = c = d = e = f = g = h = T1 = T2 = 0;}#endif /* ISC_SHA2_UNROLL_TRANSFORM */void isc_sha512_update(isc_sha512_t *context, const isc_uint8_t *data, size_t len) {	unsigned int	freespace, usedspace;	if (len == 0U) {		/* Calling with no data is valid - we do nothing */		return;	}	/* Sanity check: */	REQUIRE(context != (isc_sha512_t *)0 && data != (isc_uint8_t*)0);	usedspace = (unsigned int)((context->bitcount[0] >> 3) %				   ISC_SHA512_BLOCK_LENGTH);	if (usedspace > 0) {		/* Calculate how much free space is available in the buffer */		freespace = ISC_SHA512_BLOCK_LENGTH - usedspace;		if (len >= freespace) {			/* Fill the buffer completely and process it */			memcpy(&context->buffer[usedspace], data, freespace);			ADDINC128(context->bitcount, freespace << 3);			len -= freespace;			data += freespace;			isc_sha512_transform(context,					     (isc_uint64_t*)context->buffer);		} else {			/* The buffer is not yet full */			memcpy(&context->buffer[usedspace], data, len);			ADDINC128(context->bitcount, len << 3);			/* Clean up: */			usedspace = freespace = 0;			return;		}	}	while (len >= ISC_SHA512_BLOCK_LENGTH) {		/* Process as many complete blocks as we can */		memcpy(context->buffer, data, ISC_SHA512_BLOCK_LENGTH);		isc_sha512_transform(context, (isc_uint64_t*)context->buffer);		ADDINC128(context->bitcount, ISC_SHA512_BLOCK_LENGTH << 3);		len -= ISC_SHA512_BLOCK_LENGTH;		data += ISC_SHA512_BLOCK_LENGTH;	}	if (len > 0U) {		/* There's left-overs, so save 'em */		memcpy(context->buffer, data, len);		ADDINC128(context->bitcount, len << 3);	}	/* Clean up: */	usedspace = freespace = 0;}void isc_sha512_last(isc_sha512_t *context) {	unsigned int	usedspace;	usedspace = (unsigned int)((context->bitcount[0] >> 3) %				    ISC_SHA512_BLOCK_LENGTH);#if BYTE_ORDER == LITTLE_ENDIAN	/* Convert FROM host byte order */	REVERSE64(context->bitcount[0],context->bitcount[0]);	REVERSE64(context->bitcount[1],context->bitcount[1]);#endif	if (usedspace > 0) {		/* Begin padding with a 1 bit: */		context->buffer[usedspace++] = 0x80;		if (usedspace <= ISC_SHA512_SHORT_BLOCK_LENGTH) {			/* Set-up for the last transform: */			memset(&context->buffer[usedspace], 0,			       ISC_SHA512_SHORT_BLOCK_LENGTH - usedspace);		} else {			if (usedspace < ISC_SHA512_BLOCK_LENGTH) {				memset(&context->buffer[usedspace], 0,				       ISC_SHA512_BLOCK_LENGTH - usedspace);			}			/* Do second-to-last transform: */			isc_sha512_transform(context,					    (isc_uint64_t*)context->buffer);			/* And set-up for the last transform: */			memset(context->buffer, 0, ISC_SHA512_BLOCK_LENGTH - 2);		}	} else {		/* Prepare for final transform: */		memset(context->buffer, 0, ISC_SHA512_SHORT_BLOCK_LENGTH);		/* Begin padding with a 1 bit: */		*context->buffer = 0x80;	}	/* Store the length of input data (in bits): */	*(isc_uint64_t*)&context->buffer[ISC_SHA512_SHORT_BLOCK_LENGTH] = context->bitcount[1];	*(isc_uint64_t*)&context->buffer[ISC_SHA512_SHORT_BLOCK_LENGTH+8] = context->bitcount[0];	/* Final transform: */	isc_sha512_transform(context, (isc_uint64_t*)context->buffer);}void isc_sha512_final(isc_uint8_t digest[], isc_sha512_t *context) {	isc_uint64_t	*d = (isc_uint64_t*)digest;	/* Sanity check: */	REQUIRE(context != (isc_sha512_t *)0);	/* If no digest buffer is passed, we don't bother doing this: */	if (digest != (isc_uint8_t*)0) {		isc_sha512_last(context);		/* Save the hash data for output: */#if BYTE_ORDER == LITTLE_ENDIAN		{			/* Convert TO host byte order */			int	j;			for (j = 0; j < 8; j++) {				REVERSE64(context->state[j],context->state[j]);				*d++ = context->state[j];			}		}#else		memcpy(d, context->state, ISC_SHA512_DIGESTLENGTH);#endif	}	/* Zero out state data */	memset(context, 0, sizeof(context));}char *isc_sha512_end(isc_sha512_t *context, char buffer[]) {	isc_uint8_t	digest[ISC_SHA512_DIGESTLENGTH], *d = digest;	unsigned int	i;	/* Sanity check: */	REQUIRE(context != (isc_sha512_t *)0);	if (buffer != (char*)0) {		isc_sha512_final(digest, context);		for (i = 0; i < ISC_SHA512_DIGESTLENGTH; i++) {			*buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];			*buffer++ = sha2_hex_digits[*d & 0x0f];			d++;		}		*buffer = (char)0;	} else {		memset(context, 0, sizeof(context));	}	memset(digest, 0, ISC_SHA512_DIGESTLENGTH);	return buffer;}char *isc_sha512_data(const isc_uint8_t *data, size_t len,		char digest[ISC_SHA512_DIGESTSTRINGLENGTH]){	isc_sha512_t 	context;	isc_sha512_init(&context);	isc_sha512_update(&context, data, len);	return (isc_sha512_end(&context, digest));}/*** SHA-384: *********************************************************/voidisc_sha384_init(isc_sha384_t *context) {	if (context == (isc_sha384_t *)0) {		return;	}	memcpy(context->state, sha384_initial_hash_value,	       ISC_SHA512_DIGESTLENGTH);	memset(context->buffer, 0, ISC_SHA384_BLOCK_LENGTH);	context->bitcount[0] = context->bitcount[1] = 0;}void isc_sha384_update(isc_sha384_t *context, const isc_uint8_t* data, size_t len) {	isc_sha512_update((isc_sha512_t *)context, data, len);}void isc_sha384_final(isc_uint8_t digest[], isc_sha384_t *context) {	isc_uint64_t	*d = (isc_uint64_t*)digest;	/* Sanity check: */	REQUIRE(context != (isc_sha384_t *)0);	/* If no digest buffer is passed, we don't bother doing this: */	if (digest != (isc_uint8_t*)0) {		isc_sha512_last((isc_sha512_t *)context);		/* Save the hash data for output: */#if BYTE_ORDER == LITTLE_ENDIAN		{			/* Convert TO host byte order */			int	j;			for (j = 0; j < 6; j++) {				REVERSE64(context->state[j],context->state[j]);				*d++ = context->state[j];			}		}#else		memcpy(d, context->state, ISC_SHA384_DIGESTLENGTH);#endif	}	/* Zero out state data */	memset(context, 0, sizeof(context));}char *isc_sha384_end(isc_sha384_t *context, char buffer[]) {	isc_uint8_t	digest[ISC_SHA384_DIGESTLENGTH], *d = digest;	unsigned int	i;	/* Sanity check: */	REQUIRE(context != (isc_sha384_t *)0);	if (buffer != (char*)0) {		isc_sha384_final(digest, context);		for (i = 0; i < ISC_SHA384_DIGESTLENGTH; i++) {			*buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4];			*buffer++ = sha2_hex_digits[*d & 0x0f];			d++;		}		*buffer = (char)0;	} else {		memset(context, 0, sizeof(context));	}	memset(digest, 0, ISC_SHA384_DIGESTLENGTH);	return buffer;}char*isc_sha384_data(const isc_uint8_t *data, size_t len,	        char digest[ISC_SHA384_DIGESTSTRINGLENGTH]){	isc_sha384_t context;	isc_sha384_init(&context);	isc_sha384_update(&context, data, len);	return (isc_sha384_end(&context, digest));}

⌨️ 快捷键说明

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