Changeset View
Changeset View
Standalone View
Standalone View
contrib/ldns/sha2.c
Show First 20 Lines • Show All 67 Lines • ▼ Show 20 Lines | |||||
/*** SHA-256/384/512 Machine Architecture Definitions *****************/ | /*** SHA-256/384/512 Machine Architecture Definitions *****************/ | ||||
/* | /* | ||||
* BYTE_ORDER NOTE: | * BYTE_ORDER NOTE: | ||||
* | * | ||||
* Please make sure that your system defines BYTE_ORDER. If your | * Please make sure that your system defines BYTE_ORDER. If your | ||||
* architecture is little-endian, make sure it also defines | * architecture is little-endian, make sure it also defines | ||||
* LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are | * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are | ||||
* equivilent. | * equivalent. | ||||
* | * | ||||
* If your system does not define the above, then you can do so by | * If your system does not define the above, then you can do so by | ||||
* hand like this: | * hand like this: | ||||
* | * | ||||
* #define LITTLE_ENDIAN 1234 | * #define LITTLE_ENDIAN 1234 | ||||
* #define BIG_ENDIAN 4321 | * #define BIG_ENDIAN 4321 | ||||
* | * | ||||
* And for little-endian machines, add: | * And for little-endian machines, add: | ||||
▲ Show 20 Lines • Show All 404 Lines • ▼ Show 20 Lines | #endif /* BYTE_ORDER == LITTLE_ENDIAN */ | ||||
context->state[3] += d; | context->state[3] += d; | ||||
context->state[4] += e; | context->state[4] += e; | ||||
context->state[5] += f; | context->state[5] += f; | ||||
context->state[6] += g; | context->state[6] += g; | ||||
context->state[7] += h; | context->state[7] += h; | ||||
/* Clean up */ | /* Clean up */ | ||||
a = b = c = d = e = f = g = h = T1 = T2 = 0; | a = b = c = d = e = f = g = h = T1 = T2 = 0; | ||||
(void)a; | |||||
} | } | ||||
#endif /* SHA2_UNROLL_TRANSFORM */ | #endif /* SHA2_UNROLL_TRANSFORM */ | ||||
void ldns_sha256_update(ldns_sha256_CTX* context, const sha2_byte *data, size_t len) { | void ldns_sha256_update(ldns_sha256_CTX* context, const sha2_byte *data, size_t len) { | ||||
size_t freespace, usedspace; | size_t freespace, usedspace; | ||||
if (len == 0) { | if (len == 0) { | ||||
Show All 17 Lines | if (len >= freespace) { | ||||
data += freespace; | data += freespace; | ||||
ldns_sha256_Transform(context, (sha2_word32*)context->buffer); | ldns_sha256_Transform(context, (sha2_word32*)context->buffer); | ||||
} else { | } else { | ||||
/* The buffer is not yet full */ | /* The buffer is not yet full */ | ||||
MEMCPY_BCOPY(&context->buffer[usedspace], data, len); | MEMCPY_BCOPY(&context->buffer[usedspace], data, len); | ||||
context->bitcount += len << 3; | context->bitcount += len << 3; | ||||
/* Clean up: */ | /* Clean up: */ | ||||
usedspace = freespace = 0; | usedspace = freespace = 0; | ||||
(void)usedspace; | |||||
return; | return; | ||||
} | } | ||||
} | } | ||||
while (len >= LDNS_SHA256_BLOCK_LENGTH) { | while (len >= LDNS_SHA256_BLOCK_LENGTH) { | ||||
/* Process as many complete blocks as we can */ | /* Process as many complete blocks as we can */ | ||||
ldns_sha256_Transform(context, (sha2_word32*)data); | ldns_sha256_Transform(context, (sha2_word32*)data); | ||||
context->bitcount += LDNS_SHA256_BLOCK_LENGTH << 3; | context->bitcount += LDNS_SHA256_BLOCK_LENGTH << 3; | ||||
len -= LDNS_SHA256_BLOCK_LENGTH; | len -= LDNS_SHA256_BLOCK_LENGTH; | ||||
data += LDNS_SHA256_BLOCK_LENGTH; | data += LDNS_SHA256_BLOCK_LENGTH; | ||||
} | } | ||||
if (len > 0) { | if (len > 0) { | ||||
/* There's left-overs, so save 'em */ | /* There's left-overs, so save 'em */ | ||||
MEMCPY_BCOPY(context->buffer, data, len); | MEMCPY_BCOPY(context->buffer, data, len); | ||||
context->bitcount += len << 3; | context->bitcount += len << 3; | ||||
} | } | ||||
/* Clean up: */ | /* Clean up: */ | ||||
usedspace = freespace = 0; | usedspace = freespace = 0; | ||||
(void)usedspace; | |||||
} | } | ||||
typedef union _ldns_sha2_buffer_union { | typedef union _ldns_sha2_buffer_union { | ||||
uint8_t* theChars; | uint8_t* theChars; | ||||
uint64_t* theLongs; | uint64_t* theLongs; | ||||
} ldns_sha2_buffer_union; | } ldns_sha2_buffer_union; | ||||
void ldns_sha256_final(sha2_byte digest[], ldns_sha256_CTX* context) { | void ldns_sha256_final(sha2_byte digest[LDNS_SHA256_DIGEST_LENGTH], ldns_sha256_CTX* context) { | ||||
sha2_word32 *d = (sha2_word32*)digest; | sha2_word32 *d = (sha2_word32*)digest; | ||||
size_t usedspace; | size_t usedspace; | ||||
ldns_sha2_buffer_union cast_var; | ldns_sha2_buffer_union cast_var; | ||||
/* Sanity check: */ | /* Sanity check: */ | ||||
assert(context != (ldns_sha256_CTX*)0); | assert(context != (ldns_sha256_CTX*)0); | ||||
/* If no digest buffer is passed, we don't bother doing this: */ | /* If no digest buffer is passed, we don't bother doing this: */ | ||||
▲ Show 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | |||||
#else | #else | ||||
MEMCPY_BCOPY(d, context->state, LDNS_SHA256_DIGEST_LENGTH); | MEMCPY_BCOPY(d, context->state, LDNS_SHA256_DIGEST_LENGTH); | ||||
#endif | #endif | ||||
} | } | ||||
/* Clean up state data: */ | /* Clean up state data: */ | ||||
MEMSET_BZERO(context, sizeof(ldns_sha256_CTX)); | MEMSET_BZERO(context, sizeof(ldns_sha256_CTX)); | ||||
usedspace = 0; | usedspace = 0; | ||||
(void)usedspace; | |||||
} | } | ||||
unsigned char * | unsigned char * | ||||
ldns_sha256(unsigned char *data, unsigned int data_len, unsigned char *digest) | ldns_sha256(const unsigned char *data, unsigned int data_len, unsigned char *digest) | ||||
{ | { | ||||
ldns_sha256_CTX ctx; | ldns_sha256_CTX ctx; | ||||
ldns_sha256_init(&ctx); | ldns_sha256_init(&ctx); | ||||
ldns_sha256_update(&ctx, data, data_len); | ldns_sha256_update(&ctx, data, data_len); | ||||
ldns_sha256_final(digest, &ctx); | ldns_sha256_final(digest, &ctx); | ||||
return digest; | return digest; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 169 Lines • ▼ Show 20 Lines | #endif /* BYTE_ORDER == LITTLE_ENDIAN */ | ||||
context->state[3] += d; | context->state[3] += d; | ||||
context->state[4] += e; | context->state[4] += e; | ||||
context->state[5] += f; | context->state[5] += f; | ||||
context->state[6] += g; | context->state[6] += g; | ||||
context->state[7] += h; | context->state[7] += h; | ||||
/* Clean up */ | /* Clean up */ | ||||
a = b = c = d = e = f = g = h = T1 = T2 = 0; | a = b = c = d = e = f = g = h = T1 = T2 = 0; | ||||
(void)a; | |||||
} | } | ||||
#endif /* SHA2_UNROLL_TRANSFORM */ | #endif /* SHA2_UNROLL_TRANSFORM */ | ||||
void ldns_sha512_update(ldns_sha512_CTX* context, const sha2_byte *data, size_t len) { | void ldns_sha512_update(ldns_sha512_CTX* context, const sha2_byte *data, size_t len) { | ||||
size_t freespace, usedspace; | size_t freespace, usedspace; | ||||
if (len == 0) { | if (len == 0) { | ||||
Show All 17 Lines | if (len >= freespace) { | ||||
data += freespace; | data += freespace; | ||||
ldns_sha512_Transform(context, (sha2_word64*)context->buffer); | ldns_sha512_Transform(context, (sha2_word64*)context->buffer); | ||||
} else { | } else { | ||||
/* The buffer is not yet full */ | /* The buffer is not yet full */ | ||||
MEMCPY_BCOPY(&context->buffer[usedspace], data, len); | MEMCPY_BCOPY(&context->buffer[usedspace], data, len); | ||||
ADDINC128(context->bitcount, len << 3); | ADDINC128(context->bitcount, len << 3); | ||||
/* Clean up: */ | /* Clean up: */ | ||||
usedspace = freespace = 0; | usedspace = freespace = 0; | ||||
(void)usedspace; | |||||
return; | return; | ||||
} | } | ||||
} | } | ||||
while (len >= LDNS_SHA512_BLOCK_LENGTH) { | while (len >= LDNS_SHA512_BLOCK_LENGTH) { | ||||
/* Process as many complete blocks as we can */ | /* Process as many complete blocks as we can */ | ||||
ldns_sha512_Transform(context, (sha2_word64*)data); | ldns_sha512_Transform(context, (sha2_word64*)data); | ||||
ADDINC128(context->bitcount, LDNS_SHA512_BLOCK_LENGTH << 3); | ADDINC128(context->bitcount, LDNS_SHA512_BLOCK_LENGTH << 3); | ||||
len -= LDNS_SHA512_BLOCK_LENGTH; | len -= LDNS_SHA512_BLOCK_LENGTH; | ||||
data += LDNS_SHA512_BLOCK_LENGTH; | data += LDNS_SHA512_BLOCK_LENGTH; | ||||
} | } | ||||
if (len > 0) { | if (len > 0) { | ||||
/* There's left-overs, so save 'em */ | /* There's left-overs, so save 'em */ | ||||
MEMCPY_BCOPY(context->buffer, data, len); | MEMCPY_BCOPY(context->buffer, data, len); | ||||
ADDINC128(context->bitcount, len << 3); | ADDINC128(context->bitcount, len << 3); | ||||
} | } | ||||
/* Clean up: */ | /* Clean up: */ | ||||
usedspace = freespace = 0; | usedspace = freespace = 0; | ||||
(void)usedspace; | |||||
} | } | ||||
static void ldns_sha512_Last(ldns_sha512_CTX* context) { | static void ldns_sha512_Last(ldns_sha512_CTX* context) { | ||||
size_t usedspace; | size_t usedspace; | ||||
ldns_sha2_buffer_union cast_var; | ldns_sha2_buffer_union cast_var; | ||||
usedspace = (context->bitcount[0] >> 3) % LDNS_SHA512_BLOCK_LENGTH; | usedspace = (context->bitcount[0] >> 3) % LDNS_SHA512_BLOCK_LENGTH; | ||||
#if BYTE_ORDER == LITTLE_ENDIAN | #if BYTE_ORDER == LITTLE_ENDIAN | ||||
Show All 29 Lines | #endif | ||||
cast_var.theChars = context->buffer; | cast_var.theChars = context->buffer; | ||||
cast_var.theLongs[ldns_sha512_SHORT_BLOCK_LENGTH / 8] = context->bitcount[1]; | cast_var.theLongs[ldns_sha512_SHORT_BLOCK_LENGTH / 8] = context->bitcount[1]; | ||||
cast_var.theLongs[ldns_sha512_SHORT_BLOCK_LENGTH / 8 + 1] = context->bitcount[0]; | cast_var.theLongs[ldns_sha512_SHORT_BLOCK_LENGTH / 8 + 1] = context->bitcount[0]; | ||||
/* final transform: */ | /* final transform: */ | ||||
ldns_sha512_Transform(context, (sha2_word64*)context->buffer); | ldns_sha512_Transform(context, (sha2_word64*)context->buffer); | ||||
} | } | ||||
void ldns_sha512_final(sha2_byte digest[], ldns_sha512_CTX* context) { | void ldns_sha512_final(sha2_byte digest[LDNS_SHA512_DIGEST_LENGTH], ldns_sha512_CTX* context) { | ||||
sha2_word64 *d = (sha2_word64*)digest; | sha2_word64 *d = (sha2_word64*)digest; | ||||
/* Sanity check: */ | /* Sanity check: */ | ||||
assert(context != (ldns_sha512_CTX*)0); | assert(context != (ldns_sha512_CTX*)0); | ||||
/* If no digest buffer is passed, we don't bother doing this: */ | /* If no digest buffer is passed, we don't bother doing this: */ | ||||
if (digest != (sha2_byte*)0) { | if (digest != (sha2_byte*)0) { | ||||
ldns_sha512_Last(context); | ldns_sha512_Last(context); | ||||
Show All 13 Lines | |||||
#endif | #endif | ||||
} | } | ||||
/* Zero out state data */ | /* Zero out state data */ | ||||
MEMSET_BZERO(context, sizeof(ldns_sha512_CTX)); | MEMSET_BZERO(context, sizeof(ldns_sha512_CTX)); | ||||
} | } | ||||
unsigned char * | unsigned char * | ||||
ldns_sha512(unsigned char *data, unsigned int data_len, unsigned char *digest) | ldns_sha512(const unsigned char *data, unsigned int data_len, unsigned char *digest) | ||||
{ | { | ||||
ldns_sha512_CTX ctx; | ldns_sha512_CTX ctx; | ||||
ldns_sha512_init(&ctx); | ldns_sha512_init(&ctx); | ||||
ldns_sha512_update(&ctx, data, data_len); | ldns_sha512_update(&ctx, data, data_len); | ||||
ldns_sha512_final(digest, &ctx); | ldns_sha512_final(digest, &ctx); | ||||
return digest; | return digest; | ||||
} | } | ||||
/*** SHA-384: *********************************************************/ | /*** SHA-384: *********************************************************/ | ||||
void ldns_sha384_init(ldns_sha384_CTX* context) { | void ldns_sha384_init(ldns_sha384_CTX* context) { | ||||
if (context == (ldns_sha384_CTX*)0) { | if (context == (ldns_sha384_CTX*)0) { | ||||
return; | return; | ||||
} | } | ||||
MEMCPY_BCOPY(context->state, sha384_initial_hash_value, LDNS_SHA512_DIGEST_LENGTH); | MEMCPY_BCOPY(context->state, sha384_initial_hash_value, LDNS_SHA512_DIGEST_LENGTH); | ||||
MEMSET_BZERO(context->buffer, LDNS_SHA384_BLOCK_LENGTH); | MEMSET_BZERO(context->buffer, LDNS_SHA384_BLOCK_LENGTH); | ||||
context->bitcount[0] = context->bitcount[1] = 0; | context->bitcount[0] = context->bitcount[1] = 0; | ||||
} | } | ||||
void ldns_sha384_update(ldns_sha384_CTX* context, const sha2_byte* data, size_t len) { | void ldns_sha384_update(ldns_sha384_CTX* context, const sha2_byte* data, size_t len) { | ||||
ldns_sha512_update((ldns_sha512_CTX*)context, data, len); | ldns_sha512_update((ldns_sha512_CTX*)context, data, len); | ||||
} | } | ||||
void ldns_sha384_final(sha2_byte digest[], ldns_sha384_CTX* context) { | void ldns_sha384_final(sha2_byte digest[LDNS_SHA384_DIGEST_LENGTH], ldns_sha384_CTX* context) { | ||||
sha2_word64 *d = (sha2_word64*)digest; | sha2_word64 *d = (sha2_word64*)digest; | ||||
/* Sanity check: */ | /* Sanity check: */ | ||||
assert(context != (ldns_sha384_CTX*)0); | assert(context != (ldns_sha384_CTX*)0); | ||||
/* If no digest buffer is passed, we don't bother doing this: */ | /* If no digest buffer is passed, we don't bother doing this: */ | ||||
if (digest != (sha2_byte*)0) { | if (digest != (sha2_byte*)0) { | ||||
ldns_sha512_Last((ldns_sha512_CTX*)context); | ldns_sha512_Last((ldns_sha512_CTX*)context); | ||||
Show All 13 Lines | |||||
#endif | #endif | ||||
} | } | ||||
/* Zero out state data */ | /* Zero out state data */ | ||||
MEMSET_BZERO(context, sizeof(ldns_sha384_CTX)); | MEMSET_BZERO(context, sizeof(ldns_sha384_CTX)); | ||||
} | } | ||||
unsigned char * | unsigned char * | ||||
ldns_sha384(unsigned char *data, unsigned int data_len, unsigned char *digest) | ldns_sha384(const unsigned char *data, unsigned int data_len, unsigned char *digest) | ||||
{ | { | ||||
ldns_sha384_CTX ctx; | ldns_sha384_CTX ctx; | ||||
ldns_sha384_init(&ctx); | ldns_sha384_init(&ctx); | ||||
ldns_sha384_update(&ctx, data, data_len); | ldns_sha384_update(&ctx, data, data_len); | ||||
ldns_sha384_final(digest, &ctx); | ldns_sha384_final(digest, &ctx); | ||||
return digest; | return digest; | ||||
} | } |