forked from cisco/hash-sigs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
hash.c
120 lines (106 loc) · 3.2 KB
/
hash.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include <string.h>
#include "hash.h"
#include "sha256.h"
#include "hss_zeroize.h"
#define ALLOW_VERBOSE 0 /* 1 -> we allow the dumping of intermediate */
/* states. Useful for debugging; horrid */
/* for security */
/*
* This is the file that implements the hashing APIs we use internally.
* At the present, our parameter sets support only one hash function
* (SHA-256, using full 256 bit output), however, that is likely to change
* in the future
*/
#if ALLOW_VERBOSE
#include <stdio.h>
#include <stdbool.h>
/*
* Debugging flag; if this is set, we chat about what we're hashing, and what
* the result is it's useful when debugging; however we probably don't want to
* do this if we're multithreaded...
*/
bool hss_verbose = false;
#endif
/*
* This will hash the message, given the hash type. It assumes that the result
* buffer is large enough for the hash
*/
void hss_hash_ctx(void *result, int hash_type, union hash_context *ctx,
const void *message, size_t message_len) {
#if ALLOW_VERBOSE
if (hss_verbose) {
int i; for (i=0; i< message_len; i++) printf( " %02x%s", ((unsigned char*)message)[i], (i%16 == 15) ? "\n" : "" );
}
#endif
switch (hash_type) {
case HASH_SHA256: {
SHA256_Init(&ctx->sha256);
SHA256_Update(&ctx->sha256, message, message_len);
SHA256_Final(result, &ctx->sha256);
#if ALLOW_VERBOSE
if (hss_verbose) {
printf( " ->" );
int i; for (i=0; i<32; i++) printf( " %02x", ((unsigned char *)result)[i] ); printf( "\n" );
}
#endif
break;
}
}
}
void hss_hash(void *result, int hash_type,
const void *message, size_t message_len) {
union hash_context ctx;
hss_hash_ctx(result, hash_type, &ctx, message, message_len);
hss_zeroize(&ctx, sizeof ctx);
}
/*
* This provides an API to do incremental hashing. We use it when hashing the
* message; since we don't know how long it could be, we don't want to
* allocate a buffer that's long enough for that, plus the decoration we add
*/
void hss_init_hash_context(int h, union hash_context *ctx) {
switch (h) {
case HASH_SHA256:
SHA256_Init( &ctx->sha256 );
break;
}
}
void hss_update_hash_context(int h, union hash_context *ctx,
const void *msg, size_t len_msg) {
#if ALLOW_VERBOSE
if (hss_verbose) {
int i; for (i=0; i<len_msg; i++) printf( " %02x", ((unsigned char*)msg)[i] );
}
#endif
switch (h) {
case HASH_SHA256:
SHA256_Update(&ctx->sha256, msg, len_msg);
break;
}
}
void hss_finalize_hash_context(int h, union hash_context *ctx, void *buffer) {
switch (h) {
case HASH_SHA256:
SHA256_Final(buffer, &ctx->sha256);
#if ALLOW_VERBOSE
if (hss_verbose) {
printf( " -->" );
int i; for (i=0; i<32; i++) printf( " %02x", ((unsigned char*)buffer)[i] );
printf( "\n" );
}
#endif
break;
}
}
unsigned hss_hash_length(int hash_type) {
switch (hash_type) {
case HASH_SHA256: return 32;
}
return 0;
}
unsigned hss_hash_blocksize(int hash_type) {
switch (hash_type) {
case HASH_SHA256: return 64;
}
return 0;
}