diff options
author | Damien Miller <djm@mindrot.org> | 2014-07-02 15:28:02 +1000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2014-07-02 15:28:02 +1000 |
commit | 8668706d0f52654fe64c0ca41a96113aeab8d2b8 (patch) | |
tree | 73e78e1ea3d39206e39870bbe0af17d6c430fb51 /cipher-3des1.c | |
parent | 2cd7929250cf9e9f658d70dcd452f529ba08c942 (diff) |
- djm@cvs.openbsd.org 2014/06/24 01:13:21
[Makefile.in auth-bsdauth.c auth-chall.c auth-options.c auth-rsa.c
[auth2-none.c auth2-pubkey.c authfile.c authfile.h cipher-3des1.c
[cipher-chachapoly.c cipher-chachapoly.h cipher.c cipher.h
[digest-libc.c digest-openssl.c digest.h dns.c entropy.c hmac.h
[hostfile.c key.c key.h krl.c monitor.c packet.c rsa.c rsa.h
[ssh-add.c ssh-agent.c ssh-dss.c ssh-ecdsa.c ssh-ed25519.c
[ssh-keygen.c ssh-pkcs11-client.c ssh-pkcs11-helper.c ssh-pkcs11.c
[ssh-rsa.c sshbuf-misc.c sshbuf.h sshconnect.c sshconnect1.c
[sshconnect2.c sshd.c sshkey.c sshkey.h
[openbsd-compat/openssl-compat.c openbsd-compat/openssl-compat.h]
New key API: refactor key-related functions to be more library-like,
existing API is offered as a set of wrappers.
with and ok markus@
Thanks also to Ben Hawkes, David Tomaschik, Ivan Fratric, Matthew
Dempsky and Ron Bowes for a detailed review a few months ago.
NB. This commit also removes portable OpenSSH support for OpenSSL
<0.9.8e.
Diffstat (limited to 'cipher-3des1.c')
-rw-r--r-- | cipher-3des1.c | 55 |
1 files changed, 18 insertions, 37 deletions
diff --git a/cipher-3des1.c b/cipher-3des1.c index b2823592b..5361f517d 100644 --- a/cipher-3des1.c +++ b/cipher-3des1.c | |||
@@ -29,13 +29,11 @@ | |||
29 | 29 | ||
30 | #include <openssl/evp.h> | 30 | #include <openssl/evp.h> |
31 | 31 | ||
32 | #include <stdarg.h> | ||
33 | #include <string.h> | 32 | #include <string.h> |
34 | 33 | ||
35 | #include "xmalloc.h" | 34 | #include "xmalloc.h" |
36 | #include "log.h" | 35 | #include "log.h" |
37 | 36 | #include "ssherr.h" | |
38 | #include "openbsd-compat/openssl-compat.h" | ||
39 | 37 | ||
40 | /* | 38 | /* |
41 | * This is used by SSH1: | 39 | * This is used by SSH1: |
@@ -57,7 +55,7 @@ struct ssh1_3des_ctx | |||
57 | }; | 55 | }; |
58 | 56 | ||
59 | const EVP_CIPHER * evp_ssh1_3des(void); | 57 | const EVP_CIPHER * evp_ssh1_3des(void); |
60 | void ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); | 58 | int ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); |
61 | 59 | ||
62 | static int | 60 | static int |
63 | ssh1_3des_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv, | 61 | ssh1_3des_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv, |
@@ -67,11 +65,12 @@ ssh1_3des_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv, | |||
67 | u_char *k1, *k2, *k3; | 65 | u_char *k1, *k2, *k3; |
68 | 66 | ||
69 | if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) { | 67 | if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) { |
70 | c = xcalloc(1, sizeof(*c)); | 68 | if ((c = calloc(1, sizeof(*c))) == NULL) |
69 | return 0; | ||
71 | EVP_CIPHER_CTX_set_app_data(ctx, c); | 70 | EVP_CIPHER_CTX_set_app_data(ctx, c); |
72 | } | 71 | } |
73 | if (key == NULL) | 72 | if (key == NULL) |
74 | return (1); | 73 | return 1; |
75 | if (enc == -1) | 74 | if (enc == -1) |
76 | enc = ctx->encrypt; | 75 | enc = ctx->encrypt; |
77 | k1 = k2 = k3 = (u_char *) key; | 76 | k1 = k2 = k3 = (u_char *) key; |
@@ -85,44 +84,29 @@ ssh1_3des_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv, | |||
85 | EVP_CIPHER_CTX_init(&c->k1); | 84 | EVP_CIPHER_CTX_init(&c->k1); |
86 | EVP_CIPHER_CTX_init(&c->k2); | 85 | EVP_CIPHER_CTX_init(&c->k2); |
87 | EVP_CIPHER_CTX_init(&c->k3); | 86 | EVP_CIPHER_CTX_init(&c->k3); |
88 | #ifdef SSH_OLD_EVP | ||
89 | EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc); | ||
90 | EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc); | ||
91 | EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc); | ||
92 | #else | ||
93 | if (EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 || | 87 | if (EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 || |
94 | EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 || | 88 | EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 || |
95 | EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) { | 89 | EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) { |
96 | explicit_bzero(c, sizeof(*c)); | 90 | explicit_bzero(c, sizeof(*c)); |
97 | free(c); | 91 | free(c); |
98 | EVP_CIPHER_CTX_set_app_data(ctx, NULL); | 92 | EVP_CIPHER_CTX_set_app_data(ctx, NULL); |
99 | return (0); | 93 | return 0; |
100 | } | 94 | } |
101 | #endif | 95 | return 1; |
102 | return (1); | ||
103 | } | 96 | } |
104 | 97 | ||
105 | static int | 98 | static int |
106 | ssh1_3des_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, | 99 | ssh1_3des_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, size_t len) |
107 | LIBCRYPTO_EVP_INL_TYPE len) | ||
108 | { | 100 | { |
109 | struct ssh1_3des_ctx *c; | 101 | struct ssh1_3des_ctx *c; |
110 | 102 | ||
111 | if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) { | 103 | if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) |
112 | error("ssh1_3des_cbc: no context"); | 104 | return 0; |
113 | return (0); | ||
114 | } | ||
115 | #ifdef SSH_OLD_EVP | ||
116 | EVP_Cipher(&c->k1, dest, (u_char *)src, len); | ||
117 | EVP_Cipher(&c->k2, dest, dest, len); | ||
118 | EVP_Cipher(&c->k3, dest, dest, len); | ||
119 | #else | ||
120 | if (EVP_Cipher(&c->k1, dest, (u_char *)src, len) == 0 || | 105 | if (EVP_Cipher(&c->k1, dest, (u_char *)src, len) == 0 || |
121 | EVP_Cipher(&c->k2, dest, dest, len) == 0 || | 106 | EVP_Cipher(&c->k2, dest, dest, len) == 0 || |
122 | EVP_Cipher(&c->k3, dest, dest, len) == 0) | 107 | EVP_Cipher(&c->k3, dest, dest, len) == 0) |
123 | return (0); | 108 | return 0; |
124 | #endif | 109 | return 1; |
125 | return (1); | ||
126 | } | 110 | } |
127 | 111 | ||
128 | static int | 112 | static int |
@@ -138,29 +122,28 @@ ssh1_3des_cleanup(EVP_CIPHER_CTX *ctx) | |||
138 | free(c); | 122 | free(c); |
139 | EVP_CIPHER_CTX_set_app_data(ctx, NULL); | 123 | EVP_CIPHER_CTX_set_app_data(ctx, NULL); |
140 | } | 124 | } |
141 | return (1); | 125 | return 1; |
142 | } | 126 | } |
143 | 127 | ||
144 | void | 128 | int |
145 | ssh1_3des_iv(EVP_CIPHER_CTX *evp, int doset, u_char *iv, int len) | 129 | ssh1_3des_iv(EVP_CIPHER_CTX *evp, int doset, u_char *iv, int len) |
146 | { | 130 | { |
147 | struct ssh1_3des_ctx *c; | 131 | struct ssh1_3des_ctx *c; |
148 | 132 | ||
149 | if (len != 24) | 133 | if (len != 24) |
150 | fatal("%s: bad 3des iv length: %d", __func__, len); | 134 | return SSH_ERR_INVALID_ARGUMENT; |
151 | if ((c = EVP_CIPHER_CTX_get_app_data(evp)) == NULL) | 135 | if ((c = EVP_CIPHER_CTX_get_app_data(evp)) == NULL) |
152 | fatal("%s: no 3des context", __func__); | 136 | return SSH_ERR_INTERNAL_ERROR; |
153 | if (doset) { | 137 | if (doset) { |
154 | debug3("%s: Installed 3DES IV", __func__); | ||
155 | memcpy(c->k1.iv, iv, 8); | 138 | memcpy(c->k1.iv, iv, 8); |
156 | memcpy(c->k2.iv, iv + 8, 8); | 139 | memcpy(c->k2.iv, iv + 8, 8); |
157 | memcpy(c->k3.iv, iv + 16, 8); | 140 | memcpy(c->k3.iv, iv + 16, 8); |
158 | } else { | 141 | } else { |
159 | debug3("%s: Copying 3DES IV", __func__); | ||
160 | memcpy(iv, c->k1.iv, 8); | 142 | memcpy(iv, c->k1.iv, 8); |
161 | memcpy(iv + 8, c->k2.iv, 8); | 143 | memcpy(iv + 8, c->k2.iv, 8); |
162 | memcpy(iv + 16, c->k3.iv, 8); | 144 | memcpy(iv + 16, c->k3.iv, 8); |
163 | } | 145 | } |
146 | return 0; | ||
164 | } | 147 | } |
165 | 148 | ||
166 | const EVP_CIPHER * | 149 | const EVP_CIPHER * |
@@ -176,8 +159,6 @@ evp_ssh1_3des(void) | |||
176 | ssh1_3des.init = ssh1_3des_init; | 159 | ssh1_3des.init = ssh1_3des_init; |
177 | ssh1_3des.cleanup = ssh1_3des_cleanup; | 160 | ssh1_3des.cleanup = ssh1_3des_cleanup; |
178 | ssh1_3des.do_cipher = ssh1_3des_cbc; | 161 | ssh1_3des.do_cipher = ssh1_3des_cbc; |
179 | #ifndef SSH_OLD_EVP | ||
180 | ssh1_3des.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH; | 162 | ssh1_3des.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH; |
181 | #endif | 163 | return &ssh1_3des; |
182 | return (&ssh1_3des); | ||
183 | } | 164 | } |