-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhmac.c
214 lines (194 loc) · 5.08 KB
/
hmac.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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
/*
CRIPTOGRAFIA FIng - UdelaR
Daniel Susviela
*/
#include <openssl/evp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// funcion auxiliar usada en el debugging
void print_byte_as_bits(char val) {
for (int i = 7; 0 <= i; i--) {
printf("%c", (val & (1 << i)) ? '1' : '0');
}
}
// hash de SHA1
unsigned int sha1Hash(char mess1[], int len, unsigned char *res) {
EVP_MD_CTX mdctx;
const EVP_MD *md;
unsigned char md_value[EVP_MAX_MD_SIZE];
int md_len, i;
/*
salida para debug
printf("\n");
printf("-----------");
printf("\n");
for (int i = 0; i < len; i++) {
print_byte_as_bits(mess1[i]);
}
printf("\n");
printf("-----------");
printf("\n");
printf("\n");
printf("buscando el hash sha1");
printf("\n");
printf("\n");
*/
md = EVP_get_digestbyname("SHA1"); // obtiene el hash sha
EVP_MD_CTX_init(&mdctx);
EVP_DigestInit_ex(&mdctx, md, NULL);
EVP_DigestUpdate(&mdctx, mess1, len); // lo hashea
EVP_DigestFinal_ex(&mdctx, md_value, &md_len); // se obtiene el resultado
/*
printf("Hash finished");
printf("\n");
*/
for (int i = 0; i < md_len; i++) {
res[i] = md_value[i]; // guardar el resultado en res
//printf("%02x", md_value[i]);
}
//printf("\n");
//printf("\n");
return md_len; //devolver el largo
}
int main(int argc, unsigned char **argv) {
if (argc != 3) {
printf("Cantidad de parametros invalidos \n");
printf("uso: ./hmac [string] [key] \n");
return -1;
}
OpenSSL_add_all_digests(); // necesario una vez sola para el openssl
// obtener los parametros
unsigned char *text = argv[1];
int textLen = strlen(text);
unsigned char *k = argv[2];
int keyLen = strlen(k);
unsigned char *k0 = (unsigned char *)malloc(64);
/* para debugear
printf("rep text: ");
for (int i = 0; i < textLen; i++) {
printf("%02x", text[i]);
}
printf("\n");
printf("rep key: ");
for (int i = 0; i < keyLen; i++) {
printf("%02x", k[i]);
}
printf("\n");
printf("\n");
*/
// se obtiene la clave k0
if (keyLen == 64) { // largo deseado
strcpy(k0, k);
} else if (keyLen < 64) { // mas chico
int charsFromKey = 0;
for (int i = 0; i < 64; i += 1) {
if (charsFromKey <= keyLen) {
k0[i] = k[charsFromKey];
charsFromKey += 1;
} else {
k0[i] = 0;
}
}
} else { // mas grande
unsigned char *kAux = (unsigned char *)malloc(64);
memset(kAux, 0, 64); // se hashea y se agregan 0s
sha1Hash(k, 20, kAux);
strcpy(k0, kAux);
}
/* para debugear
printf("k0 result: ");
for (int i = 0; i < 63; i++) {
printf("%02x", k0[i]);
}
printf("\n");
*/
// calculo de s1 y s2
unsigned char *s1 = (unsigned char *)malloc(64);
unsigned char *s2 = (unsigned char *)malloc(64);
for (int i = 0; i < 64; i++) {
s1[i] = k0[i] ^ 0x36; // 0x36 es la rep hexadecimal de ipad
s2[i] = k0[i] ^ 0x5C; // 0x5C es la rep hexadecimal de opad
}
/* para debugear
printf("s1 res: ");
for (int i = 0; i < 64; i++) {
printf("%02x", s1[i]);
}
printf("\n");
printf("s2 res: ");
for (int i = 0; i < 64; i++) {
printf("%02x", s2[i]);
}
printf("\n");
printf("\n");
*/
// calcular T'
// primero concatenar
int auxLen = textLen + 64;
unsigned char *concatenatedTextAndS1 = (unsigned char *)malloc(auxLen);
strcpy(concatenatedTextAndS1, s1);
/*
para debugear
printf("PREVIO AL concat s1 y text en bits: ");
for (int i = 0; i < auxLen; i++) {
print_byte_as_bits(concatenatedTextAndS1[i]);
}
printf("\n");
*/
strcat(concatenatedTextAndS1, text);
/* para debugear
printf("s1 concat text: ");
for (int i = 0; i < auxLen; i++) {
printf("%02x", concatenatedTextAndS1[i]);
}
printf("\n");
printf("s1 concat text en bits: ");
for (int i = 0; i < auxLen; i++) {
print_byte_as_bits(concatenatedTextAndS1[i]);
}
printf("\n");
*/
// ahora si calcular el hash
unsigned char tPrime[EVP_MAX_MD_SIZE];
unsigned int tPrimeSize = sha1Hash(concatenatedTextAndS1, auxLen, tPrime);
/* para debuggear
printf("tprime: ");
for (int i = 0; i < tPrimeSize; i++) {
printf("%02x", tPrime[i]);
}
printf("\n");
*/
// se obtiene el resultado
int auxLen2 = 64 + tPrimeSize;
unsigned char *concatenatedTextprimeAndS2 = (unsigned char *)malloc(auxLen2);
strcpy(concatenatedTextprimeAndS2, s2);
strcat(concatenatedTextprimeAndS2, tPrime);
/* para debugear
printf("tprime and s2: ");
for (int i = 0; i < auxLen2; i++) {
printf("%02x", concatenatedTextprimeAndS2[i]);
}
printf("\n");
printf("tprime and s2 bits: ");
for (int i = 0; i < auxLen2; i++) {
print_byte_as_bits(concatenatedTextprimeAndS2[i]);
}
printf("\n");
printf("last hash: ");
printf("\n");
*/
unsigned char res[EVP_MAX_MD_SIZE];
unsigned int resSize = sha1Hash(concatenatedTextprimeAndS2, auxLen2, res);
//imprimir resultado
printf("El valor de HMAC es: ");
for (int i = 0; i < resSize; i++) {
printf("%02x", res[i]);
}
printf("\n");
printf("Su valor en bianrio es: ");
for (int i = 0; i < resSize; i++) {
print_byte_as_bits(res[i]);
}
printf("\n");
}