summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorinoguchi <>2017-03-03 10:39:07 +0000
committerinoguchi <>2017-03-03 10:39:07 +0000
commit97d56837a149cc0208c55b487d71956d327193fd (patch)
treef55b9886b7ecc1012718eec4a621d7ac8d098382
parent71095999206308b62fa7ab18602ceb3fa91f6a9c (diff)
downloadopenbsd-97d56837a149cc0208c55b487d71956d327193fd.tar.gz
openbsd-97d56837a149cc0208c55b487d71956d327193fd.tar.bz2
openbsd-97d56837a149cc0208c55b487d71956d327193fd.zip
Ensure MD and key initialized before processing HMAC
Ensure both MD and key have been initialized before processing HMAC. Releasing HMAC_CTX in error path of HMAC(). In regress test, added test 4,5,6 and cleaned up the code. ok jsing@
-rw-r--r--src/lib/libcrypto/hmac/hmac.c22
-rw-r--r--src/regress/lib/libcrypto/hmac/hmactest.c237
2 files changed, 224 insertions, 35 deletions
diff --git a/src/lib/libcrypto/hmac/hmac.c b/src/lib/libcrypto/hmac/hmac.c
index 8fd980b052..84917662ca 100644
--- a/src/lib/libcrypto/hmac/hmac.c
+++ b/src/lib/libcrypto/hmac/hmac.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: hmac.c,v 1.23 2017/01/29 17:49:23 beck Exp $ */ 1/* $OpenBSD: hmac.c,v 1.24 2017/03/03 10:39:07 inoguchi Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -70,11 +70,17 @@ HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md,
70 int i, j, reset = 0; 70 int i, j, reset = 0;
71 unsigned char pad[HMAC_MAX_MD_CBLOCK]; 71 unsigned char pad[HMAC_MAX_MD_CBLOCK];
72 72
73 /* If we are changing MD then we must have a key */
74 if (md != NULL && md != ctx->md && (key == NULL || len < 0))
75 return 0;
76
73 if (md != NULL) { 77 if (md != NULL) {
74 reset = 1; 78 reset = 1;
75 ctx->md = md; 79 ctx->md = md;
76 } else 80 } else if (ctx->md != NULL)
77 md = ctx->md; 81 md = ctx->md;
82 else
83 return 0;
78 84
79 if (key != NULL) { 85 if (key != NULL) {
80 reset = 1; 86 reset = 1;
@@ -92,7 +98,7 @@ HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md,
92 &ctx->key_length)) 98 &ctx->key_length))
93 goto err; 99 goto err;
94 } else { 100 } else {
95 if ((size_t)len > sizeof(ctx->key)) { 101 if (len < 0 || (size_t)len > sizeof(ctx->key)) {
96 EVPerror(EVP_R_BAD_KEY_LENGTH); 102 EVPerror(EVP_R_BAD_KEY_LENGTH);
97 goto err; 103 goto err;
98 } 104 }
@@ -137,6 +143,9 @@ HMAC_Init(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md)
137int 143int
138HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len) 144HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len)
139{ 145{
146 if (ctx->md == NULL)
147 return 0;
148
140 return EVP_DigestUpdate(&ctx->md_ctx, data, len); 149 return EVP_DigestUpdate(&ctx->md_ctx, data, len);
141} 150}
142 151
@@ -146,6 +155,9 @@ HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len)
146 unsigned int i; 155 unsigned int i;
147 unsigned char buf[EVP_MAX_MD_SIZE]; 156 unsigned char buf[EVP_MAX_MD_SIZE];
148 157
158 if (ctx->md == NULL)
159 goto err;
160
149 if (!EVP_DigestFinal_ex(&ctx->md_ctx, buf, &i)) 161 if (!EVP_DigestFinal_ex(&ctx->md_ctx, buf, &i))
150 goto err; 162 goto err;
151 if (!EVP_MD_CTX_copy_ex(&ctx->md_ctx, &ctx->o_ctx)) 163 if (!EVP_MD_CTX_copy_ex(&ctx->md_ctx, &ctx->o_ctx))
@@ -165,6 +177,7 @@ HMAC_CTX_init(HMAC_CTX *ctx)
165 EVP_MD_CTX_init(&ctx->i_ctx); 177 EVP_MD_CTX_init(&ctx->i_ctx);
166 EVP_MD_CTX_init(&ctx->o_ctx); 178 EVP_MD_CTX_init(&ctx->o_ctx);
167 EVP_MD_CTX_init(&ctx->md_ctx); 179 EVP_MD_CTX_init(&ctx->md_ctx);
180 ctx->md = NULL;
168} 181}
169 182
170int 183int
@@ -190,7 +203,7 @@ HMAC_CTX_cleanup(HMAC_CTX *ctx)
190 EVP_MD_CTX_cleanup(&ctx->i_ctx); 203 EVP_MD_CTX_cleanup(&ctx->i_ctx);
191 EVP_MD_CTX_cleanup(&ctx->o_ctx); 204 EVP_MD_CTX_cleanup(&ctx->o_ctx);
192 EVP_MD_CTX_cleanup(&ctx->md_ctx); 205 EVP_MD_CTX_cleanup(&ctx->md_ctx);
193 memset(ctx, 0, sizeof *ctx); 206 explicit_bzero(ctx, sizeof(*ctx));
194} 207}
195 208
196unsigned char * 209unsigned char *
@@ -212,6 +225,7 @@ HMAC(const EVP_MD *evp_md, const void *key, int key_len, const unsigned char *d,
212 HMAC_CTX_cleanup(&c); 225 HMAC_CTX_cleanup(&c);
213 return md; 226 return md;
214err: 227err:
228 HMAC_CTX_cleanup(&c);
215 return NULL; 229 return NULL;
216} 230}
217 231
diff --git a/src/regress/lib/libcrypto/hmac/hmactest.c b/src/regress/lib/libcrypto/hmac/hmactest.c
index 7daaacd34f..d5a00c8aac 100644
--- a/src/regress/lib/libcrypto/hmac/hmactest.c
+++ b/src/regress/lib/libcrypto/hmac/hmactest.c
@@ -66,32 +66,33 @@
66#endif 66#endif
67 67
68#ifndef OPENSSL_NO_MD5 68#ifndef OPENSSL_NO_MD5
69static struct test_st 69static struct test_st {
70 {
71 unsigned char key[16]; 70 unsigned char key[16];
72 int key_len; 71 int key_len;
73 unsigned char data[64]; 72 unsigned char data[64];
74 int data_len; 73 int data_len;
75 unsigned char *digest; 74 unsigned char *digest;
76 } test[4]={ 75} test[8] = {
77 { "", 76 { "",
78 0, 77 0,
79 "More text test vectors to stuff up EBCDIC machines :-)", 78 "More text test vectors to stuff up EBCDIC machines :-)",
80 54, 79 54,
81 (unsigned char *)"e9139d1e6ee064ef8cf514fc7dc83e86", 80 (unsigned char *)"e9139d1e6ee064ef8cf514fc7dc83e86",
82 },{ {0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b, 81 },
82 { {0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,
83 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,}, 83 0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,0x0b,},
84 16, 84 16,
85 "Hi There", 85 "Hi There",
86 8, 86 8,
87 (unsigned char *)"9294727a3638bb1c13f48ef8158bfc9d", 87 (unsigned char *)"9294727a3638bb1c13f48ef8158bfc9d",
88 },{ "Jefe", 88 },
89 { "Jefe",
89 4, 90 4,
90 "what do ya want for nothing?", 91 "what do ya want for nothing?",
91 28, 92 28,
92 (unsigned char *)"750c783e6ab0b503eaa86e310a5db738", 93 (unsigned char *)"750c783e6ab0b503eaa86e310a5db738",
93 },{ 94 },
94 {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa, 95 { {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
95 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,}, 96 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,},
96 16, 97 16,
97 {0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd, 98 {0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,
@@ -104,51 +105,225 @@ static struct test_st
104 50, 105 50,
105 (unsigned char *)"56be34521d144c88dbb8c733f0e8b3f6", 106 (unsigned char *)"56be34521d144c88dbb8c733f0e8b3f6",
106 }, 107 },
107 }; 108 { "",
109 0,
110 "My test data",
111 12,
112 (unsigned char *)"61afdecb95429ef494d61fdee15990cabf0826fc"
113 },
114 { "",
115 0,
116 "My test data",
117 12,
118 (unsigned char *)"2274b195d90ce8e03406f4b526a47e0787a88a65479938f1a5baa3ce0f079776"
119 },
120 { "123456",
121 6,
122 "My test data",
123 12,
124 (unsigned char *)"bab53058ae861a7f191abe2d0145cbb123776a6369ee3f9d79ce455667e411dd"
125 },
126 { "12345",
127 5,
128 "My test data again",
129 12,
130 (unsigned char *)"7dbe8c764c068e3bcd6e6b0fbcd5e6fc197b15bb"
131 }
132};
108#endif 133#endif
109 134
110static char *pt(unsigned char *md); 135static char *pt(unsigned char *md, unsigned int len);
111int main(int argc, char *argv[]) 136
112 { 137int
138main(int argc, char *argv[])
139{
113#ifndef OPENSSL_NO_MD5 140#ifndef OPENSSL_NO_MD5
114 int i; 141 int i;
115 char *p; 142 char *p;
116#endif 143#endif
117 int err=0; 144 int err = 0;
145 HMAC_CTX ctx, ctx2;
146 unsigned char buf[EVP_MAX_MD_SIZE];
147 unsigned int len;
118 148
119#ifdef OPENSSL_NO_MD5 149#ifdef OPENSSL_NO_MD5
120 printf("test skipped: MD5 disabled\n"); 150 printf("test skipped: MD5 disabled\n");
121#else 151#else
122 152
123 for (i=0; i<4; i++) 153 for (i = 0; i < 4; i++) {
124 { 154 p = pt(HMAC(EVP_md5(),
125 p=pt(HMAC(EVP_md5(),
126 test[i].key, test[i].key_len, 155 test[i].key, test[i].key_len,
127 test[i].data, test[i].data_len, 156 test[i].data, test[i].data_len, NULL, NULL),
128 NULL,NULL)); 157 MD5_DIGEST_LENGTH);
129 158
130 if (strcmp(p,(char *)test[i].digest) != 0) 159 if (strcmp(p, (char *)test[i].digest) != 0) {
131 { 160 printf("error calculating HMAC on %d entry'\n", i);
132 printf("error calculating HMAC on %d entry'\n",i); 161 printf("got %s instead of %s\n", p, test[i].digest);
133 printf("got %s instead of %s\n",p,test[i].digest);
134 err++; 162 err++;
135 } 163 } else
136 else 164 printf("test %d ok\n", i);
137 printf("test %d ok\n",i); 165 }
138 }
139#endif /* OPENSSL_NO_MD5 */ 166#endif /* OPENSSL_NO_MD5 */
167
168/* test4 */
169 HMAC_CTX_init(&ctx);
170 if (HMAC_Init_ex(&ctx, NULL, 0, NULL, NULL)) {
171 printf("Should fail to initialise HMAC with empty MD and key (test 4)\n");
172 err++;
173 goto test5;
174 }
175 if (HMAC_Update(&ctx, test[4].data, test[4].data_len)) {
176 printf("Should fail HMAC_Update with ctx not set up (test 4)\n");
177 err++;
178 goto test5;
179 }
180 if (HMAC_Init_ex(&ctx, NULL, 0, EVP_sha1(), NULL)) {
181 printf("Should fail to initialise HMAC with empty key (test 4)\n");
182 err++;
183 goto test5;
184 }
185 if (HMAC_Update(&ctx, test[4].data, test[4].data_len)) {
186 printf("Should fail HMAC_Update with ctx not set up (test 4)\n");
187 err++;
188 goto test5;
189 }
190 printf("test 4 ok\n");
191 test5:
192 HMAC_CTX_cleanup(&ctx);
193 HMAC_CTX_init(&ctx);
194 if (HMAC_Init_ex(&ctx, test[4].key, test[4].key_len, NULL, NULL)) {
195 printf("Should fail to initialise HMAC with empty MD (test 5)\n");
196 err++;
197 goto test6;
198 }
199 if (HMAC_Update(&ctx, test[4].data, test[4].data_len)) {
200 printf("Should fail HMAC_Update with ctx not set up (test 5)\n");
201 err++;
202 goto test6;
203 }
204 if (HMAC_Init_ex(&ctx, test[4].key, -1, EVP_sha1(), NULL)) {
205 printf("Should fail to initialise HMAC with invalid key len(test 5)\n");
206 err++;
207 goto test6;
208 }
209 if (!HMAC_Init_ex(&ctx, test[4].key, test[4].key_len, EVP_sha1(), NULL)) {
210 printf("Failed to initialise HMAC (test 5)\n");
211 err++;
212 goto test6;
213 }
214 if (!HMAC_Update(&ctx, test[4].data, test[4].data_len)) {
215 printf("Error updating HMAC with data (test 5)\n");
216 err++;
217 goto test6;
218 }
219 if (!HMAC_Final(&ctx, buf, &len)) {
220 printf("Error finalising data (test 5)\n");
221 err++;
222 goto test6;
223 }
224 p = pt(buf, len);
225 if (strcmp(p, (char *)test[4].digest) != 0) {
226 printf("Error calculating interim HMAC on test 5\n");
227 printf("got %s instead of %s\n", p, test[4].digest);
228 err++;
229 goto test6;
230 }
231 if (HMAC_Init_ex(&ctx, NULL, 0, EVP_sha256(), NULL)) {
232 printf("Should disallow changing MD without a new key (test 5)\n");
233 err++;
234 goto test6;
235 }
236 if (!HMAC_Init_ex(&ctx, test[4].key, test[4].key_len, EVP_sha256(), NULL)) {
237 printf("Failed to reinitialise HMAC (test 5)\n");
238 err++;
239 goto test6;
240 }
241 if (!HMAC_Update(&ctx, test[5].data, test[5].data_len)) {
242 printf("Error updating HMAC with data (sha256) (test 5)\n");
243 err++;
244 goto test6;
245 }
246 if (!HMAC_Final(&ctx, buf, &len)) {
247 printf("Error finalising data (sha256) (test 5)\n");
248 err++;
249 goto test6;
250 }
251 p = pt(buf, len);
252 if (strcmp(p, (char *)test[5].digest) != 0) {
253 printf("Error calculating 2nd interim HMAC on test 5\n");
254 printf("got %s instead of %s\n", p, test[5].digest);
255 err++;
256 goto test6;
257 }
258 if (!HMAC_Init_ex(&ctx, test[6].key, test[6].key_len, NULL, NULL)) {
259 printf("Failed to reinitialise HMAC with key (test 5)\n");
260 err++;
261 goto test6;
262 }
263 if (!HMAC_Update(&ctx, test[6].data, test[6].data_len)) {
264 printf("Error updating HMAC with data (new key) (test 5)\n");
265 err++;
266 goto test6;
267 }
268 if (!HMAC_Final(&ctx, buf, &len)) {
269 printf("Error finalising data (new key) (test 5)\n");
270 err++;
271 goto test6;
272 }
273 p = pt(buf, len);
274 if (strcmp(p, (char *)test[6].digest) != 0) {
275 printf("error calculating HMAC on test 5\n");
276 printf("got %s instead of %s\n", p, test[6].digest);
277 err++;
278 } else {
279 printf("test 5 ok\n");
280 }
281 test6:
282 HMAC_CTX_cleanup(&ctx);
283 HMAC_CTX_init(&ctx);
284 if (!HMAC_Init_ex(&ctx, test[7].key, test[7].key_len, EVP_sha1(), NULL)) {
285 printf("Failed to initialise HMAC (test 6)\n");
286 err++;
287 goto end;
288 }
289 if (!HMAC_Update(&ctx, test[7].data, test[7].data_len)) {
290 printf("Error updating HMAC with data (test 6)\n");
291 err++;
292 goto end;
293 }
294 if (!HMAC_CTX_copy(&ctx2, &ctx)) {
295 printf("Failed to copy HMAC_CTX (test 6)\n");
296 err++;
297 goto end;
298 }
299 if (!HMAC_Final(&ctx2, buf, &len)) {
300 printf("Error finalising data (test 6)\n");
301 err++;
302 goto end;
303 }
304 p = pt(buf, len);
305 if (strcmp(p, (char *)test[7].digest) != 0) {
306 printf("Error calculating HMAC on test 6\n");
307 printf("got %s instead of %s\n", p, test[7].digest);
308 err++;
309 } else {
310 printf("test 6 ok\n");
311 }
312end:
313 HMAC_CTX_cleanup(&ctx);
140 exit(err); 314 exit(err);
141 return(0); 315 return(0);
142 } 316}
143 317
144#ifndef OPENSSL_NO_MD5 318#ifndef OPENSSL_NO_MD5
145static char *pt(unsigned char *md) 319static char *
146 { 320pt(unsigned char *md, unsigned int len)
321{
147 int i; 322 int i;
148 static char buf[80]; 323 static char buf[80];
149 324
150 for (i=0; i<MD5_DIGEST_LENGTH; i++) 325 for (i = 0; i < len; i++)
151 snprintf(buf + i*2, sizeof(buf) - i*2, "%02x",md[i]); 326 snprintf(buf + i * 2, sizeof(buf) - i * 2, "%02x", md[i]);
152 return(buf); 327 return(buf);
153 } 328}
154#endif 329#endif