Merge pull request #925 from splinterofchaos/sha256

sha256.c: clint, -Wconversion, stdbool, and other improvements.
This commit is contained in:
Justin M. Keyes
2015-01-02 18:31:10 -05:00
4 changed files with 61 additions and 54 deletions

View File

@@ -106,8 +106,6 @@ src/nvim/screen.c
src/nvim/screen.h src/nvim/screen.h
src/nvim/search.c src/nvim/search.c
src/nvim/search.h src/nvim/search.h
src/nvim/sha256.c
src/nvim/sha256.h
src/nvim/sign_defs.h src/nvim/sign_defs.h
src/nvim/spell.c src/nvim/spell.c
src/nvim/spell.h src/nvim/spell.h

View File

@@ -81,7 +81,6 @@ set(CONV_SOURCES
regexp.c regexp.c
screen.c screen.c
search.c search.c
sha256.c
spell.c spell.c
syntax.c syntax.c
tag.c tag.c

View File

@@ -12,12 +12,13 @@
/// 2. sha2_seed() generates a random header. /// 2. sha2_seed() generates a random header.
/// sha256_self_test() is implicitly called once. /// sha256_self_test() is implicitly called once.
#include <inttypes.h> #include <stddef.h> // for size_t
#include <string.h> #include <stdio.h> // for snprintf().
#include <stdlib.h> // for rand_r().
#include "nvim/os/time.h" #include "nvim/os/time.h" // for os_hrtime().
#include "nvim/vim.h" #include "nvim/sha256.h" // for context_sha256_T
#include "nvim/sha256.h" #include "nvim/vim.h" // for STRCPY()/STRLEN().
#ifdef INCLUDE_GENERATED_DECLARATIONS #ifdef INCLUDE_GENERATED_DECLARATIONS
# include "sha256.c.generated.h" # include "sha256.c.generated.h"
@@ -51,9 +52,10 @@ void sha256_start(context_sha256_T *ctx)
ctx->state[7] = 0x5BE0CD19; ctx->state[7] = 0x5BE0CD19;
} }
static void sha256_process(context_sha256_T *ctx, char_u data[64]) static void sha256_process(context_sha256_T *ctx,
const char_u data[SHA256_BUFFER_SIZE])
{ {
uint32_t temp1, temp2, W[64]; uint32_t temp1, temp2, W[SHA256_BUFFER_SIZE];
uint32_t A, B, C, D, E, F, G, H; uint32_t A, B, C, D, E, F, G, H;
GET_UINT32(W[0], data, 0); GET_UINT32(W[0], data, 0);
@@ -179,24 +181,23 @@ static void sha256_process(context_sha256_T *ctx, char_u data[64])
ctx->state[7] += H; ctx->state[7] += H;
} }
void sha256_update(context_sha256_T *ctx, char_u *input, uint32_t length) void sha256_update(context_sha256_T *ctx, const char_u *input, size_t length)
{ {
uint32_t left, fill;
if (length == 0) { if (length == 0) {
return; return;
} }
left = ctx->total[0] & 0x3F; uint32_t left = ctx->total[0] & (SHA256_BUFFER_SIZE-1); // left < buf size
fill = 64 - left;
ctx->total[0] += length; ctx->total[0] += (uint32_t) length;
ctx->total[0] &= 0xFFFFFFFF; ctx->total[0] &= 0xFFFFFFFF;
if (ctx->total[0] < length) { if (ctx->total[0] < length) {
ctx->total[1]++; ctx->total[1]++;
} }
size_t fill = SHA256_BUFFER_SIZE - left;
if (left && (length >= fill)) { if (left && (length >= fill)) {
memcpy((void *)(ctx->buffer + left), (void *)input, fill); memcpy((void *)(ctx->buffer + left), (void *)input, fill);
sha256_process(ctx, ctx->buffer); sha256_process(ctx, ctx->buffer);
@@ -205,10 +206,10 @@ void sha256_update(context_sha256_T *ctx, char_u *input, uint32_t length)
left = 0; left = 0;
} }
while (length >= 64) { while (length >= SHA256_BUFFER_SIZE) {
sha256_process(ctx, input); sha256_process(ctx, input);
length -= 64; length -= SHA256_BUFFER_SIZE;
input += 64; input += SHA256_BUFFER_SIZE;
} }
if (length) { if (length) {
@@ -216,14 +217,14 @@ void sha256_update(context_sha256_T *ctx, char_u *input, uint32_t length)
} }
} }
static char_u sha256_padding[64] = { static char_u sha256_padding[SHA256_BUFFER_SIZE] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
}; };
void sha256_finish(context_sha256_T *ctx, char_u digest[32]) void sha256_finish(context_sha256_T *ctx, char_u digest[SHA256_SUM_SIZE])
{ {
uint32_t last, padn; uint32_t last, padn;
uint32_t high, low; uint32_t high, low;
@@ -251,6 +252,7 @@ void sha256_finish(context_sha256_T *ctx, char_u digest[32])
PUT_UINT32(ctx->state[7], digest, 28); PUT_UINT32(ctx->state[7], digest, 28);
} }
#define SHA_STEP 2
/// Gets the hex digest of the buffer. /// Gets the hex digest of the buffer.
/// ///
@@ -261,25 +263,25 @@ void sha256_finish(context_sha256_T *ctx, char_u digest[32])
/// ///
/// @returns hex digest of "buf[buf_len]" in a static array. /// @returns hex digest of "buf[buf_len]" in a static array.
/// if "salt" is not NULL also do "salt[salt_len]". /// if "salt" is not NULL also do "salt[salt_len]".
char_u *sha256_bytes(char_u *buf, int buf_len, char_u *salt, int salt_len) char_u *sha256_bytes(const char_u *restrict buf, size_t buf_len,
const char_u *restrict salt, size_t salt_len)
{ {
char_u sha256sum[32]; char_u sha256sum[SHA256_SUM_SIZE];
static char_u hexit[65]; static char_u hexit[SHA256_BUFFER_SIZE + 1]; // buf size + NULL
int j;
context_sha256_T ctx; context_sha256_T ctx;
sha256_self_test(); sha256_self_test();
sha256_start(&ctx); sha256_start(&ctx);
sha256_update(&ctx, buf, buf_len); sha256_update(&ctx, buf, buf_len);
if (salt != NULL) { if (salt != NULL) {
sha256_update(&ctx, salt, salt_len); sha256_update(&ctx, salt, salt_len);
} }
sha256_finish(&ctx, sha256sum); sha256_finish(&ctx, sha256sum);
for (j = 0; j < 32; j++) { for (size_t j = 0; j < SHA256_SUM_SIZE; j++) {
sprintf((char *) hexit + j * 2, "%02x", sha256sum[j]); snprintf((char *) hexit + j * SHA_STEP, SHA_STEP+1, "%02x", sha256sum[j]);
} }
hexit[sizeof(hexit) - 1] = '\0'; hexit[sizeof(hexit) - 1] = '\0';
return hexit; return hexit;
@@ -303,51 +305,51 @@ static char *sha_self_test_vector[] = {
/// Perform a test on the SHA256 algorithm. /// Perform a test on the SHA256 algorithm.
/// ///
/// @return FAIL or OK. /// @returns true if not failures generated.
int sha256_self_test(void) bool sha256_self_test(void)
{ {
int i, j; char output[SHA256_BUFFER_SIZE + 1]; // buf size + NULL
char output[65];
context_sha256_T ctx; context_sha256_T ctx;
char_u buf[1000]; char_u buf[1000];
char_u sha256sum[32]; char_u sha256sum[SHA256_SUM_SIZE];
static int failures = 0;
char_u *hexit; char_u *hexit;
static int sha256_self_tested = 0;
if (sha256_self_tested > 0) { static bool sha256_self_tested = false;
return failures > 0 ? FAIL : OK; static bool failures = false;
if (sha256_self_tested) {
return failures == false;
} }
sha256_self_tested = 1; sha256_self_tested = true;
for (i = 0; i < 3; i++) { for (size_t i = 0; i < 3; i++) {
if (i < 2) { if (i < 2) {
hexit = sha256_bytes((char_u *) sha_self_test_msg[i], hexit = sha256_bytes((char_u *) sha_self_test_msg[i],
(int) STRLEN(sha_self_test_msg[i]), STRLEN(sha_self_test_msg[i]),
NULL, 0); NULL, 0);
STRCPY(output, hexit); STRCPY(output, hexit);
} else { } else {
sha256_start(&ctx); sha256_start(&ctx);
memset(buf, 'a', 1000); memset(buf, 'a', 1000);
for (j = 0; j < 1000; j++) { for (size_t j = 0; j < 1000; j++) {
sha256_update(&ctx, (char_u *) buf, 1000); sha256_update(&ctx, (char_u *) buf, 1000);
} }
sha256_finish(&ctx, sha256sum); sha256_finish(&ctx, sha256sum);
for (j = 0; j < 32; j++) { for (size_t j = 0; j < SHA256_SUM_SIZE; j++) {
sprintf(output + j * 2, "%02x", sha256sum[j]); snprintf(output + j * SHA_STEP, SHA_STEP+1, "%02x", sha256sum[j]);
} }
} }
if (memcmp(output, sha_self_test_vector[i], 64)) { if (memcmp(output, sha_self_test_vector[i], SHA256_BUFFER_SIZE)) {
failures++; failures = true;
output[sizeof(output) - 1] = '\0'; output[sizeof(output) - 1] = '\0';
// printf("sha256_self_test %d failed %s\n", i, output); // printf("sha256_self_test %d failed %s\n", i, output);
} }
} }
return failures > 0 ? FAIL : OK; return failures == false;
} }
/// Fill "header[header_len]" with random_data. /// Fill "header[header_len]" with random_data.
@@ -357,20 +359,21 @@ int sha256_self_test(void)
/// @param header_len /// @param header_len
/// @param salt /// @param salt
/// @param salt_len /// @param salt_len
void sha2_seed(char_u *header, int header_len, char_u *salt, int salt_len) void sha2_seed(char_u *restrict header, size_t header_len,
char_u *restrict salt, size_t salt_len)
{ {
static char_u random_data[1000]; static char_u random_data[1000];
char_u sha256sum[32]; char_u sha256sum[SHA256_SUM_SIZE];
context_sha256_T ctx; context_sha256_T ctx;
srand((unsigned int) os_hrtime()); unsigned int seed = (unsigned int) os_hrtime();
int i; size_t i;
for (i = 0; i < (int) sizeof(random_data) - 1; i++) { for (i = 0; i < sizeof(random_data) - 1; i++) {
random_data[i] = (char_u) ((os_hrtime() ^ rand()) & 0xff); random_data[i] = (char_u) ((os_hrtime() ^ (uint64_t)rand_r(&seed)) & 0xff);
} }
sha256_start(&ctx); sha256_start(&ctx);
sha256_update(&ctx, (char_u *) random_data, sizeof(random_data)); sha256_update(&ctx, random_data, sizeof(random_data));
sha256_finish(&ctx, sha256sum); sha256_finish(&ctx, sha256sum);
// put first block into header. // put first block into header.

View File

@@ -1,10 +1,17 @@
#ifndef NVIM_SHA256_H #ifndef NVIM_SHA256_H
#define NVIM_SHA256_H #define NVIM_SHA256_H
#include <stdint.h> // for uint32_t
#include "nvim/types.h" // for char_u
#define SHA256_BUFFER_SIZE 64
#define SHA256_SUM_SIZE 32
typedef struct { typedef struct {
uint32_t total[2]; uint32_t total[2];
uint32_t state[8]; uint32_t state[8];
char_u buffer[64]; char_u buffer[SHA256_BUFFER_SIZE];
} context_sha256_T; } context_sha256_T;
#ifdef INCLUDE_GENERATED_DECLARATIONS #ifdef INCLUDE_GENERATED_DECLARATIONS