diff options
author | Damien Miller <djm@mindrot.org> | 2014-02-04 11:02:42 +1100 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2014-02-04 11:02:42 +1100 |
commit | 4e8d937af79ce4e253f77ec93489d098b25becc3 (patch) | |
tree | 83b0293313eea8dfebcc7f906c5058f530238e8b /mac.c | |
parent | 69d0d09f76bab5aec86fbf78489169f63bd16475 (diff) |
- markus@cvs.openbsd.org 2014/01/27 18:58:14
[Makefile.in digest.c digest.h hostfile.c kex.h mac.c hmac.c hmac.h]
replace openssl HMAC with an implementation based on our ssh_digest_*
ok and feedback djm@
Diffstat (limited to 'mac.c')
-rw-r--r-- | mac.c | 85 |
1 files changed, 41 insertions, 44 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: mac.c,v 1.26 2014/01/04 17:50:55 tedu Exp $ */ | 1 | /* $OpenBSD: mac.c,v 1.27 2014/01/27 18:58:14 markus Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -27,8 +27,6 @@ | |||
27 | 27 | ||
28 | #include <sys/types.h> | 28 | #include <sys/types.h> |
29 | 29 | ||
30 | #include <openssl/hmac.h> | ||
31 | |||
32 | #include <stdarg.h> | 30 | #include <stdarg.h> |
33 | #include <string.h> | 31 | #include <string.h> |
34 | #include <signal.h> | 32 | #include <signal.h> |
@@ -42,18 +40,20 @@ | |||
42 | #include "mac.h" | 40 | #include "mac.h" |
43 | #include "misc.h" | 41 | #include "misc.h" |
44 | 42 | ||
43 | #include "digest.h" | ||
44 | #include "hmac.h" | ||
45 | #include "umac.h" | 45 | #include "umac.h" |
46 | 46 | ||
47 | #include "openbsd-compat/openssl-compat.h" | 47 | #include "openbsd-compat/openssl-compat.h" |
48 | 48 | ||
49 | #define SSH_EVP 1 /* OpenSSL EVP-based MAC */ | 49 | #define SSH_DIGEST 1 /* SSH_DIGEST_XXX */ |
50 | #define SSH_UMAC 2 /* UMAC (not integrated with OpenSSL) */ | 50 | #define SSH_UMAC 2 /* UMAC (not integrated with OpenSSL) */ |
51 | #define SSH_UMAC128 3 | 51 | #define SSH_UMAC128 3 |
52 | 52 | ||
53 | struct macalg { | 53 | struct macalg { |
54 | char *name; | 54 | char *name; |
55 | int type; | 55 | int type; |
56 | const EVP_MD * (*mdfunc)(void); | 56 | int alg; |
57 | int truncatebits; /* truncate digest if != 0 */ | 57 | int truncatebits; /* truncate digest if != 0 */ |
58 | int key_len; /* just for UMAC */ | 58 | int key_len; /* just for UMAC */ |
59 | int len; /* just for UMAC */ | 59 | int len; /* just for UMAC */ |
@@ -62,33 +62,33 @@ struct macalg { | |||
62 | 62 | ||
63 | static const struct macalg macs[] = { | 63 | static const struct macalg macs[] = { |
64 | /* Encrypt-and-MAC (encrypt-and-authenticate) variants */ | 64 | /* Encrypt-and-MAC (encrypt-and-authenticate) variants */ |
65 | { "hmac-sha1", SSH_EVP, EVP_sha1, 0, 0, 0, 0 }, | 65 | { "hmac-sha1", SSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 0 }, |
66 | { "hmac-sha1-96", SSH_EVP, EVP_sha1, 96, 0, 0, 0 }, | 66 | { "hmac-sha1-96", SSH_DIGEST, SSH_DIGEST_SHA1, 96, 0, 0, 0 }, |
67 | #ifdef HAVE_EVP_SHA256 | 67 | #ifdef HAVE_EVP_SHA256 |
68 | { "hmac-sha2-256", SSH_EVP, EVP_sha256, 0, 0, 0, 0 }, | 68 | { "hmac-sha2-256", SSH_DIGEST, SSH_DIGEST_SHA256, 0, 0, 0, 0 }, |
69 | { "hmac-sha2-512", SSH_EVP, EVP_sha512, 0, 0, 0, 0 }, | 69 | { "hmac-sha2-512", SSH_DIGEST, SSH_DIGEST_SHA512, 0, 0, 0, 0 }, |
70 | #endif | 70 | #endif |
71 | { "hmac-md5", SSH_EVP, EVP_md5, 0, 0, 0, 0 }, | 71 | { "hmac-md5", SSH_DIGEST, SSH_DIGEST_MD5, 0, 0, 0, 0 }, |
72 | { "hmac-md5-96", SSH_EVP, EVP_md5, 96, 0, 0, 0 }, | 72 | { "hmac-md5-96", SSH_DIGEST, SSH_DIGEST_MD5, 96, 0, 0, 0 }, |
73 | { "hmac-ripemd160", SSH_EVP, EVP_ripemd160, 0, 0, 0, 0 }, | 73 | { "hmac-ripemd160", SSH_DIGEST, SSH_DIGEST_RIPEMD160, 0, 0, 0, 0 }, |
74 | { "hmac-ripemd160@openssh.com", SSH_EVP, EVP_ripemd160, 0, 0, 0, 0 }, | 74 | { "hmac-ripemd160@openssh.com", SSH_DIGEST, SSH_DIGEST_RIPEMD160, 0, 0, 0, 0 }, |
75 | { "umac-64@openssh.com", SSH_UMAC, NULL, 0, 128, 64, 0 }, | 75 | { "umac-64@openssh.com", SSH_UMAC, 0, 0, 128, 64, 0 }, |
76 | { "umac-128@openssh.com", SSH_UMAC128, NULL, 0, 128, 128, 0 }, | 76 | { "umac-128@openssh.com", SSH_UMAC128, 0, 0, 128, 128, 0 }, |
77 | 77 | ||
78 | /* Encrypt-then-MAC variants */ | 78 | /* Encrypt-then-MAC variants */ |
79 | { "hmac-sha1-etm@openssh.com", SSH_EVP, EVP_sha1, 0, 0, 0, 1 }, | 79 | { "hmac-sha1-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA1, 0, 0, 0, 1 }, |
80 | { "hmac-sha1-96-etm@openssh.com", SSH_EVP, EVP_sha1, 96, 0, 0, 1 }, | 80 | { "hmac-sha1-96-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA1, 96, 0, 0, 1 }, |
81 | #ifdef HAVE_EVP_SHA256 | 81 | #ifdef HAVE_EVP_SHA256 |
82 | { "hmac-sha2-256-etm@openssh.com", SSH_EVP, EVP_sha256, 0, 0, 0, 1 }, | 82 | { "hmac-sha2-256-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA256, 0, 0, 0, 1 }, |
83 | { "hmac-sha2-512-etm@openssh.com", SSH_EVP, EVP_sha512, 0, 0, 0, 1 }, | 83 | { "hmac-sha2-512-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_SHA512, 0, 0, 0, 1 }, |
84 | #endif | 84 | #endif |
85 | { "hmac-md5-etm@openssh.com", SSH_EVP, EVP_md5, 0, 0, 0, 1 }, | 85 | { "hmac-md5-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_MD5, 0, 0, 0, 1 }, |
86 | { "hmac-md5-96-etm@openssh.com", SSH_EVP, EVP_md5, 96, 0, 0, 1 }, | 86 | { "hmac-md5-96-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_MD5, 96, 0, 0, 1 }, |
87 | { "hmac-ripemd160-etm@openssh.com", SSH_EVP, EVP_ripemd160, 0, 0, 0, 1 }, | 87 | { "hmac-ripemd160-etm@openssh.com", SSH_DIGEST, SSH_DIGEST_RIPEMD160, 0, 0, 0, 1 }, |
88 | { "umac-64-etm@openssh.com", SSH_UMAC, NULL, 0, 128, 64, 1 }, | 88 | { "umac-64-etm@openssh.com", SSH_UMAC, 0, 0, 128, 64, 1 }, |
89 | { "umac-128-etm@openssh.com", SSH_UMAC128, NULL, 0, 128, 128, 1 }, | 89 | { "umac-128-etm@openssh.com", SSH_UMAC128, 0, 0, 128, 128, 1 }, |
90 | 90 | ||
91 | { NULL, 0, NULL, 0, 0, 0, 0 } | 91 | { NULL, 0, 0, 0, 0, 0, 0 } |
92 | }; | 92 | }; |
93 | 93 | ||
94 | /* Returns a list of supported MACs separated by the specified char. */ | 94 | /* Returns a list of supported MACs separated by the specified char. */ |
@@ -113,14 +113,11 @@ mac_alg_list(char sep) | |||
113 | static void | 113 | static void |
114 | mac_setup_by_alg(Mac *mac, const struct macalg *macalg) | 114 | mac_setup_by_alg(Mac *mac, const struct macalg *macalg) |
115 | { | 115 | { |
116 | int evp_len; | ||
117 | |||
118 | mac->type = macalg->type; | 116 | mac->type = macalg->type; |
119 | if (mac->type == SSH_EVP) { | 117 | if (mac->type == SSH_DIGEST) { |
120 | mac->evp_md = macalg->mdfunc(); | 118 | if ((mac->hmac_ctx = ssh_hmac_start(macalg->alg)) == NULL) |
121 | if ((evp_len = EVP_MD_size(mac->evp_md)) <= 0) | 119 | fatal("ssh_hmac_start(alg=%d) failed", macalg->alg); |
122 | fatal("mac %s len %d", mac->name, evp_len); | 120 | mac->key_len = mac->mac_len = ssh_hmac_bytes(macalg->alg); |
123 | mac->key_len = mac->mac_len = (u_int)evp_len; | ||
124 | } else { | 121 | } else { |
125 | mac->mac_len = macalg->len / 8; | 122 | mac->mac_len = macalg->len / 8; |
126 | mac->key_len = macalg->key_len / 8; | 123 | mac->key_len = macalg->key_len / 8; |
@@ -154,11 +151,10 @@ mac_init(Mac *mac) | |||
154 | if (mac->key == NULL) | 151 | if (mac->key == NULL) |
155 | fatal("mac_init: no key"); | 152 | fatal("mac_init: no key"); |
156 | switch (mac->type) { | 153 | switch (mac->type) { |
157 | case SSH_EVP: | 154 | case SSH_DIGEST: |
158 | if (mac->evp_md == NULL) | 155 | if (mac->hmac_ctx == NULL || |
156 | ssh_hmac_init(mac->hmac_ctx, mac->key, mac->key_len) < 0) | ||
159 | return -1; | 157 | return -1; |
160 | HMAC_CTX_init(&mac->evp_ctx); | ||
161 | HMAC_Init(&mac->evp_ctx, mac->key, mac->key_len, mac->evp_md); | ||
162 | return 0; | 158 | return 0; |
163 | case SSH_UMAC: | 159 | case SSH_UMAC: |
164 | mac->umac_ctx = umac_new(mac->key); | 160 | mac->umac_ctx = umac_new(mac->key); |
@@ -185,13 +181,14 @@ mac_compute(Mac *mac, u_int32_t seqno, u_char *data, int datalen) | |||
185 | mac->mac_len, sizeof(u)); | 181 | mac->mac_len, sizeof(u)); |
186 | 182 | ||
187 | switch (mac->type) { | 183 | switch (mac->type) { |
188 | case SSH_EVP: | 184 | case SSH_DIGEST: |
189 | put_u32(b, seqno); | 185 | put_u32(b, seqno); |
190 | /* reset HMAC context */ | 186 | /* reset HMAC context */ |
191 | HMAC_Init(&mac->evp_ctx, NULL, 0, NULL); | 187 | if (ssh_hmac_init(mac->hmac_ctx, NULL, 0) < 0 || |
192 | HMAC_Update(&mac->evp_ctx, b, sizeof(b)); | 188 | ssh_hmac_update(mac->hmac_ctx, b, sizeof(b)) < 0 || |
193 | HMAC_Update(&mac->evp_ctx, data, datalen); | 189 | ssh_hmac_update(mac->hmac_ctx, data, datalen) < 0 || |
194 | HMAC_Final(&mac->evp_ctx, u.m, NULL); | 190 | ssh_hmac_final(mac->hmac_ctx, u.m, sizeof(u.m)) < 0) |
191 | fatal("ssh_hmac failed"); | ||
195 | break; | 192 | break; |
196 | case SSH_UMAC: | 193 | case SSH_UMAC: |
197 | put_u64(nonce, seqno); | 194 | put_u64(nonce, seqno); |
@@ -218,9 +215,9 @@ mac_clear(Mac *mac) | |||
218 | } else if (mac->type == SSH_UMAC128) { | 215 | } else if (mac->type == SSH_UMAC128) { |
219 | if (mac->umac_ctx != NULL) | 216 | if (mac->umac_ctx != NULL) |
220 | umac128_delete(mac->umac_ctx); | 217 | umac128_delete(mac->umac_ctx); |
221 | } else if (mac->evp_md != NULL) | 218 | } else if (mac->hmac_ctx != NULL) |
222 | HMAC_cleanup(&mac->evp_ctx); | 219 | ssh_hmac_free(mac->hmac_ctx); |
223 | mac->evp_md = NULL; | 220 | mac->hmac_ctx = NULL; |
224 | mac->umac_ctx = NULL; | 221 | mac->umac_ctx = NULL; |
225 | } | 222 | } |
226 | 223 | ||