diff options
author | Colin Watson <cjwatson@debian.org> | 2013-09-14 15:43:03 +0100 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2013-09-14 15:43:03 +0100 |
commit | 8faf8c84430cf3c19705b1d9f8889d256e7fd1fd (patch) | |
tree | e6cb74192adb00fda5e4d1457547851d7e0d86af /mac.c | |
parent | 328b60656f29db6306994d7498dede386ec2d1c3 (diff) | |
parent | c41345ad7ee5a22689e2c009595e85fa27b4b39a (diff) |
merge 6.3p1
Diffstat (limited to 'mac.c')
-rw-r--r-- | mac.c | 83 |
1 files changed, 54 insertions, 29 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: mac.c,v 1.21 2012/12/11 22:51:45 sthen Exp $ */ | 1 | /* $OpenBSD: mac.c,v 1.24 2013/06/03 00:03:18 dtucker Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -50,7 +50,7 @@ | |||
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 { | 53 | struct macalg { |
54 | char *name; | 54 | char *name; |
55 | int type; | 55 | int type; |
56 | const EVP_MD * (*mdfunc)(void); | 56 | const EVP_MD * (*mdfunc)(void); |
@@ -58,7 +58,9 @@ struct { | |||
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 */ |
60 | int etm; /* Encrypt-then-MAC */ | 60 | int etm; /* Encrypt-then-MAC */ |
61 | } macs[] = { | 61 | }; |
62 | |||
63 | static const struct macalg macs[] = { | ||
62 | /* Encrypt-and-MAC (encrypt-and-authenticate) variants */ | 64 | /* Encrypt-and-MAC (encrypt-and-authenticate) variants */ |
63 | { "hmac-sha1", SSH_EVP, EVP_sha1, 0, 0, 0, 0 }, | 65 | { "hmac-sha1", SSH_EVP, EVP_sha1, 0, 0, 0, 0 }, |
64 | { "hmac-sha1-96", SSH_EVP, EVP_sha1, 96, 0, 0, 0 }, | 66 | { "hmac-sha1-96", SSH_EVP, EVP_sha1, 96, 0, 0, 0 }, |
@@ -89,38 +91,58 @@ struct { | |||
89 | { NULL, 0, NULL, 0, 0, 0, 0 } | 91 | { NULL, 0, NULL, 0, 0, 0, 0 } |
90 | }; | 92 | }; |
91 | 93 | ||
94 | /* Returns a comma-separated list of supported MACs. */ | ||
95 | char * | ||
96 | mac_alg_list(void) | ||
97 | { | ||
98 | char *ret = NULL; | ||
99 | size_t nlen, rlen = 0; | ||
100 | const struct macalg *m; | ||
101 | |||
102 | for (m = macs; m->name != NULL; m++) { | ||
103 | if (ret != NULL) | ||
104 | ret[rlen++] = '\n'; | ||
105 | nlen = strlen(m->name); | ||
106 | ret = xrealloc(ret, 1, rlen + nlen + 2); | ||
107 | memcpy(ret + rlen, m->name, nlen + 1); | ||
108 | rlen += nlen; | ||
109 | } | ||
110 | return ret; | ||
111 | } | ||
112 | |||
92 | static void | 113 | static void |
93 | mac_setup_by_id(Mac *mac, int which) | 114 | mac_setup_by_alg(Mac *mac, const struct macalg *macalg) |
94 | { | 115 | { |
95 | int evp_len; | 116 | int evp_len; |
96 | mac->type = macs[which].type; | 117 | |
118 | mac->type = macalg->type; | ||
97 | if (mac->type == SSH_EVP) { | 119 | if (mac->type == SSH_EVP) { |
98 | mac->evp_md = (*macs[which].mdfunc)(); | 120 | mac->evp_md = macalg->mdfunc(); |
99 | if ((evp_len = EVP_MD_size(mac->evp_md)) <= 0) | 121 | if ((evp_len = EVP_MD_size(mac->evp_md)) <= 0) |
100 | fatal("mac %s len %d", mac->name, evp_len); | 122 | fatal("mac %s len %d", mac->name, evp_len); |
101 | mac->key_len = mac->mac_len = (u_int)evp_len; | 123 | mac->key_len = mac->mac_len = (u_int)evp_len; |
102 | } else { | 124 | } else { |
103 | mac->mac_len = macs[which].len / 8; | 125 | mac->mac_len = macalg->len / 8; |
104 | mac->key_len = macs[which].key_len / 8; | 126 | mac->key_len = macalg->key_len / 8; |
105 | mac->umac_ctx = NULL; | 127 | mac->umac_ctx = NULL; |
106 | } | 128 | } |
107 | if (macs[which].truncatebits != 0) | 129 | if (macalg->truncatebits != 0) |
108 | mac->mac_len = macs[which].truncatebits / 8; | 130 | mac->mac_len = macalg->truncatebits / 8; |
109 | mac->etm = macs[which].etm; | 131 | mac->etm = macalg->etm; |
110 | } | 132 | } |
111 | 133 | ||
112 | int | 134 | int |
113 | mac_setup(Mac *mac, char *name) | 135 | mac_setup(Mac *mac, char *name) |
114 | { | 136 | { |
115 | int i; | 137 | const struct macalg *m; |
116 | 138 | ||
117 | for (i = 0; macs[i].name; i++) { | 139 | for (m = macs; m->name != NULL; m++) { |
118 | if (strcmp(name, macs[i].name) == 0) { | 140 | if (strcmp(name, m->name) != 0) |
119 | if (mac != NULL) | 141 | continue; |
120 | mac_setup_by_id(mac, i); | 142 | if (mac != NULL) |
121 | debug2("mac_setup: found %s", name); | 143 | mac_setup_by_alg(mac, m); |
122 | return (0); | 144 | debug2("mac_setup: found %s", name); |
123 | } | 145 | return (0); |
124 | } | 146 | } |
125 | debug2("mac_setup: unknown %s", name); | 147 | debug2("mac_setup: unknown %s", name); |
126 | return (-1); | 148 | return (-1); |
@@ -152,12 +174,15 @@ mac_init(Mac *mac) | |||
152 | u_char * | 174 | u_char * |
153 | mac_compute(Mac *mac, u_int32_t seqno, u_char *data, int datalen) | 175 | mac_compute(Mac *mac, u_int32_t seqno, u_char *data, int datalen) |
154 | { | 176 | { |
155 | static u_char m[EVP_MAX_MD_SIZE]; | 177 | static union { |
178 | u_char m[EVP_MAX_MD_SIZE]; | ||
179 | u_int64_t for_align; | ||
180 | } u; | ||
156 | u_char b[4], nonce[8]; | 181 | u_char b[4], nonce[8]; |
157 | 182 | ||
158 | if (mac->mac_len > sizeof(m)) | 183 | if (mac->mac_len > sizeof(u)) |
159 | fatal("mac_compute: mac too long %u %lu", | 184 | fatal("mac_compute: mac too long %u %lu", |
160 | mac->mac_len, (u_long)sizeof(m)); | 185 | mac->mac_len, (u_long)sizeof(u)); |
161 | 186 | ||
162 | switch (mac->type) { | 187 | switch (mac->type) { |
163 | case SSH_EVP: | 188 | case SSH_EVP: |
@@ -166,22 +191,22 @@ mac_compute(Mac *mac, u_int32_t seqno, u_char *data, int datalen) | |||
166 | HMAC_Init(&mac->evp_ctx, NULL, 0, NULL); | 191 | HMAC_Init(&mac->evp_ctx, NULL, 0, NULL); |
167 | HMAC_Update(&mac->evp_ctx, b, sizeof(b)); | 192 | HMAC_Update(&mac->evp_ctx, b, sizeof(b)); |
168 | HMAC_Update(&mac->evp_ctx, data, datalen); | 193 | HMAC_Update(&mac->evp_ctx, data, datalen); |
169 | HMAC_Final(&mac->evp_ctx, m, NULL); | 194 | HMAC_Final(&mac->evp_ctx, u.m, NULL); |
170 | break; | 195 | break; |
171 | case SSH_UMAC: | 196 | case SSH_UMAC: |
172 | put_u64(nonce, seqno); | 197 | put_u64(nonce, seqno); |
173 | umac_update(mac->umac_ctx, data, datalen); | 198 | umac_update(mac->umac_ctx, data, datalen); |
174 | umac_final(mac->umac_ctx, m, nonce); | 199 | umac_final(mac->umac_ctx, u.m, nonce); |
175 | break; | 200 | break; |
176 | case SSH_UMAC128: | 201 | case SSH_UMAC128: |
177 | put_u64(nonce, seqno); | 202 | put_u64(nonce, seqno); |
178 | umac128_update(mac->umac_ctx, data, datalen); | 203 | umac128_update(mac->umac_ctx, data, datalen); |
179 | umac128_final(mac->umac_ctx, m, nonce); | 204 | umac128_final(mac->umac_ctx, u.m, nonce); |
180 | break; | 205 | break; |
181 | default: | 206 | default: |
182 | fatal("mac_compute: unknown MAC type"); | 207 | fatal("mac_compute: unknown MAC type"); |
183 | } | 208 | } |
184 | return (m); | 209 | return (u.m); |
185 | } | 210 | } |
186 | 211 | ||
187 | void | 212 | void |
@@ -213,13 +238,13 @@ mac_valid(const char *names) | |||
213 | (p = strsep(&cp, MAC_SEP))) { | 238 | (p = strsep(&cp, MAC_SEP))) { |
214 | if (mac_setup(NULL, p) < 0) { | 239 | if (mac_setup(NULL, p) < 0) { |
215 | debug("bad mac %s [%s]", p, names); | 240 | debug("bad mac %s [%s]", p, names); |
216 | xfree(maclist); | 241 | free(maclist); |
217 | return (0); | 242 | return (0); |
218 | } else { | 243 | } else { |
219 | debug3("mac ok: %s [%s]", p, names); | 244 | debug3("mac ok: %s [%s]", p, names); |
220 | } | 245 | } |
221 | } | 246 | } |
222 | debug3("macs ok: [%s]", names); | 247 | debug3("macs ok: [%s]", names); |
223 | xfree(maclist); | 248 | free(maclist); |
224 | return (1); | 249 | return (1); |
225 | } | 250 | } |