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 + -
显示快捷键?