Deleted Added
full compact
cipher.c (98684) cipher.c (98941)
1/*
2 * Author: Tatu Ylonen <ylo@cs.hut.fi>
3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4 * All rights reserved
5 *
6 * As far as I am concerned, the code I have written for this software
7 * can be used freely for any purpose. Any derived versions of this
8 * software must be clearly marked as such, and if the derived work is

--- 22 unchanged lines hidden (view full) ---

31 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 */
36
37#include "includes.h"
38RCSID("$OpenBSD: cipher.c,v 1.59 2002/06/19 18:01:00 markus Exp $");
1/*
2 * Author: Tatu Ylonen <ylo@cs.hut.fi>
3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4 * All rights reserved
5 *
6 * As far as I am concerned, the code I have written for this software
7 * can be used freely for any purpose. Any derived versions of this
8 * software must be clearly marked as such, and if the derived work is

--- 22 unchanged lines hidden (view full) ---

31 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 */
36
37#include "includes.h"
38RCSID("$OpenBSD: cipher.c,v 1.59 2002/06/19 18:01:00 markus Exp $");
39RCSID("$FreeBSD: head/crypto/openssh/cipher.c 98684 2002-06-23 16:09:08Z des $");
40
41#include "xmalloc.h"
42#include "log.h"
43#include "cipher.h"
44
45#include <openssl/md5.h>
46
39
40#include "xmalloc.h"
41#include "log.h"
42#include "cipher.h"
43
44#include <openssl/md5.h>
45
46#if OPENSSL_VERSION_NUMBER < 0x00906000L
47#define SSH_OLD_EVP
48#define EVP_CIPHER_CTX_get_app_data(e) ((e)->app_data)
49#endif
50
47#if OPENSSL_VERSION_NUMBER < 0x00907000L
48#include "rijndael.h"
49static const EVP_CIPHER *evp_rijndael(void);
50#endif
51static const EVP_CIPHER *evp_ssh1_3des(void);
52static const EVP_CIPHER *evp_ssh1_bf(void);
53
54struct Cipher {

--- 129 unchanged lines hidden (view full) ---

184}
185
186void
187cipher_init(CipherContext *cc, Cipher *cipher,
188 const u_char *key, u_int keylen, const u_char *iv, u_int ivlen,
189 int encrypt)
190{
191 static int dowarn = 1;
51#if OPENSSL_VERSION_NUMBER < 0x00907000L
52#include "rijndael.h"
53static const EVP_CIPHER *evp_rijndael(void);
54#endif
55static const EVP_CIPHER *evp_ssh1_3des(void);
56static const EVP_CIPHER *evp_ssh1_bf(void);
57
58struct Cipher {

--- 129 unchanged lines hidden (view full) ---

188}
189
190void
191cipher_init(CipherContext *cc, Cipher *cipher,
192 const u_char *key, u_int keylen, const u_char *iv, u_int ivlen,
193 int encrypt)
194{
195 static int dowarn = 1;
196#ifdef SSH_OLD_EVP
197 EVP_CIPHER *type;
198#else
192 const EVP_CIPHER *type;
199 const EVP_CIPHER *type;
200#endif
193 int klen;
194
195 if (cipher->number == SSH_CIPHER_DES) {
196 if (dowarn) {
197 error("Warning: use of DES is strongly discouraged "
198 "due to cryptographic weaknesses");
199 dowarn = 0;
200 }

--- 8 unchanged lines hidden (view full) ---

209 if (iv != NULL && ivlen < cipher->block_size)
210 fatal("cipher_init: iv length %d is insufficient for %s.",
211 ivlen, cipher->name);
212 cc->cipher = cipher;
213
214 type = (*cipher->evptype)();
215
216 EVP_CIPHER_CTX_init(&cc->evp);
201 int klen;
202
203 if (cipher->number == SSH_CIPHER_DES) {
204 if (dowarn) {
205 error("Warning: use of DES is strongly discouraged "
206 "due to cryptographic weaknesses");
207 dowarn = 0;
208 }

--- 8 unchanged lines hidden (view full) ---

217 if (iv != NULL && ivlen < cipher->block_size)
218 fatal("cipher_init: iv length %d is insufficient for %s.",
219 ivlen, cipher->name);
220 cc->cipher = cipher;
221
222 type = (*cipher->evptype)();
223
224 EVP_CIPHER_CTX_init(&cc->evp);
225#ifdef SSH_OLD_EVP
226 if (type->key_len > 0 && type->key_len != keylen) {
227 debug("cipher_init: set keylen (%d -> %d)",
228 type->key_len, keylen);
229 type->key_len = keylen;
230 }
231 EVP_CipherInit(&cc->evp, type, (u_char *)key, (u_char *)iv,
232 (encrypt == CIPHER_ENCRYPT));
233#else
217 if (EVP_CipherInit(&cc->evp, type, NULL, (u_char *)iv,
218 (encrypt == CIPHER_ENCRYPT)) == 0)
219 fatal("cipher_init: EVP_CipherInit failed for %s",
220 cipher->name);
221 klen = EVP_CIPHER_CTX_key_length(&cc->evp);
222 if (klen > 0 && keylen != klen) {
223 debug("cipher_init: set keylen (%d -> %d)", klen, keylen);
224 if (EVP_CIPHER_CTX_set_key_length(&cc->evp, keylen) == 0)
225 fatal("cipher_init: set keylen failed (%d -> %d)",
226 klen, keylen);
227 }
228 if (EVP_CipherInit(&cc->evp, NULL, (u_char *)key, NULL, -1) == 0)
229 fatal("cipher_init: EVP_CipherInit: set key failed for %s",
230 cipher->name);
234 if (EVP_CipherInit(&cc->evp, type, NULL, (u_char *)iv,
235 (encrypt == CIPHER_ENCRYPT)) == 0)
236 fatal("cipher_init: EVP_CipherInit failed for %s",
237 cipher->name);
238 klen = EVP_CIPHER_CTX_key_length(&cc->evp);
239 if (klen > 0 && keylen != klen) {
240 debug("cipher_init: set keylen (%d -> %d)", klen, keylen);
241 if (EVP_CIPHER_CTX_set_key_length(&cc->evp, keylen) == 0)
242 fatal("cipher_init: set keylen failed (%d -> %d)",
243 klen, keylen);
244 }
245 if (EVP_CipherInit(&cc->evp, NULL, (u_char *)key, NULL, -1) == 0)
246 fatal("cipher_init: EVP_CipherInit: set key failed for %s",
247 cipher->name);
248#endif
231}
232
233void
234cipher_crypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len)
235{
236 if (len % cc->cipher->block_size)
237 fatal("cipher_encrypt: bad plaintext length %d", len);
249}
250
251void
252cipher_crypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len)
253{
254 if (len % cc->cipher->block_size)
255 fatal("cipher_encrypt: bad plaintext length %d", len);
256#ifdef SSH_OLD_EVP
257 EVP_Cipher(&cc->evp, dest, (u_char *)src, len);
258#else
238 if (EVP_Cipher(&cc->evp, dest, (u_char *)src, len) == 0)
239 fatal("evp_crypt: EVP_Cipher failed");
259 if (EVP_Cipher(&cc->evp, dest, (u_char *)src, len) == 0)
260 fatal("evp_crypt: EVP_Cipher failed");
261#endif
240}
241
242void
243cipher_cleanup(CipherContext *cc)
244{
262}
263
264void
265cipher_cleanup(CipherContext *cc)
266{
267#ifdef SSH_OLD_EVP
268 EVP_CIPHER_CTX_cleanup(&cc->evp);
269#else
245 if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0)
246 error("cipher_cleanup: EVP_CIPHER_CTX_cleanup failed");
270 if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0)
271 error("cipher_cleanup: EVP_CIPHER_CTX_cleanup failed");
272#endif
247}
248
249/*
250 * Selects the cipher, and keys if by computing the MD5 checksum of the
251 * passphrase and using the resulting 16 bytes as the key.
252 */
253
254void

