diff options
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | Makefile.in | 4 | ||||
-rw-r--r-- | digest.c | 25 | ||||
-rw-r--r-- | digest.h | 12 | ||||
-rw-r--r-- | hmac.c | 197 | ||||
-rw-r--r-- | hmac.h | 37 | ||||
-rw-r--r-- | hostfile.c | 29 | ||||
-rw-r--r-- | kex.h | 7 | ||||
-rw-r--r-- | mac.c | 85 |
9 files changed, 332 insertions, 71 deletions
@@ -1,3 +1,10 @@ | |||
1 | 20140204 | ||
2 | - OpenBSD CVS Sync | ||
3 | - markus@cvs.openbsd.org 2014/01/27 18:58:14 | ||
4 | [Makefile.in digest.c digest.h hostfile.c kex.h mac.c hmac.c hmac.h] | ||
5 | replace openssl HMAC with an implementation based on our ssh_digest_* | ||
6 | ok and feedback djm@ | ||
7 | |||
1 | 20140131 | 8 | 20140131 |
2 | - (djm) [sandbox-seccomp-filter.c sandbox-systrace.c] Allow shutdown(2) | 9 | - (djm) [sandbox-seccomp-filter.c sandbox-systrace.c] Allow shutdown(2) |
3 | syscall from sandboxes; it may be called by packet_close. | 10 | syscall from sandboxes; it may be called by packet_close. |
diff --git a/Makefile.in b/Makefile.in index 41f704bb4..99ac27ebb 100644 --- a/Makefile.in +++ b/Makefile.in | |||
@@ -1,4 +1,4 @@ | |||
1 | # $Id: Makefile.in,v 1.353 2014/01/31 22:25:19 tim Exp $ | 1 | # $Id: Makefile.in,v 1.354 2014/02/04 00:02:43 djm Exp $ |
2 | 2 | ||
3 | # uncomment if you run a non bourne compatable shell. Ie. csh | 3 | # uncomment if you run a non bourne compatable shell. Ie. csh |
4 | #SHELL = @SH@ | 4 | #SHELL = @SH@ |
@@ -75,7 +75,7 @@ LIBSSH_OBJS=authfd.o authfile.o bufaux.o bufbn.o buffer.o \ | |||
75 | msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ | 75 | msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ |
76 | jpake.o schnorr.o ssh-pkcs11.o krl.o smult_curve25519_ref.o \ | 76 | jpake.o schnorr.o ssh-pkcs11.o krl.o smult_curve25519_ref.o \ |
77 | kexc25519.o kexc25519c.o poly1305.o chacha.o cipher-chachapoly.o \ | 77 | kexc25519.o kexc25519c.o poly1305.o chacha.o cipher-chachapoly.o \ |
78 | ssh-ed25519.o digest.o \ | 78 | ssh-ed25519.o digest.o hmac.o \ |
79 | sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o blocks.o | 79 | sc25519.o ge25519.o fe25519.o ed25519.o verify.o hash.o blocks.o |
80 | 80 | ||
81 | SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ | 81 | SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: digest.c,v 1.3 2014/01/20 00:08:48 djm Exp $ */ | 1 | /* $OpenBSD: digest.c,v 1.4 2014/01/27 18:58:14 markus Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2013 Damien Miller <djm@mindrot.org> | 3 | * Copyright (c) 2013 Damien Miller <djm@mindrot.org> |
4 | * | 4 | * |
@@ -72,6 +72,12 @@ ssh_digest_bytes(int alg) | |||
72 | return digest == NULL ? 0 : digest->digest_len; | 72 | return digest == NULL ? 0 : digest->digest_len; |
73 | } | 73 | } |
74 | 74 | ||
75 | size_t | ||
76 | ssh_digest_blocksize(struct ssh_digest_ctx *ctx) | ||
77 | { | ||
78 | return EVP_MD_CTX_block_size(&ctx->mdctx); | ||
79 | } | ||
80 | |||
75 | struct ssh_digest_ctx * | 81 | struct ssh_digest_ctx * |
76 | ssh_digest_start(int alg) | 82 | ssh_digest_start(int alg) |
77 | { | 83 | { |
@@ -90,6 +96,15 @@ ssh_digest_start(int alg) | |||
90 | } | 96 | } |
91 | 97 | ||
92 | int | 98 | int |
99 | ssh_digest_copy_state(struct ssh_digest_ctx *from, struct ssh_digest_ctx *to) | ||
100 | { | ||
101 | /* we have bcopy-style order while openssl has memcpy-style */ | ||
102 | if (!EVP_MD_CTX_copy_ex(&to->mdctx, &from->mdctx)) | ||
103 | return -1; | ||
104 | return 0; | ||
105 | } | ||
106 | |||
107 | int | ||
93 | ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen) | 108 | ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen) |
94 | { | 109 | { |
95 | if (EVP_DigestUpdate(&ctx->mdctx, m, mlen) != 1) | 110 | if (EVP_DigestUpdate(&ctx->mdctx, m, mlen) != 1) |
@@ -123,9 +138,11 @@ ssh_digest_final(struct ssh_digest_ctx *ctx, u_char *d, size_t dlen) | |||
123 | void | 138 | void |
124 | ssh_digest_free(struct ssh_digest_ctx *ctx) | 139 | ssh_digest_free(struct ssh_digest_ctx *ctx) |
125 | { | 140 | { |
126 | EVP_MD_CTX_cleanup(&ctx->mdctx); | 141 | if (ctx != NULL) { |
127 | memset(ctx, 0, sizeof(*ctx)); | 142 | EVP_MD_CTX_cleanup(&ctx->mdctx); |
128 | free(ctx); | 143 | memset(ctx, 0, sizeof(*ctx)); |
144 | free(ctx); | ||
145 | } | ||
129 | } | 146 | } |
130 | 147 | ||
131 | int | 148 | int |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: digest.h,v 1.1 2014/01/09 23:20:00 djm Exp $ */ | 1 | /* $OpenBSD: digest.h,v 1.2 2014/01/27 18:58:14 markus Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2013 Damien Miller <djm@mindrot.org> | 3 | * Copyright (c) 2013 Damien Miller <djm@mindrot.org> |
4 | * | 4 | * |
@@ -30,9 +30,18 @@ | |||
30 | #define SSH_DIGEST_SHA512 5 | 30 | #define SSH_DIGEST_SHA512 5 |
31 | #define SSH_DIGEST_MAX 6 | 31 | #define SSH_DIGEST_MAX 6 |
32 | 32 | ||
33 | struct ssh_digest_ctx; | ||
34 | |||
33 | /* Returns the algorithm's digest length in bytes or 0 for invalid algorithm */ | 35 | /* Returns the algorithm's digest length in bytes or 0 for invalid algorithm */ |
34 | size_t ssh_digest_bytes(int alg); | 36 | size_t ssh_digest_bytes(int alg); |
35 | 37 | ||
38 | /* Returns the block size of the digest, e.g. for implementing HMAC */ | ||
39 | size_t ssh_digest_blocksize(struct ssh_digest_ctx *ctx); | ||
40 | |||
41 | /* Copies internal state of digest of 'from' to 'to' */ | ||
42 | int ssh_digest_copy_state(struct ssh_digest_ctx *from, | ||
43 | struct ssh_digest_ctx *to); | ||
44 | |||
36 | /* One-shot API */ | 45 | /* One-shot API */ |
37 | int ssh_digest_memory(int alg, const void *m, size_t mlen, | 46 | int ssh_digest_memory(int alg, const void *m, size_t mlen, |
38 | u_char *d, size_t dlen) | 47 | u_char *d, size_t dlen) |
@@ -42,7 +51,6 @@ int ssh_digest_buffer(int alg, const Buffer *b, u_char *d, size_t dlen) | |||
42 | __attribute__((__bounded__(__buffer__, 3, 4))); | 51 | __attribute__((__bounded__(__buffer__, 3, 4))); |
43 | 52 | ||
44 | /* Update API */ | 53 | /* Update API */ |
45 | struct ssh_digest_ctx; | ||
46 | struct ssh_digest_ctx *ssh_digest_start(int alg); | 54 | struct ssh_digest_ctx *ssh_digest_start(int alg); |
47 | int ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen) | 55 | int ssh_digest_update(struct ssh_digest_ctx *ctx, const void *m, size_t mlen) |
48 | __attribute__((__bounded__(__buffer__, 2, 3))); | 56 | __attribute__((__bounded__(__buffer__, 2, 3))); |
@@ -0,0 +1,197 @@ | |||
1 | /* $OpenBSD: hmac.c,v 1.10 2014/01/31 16:39:19 tedu Exp $ */ | ||
2 | /* | ||
3 | * Copyright (c) 2014 Markus Friedl. All rights reserved. | ||
4 | * | ||
5 | * Permission to use, copy, modify, and distribute this software for any | ||
6 | * purpose with or without fee is hereby granted, provided that the above | ||
7 | * copyright notice and this permission notice appear in all copies. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
16 | */ | ||
17 | |||
18 | #include "includes.h" | ||
19 | |||
20 | #include <sys/types.h> | ||
21 | #include <string.h> | ||
22 | |||
23 | #include "buffer.h" | ||
24 | #include "digest.h" | ||
25 | #include "hmac.h" | ||
26 | |||
27 | struct ssh_hmac_ctx { | ||
28 | int alg; | ||
29 | struct ssh_digest_ctx *ictx; | ||
30 | struct ssh_digest_ctx *octx; | ||
31 | struct ssh_digest_ctx *digest; | ||
32 | u_char *buf; | ||
33 | size_t buf_len; | ||
34 | }; | ||
35 | |||
36 | size_t | ||
37 | ssh_hmac_bytes(int alg) | ||
38 | { | ||
39 | return ssh_digest_bytes(alg); | ||
40 | } | ||
41 | |||
42 | struct ssh_hmac_ctx * | ||
43 | ssh_hmac_start(int alg) | ||
44 | { | ||
45 | struct ssh_hmac_ctx *ret; | ||
46 | |||
47 | if ((ret = calloc(1, sizeof(*ret))) == NULL) | ||
48 | return NULL; | ||
49 | ret->alg = alg; | ||
50 | if ((ret->ictx = ssh_digest_start(alg)) == NULL || | ||
51 | (ret->octx = ssh_digest_start(alg)) == NULL || | ||
52 | (ret->digest = ssh_digest_start(alg)) == NULL) | ||
53 | goto fail; | ||
54 | ret->buf_len = ssh_digest_blocksize(ret->ictx); | ||
55 | if ((ret->buf = calloc(1, ret->buf_len)) == NULL) | ||
56 | goto fail; | ||
57 | return ret; | ||
58 | fail: | ||
59 | ssh_hmac_free(ret); | ||
60 | return NULL; | ||
61 | } | ||
62 | |||
63 | int | ||
64 | ssh_hmac_init(struct ssh_hmac_ctx *ctx, const void *key, size_t klen) | ||
65 | { | ||
66 | size_t i; | ||
67 | |||
68 | /* reset ictx and octx if no is key given */ | ||
69 | if (key != NULL) { | ||
70 | /* truncate long keys */ | ||
71 | if (klen <= ctx->buf_len) | ||
72 | memcpy(ctx->buf, key, klen); | ||
73 | else if (ssh_digest_memory(ctx->alg, key, klen, ctx->buf, | ||
74 | ctx->buf_len) < 0) | ||
75 | return -1; | ||
76 | for (i = 0; i < ctx->buf_len; i++) | ||
77 | ctx->buf[i] ^= 0x36; | ||
78 | if (ssh_digest_update(ctx->ictx, ctx->buf, ctx->buf_len) < 0) | ||
79 | return -1; | ||
80 | for (i = 0; i < ctx->buf_len; i++) | ||
81 | ctx->buf[i] ^= 0x36 ^ 0x5c; | ||
82 | if (ssh_digest_update(ctx->octx, ctx->buf, ctx->buf_len) < 0) | ||
83 | return -1; | ||
84 | explicit_bzero(ctx->buf, ctx->buf_len); | ||
85 | } | ||
86 | /* start with ictx */ | ||
87 | if (ssh_digest_copy_state(ctx->ictx, ctx->digest) < 0) | ||
88 | return -1; | ||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | int | ||
93 | ssh_hmac_update(struct ssh_hmac_ctx *ctx, const void *m, size_t mlen) | ||
94 | { | ||
95 | return ssh_digest_update(ctx->digest, m, mlen); | ||
96 | } | ||
97 | |||
98 | int | ||
99 | ssh_hmac_update_buffer(struct ssh_hmac_ctx *ctx, const Buffer *b) | ||
100 | { | ||
101 | return ssh_digest_update_buffer(ctx->digest, b); | ||
102 | } | ||
103 | |||
104 | int | ||
105 | ssh_hmac_final(struct ssh_hmac_ctx *ctx, u_char *d, size_t dlen) | ||
106 | { | ||
107 | size_t len; | ||
108 | |||
109 | len = ssh_digest_bytes(ctx->alg); | ||
110 | if (dlen < len || | ||
111 | ssh_digest_final(ctx->digest, ctx->buf, len)) | ||
112 | return -1; | ||
113 | /* switch to octx */ | ||
114 | if (ssh_digest_copy_state(ctx->octx, ctx->digest) < 0 || | ||
115 | ssh_digest_update(ctx->digest, ctx->buf, len) < 0 || | ||
116 | ssh_digest_final(ctx->digest, d, dlen) < 0) | ||
117 | return -1; | ||
118 | return 0; | ||
119 | } | ||
120 | |||
121 | void | ||
122 | ssh_hmac_free(struct ssh_hmac_ctx *ctx) | ||
123 | { | ||
124 | if (ctx != NULL) { | ||
125 | ssh_digest_free(ctx->ictx); | ||
126 | ssh_digest_free(ctx->octx); | ||
127 | ssh_digest_free(ctx->digest); | ||
128 | if (ctx->buf) { | ||
129 | explicit_bzero(ctx->buf, ctx->buf_len); | ||
130 | free(ctx->buf); | ||
131 | } | ||
132 | explicit_bzero(ctx, sizeof(*ctx)); | ||
133 | free(ctx); | ||
134 | } | ||
135 | } | ||
136 | |||
137 | #ifdef TEST | ||
138 | |||
139 | /* cc -DTEST hmac.c digest.c buffer.c cleanup.c fatal.c log.c xmalloc.c -lcrypto */ | ||
140 | static void | ||
141 | hmac_test(void *key, size_t klen, void *m, size_t mlen, u_char *e, size_t elen) | ||
142 | { | ||
143 | struct ssh_hmac_ctx *ctx; | ||
144 | size_t i; | ||
145 | u_char digest[16]; | ||
146 | |||
147 | if ((ctx = ssh_hmac_start(SSH_DIGEST_MD5)) == NULL) | ||
148 | printf("ssh_hmac_start failed"); | ||
149 | if (ssh_hmac_init(ctx, key, klen) < 0 || | ||
150 | ssh_hmac_update(ctx, m, mlen) < 0 || | ||
151 | ssh_hmac_final(ctx, digest, sizeof(digest)) < 0) | ||
152 | printf("ssh_hmac_xxx failed"); | ||
153 | ssh_hmac_free(ctx); | ||
154 | |||
155 | if (memcmp(e, digest, elen)) { | ||
156 | for (i = 0; i < elen; i++) | ||
157 | printf("[%zd] %2.2x %2.2x\n", i, e[i], digest[i]); | ||
158 | printf("mismatch\n"); | ||
159 | } else | ||
160 | printf("ok\n"); | ||
161 | } | ||
162 | |||
163 | int | ||
164 | main(int argc, char **argv) | ||
165 | { | ||
166 | /* try test vectors from RFC 2104 */ | ||
167 | |||
168 | u_char key1[16] = { | ||
169 | 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, | ||
170 | 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb, 0xb }; | ||
171 | u_char *data1 = "Hi There"; | ||
172 | u_char dig1[16] = { | ||
173 | 0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c, | ||
174 | 0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d }; | ||
175 | |||
176 | u_char *key2 = "Jefe"; | ||
177 | u_char *data2 = "what do ya want for nothing?"; | ||
178 | u_char dig2[16] = { | ||
179 | 0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03, | ||
180 | 0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38 }; | ||
181 | |||
182 | u_char key3[16]; | ||
183 | u_char data3[50]; | ||
184 | u_char dig3[16] = { | ||
185 | 0x56, 0xbe, 0x34, 0x52, 0x1d, 0x14, 0x4c, 0x88, | ||
186 | 0xdb, 0xb8, 0xc7, 0x33, 0xf0, 0xe8, 0xb3, 0xf6 }; | ||
187 | memset(key3, 0xaa, sizeof(key3)); | ||
188 | memset(data3, 0xdd, sizeof(data3)); | ||
189 | |||
190 | hmac_test(key1, sizeof(key1), data1, strlen(data1), dig1, sizeof(dig1)); | ||
191 | hmac_test(key2, strlen(key2), data2, strlen(data2), dig2, sizeof(dig2)); | ||
192 | hmac_test(key3, sizeof(key3), data3, sizeof(data3), dig3, sizeof(dig3)); | ||
193 | |||
194 | return 0; | ||
195 | } | ||
196 | |||
197 | #endif | ||
@@ -0,0 +1,37 @@ | |||
1 | /* $OpenBSD: hmac.h,v 1.6 2014/01/27 18:58:14 markus Exp $ */ | ||
2 | /* | ||
3 | * Copyright (c) 2014 Markus Friedl. All rights reserved. | ||
4 | * | ||
5 | * Permission to use, copy, modify, and distribute this software for any | ||
6 | * purpose with or without fee is hereby granted, provided that the above | ||
7 | * copyright notice and this permission notice appear in all copies. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
16 | */ | ||
17 | |||
18 | #ifndef _HMAC_H | ||
19 | #define _HMAC_H | ||
20 | |||
21 | /* Returns the algorithm's digest length in bytes or 0 for invalid algorithm */ | ||
22 | size_t ssh_hmac_bytes(int alg); | ||
23 | |||
24 | struct ssh_hmac_ctx; | ||
25 | struct ssh_hmac_ctx *ssh_hmac_start(int alg); | ||
26 | |||
27 | /* Sets the state of the HMAC or resets the state if key == NULL */ | ||
28 | int ssh_hmac_init(struct ssh_hmac_ctx *ctx, const void *key, size_t klen) | ||
29 | __attribute__((__bounded__(__buffer__, 2, 3))); | ||
30 | int ssh_hmac_update(struct ssh_hmac_ctx *ctx, const void *m, size_t mlen) | ||
31 | __attribute__((__bounded__(__buffer__, 2, 3))); | ||
32 | int ssh_hmac_update_buffer(struct ssh_hmac_ctx *ctx, const Buffer *b); | ||
33 | int ssh_hmac_final(struct ssh_hmac_ctx *ctx, u_char *d, size_t dlen) | ||
34 | __attribute__((__bounded__(__buffer__, 2, 3))); | ||
35 | void ssh_hmac_free(struct ssh_hmac_ctx *ctx); | ||
36 | |||
37 | #endif /* _HMAC_H */ | ||
diff --git a/hostfile.c b/hostfile.c index 2778fb5df..0198cd001 100644 --- a/hostfile.c +++ b/hostfile.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: hostfile.c,v 1.53 2014/01/09 23:20:00 djm Exp $ */ | 1 | /* $OpenBSD: hostfile.c,v 1.54 2014/01/27 18:58:14 markus Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -42,9 +42,6 @@ | |||
42 | 42 | ||
43 | #include <netinet/in.h> | 43 | #include <netinet/in.h> |
44 | 44 | ||
45 | #include <openssl/hmac.h> | ||
46 | #include <openssl/sha.h> | ||
47 | |||
48 | #include <resolv.h> | 45 | #include <resolv.h> |
49 | #include <stdarg.h> | 46 | #include <stdarg.h> |
50 | #include <stdio.h> | 47 | #include <stdio.h> |
@@ -58,6 +55,7 @@ | |||
58 | #include "log.h" | 55 | #include "log.h" |
59 | #include "misc.h" | 56 | #include "misc.h" |
60 | #include "digest.h" | 57 | #include "digest.h" |
58 | #include "hmac.h" | ||
61 | 59 | ||
62 | struct hostkeys { | 60 | struct hostkeys { |
63 | struct hostkey_entry *entries; | 61 | struct hostkey_entry *entries; |
@@ -102,9 +100,9 @@ extract_salt(const char *s, u_int l, u_char *salt, size_t salt_len) | |||
102 | debug2("extract_salt: salt decode error"); | 100 | debug2("extract_salt: salt decode error"); |
103 | return (-1); | 101 | return (-1); |
104 | } | 102 | } |
105 | if (ret != SHA_DIGEST_LENGTH) { | 103 | if (ret != (int)ssh_hmac_bytes(SSH_DIGEST_SHA1)) { |
106 | debug2("extract_salt: expected salt len %d, got %d", | 104 | debug2("extract_salt: expected salt len %zd, got %d", |
107 | SHA_DIGEST_LENGTH, ret); | 105 | ssh_hmac_bytes(SSH_DIGEST_SHA1), ret); |
108 | return (-1); | 106 | return (-1); |
109 | } | 107 | } |
110 | 108 | ||
@@ -114,14 +112,13 @@ extract_salt(const char *s, u_int l, u_char *salt, size_t salt_len) | |||
114 | char * | 112 | char * |
115 | host_hash(const char *host, const char *name_from_hostfile, u_int src_len) | 113 | host_hash(const char *host, const char *name_from_hostfile, u_int src_len) |
116 | { | 114 | { |
117 | const EVP_MD *md = EVP_sha1(); | 115 | struct ssh_hmac_ctx *ctx; |
118 | HMAC_CTX mac_ctx; | ||
119 | u_char salt[256], result[256]; | 116 | u_char salt[256], result[256]; |
120 | char uu_salt[512], uu_result[512]; | 117 | char uu_salt[512], uu_result[512]; |
121 | static char encoded[1024]; | 118 | static char encoded[1024]; |
122 | u_int i, len; | 119 | u_int i, len; |
123 | 120 | ||
124 | len = EVP_MD_size(md); | 121 | len = ssh_digest_bytes(SSH_DIGEST_SHA1); |
125 | 122 | ||
126 | if (name_from_hostfile == NULL) { | 123 | if (name_from_hostfile == NULL) { |
127 | /* Create new salt */ | 124 | /* Create new salt */ |
@@ -134,14 +131,16 @@ host_hash(const char *host, const char *name_from_hostfile, u_int src_len) | |||
134 | return (NULL); | 131 | return (NULL); |
135 | } | 132 | } |
136 | 133 | ||
137 | HMAC_Init(&mac_ctx, salt, len, md); | 134 | if ((ctx = ssh_hmac_start(SSH_DIGEST_SHA1)) == NULL || |
138 | HMAC_Update(&mac_ctx, (u_char *)host, strlen(host)); | 135 | ssh_hmac_init(ctx, salt, len) < 0 || |
139 | HMAC_Final(&mac_ctx, result, NULL); | 136 | ssh_hmac_update(ctx, host, strlen(host)) < 0 || |
140 | HMAC_cleanup(&mac_ctx); | 137 | ssh_hmac_final(ctx, result, sizeof(result))) |
138 | fatal("%s: ssh_hmac failed", __func__); | ||
139 | ssh_hmac_free(ctx); | ||
141 | 140 | ||
142 | if (__b64_ntop(salt, len, uu_salt, sizeof(uu_salt)) == -1 || | 141 | if (__b64_ntop(salt, len, uu_salt, sizeof(uu_salt)) == -1 || |
143 | __b64_ntop(result, len, uu_result, sizeof(uu_result)) == -1) | 142 | __b64_ntop(result, len, uu_result, sizeof(uu_result)) == -1) |
144 | fatal("host_hash: __b64_ntop failed"); | 143 | fatal("%s: __b64_ntop failed", __func__); |
145 | 144 | ||
146 | snprintf(encoded, sizeof(encoded), "%s%s%c%s", HASH_MAGIC, uu_salt, | 145 | snprintf(encoded, sizeof(encoded), "%s%s%c%s", HASH_MAGIC, uu_salt, |
147 | HASH_DELIM, uu_result); | 146 | HASH_DELIM, uu_result); |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: kex.h,v 1.61 2014/01/25 10:12:50 dtucker Exp $ */ | 1 | /* $OpenBSD: kex.h,v 1.62 2014/01/27 18:58:14 markus Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. | 4 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. |
@@ -105,9 +105,8 @@ struct Mac { | |||
105 | u_int key_len; | 105 | u_int key_len; |
106 | int type; | 106 | int type; |
107 | int etm; /* Encrypt-then-MAC */ | 107 | int etm; /* Encrypt-then-MAC */ |
108 | const EVP_MD *evp_md; | 108 | struct ssh_hmac_ctx *hmac_ctx; |
109 | HMAC_CTX evp_ctx; | 109 | struct umac_ctx *umac_ctx; |
110 | struct umac_ctx *umac_ctx; | ||
111 | }; | 110 | }; |
112 | struct Comp { | 111 | struct Comp { |
113 | int type; | 112 | int type; |
@@ -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 | ||