1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
#include "ssh_cipher.h"
#include <openssl/des.h>
#include <string.h>
struct ssh1_3des_priv
{
DES_cblock d_IV1;
DES_cblock d_IV2;
DES_cblock d_IV3;
DES_key_schedule d_key1;
DES_key_schedule d_key2;
DES_key_schedule d_key3;
};
static int
init_3des(SSH_CIPHER* my, const uint8_t *dkey, const uint8_t *IV)
{
struct ssh1_3des_priv *priv = (struct ssh1_3des_priv*)my->priv;
const_DES_cblock *key = (const_DES_cblock*)dkey;
DES_set_key(key, &priv->d_key1);
DES_set_key(key+1, &priv->d_key2);
DES_set_key(key+2, &priv->d_key3);
memset(priv->d_IV1, 0, sizeof(DES_cblock));
memset(priv->d_IV2, 0, sizeof(DES_cblock));
memset(priv->d_IV3, 0, sizeof(DES_cblock));
my->started = true;
return 1;
}
static void
cleanup(SSH_CIPHER* my)
{
if (my->priv!=NULL)
free(my->priv);
free(my);
}
static int
decrypt(SSH_CIPHER* my, const uint8_t *source, uint8_t *dest, size_t len)
{
struct ssh1_3des_priv *priv = (struct ssh1_3des_priv*)my->priv;
DES_ncbc_encrypt(source, dest, len, &priv->d_key3, &priv->d_IV3, 0);
DES_ncbc_encrypt(dest, dest, len, &priv->d_key2, &priv->d_IV2, 1);
DES_ncbc_encrypt(dest, dest, len, &priv->d_key1, &priv->d_IV1, 0);
return 1;
}
static int
encrypt(SSH_CIPHER* my, const uint8_t *source, uint8_t *dest, size_t len)
{
struct ssh1_3des_priv *priv = (struct ssh1_3des_priv*)my->priv;
DES_ncbc_encrypt(source, dest, len, &priv->d_key1, &priv->d_IV1, 1);
DES_ncbc_encrypt(dest, dest, len, &priv->d_key2, &priv->d_IV2, 0);
DES_ncbc_encrypt(dest, dest, len, &priv->d_key3, &priv->d_IV3, 1);
return 1;
}
SSH_CIPHER*
new_3des_ssh1(int enc)
{
SSH_CIPHER *cipher = (SSH_CIPHER*)malloc(sizeof(SSH_CIPHER));
cipher->priv = malloc(sizeof(struct ssh1_3des_priv));
cipher->blkSize = 8;
cipher->IVSize = 0;
cipher->keySize = 24;
if (enc)
cipher->crypt = encrypt;
else
cipher->crypt = decrypt;
cipher->init = init_3des;
cipher->cleanup = cleanup;
cipher->started = false;
return cipher;
}
|