--- 54 unchanged lines hidden (view full) ---

309 if (enc)
310 k3 += 16;
311 else
312 k1 += 16;
313 }
314 EVP_CIPHER_CTX_init(&c->k1);
315 EVP_CIPHER_CTX_init(&c->k2);
316 EVP_CIPHER_CTX_init(&c->k3);
273}
274
275/*
276 * Selects the cipher, and keys if by computing the MD5 checksum of the
277 * passphrase and using the resulting 16 bytes as the key.
278 */
279
280void

--- 54 unchanged lines hidden (view full) ---

335 if (enc)
336 k3 += 16;
337 else
338 k1 += 16;
339 }
340 EVP_CIPHER_CTX_init(&c->k1);
341 EVP_CIPHER_CTX_init(&c->k2);
342 EVP_CIPHER_CTX_init(&c->k3);
343#ifdef SSH_OLD_EVP
344 EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc);
345 EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc);
346 EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc);
347#else
317 if (EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 ||
318 EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 ||
319 EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) {
320 memset(c, 0, sizeof(*c));
321 xfree(c);
322 EVP_CIPHER_CTX_set_app_data(ctx, NULL);
323 return (0);
324 }
348 if (EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 ||
349 EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 ||
350 EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) {
351 memset(c, 0, sizeof(*c));
352 xfree(c);
353 EVP_CIPHER_CTX_set_app_data(ctx, NULL);
354 return (0);
355 }
356#endif
325 return (1);
326}
327static int
328ssh1_3des_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, u_int len)
329{
330 struct ssh1_3des_ctx *c;
331
332 if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
333 error("ssh1_3des_cbc: no context");
334 return (0);
335 }
357 return (1);
358}
359static int
360ssh1_3des_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, u_int len)
361{
362 struct ssh1_3des_ctx *c;
363
364 if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
365 error("ssh1_3des_cbc: no context");
366 return (0);
367 }
368#ifdef SSH_OLD_EVP
369 EVP_Cipher(&c->k1, dest, (u_char *)src, len);
370 EVP_Cipher(&c->k2, dest, dest, len);
371 EVP_Cipher(&c->k3, dest, dest, len);
372#else
336 if (EVP_Cipher(&c->k1, dest, (u_char *)src, len) == 0 ||
337 EVP_Cipher(&c->k2, dest, dest, len) == 0 ||
338 EVP_Cipher(&c->k3, dest, dest, len) == 0)
339 return (0);
373 if (EVP_Cipher(&c->k1, dest, (u_char *)src, len) == 0 ||
374 EVP_Cipher(&c->k2, dest, dest, len) == 0 ||
375 EVP_Cipher(&c->k3, dest, dest, len) == 0)
376 return (0);
377#endif
340 return (1);
341}
342static int
343ssh1_3des_cleanup(EVP_CIPHER_CTX *ctx)
344{
345 struct ssh1_3des_ctx *c;
346
347 if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {

--- 11 unchanged lines hidden (view full) ---

359 memset(&ssh1_3des, 0, sizeof(EVP_CIPHER));
360 ssh1_3des.nid = NID_undef;
361 ssh1_3des.block_size = 8;
362 ssh1_3des.iv_len = 0;
363 ssh1_3des.key_len = 16;
364 ssh1_3des.init = ssh1_3des_init;
365 ssh1_3des.cleanup = ssh1_3des_cleanup;
366 ssh1_3des.do_cipher = ssh1_3des_cbc;
378 return (1);
379}
380static int
381ssh1_3des_cleanup(EVP_CIPHER_CTX *ctx)
382{
383 struct ssh1_3des_ctx *c;
384
385 if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {

--- 11 unchanged lines hidden (view full) ---

397 memset(&ssh1_3des, 0, sizeof(EVP_CIPHER));
398 ssh1_3des.nid = NID_undef;
399 ssh1_3des.block_size = 8;
400 ssh1_3des.iv_len = 0;
401 ssh1_3des.key_len = 16;
402 ssh1_3des.init = ssh1_3des_init;
403 ssh1_3des.cleanup = ssh1_3des_cleanup;
404 ssh1_3des.do_cipher = ssh1_3des_cbc;
405#ifndef SSH_OLD_EVP
367 ssh1_3des.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH;
406 ssh1_3des.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH;
407#endif
368 return (&ssh1_3des);
369}
370
371/*
372 * SSH1 uses a variation on Blowfish, all bytes must be swapped before
373 * and after encryption/decryption. Thus the swap_bytes stuff (yuk).
374 */
375static void

--- 132 unchanged lines hidden (view full) ---

508 memset(&rijndal_cbc, 0, sizeof(EVP_CIPHER));
509 rijndal_cbc.nid = NID_undef;
510 rijndal_cbc.block_size = RIJNDAEL_BLOCKSIZE;
511 rijndal_cbc.iv_len = RIJNDAEL_BLOCKSIZE;
512 rijndal_cbc.key_len = 16;
513 rijndal_cbc.init = ssh_rijndael_init;
514 rijndal_cbc.cleanup = ssh_rijndael_cleanup;
515 rijndal_cbc.do_cipher = ssh_rijndael_cbc;
408 return (&ssh1_3des);
409}
410
411/*
412 * SSH1 uses a variation on Blowfish, all bytes must be swapped before
413 * and after encryption/decryption. Thus the swap_bytes stuff (yuk).
414 */
415static void

--- 132 unchanged lines hidden (view full) ---

548 memset(&rijndal_cbc, 0, sizeof(EVP_CIPHER));
549 rijndal_cbc.nid = NID_undef;
550 rijndal_cbc.block_size = RIJNDAEL_BLOCKSIZE;
551 rijndal_cbc.iv_len = RIJNDAEL_BLOCKSIZE;
552 rijndal_cbc.key_len = 16;
553 rijndal_cbc.init = ssh_rijndael_init;
554 rijndal_cbc.cleanup = ssh_rijndael_cleanup;
555 rijndal_cbc.do_cipher = ssh_rijndael_cbc;
556#ifndef SSH_OLD_EVP
516 rijndal_cbc.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH |
517 EVP_CIPH_ALWAYS_CALL_INIT;
557 rijndal_cbc.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH |
558 EVP_CIPH_ALWAYS_CALL_INIT;
559#endif
518 return (&rijndal_cbc);
519}
520#endif
521
522/*
523 * Exports an IV from the CipherContext required to export the key
524 * state back from the unprivileged child to the privileged parent
525 * process.

--- 146 unchanged lines hidden ---
560 return (&rijndal_cbc);
561}
562#endif
563
564/*
565 * Exports an IV from the CipherContext required to export the key
566 * state back from the unprivileged child to the privileged parent
567 * process.

--- 146 unchanged lines hidden ---