mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 09:27:59 +00:00
Merge the ssh1_cipher type into ssh2_cipher.
The aim of this reorganisation is to make it easier to test all the ciphers in PuTTY in a uniform way. It was inconvenient that there were two separate vtable systems for the ciphers used in SSH-1 and SSH-2 with different functionality. Now there's only one type, called ssh_cipher. But really it's the old ssh2_cipher, just renamed: I haven't made any changes to the API on the SSH-2 side. Instead, I've removed ssh1_cipher completely, and adapted the SSH-1 BPP to use the SSH-2 style API. (The relevant differences are that ssh1_cipher encapsulated both the sending and receiving directions in one object - so now ssh1bpp has to make a separate cipher instance per direction - and that ssh1_cipher automatically initialised the IV to all zeroes, which ssh1bpp now has to do by hand.) The previous ssh1_cipher vtable for single-DES has been removed completely, because when converted into the new API it became identical to the SSH-2 single-DES vtable; so now there's just one vtable for DES-CBC which works in both protocols. The other two SSH-1 ciphers each had to stay separate, because 3DES is completely different between SSH-1 and SSH-2 (three layers of CBC structure versus one), and Blowfish varies in endianness and key length between the two. (Actually, while I'm here, I've only just noticed that the SSH-1 Blowfish cipher mis-describes itself in log messages as Blowfish-128. In fact it passes the whole of the input key buffer, which has length SSH1_SESSION_KEY_LENGTH == 32 bytes == 256 bits. So it's actually Blowfish-256, and has been all along!)
This commit is contained in:
parent
20930e7d0c
commit
986508a570
6
defs.h
6
defs.h
@ -102,11 +102,9 @@ typedef struct ssh_compression_alg ssh_compression_alg;
|
||||
typedef struct ssh2_userkey ssh2_userkey;
|
||||
typedef struct ssh2_macalg ssh2_macalg;
|
||||
typedef struct ssh2_mac ssh2_mac;
|
||||
typedef struct ssh2_cipheralg ssh2_cipheralg;
|
||||
typedef struct ssh2_cipher ssh2_cipher;
|
||||
typedef struct ssh_cipheralg ssh_cipheralg;
|
||||
typedef struct ssh_cipher ssh_cipher;
|
||||
typedef struct ssh2_ciphers ssh2_ciphers;
|
||||
typedef struct ssh1_cipheralg ssh1_cipheralg;
|
||||
typedef struct ssh1_cipher ssh1_cipher;
|
||||
typedef struct dh_ctx dh_ctx;
|
||||
typedef struct ecdh_key ecdh_key;
|
||||
|
||||
|
34
import.c
34
import.c
@ -547,11 +547,11 @@ static ssh2_userkey *openssh_pem_read(
|
||||
des3_decrypt_pubkey_ossh(keybuf, key->iv,
|
||||
key->keyblob->u, key->keyblob->len);
|
||||
else {
|
||||
ssh2_cipher *cipher = ssh2_cipher_new(&ssh_aes128_cbc);
|
||||
ssh2_cipher_setkey(cipher, keybuf);
|
||||
ssh2_cipher_setiv(cipher, key->iv);
|
||||
ssh2_cipher_decrypt(cipher, key->keyblob->u, key->keyblob->len);
|
||||
ssh2_cipher_free(cipher);
|
||||
ssh_cipher *cipher = ssh_cipher_new(&ssh_aes128_cbc);
|
||||
ssh_cipher_setkey(cipher, keybuf);
|
||||
ssh_cipher_setiv(cipher, key->iv);
|
||||
ssh_cipher_decrypt(cipher, key->keyblob->u, key->keyblob->len);
|
||||
ssh_cipher_free(cipher);
|
||||
}
|
||||
|
||||
smemclr(&md5c, sizeof(md5c));
|
||||
@ -1388,16 +1388,16 @@ static ssh2_userkey *openssh_new_read(
|
||||
goto error;
|
||||
}
|
||||
{
|
||||
ssh2_cipher *cipher = ssh2_cipher_new(
|
||||
ssh_cipher *cipher = ssh_cipher_new(
|
||||
key->cipher == ON_E_AES256CBC ?
|
||||
&ssh_aes256_cbc : &ssh_aes256_sdctr);
|
||||
ssh2_cipher_setkey(cipher, keybuf);
|
||||
ssh2_cipher_setiv(cipher, keybuf + 32);
|
||||
ssh_cipher_setkey(cipher, keybuf);
|
||||
ssh_cipher_setiv(cipher, keybuf + 32);
|
||||
/* Decrypt the private section in place, casting away
|
||||
* the const from key->private being a ptrlen */
|
||||
ssh2_cipher_decrypt(cipher, (char *)key->private.ptr,
|
||||
key->private.len);
|
||||
ssh2_cipher_free(cipher);
|
||||
ssh_cipher_decrypt(cipher, (char *)key->private.ptr,
|
||||
key->private.len);
|
||||
ssh_cipher_free(cipher);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -1588,17 +1588,17 @@ static bool openssh_new_write(
|
||||
* material: 32 bytes AES key + 16 bytes iv.
|
||||
*/
|
||||
unsigned char keybuf[48];
|
||||
ssh2_cipher *cipher;
|
||||
ssh_cipher *cipher;
|
||||
|
||||
openssh_bcrypt(passphrase,
|
||||
bcrypt_salt, sizeof(bcrypt_salt), bcrypt_rounds,
|
||||
keybuf, sizeof(keybuf));
|
||||
|
||||
cipher = ssh2_cipher_new(&ssh_aes256_sdctr);
|
||||
ssh2_cipher_setkey(cipher, keybuf);
|
||||
ssh2_cipher_setiv(cipher, keybuf + 32);
|
||||
ssh2_cipher_encrypt(cipher, cpblob->u, cpblob->len);
|
||||
ssh2_cipher_free(cipher);
|
||||
cipher = ssh_cipher_new(&ssh_aes256_sdctr);
|
||||
ssh_cipher_setkey(cipher, keybuf);
|
||||
ssh_cipher_setiv(cipher, keybuf + 32);
|
||||
ssh_cipher_encrypt(cipher, cpblob->u, cpblob->len);
|
||||
ssh_cipher_free(cipher);
|
||||
|
||||
smemclr(keybuf, sizeof(keybuf));
|
||||
}
|
||||
|
125
ssh.h
125
ssh.h
@ -554,8 +554,8 @@ mp_int *dss_gen_k(const char *id_string,
|
||||
mp_int *modulus, mp_int *private_key,
|
||||
unsigned char *digest, int digest_len);
|
||||
|
||||
struct ssh2_cipher {
|
||||
const ssh2_cipheralg *vt;
|
||||
struct ssh_cipher {
|
||||
const ssh_cipheralg *vt;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
@ -625,39 +625,19 @@ void SHA384_Init(SHA384_State * s);
|
||||
void SHA384_Final(SHA384_State * s, unsigned char *output);
|
||||
void SHA384_Simple(const void *p, int len, unsigned char *output);
|
||||
|
||||
struct ssh1_cipher {
|
||||
const ssh1_cipheralg *vt;
|
||||
};
|
||||
|
||||
struct ssh1_cipheralg {
|
||||
ssh1_cipher *(*new)(void);
|
||||
void (*free)(ssh1_cipher *);
|
||||
void (*sesskey)(ssh1_cipher *, const void *key);
|
||||
void (*encrypt)(ssh1_cipher *, void *blk, int len);
|
||||
void (*decrypt)(ssh1_cipher *, void *blk, int len);
|
||||
int blksize;
|
||||
const char *text_name;
|
||||
};
|
||||
|
||||
#define ssh1_cipher_new(alg) ((alg)->new())
|
||||
#define ssh1_cipher_free(ctx) ((ctx)->vt->free(ctx))
|
||||
#define ssh1_cipher_sesskey(ctx, key) ((ctx)->vt->sesskey(ctx, key))
|
||||
#define ssh1_cipher_encrypt(ctx, blk, len) ((ctx)->vt->encrypt(ctx, blk, len))
|
||||
#define ssh1_cipher_decrypt(ctx, blk, len) ((ctx)->vt->decrypt(ctx, blk, len))
|
||||
|
||||
struct ssh2_cipheralg {
|
||||
ssh2_cipher *(*new)(const ssh2_cipheralg *alg);
|
||||
void (*free)(ssh2_cipher *);
|
||||
void (*setiv)(ssh2_cipher *, const void *iv);
|
||||
void (*setkey)(ssh2_cipher *, const void *key);
|
||||
void (*encrypt)(ssh2_cipher *, void *blk, int len);
|
||||
void (*decrypt)(ssh2_cipher *, void *blk, int len);
|
||||
struct ssh_cipheralg {
|
||||
ssh_cipher *(*new)(const ssh_cipheralg *alg);
|
||||
void (*free)(ssh_cipher *);
|
||||
void (*setiv)(ssh_cipher *, const void *iv);
|
||||
void (*setkey)(ssh_cipher *, const void *key);
|
||||
void (*encrypt)(ssh_cipher *, void *blk, int len);
|
||||
void (*decrypt)(ssh_cipher *, void *blk, int len);
|
||||
/* Ignored unless SSH_CIPHER_SEPARATE_LENGTH flag set */
|
||||
void (*encrypt_length)(ssh2_cipher *, void *blk, int len,
|
||||
void (*encrypt_length)(ssh_cipher *, void *blk, int len,
|
||||
unsigned long seq);
|
||||
void (*decrypt_length)(ssh2_cipher *, void *blk, int len,
|
||||
void (*decrypt_length)(ssh_cipher *, void *blk, int len,
|
||||
unsigned long seq);
|
||||
const char *name;
|
||||
const char *ssh2_id;
|
||||
int blksize;
|
||||
/* real_keybits is the number of bits of entropy genuinely used by
|
||||
* the cipher scheme; it's used for deciding how big a
|
||||
@ -683,21 +663,21 @@ struct ssh2_cipheralg {
|
||||
const void *extra;
|
||||
};
|
||||
|
||||
#define ssh2_cipher_new(alg) ((alg)->new(alg))
|
||||
#define ssh2_cipher_free(ctx) ((ctx)->vt->free(ctx))
|
||||
#define ssh2_cipher_setiv(ctx, iv) ((ctx)->vt->setiv(ctx, iv))
|
||||
#define ssh2_cipher_setkey(ctx, key) ((ctx)->vt->setkey(ctx, key))
|
||||
#define ssh2_cipher_encrypt(ctx, blk, len) ((ctx)->vt->encrypt(ctx, blk, len))
|
||||
#define ssh2_cipher_decrypt(ctx, blk, len) ((ctx)->vt->decrypt(ctx, blk, len))
|
||||
#define ssh2_cipher_encrypt_length(ctx, blk, len, seq) \
|
||||
#define ssh_cipher_new(alg) ((alg)->new(alg))
|
||||
#define ssh_cipher_free(ctx) ((ctx)->vt->free(ctx))
|
||||
#define ssh_cipher_setiv(ctx, iv) ((ctx)->vt->setiv(ctx, iv))
|
||||
#define ssh_cipher_setkey(ctx, key) ((ctx)->vt->setkey(ctx, key))
|
||||
#define ssh_cipher_encrypt(ctx, blk, len) ((ctx)->vt->encrypt(ctx, blk, len))
|
||||
#define ssh_cipher_decrypt(ctx, blk, len) ((ctx)->vt->decrypt(ctx, blk, len))
|
||||
#define ssh_cipher_encrypt_length(ctx, blk, len, seq) \
|
||||
((ctx)->vt->encrypt_length(ctx, blk, len, seq))
|
||||
#define ssh2_cipher_decrypt_length(ctx, blk, len, seq) \
|
||||
#define ssh_cipher_decrypt_length(ctx, blk, len, seq) \
|
||||
((ctx)->vt->decrypt_length(ctx, blk, len, seq))
|
||||
#define ssh2_cipher_alg(ctx) ((ctx)->vt)
|
||||
#define ssh_cipher_alg(ctx) ((ctx)->vt)
|
||||
|
||||
struct ssh2_ciphers {
|
||||
int nciphers;
|
||||
const ssh2_cipheralg *const *list;
|
||||
const ssh_cipheralg *const *list;
|
||||
};
|
||||
|
||||
struct ssh2_mac {
|
||||
@ -707,7 +687,7 @@ struct ssh2_mac {
|
||||
|
||||
struct ssh2_macalg {
|
||||
/* Passes in the cipher context */
|
||||
ssh2_mac *(*new)(const ssh2_macalg *alg, ssh2_cipher *cipher);
|
||||
ssh2_mac *(*new)(const ssh2_macalg *alg, ssh_cipher *cipher);
|
||||
void (*free)(ssh2_mac *);
|
||||
void (*setkey)(ssh2_mac *, ptrlen key);
|
||||
void (*start)(ssh2_mac *);
|
||||
@ -854,36 +834,35 @@ struct ssh2_userkey {
|
||||
/* The maximum length of any hash algorithm. (bytes) */
|
||||
#define MAX_HASH_LEN (64) /* longest is SHA-512 */
|
||||
|
||||
extern const ssh1_cipheralg ssh1_3des;
|
||||
extern const ssh1_cipheralg ssh1_des;
|
||||
extern const ssh1_cipheralg ssh1_blowfish;
|
||||
extern const ssh2_cipheralg ssh_3des_ssh2_ctr;
|
||||
extern const ssh2_cipheralg ssh_3des_ssh2;
|
||||
extern const ssh2_cipheralg ssh_des_ssh2;
|
||||
extern const ssh2_cipheralg ssh_des_sshcom_ssh2;
|
||||
extern const ssh2_cipheralg ssh_aes256_sdctr;
|
||||
extern const ssh2_cipheralg ssh_aes256_sdctr_hw;
|
||||
extern const ssh2_cipheralg ssh_aes256_sdctr_sw;
|
||||
extern const ssh2_cipheralg ssh_aes256_cbc;
|
||||
extern const ssh2_cipheralg ssh_aes256_cbc_hw;
|
||||
extern const ssh2_cipheralg ssh_aes256_cbc_sw;
|
||||
extern const ssh2_cipheralg ssh_aes192_sdctr;
|
||||
extern const ssh2_cipheralg ssh_aes192_sdctr_hw;
|
||||
extern const ssh2_cipheralg ssh_aes192_sdctr_sw;
|
||||
extern const ssh2_cipheralg ssh_aes192_cbc;
|
||||
extern const ssh2_cipheralg ssh_aes192_cbc_hw;
|
||||
extern const ssh2_cipheralg ssh_aes192_cbc_sw;
|
||||
extern const ssh2_cipheralg ssh_aes128_sdctr;
|
||||
extern const ssh2_cipheralg ssh_aes128_sdctr_hw;
|
||||
extern const ssh2_cipheralg ssh_aes128_sdctr_sw;
|
||||
extern const ssh2_cipheralg ssh_aes128_cbc;
|
||||
extern const ssh2_cipheralg ssh_aes128_cbc_hw;
|
||||
extern const ssh2_cipheralg ssh_aes128_cbc_sw;
|
||||
extern const ssh2_cipheralg ssh_blowfish_ssh2_ctr;
|
||||
extern const ssh2_cipheralg ssh_blowfish_ssh2;
|
||||
extern const ssh2_cipheralg ssh_arcfour256_ssh2;
|
||||
extern const ssh2_cipheralg ssh_arcfour128_ssh2;
|
||||
extern const ssh2_cipheralg ssh2_chacha20_poly1305;
|
||||
extern const ssh_cipheralg ssh_3des_ssh1;
|
||||
extern const ssh_cipheralg ssh_blowfish_ssh1;
|
||||
extern const ssh_cipheralg ssh_3des_ssh2_ctr;
|
||||
extern const ssh_cipheralg ssh_3des_ssh2;
|
||||
extern const ssh_cipheralg ssh_des;
|
||||
extern const ssh_cipheralg ssh_des_sshcom_ssh2;
|
||||
extern const ssh_cipheralg ssh_aes256_sdctr;
|
||||
extern const ssh_cipheralg ssh_aes256_sdctr_hw;
|
||||
extern const ssh_cipheralg ssh_aes256_sdctr_sw;
|
||||
extern const ssh_cipheralg ssh_aes256_cbc;
|
||||
extern const ssh_cipheralg ssh_aes256_cbc_hw;
|
||||
extern const ssh_cipheralg ssh_aes256_cbc_sw;
|
||||
extern const ssh_cipheralg ssh_aes192_sdctr;
|
||||
extern const ssh_cipheralg ssh_aes192_sdctr_hw;
|
||||
extern const ssh_cipheralg ssh_aes192_sdctr_sw;
|
||||
extern const ssh_cipheralg ssh_aes192_cbc;
|
||||
extern const ssh_cipheralg ssh_aes192_cbc_hw;
|
||||
extern const ssh_cipheralg ssh_aes192_cbc_sw;
|
||||
extern const ssh_cipheralg ssh_aes128_sdctr;
|
||||
extern const ssh_cipheralg ssh_aes128_sdctr_hw;
|
||||
extern const ssh_cipheralg ssh_aes128_sdctr_sw;
|
||||
extern const ssh_cipheralg ssh_aes128_cbc;
|
||||
extern const ssh_cipheralg ssh_aes128_cbc_hw;
|
||||
extern const ssh_cipheralg ssh_aes128_cbc_sw;
|
||||
extern const ssh_cipheralg ssh_blowfish_ssh2_ctr;
|
||||
extern const ssh_cipheralg ssh_blowfish_ssh2;
|
||||
extern const ssh_cipheralg ssh_arcfour256_ssh2;
|
||||
extern const ssh_cipheralg ssh_arcfour128_ssh2;
|
||||
extern const ssh_cipheralg ssh2_chacha20_poly1305;
|
||||
extern const ssh2_ciphers ssh2_3des;
|
||||
extern const ssh2_ciphers ssh2_des;
|
||||
extern const ssh2_ciphers ssh2_aes;
|
||||
|
35
ssh1bpp.c
35
ssh1bpp.c
@ -17,7 +17,7 @@ struct ssh1_bpp_state {
|
||||
int chunk;
|
||||
PktIn *pktin;
|
||||
|
||||
ssh1_cipher *cipher;
|
||||
ssh_cipher *cipher_in, *cipher_out;
|
||||
|
||||
struct crcda_ctx *crcda_ctx;
|
||||
uint8_t iv[8]; /* for crcda */
|
||||
@ -57,8 +57,10 @@ BinaryPacketProtocol *ssh1_bpp_new(LogContext *logctx)
|
||||
static void ssh1_bpp_free(BinaryPacketProtocol *bpp)
|
||||
{
|
||||
struct ssh1_bpp_state *s = container_of(bpp, struct ssh1_bpp_state, bpp);
|
||||
if (s->cipher)
|
||||
ssh1_cipher_free(s->cipher);
|
||||
if (s->cipher_in)
|
||||
ssh_cipher_free(s->cipher_in);
|
||||
if (s->cipher_out)
|
||||
ssh_cipher_free(s->cipher_out);
|
||||
if (s->compctx)
|
||||
ssh_compressor_free(s->compctx);
|
||||
if (s->decompctx)
|
||||
@ -70,18 +72,21 @@ static void ssh1_bpp_free(BinaryPacketProtocol *bpp)
|
||||
}
|
||||
|
||||
void ssh1_bpp_new_cipher(BinaryPacketProtocol *bpp,
|
||||
const ssh1_cipheralg *cipher,
|
||||
const ssh_cipheralg *cipher,
|
||||
const void *session_key)
|
||||
{
|
||||
struct ssh1_bpp_state *s;
|
||||
assert(bpp->vt == &ssh1_bpp_vtable);
|
||||
s = container_of(bpp, struct ssh1_bpp_state, bpp);
|
||||
|
||||
assert(!s->cipher);
|
||||
assert(!s->cipher_in);
|
||||
assert(!s->cipher_out);
|
||||
|
||||
if (cipher) {
|
||||
s->cipher = ssh1_cipher_new(cipher);
|
||||
ssh1_cipher_sesskey(s->cipher, session_key);
|
||||
s->cipher_in = ssh_cipher_new(cipher);
|
||||
s->cipher_out = ssh_cipher_new(cipher);
|
||||
ssh_cipher_setkey(s->cipher_in, session_key);
|
||||
ssh_cipher_setkey(s->cipher_out, session_key);
|
||||
|
||||
assert(!s->crcda_ctx);
|
||||
s->crcda_ctx = crcda_make_context();
|
||||
@ -89,6 +94,10 @@ void ssh1_bpp_new_cipher(BinaryPacketProtocol *bpp,
|
||||
bpp_logevent("Initialised %s encryption", cipher->text_name);
|
||||
|
||||
memset(s->iv, 0, sizeof(s->iv));
|
||||
|
||||
assert(cipher->blksize <= sizeof(s->iv));
|
||||
ssh_cipher_setiv(s->cipher_in, s->iv);
|
||||
ssh_cipher_setiv(s->cipher_out, s->iv);
|
||||
}
|
||||
}
|
||||
|
||||
@ -157,8 +166,8 @@ static void ssh1_bpp_handle_input(BinaryPacketProtocol *bpp)
|
||||
|
||||
BPP_READ(s->data, s->biglen);
|
||||
|
||||
if (s->cipher && detect_attack(s->crcda_ctx,
|
||||
s->data, s->biglen, s->iv)) {
|
||||
if (s->cipher_in && detect_attack(s->crcda_ctx,
|
||||
s->data, s->biglen, s->iv)) {
|
||||
ssh_sw_abort(s->bpp.ssh,
|
||||
"Network attack (CRC compensation) detected!");
|
||||
crStopV;
|
||||
@ -168,8 +177,8 @@ static void ssh1_bpp_handle_input(BinaryPacketProtocol *bpp)
|
||||
assert(s->biglen >= 8);
|
||||
memcpy(s->iv, s->data + s->biglen - 8, sizeof(s->iv));
|
||||
|
||||
if (s->cipher)
|
||||
ssh1_cipher_decrypt(s->cipher, s->data, s->biglen);
|
||||
if (s->cipher_in)
|
||||
ssh_cipher_decrypt(s->cipher_in, s->data, s->biglen);
|
||||
|
||||
s->realcrc = crc32_ssh1(make_ptrlen(s->data, s->biglen - 4));
|
||||
s->gotcrc = GET_32BIT(s->data + s->biglen - 4);
|
||||
@ -327,8 +336,8 @@ static void ssh1_bpp_format_packet(struct ssh1_bpp_state *s, PktOut *pkt)
|
||||
PUT_32BIT(pkt->data + pktoffs + 4 + biglen - 4, crc);
|
||||
PUT_32BIT(pkt->data + pktoffs, len);
|
||||
|
||||
if (s->cipher)
|
||||
ssh1_cipher_encrypt(s->cipher, pkt->data + pktoffs + 4, biglen);
|
||||
if (s->cipher_out)
|
||||
ssh_cipher_encrypt(s->cipher_out, pkt->data + pktoffs + 4, biglen);
|
||||
|
||||
bufchain_add(s->bpp.out_raw, pkt->data + pktoffs,
|
||||
biglen + 4); /* len(length+padding+type+data+CRC) */
|
||||
|
@ -241,9 +241,9 @@ static void ssh1_login_server_process_queue(PacketProtocolLayer *ppl)
|
||||
s->session_key[i] ^= s->session_id[i];
|
||||
|
||||
{
|
||||
const ssh1_cipheralg *cipher =
|
||||
(s->cipher_type == SSH_CIPHER_BLOWFISH ? &ssh1_blowfish :
|
||||
s->cipher_type == SSH_CIPHER_DES ? &ssh1_des : &ssh1_3des);
|
||||
const ssh_cipheralg *cipher =
|
||||
(s->cipher_type == SSH_CIPHER_BLOWFISH ? &ssh_blowfish_ssh1 :
|
||||
s->cipher_type == SSH_CIPHER_DES ? &ssh_des : &ssh_3des_ssh1);
|
||||
ssh1_bpp_new_cipher(s->ppl.bpp, cipher, s->session_key);
|
||||
}
|
||||
|
||||
|
@ -362,9 +362,9 @@ static void ssh1_login_process_queue(PacketProtocolLayer *ppl)
|
||||
ssh_bpp_handle_output(s->ppl.bpp);
|
||||
|
||||
{
|
||||
const ssh1_cipheralg *cipher =
|
||||
(s->cipher_type == SSH_CIPHER_BLOWFISH ? &ssh1_blowfish :
|
||||
s->cipher_type == SSH_CIPHER_DES ? &ssh1_des : &ssh1_3des);
|
||||
const ssh_cipheralg *cipher =
|
||||
(s->cipher_type == SSH_CIPHER_BLOWFISH ? &ssh_blowfish_ssh1 :
|
||||
s->cipher_type == SSH_CIPHER_DES ? &ssh_des : &ssh_3des_ssh1);
|
||||
ssh1_bpp_new_cipher(s->ppl.bpp, cipher, s->session_key);
|
||||
}
|
||||
|
||||
|
71
ssh2bpp.c
71
ssh2bpp.c
@ -11,7 +11,7 @@
|
||||
|
||||
struct ssh2_bpp_direction {
|
||||
unsigned long sequence;
|
||||
ssh2_cipher *cipher;
|
||||
ssh_cipher *cipher;
|
||||
ssh2_mac *mac;
|
||||
bool etm_mode;
|
||||
const ssh_compression_alg *pending_compression;
|
||||
@ -73,7 +73,7 @@ static void ssh2_bpp_free_outgoing_crypto(struct ssh2_bpp_state *s)
|
||||
* We must free the MAC before the cipher, because sometimes the
|
||||
* MAC is not actually separately allocated but just a different
|
||||
* facet of the same object as the cipher, in which case
|
||||
* ssh2_mac_free does nothing and ssh2_cipher_free does the actual
|
||||
* ssh2_mac_free does nothing and ssh_cipher_free does the actual
|
||||
* freeing. So if we freed the cipher first and then tried to
|
||||
* dereference the MAC's vtable pointer to find out how to free
|
||||
* that too, we'd be accessing freed memory.
|
||||
@ -81,7 +81,7 @@ static void ssh2_bpp_free_outgoing_crypto(struct ssh2_bpp_state *s)
|
||||
if (s->out.mac)
|
||||
ssh2_mac_free(s->out.mac);
|
||||
if (s->out.cipher)
|
||||
ssh2_cipher_free(s->out.cipher);
|
||||
ssh_cipher_free(s->out.cipher);
|
||||
if (s->out_comp)
|
||||
ssh_compressor_free(s->out_comp);
|
||||
}
|
||||
@ -92,7 +92,7 @@ static void ssh2_bpp_free_incoming_crypto(struct ssh2_bpp_state *s)
|
||||
if (s->in.mac)
|
||||
ssh2_mac_free(s->in.mac);
|
||||
if (s->in.cipher)
|
||||
ssh2_cipher_free(s->in.cipher);
|
||||
ssh_cipher_free(s->in.cipher);
|
||||
if (s->in_decomp)
|
||||
ssh_decompressor_free(s->in_decomp);
|
||||
}
|
||||
@ -109,7 +109,7 @@ static void ssh2_bpp_free(BinaryPacketProtocol *bpp)
|
||||
|
||||
void ssh2_bpp_new_outgoing_crypto(
|
||||
BinaryPacketProtocol *bpp,
|
||||
const ssh2_cipheralg *cipher, const void *ckey, const void *iv,
|
||||
const ssh_cipheralg *cipher, const void *ckey, const void *iv,
|
||||
const ssh2_macalg *mac, bool etm_mode, const void *mac_key,
|
||||
const ssh_compression_alg *compression, bool delayed_compression)
|
||||
{
|
||||
@ -120,16 +120,16 @@ void ssh2_bpp_new_outgoing_crypto(
|
||||
ssh2_bpp_free_outgoing_crypto(s);
|
||||
|
||||
if (cipher) {
|
||||
s->out.cipher = ssh2_cipher_new(cipher);
|
||||
ssh2_cipher_setkey(s->out.cipher, ckey);
|
||||
ssh2_cipher_setiv(s->out.cipher, iv);
|
||||
s->out.cipher = ssh_cipher_new(cipher);
|
||||
ssh_cipher_setkey(s->out.cipher, ckey);
|
||||
ssh_cipher_setiv(s->out.cipher, iv);
|
||||
|
||||
s->cbc_ignore_workaround = (
|
||||
(ssh2_cipher_alg(s->out.cipher)->flags & SSH_CIPHER_IS_CBC) &&
|
||||
(ssh_cipher_alg(s->out.cipher)->flags & SSH_CIPHER_IS_CBC) &&
|
||||
!(s->bpp.remote_bugs & BUG_CHOKES_ON_SSH2_IGNORE));
|
||||
|
||||
bpp_logevent("Initialised %s outbound encryption",
|
||||
ssh2_cipher_alg(s->out.cipher)->text_name);
|
||||
ssh_cipher_alg(s->out.cipher)->text_name);
|
||||
} else {
|
||||
s->out.cipher = NULL;
|
||||
s->cbc_ignore_workaround = false;
|
||||
@ -143,7 +143,7 @@ void ssh2_bpp_new_outgoing_crypto(
|
||||
ssh2_mac_alg(s->out.mac)->text_name,
|
||||
etm_mode ? " (in ETM mode)" : "",
|
||||
(s->out.cipher &&
|
||||
ssh2_cipher_alg(s->out.cipher)->required_mac ?
|
||||
ssh_cipher_alg(s->out.cipher)->required_mac ?
|
||||
" (required by cipher)" : ""));
|
||||
} else {
|
||||
s->out.mac = NULL;
|
||||
@ -171,7 +171,7 @@ void ssh2_bpp_new_outgoing_crypto(
|
||||
|
||||
void ssh2_bpp_new_incoming_crypto(
|
||||
BinaryPacketProtocol *bpp,
|
||||
const ssh2_cipheralg *cipher, const void *ckey, const void *iv,
|
||||
const ssh_cipheralg *cipher, const void *ckey, const void *iv,
|
||||
const ssh2_macalg *mac, bool etm_mode, const void *mac_key,
|
||||
const ssh_compression_alg *compression, bool delayed_compression)
|
||||
{
|
||||
@ -182,12 +182,12 @@ void ssh2_bpp_new_incoming_crypto(
|
||||
ssh2_bpp_free_incoming_crypto(s);
|
||||
|
||||
if (cipher) {
|
||||
s->in.cipher = ssh2_cipher_new(cipher);
|
||||
ssh2_cipher_setkey(s->in.cipher, ckey);
|
||||
ssh2_cipher_setiv(s->in.cipher, iv);
|
||||
s->in.cipher = ssh_cipher_new(cipher);
|
||||
ssh_cipher_setkey(s->in.cipher, ckey);
|
||||
ssh_cipher_setiv(s->in.cipher, iv);
|
||||
|
||||
bpp_logevent("Initialised %s inbound encryption",
|
||||
ssh2_cipher_alg(s->in.cipher)->text_name);
|
||||
ssh_cipher_alg(s->in.cipher)->text_name);
|
||||
} else {
|
||||
s->in.cipher = NULL;
|
||||
}
|
||||
@ -200,7 +200,7 @@ void ssh2_bpp_new_incoming_crypto(
|
||||
ssh2_mac_alg(s->in.mac)->text_name,
|
||||
etm_mode ? " (in ETM mode)" : "",
|
||||
(s->in.cipher &&
|
||||
ssh2_cipher_alg(s->in.cipher)->required_mac ?
|
||||
ssh_cipher_alg(s->in.cipher)->required_mac ?
|
||||
" (required by cipher)" : ""));
|
||||
} else {
|
||||
s->in.mac = NULL;
|
||||
@ -283,7 +283,7 @@ static void ssh2_bpp_handle_input(BinaryPacketProtocol *bpp)
|
||||
s->maxlen = 0;
|
||||
s->length = 0;
|
||||
if (s->in.cipher)
|
||||
s->cipherblk = ssh2_cipher_alg(s->in.cipher)->blksize;
|
||||
s->cipherblk = ssh_cipher_alg(s->in.cipher)->blksize;
|
||||
else
|
||||
s->cipherblk = 8;
|
||||
if (s->cipherblk < 8)
|
||||
@ -291,7 +291,7 @@ static void ssh2_bpp_handle_input(BinaryPacketProtocol *bpp)
|
||||
s->maclen = s->in.mac ? ssh2_mac_alg(s->in.mac)->len : 0;
|
||||
|
||||
if (s->in.cipher &&
|
||||
(ssh2_cipher_alg(s->in.cipher)->flags & SSH_CIPHER_IS_CBC) &&
|
||||
(ssh_cipher_alg(s->in.cipher)->flags & SSH_CIPHER_IS_CBC) &&
|
||||
s->in.mac && !s->in.etm_mode) {
|
||||
/*
|
||||
* When dealing with a CBC-mode cipher, we want to avoid the
|
||||
@ -333,8 +333,8 @@ static void ssh2_bpp_handle_input(BinaryPacketProtocol *bpp)
|
||||
BPP_READ(s->buf + (s->packetlen + s->maclen), s->cipherblk);
|
||||
/* Decrypt one more block (a little further back in
|
||||
* the stream). */
|
||||
ssh2_cipher_decrypt(s->in.cipher,
|
||||
s->buf + s->packetlen, s->cipherblk);
|
||||
ssh_cipher_decrypt(s->in.cipher,
|
||||
s->buf + s->packetlen, s->cipherblk);
|
||||
|
||||
/* Feed that block to the MAC. */
|
||||
put_data(s->in.mac,
|
||||
@ -376,12 +376,12 @@ static void ssh2_bpp_handle_input(BinaryPacketProtocol *bpp)
|
||||
BPP_READ(s->buf, 4);
|
||||
|
||||
/* Cipher supports length decryption, so do it */
|
||||
if (s->in.cipher && (ssh2_cipher_alg(s->in.cipher)->flags &
|
||||
if (s->in.cipher && (ssh_cipher_alg(s->in.cipher)->flags &
|
||||
SSH_CIPHER_SEPARATE_LENGTH)) {
|
||||
/* Keep the packet the same though, so the MAC passes */
|
||||
unsigned char len[4];
|
||||
memcpy(len, s->buf, 4);
|
||||
ssh2_cipher_decrypt_length(
|
||||
ssh_cipher_decrypt_length(
|
||||
s->in.cipher, len, 4, s->in.sequence);
|
||||
s->len = toint(GET_32BIT(len));
|
||||
} else {
|
||||
@ -430,7 +430,7 @@ static void ssh2_bpp_handle_input(BinaryPacketProtocol *bpp)
|
||||
|
||||
/* Decrypt everything between the length field and the MAC. */
|
||||
if (s->in.cipher)
|
||||
ssh2_cipher_decrypt(
|
||||
ssh_cipher_decrypt(
|
||||
s->in.cipher, s->data + 4, s->packetlen - 4);
|
||||
} else {
|
||||
if (s->bufsize < s->cipherblk) {
|
||||
@ -445,8 +445,7 @@ static void ssh2_bpp_handle_input(BinaryPacketProtocol *bpp)
|
||||
BPP_READ(s->buf, s->cipherblk);
|
||||
|
||||
if (s->in.cipher)
|
||||
ssh2_cipher_decrypt(
|
||||
s->in.cipher, s->buf, s->cipherblk);
|
||||
ssh_cipher_decrypt(s->in.cipher, s->buf, s->cipherblk);
|
||||
|
||||
/*
|
||||
* Now get the length figure.
|
||||
@ -488,7 +487,7 @@ static void ssh2_bpp_handle_input(BinaryPacketProtocol *bpp)
|
||||
|
||||
/* Decrypt everything _except_ the MAC. */
|
||||
if (s->in.cipher)
|
||||
ssh2_cipher_decrypt(
|
||||
ssh_cipher_decrypt(
|
||||
s->in.cipher,
|
||||
s->data + s->cipherblk, s->packetlen - s->cipherblk);
|
||||
|
||||
@ -684,7 +683,7 @@ static void ssh2_bpp_format_packet_inner(struct ssh2_bpp_state *s, PktOut *pkt)
|
||||
pkt->downstream_id, pkt->additional_log_text);
|
||||
}
|
||||
|
||||
cipherblk = s->out.cipher ? ssh2_cipher_alg(s->out.cipher)->blksize : 8;
|
||||
cipherblk = s->out.cipher ? ssh_cipher_alg(s->out.cipher)->blksize : 8;
|
||||
cipherblk = cipherblk < 8 ? 8 : cipherblk; /* or 8 if blksize < 8 */
|
||||
|
||||
if (s->out_comp) {
|
||||
@ -733,9 +732,9 @@ static void ssh2_bpp_format_packet_inner(struct ssh2_bpp_state *s, PktOut *pkt)
|
||||
|
||||
/* Encrypt length if the scheme requires it */
|
||||
if (s->out.cipher &&
|
||||
(ssh2_cipher_alg(s->out.cipher)->flags & SSH_CIPHER_SEPARATE_LENGTH)) {
|
||||
ssh2_cipher_encrypt_length(s->out.cipher, pkt->data, 4,
|
||||
s->out.sequence);
|
||||
(ssh_cipher_alg(s->out.cipher)->flags & SSH_CIPHER_SEPARATE_LENGTH)) {
|
||||
ssh_cipher_encrypt_length(s->out.cipher, pkt->data, 4,
|
||||
s->out.sequence);
|
||||
}
|
||||
|
||||
put_padding(pkt, maclen, 0);
|
||||
@ -745,8 +744,8 @@ static void ssh2_bpp_format_packet_inner(struct ssh2_bpp_state *s, PktOut *pkt)
|
||||
* OpenSSH-defined encrypt-then-MAC protocol.
|
||||
*/
|
||||
if (s->out.cipher)
|
||||
ssh2_cipher_encrypt(s->out.cipher,
|
||||
pkt->data + 4, origlen + padding - 4);
|
||||
ssh_cipher_encrypt(s->out.cipher,
|
||||
pkt->data + 4, origlen + padding - 4);
|
||||
ssh2_mac_generate(s->out.mac, pkt->data, origlen + padding,
|
||||
s->out.sequence);
|
||||
} else {
|
||||
@ -757,7 +756,7 @@ static void ssh2_bpp_format_packet_inner(struct ssh2_bpp_state *s, PktOut *pkt)
|
||||
ssh2_mac_generate(s->out.mac, pkt->data, origlen + padding,
|
||||
s->out.sequence);
|
||||
if (s->out.cipher)
|
||||
ssh2_cipher_encrypt(s->out.cipher, pkt->data, origlen + padding);
|
||||
ssh_cipher_encrypt(s->out.cipher, pkt->data, origlen + padding);
|
||||
}
|
||||
|
||||
s->out.sequence++; /* whether or not we MACed */
|
||||
@ -791,7 +790,7 @@ static void ssh2_bpp_format_packet(struct ssh2_bpp_state *s, PktOut *pkt)
|
||||
int block, length;
|
||||
PktOut *ignore_pkt;
|
||||
|
||||
block = s->out.cipher ? ssh2_cipher_alg(s->out.cipher)->blksize : 0;
|
||||
block = s->out.cipher ? ssh_cipher_alg(s->out.cipher)->blksize : 0;
|
||||
if (block < 8)
|
||||
block = 8;
|
||||
length = pkt->length;
|
||||
@ -874,7 +873,7 @@ static void ssh2_bpp_handle_output(BinaryPacketProtocol *bpp)
|
||||
* from out_raw).
|
||||
*/
|
||||
if (bufchain_size(s->bpp.out_raw) <
|
||||
(ssh2_cipher_alg(s->out.cipher)->blksize +
|
||||
(ssh_cipher_alg(s->out.cipher)->blksize +
|
||||
ssh2_mac_alg(s->out.mac)->len)) {
|
||||
/*
|
||||
* There's less data in out_raw than the MAC size plus the
|
||||
|
@ -652,7 +652,7 @@ static void ssh2_write_kexinit_lists(
|
||||
if (!c) warn = true;
|
||||
else for (j = 0; j < c->nciphers; j++) {
|
||||
alg = ssh2_kexinit_addalg(kexlists[k],
|
||||
c->list[j]->name);
|
||||
c->list[j]->ssh2_id);
|
||||
alg->u.cipher.cipher = c->list[j];
|
||||
alg->u.cipher.warn = warn;
|
||||
}
|
||||
@ -1200,7 +1200,7 @@ static void ssh2_transport_process_queue(PacketProtocolLayer *ppl)
|
||||
|
||||
if (s->warn_cscipher) {
|
||||
s->dlgret = seat_confirm_weak_crypto_primitive(
|
||||
s->ppl.seat, "client-to-server cipher", s->out.cipher->name,
|
||||
s->ppl.seat, "client-to-server cipher", s->out.cipher->ssh2_id,
|
||||
ssh2_transport_dialog_callback, s);
|
||||
crMaybeWaitUntilV(s->dlgret >= 0);
|
||||
if (s->dlgret == 0) {
|
||||
@ -1211,7 +1211,7 @@ static void ssh2_transport_process_queue(PacketProtocolLayer *ppl)
|
||||
|
||||
if (s->warn_sccipher) {
|
||||
s->dlgret = seat_confirm_weak_crypto_primitive(
|
||||
s->ppl.seat, "server-to-client cipher", s->in.cipher->name,
|
||||
s->ppl.seat, "server-to-client cipher", s->in.cipher->ssh2_id,
|
||||
ssh2_transport_dialog_callback, s);
|
||||
crMaybeWaitUntilV(s->dlgret >= 0);
|
||||
if (s->dlgret == 0) {
|
||||
|
@ -36,7 +36,7 @@ struct kexinit_algorithm {
|
||||
bool warn;
|
||||
} hk;
|
||||
struct {
|
||||
const ssh2_cipheralg *cipher;
|
||||
const ssh_cipheralg *cipher;
|
||||
bool warn;
|
||||
} cipher;
|
||||
struct {
|
||||
@ -103,7 +103,7 @@ typedef enum RekeyClass {
|
||||
} RekeyClass;
|
||||
|
||||
typedef struct transport_direction {
|
||||
const ssh2_cipheralg *cipher;
|
||||
const ssh_cipheralg *cipher;
|
||||
const ssh2_macalg *mac;
|
||||
bool etm_mode;
|
||||
const ssh_compression_alg *comp;
|
||||
|
164
sshaes.c
164
sshaes.c
@ -87,34 +87,34 @@
|
||||
* instance of.
|
||||
*/
|
||||
|
||||
static ssh2_cipher *aes_select(const ssh2_cipheralg *alg);
|
||||
static ssh2_cipher *aes_sw_new(const ssh2_cipheralg *alg);
|
||||
static void aes_sw_free(ssh2_cipher *);
|
||||
static void aes_sw_setiv_cbc(ssh2_cipher *, const void *iv);
|
||||
static void aes_sw_setiv_sdctr(ssh2_cipher *, const void *iv);
|
||||
static void aes_sw_setkey(ssh2_cipher *, const void *key);
|
||||
static ssh2_cipher *aes_hw_new(const ssh2_cipheralg *alg);
|
||||
static void aes_hw_free(ssh2_cipher *);
|
||||
static void aes_hw_setiv_cbc(ssh2_cipher *, const void *iv);
|
||||
static void aes_hw_setiv_sdctr(ssh2_cipher *, const void *iv);
|
||||
static void aes_hw_setkey(ssh2_cipher *, const void *key);
|
||||
static ssh_cipher *aes_select(const ssh_cipheralg *alg);
|
||||
static ssh_cipher *aes_sw_new(const ssh_cipheralg *alg);
|
||||
static void aes_sw_free(ssh_cipher *);
|
||||
static void aes_sw_setiv_cbc(ssh_cipher *, const void *iv);
|
||||
static void aes_sw_setiv_sdctr(ssh_cipher *, const void *iv);
|
||||
static void aes_sw_setkey(ssh_cipher *, const void *key);
|
||||
static ssh_cipher *aes_hw_new(const ssh_cipheralg *alg);
|
||||
static void aes_hw_free(ssh_cipher *);
|
||||
static void aes_hw_setiv_cbc(ssh_cipher *, const void *iv);
|
||||
static void aes_hw_setiv_sdctr(ssh_cipher *, const void *iv);
|
||||
static void aes_hw_setkey(ssh_cipher *, const void *key);
|
||||
|
||||
struct aes_extra {
|
||||
const ssh2_cipheralg *sw, *hw;
|
||||
const ssh_cipheralg *sw, *hw;
|
||||
};
|
||||
|
||||
#define VTABLES(cid, pid, bits, name, encsuffix, decsuffix, setiv) \
|
||||
static void cid##_sw##encsuffix(ssh2_cipher *, void *blk, int len); \
|
||||
static void cid##_sw##decsuffix(ssh2_cipher *, void *blk, int len); \
|
||||
const ssh2_cipheralg ssh_##cid##_sw = { \
|
||||
static void cid##_sw##encsuffix(ssh_cipher *, void *blk, int len); \
|
||||
static void cid##_sw##decsuffix(ssh_cipher *, void *blk, int len); \
|
||||
const ssh_cipheralg ssh_##cid##_sw = { \
|
||||
aes_sw_new, aes_sw_free, aes_sw_##setiv, aes_sw_setkey, \
|
||||
cid##_sw##encsuffix, cid##_sw##decsuffix, NULL, NULL, \
|
||||
pid, 16, bits, bits/8, 0, name " (unaccelerated)", \
|
||||
NULL, NULL }; \
|
||||
\
|
||||
static void cid##_hw##encsuffix(ssh2_cipher *, void *blk, int len); \
|
||||
static void cid##_hw##decsuffix(ssh2_cipher *, void *blk, int len); \
|
||||
const ssh2_cipheralg ssh_##cid##_hw = { \
|
||||
static void cid##_hw##encsuffix(ssh_cipher *, void *blk, int len); \
|
||||
static void cid##_hw##decsuffix(ssh_cipher *, void *blk, int len); \
|
||||
const ssh_cipheralg ssh_##cid##_hw = { \
|
||||
aes_hw_new, aes_hw_free, aes_hw_##setiv, aes_hw_setkey, \
|
||||
cid##_hw##encsuffix, cid##_hw##decsuffix, NULL, NULL, \
|
||||
pid, 16, bits, bits/8, 0, name HW_NAME_SUFFIX, \
|
||||
@ -123,7 +123,7 @@ struct aes_extra {
|
||||
const struct aes_extra extra_##cid = { \
|
||||
&ssh_##cid##_sw, &ssh_##cid##_hw }; \
|
||||
\
|
||||
const ssh2_cipheralg ssh_##cid = { \
|
||||
const ssh_cipheralg ssh_##cid = { \
|
||||
aes_select, NULL, NULL, NULL, NULL, NULL, NULL, NULL, \
|
||||
pid, 16, bits, bits/8, 0, name " (dummy selector vtable)", \
|
||||
NULL, &extra_##cid }; \
|
||||
@ -135,14 +135,14 @@ VTABLES(aes128_sdctr, "aes128-ctr", 128, "AES-128 SDCTR",,, setiv_sdctr)
|
||||
VTABLES(aes192_sdctr, "aes192-ctr", 192, "AES-192 SDCTR",,, setiv_sdctr)
|
||||
VTABLES(aes256_sdctr, "aes256-ctr", 256, "AES-256 SDCTR",,, setiv_sdctr)
|
||||
|
||||
static const ssh2_cipheralg ssh_rijndael_lysator = {
|
||||
static const ssh_cipheralg ssh_rijndael_lysator = {
|
||||
/* Same as aes256_cbc, but with a different protocol ID */
|
||||
aes_select, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
"rijndael-cbc@lysator.liu.se", 16, 256, 256/8, 0,
|
||||
"AES-256 CBC (dummy selector vtable)", NULL, &extra_aes256_cbc
|
||||
};
|
||||
|
||||
static const ssh2_cipheralg *const aes_list[] = {
|
||||
static const ssh_cipheralg *const aes_list[] = {
|
||||
&ssh_aes256_sdctr,
|
||||
&ssh_aes256_cbc,
|
||||
&ssh_rijndael_lysator,
|
||||
@ -175,13 +175,13 @@ static bool aes_hw_available_cached(void)
|
||||
return hw_available;
|
||||
}
|
||||
|
||||
static ssh2_cipher *aes_select(const ssh2_cipheralg *alg)
|
||||
static ssh_cipher *aes_select(const ssh_cipheralg *alg)
|
||||
{
|
||||
const struct aes_extra *extra = (const struct aes_extra *)alg->extra;
|
||||
const ssh2_cipheralg *real_alg =
|
||||
const ssh_cipheralg *real_alg =
|
||||
aes_hw_available_cached() ? extra->hw : extra->sw;
|
||||
|
||||
return ssh2_cipher_new(real_alg);
|
||||
return ssh_cipher_new(real_alg);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
@ -987,36 +987,36 @@ struct aes_sw_context {
|
||||
uint8_t *keystream_pos;
|
||||
} sdctr;
|
||||
} iv;
|
||||
ssh2_cipher ciph;
|
||||
ssh_cipher ciph;
|
||||
};
|
||||
|
||||
static ssh2_cipher *aes_sw_new(const ssh2_cipheralg *alg)
|
||||
static ssh_cipher *aes_sw_new(const ssh_cipheralg *alg)
|
||||
{
|
||||
aes_sw_context *ctx = snew(aes_sw_context);
|
||||
ctx->ciph.vt = alg;
|
||||
return &ctx->ciph;
|
||||
}
|
||||
|
||||
static void aes_sw_free(ssh2_cipher *ciph)
|
||||
static void aes_sw_free(ssh_cipher *ciph)
|
||||
{
|
||||
aes_sw_context *ctx = container_of(ciph, aes_sw_context, ciph);
|
||||
smemclr(ctx, sizeof(*ctx));
|
||||
sfree(ctx);
|
||||
}
|
||||
|
||||
static void aes_sw_setkey(ssh2_cipher *ciph, const void *vkey)
|
||||
static void aes_sw_setkey(ssh_cipher *ciph, const void *vkey)
|
||||
{
|
||||
aes_sw_context *ctx = container_of(ciph, aes_sw_context, ciph);
|
||||
aes_sliced_key_setup(&ctx->sk, vkey, ctx->ciph.vt->real_keybits);
|
||||
}
|
||||
|
||||
static void aes_sw_setiv_cbc(ssh2_cipher *ciph, const void *iv)
|
||||
static void aes_sw_setiv_cbc(ssh_cipher *ciph, const void *iv)
|
||||
{
|
||||
aes_sw_context *ctx = container_of(ciph, aes_sw_context, ciph);
|
||||
memcpy(ctx->iv.cbc.prevblk, iv, 16);
|
||||
}
|
||||
|
||||
static void aes_sw_setiv_sdctr(ssh2_cipher *ciph, const void *viv)
|
||||
static void aes_sw_setiv_sdctr(ssh_cipher *ciph, const void *viv)
|
||||
{
|
||||
aes_sw_context *ctx = container_of(ciph, aes_sw_context, ciph);
|
||||
const uint8_t *iv = (const uint8_t *)viv;
|
||||
@ -1050,7 +1050,7 @@ static inline void memxor16(void *vout, const void *vlhs, const void *vrhs)
|
||||
}
|
||||
|
||||
static inline void aes_cbc_sw_encrypt(
|
||||
ssh2_cipher *ciph, void *vblk, int blklen)
|
||||
ssh_cipher *ciph, void *vblk, int blklen)
|
||||
{
|
||||
aes_sw_context *ctx = container_of(ciph, aes_sw_context, ciph);
|
||||
|
||||
@ -1081,7 +1081,7 @@ static inline void aes_cbc_sw_encrypt(
|
||||
}
|
||||
|
||||
static inline void aes_cbc_sw_decrypt(
|
||||
ssh2_cipher *ciph, void *vblk, int blklen)
|
||||
ssh_cipher *ciph, void *vblk, int blklen)
|
||||
{
|
||||
aes_sw_context *ctx = container_of(ciph, aes_sw_context, ciph);
|
||||
uint8_t *blk = (uint8_t *)vblk;
|
||||
@ -1132,7 +1132,7 @@ static inline void aes_cbc_sw_decrypt(
|
||||
}
|
||||
|
||||
static inline void aes_sdctr_sw(
|
||||
ssh2_cipher *ciph, void *vblk, int blklen)
|
||||
ssh_cipher *ciph, void *vblk, int blklen)
|
||||
{
|
||||
aes_sw_context *ctx = container_of(ciph, aes_sw_context, ciph);
|
||||
|
||||
@ -1182,13 +1182,13 @@ static inline void aes_sdctr_sw(
|
||||
|
||||
#define SW_ENC_DEC(len) \
|
||||
static void aes##len##_cbc_sw_encrypt( \
|
||||
ssh2_cipher *ciph, void *vblk, int blklen) \
|
||||
ssh_cipher *ciph, void *vblk, int blklen) \
|
||||
{ aes_cbc_sw_encrypt(ciph, vblk, blklen); } \
|
||||
static void aes##len##_cbc_sw_decrypt( \
|
||||
ssh2_cipher *ciph, void *vblk, int blklen) \
|
||||
ssh_cipher *ciph, void *vblk, int blklen) \
|
||||
{ aes_cbc_sw_decrypt(ciph, vblk, blklen); } \
|
||||
static void aes##len##_sdctr_sw( \
|
||||
ssh2_cipher *ciph, void *vblk, int blklen) \
|
||||
ssh_cipher *ciph, void *vblk, int blklen) \
|
||||
{ aes_sdctr_sw(ciph, vblk, blklen); }
|
||||
|
||||
SW_ENC_DEC(128)
|
||||
@ -1367,10 +1367,10 @@ struct aes_ni_context {
|
||||
__m128i keysched_e[MAXROUNDKEYS], keysched_d[MAXROUNDKEYS], iv;
|
||||
|
||||
void *pointer_to_free;
|
||||
ssh2_cipher ciph;
|
||||
ssh_cipher ciph;
|
||||
};
|
||||
|
||||
static ssh2_cipher *aes_hw_new(const ssh2_cipheralg *alg)
|
||||
static ssh_cipher *aes_hw_new(const ssh_cipheralg *alg)
|
||||
{
|
||||
if (!aes_hw_available_cached())
|
||||
return NULL;
|
||||
@ -1393,7 +1393,7 @@ static ssh2_cipher *aes_hw_new(const ssh2_cipheralg *alg)
|
||||
return &ctx->ciph;
|
||||
}
|
||||
|
||||
static void aes_hw_free(ssh2_cipher *ciph)
|
||||
static void aes_hw_free(ssh_cipher *ciph)
|
||||
{
|
||||
aes_ni_context *ctx = container_of(ciph, aes_ni_context, ciph);
|
||||
void *allocation = ctx->pointer_to_free;
|
||||
@ -1401,7 +1401,7 @@ static void aes_hw_free(ssh2_cipher *ciph)
|
||||
sfree(allocation);
|
||||
}
|
||||
|
||||
static void aes_hw_setkey(ssh2_cipher *ciph, const void *vkey)
|
||||
static void aes_hw_setkey(ssh_cipher *ciph, const void *vkey)
|
||||
{
|
||||
aes_ni_context *ctx = container_of(ciph, aes_ni_context, ciph);
|
||||
const unsigned char *key = (const unsigned char *)vkey;
|
||||
@ -1410,13 +1410,13 @@ static void aes_hw_setkey(ssh2_cipher *ciph, const void *vkey)
|
||||
ctx->keysched_e, ctx->keysched_d);
|
||||
}
|
||||
|
||||
static FUNC_ISA void aes_hw_setiv_cbc(ssh2_cipher *ciph, const void *iv)
|
||||
static FUNC_ISA void aes_hw_setiv_cbc(ssh_cipher *ciph, const void *iv)
|
||||
{
|
||||
aes_ni_context *ctx = container_of(ciph, aes_ni_context, ciph);
|
||||
ctx->iv = _mm_loadu_si128(iv);
|
||||
}
|
||||
|
||||
static FUNC_ISA void aes_hw_setiv_sdctr(ssh2_cipher *ciph, const void *iv)
|
||||
static FUNC_ISA void aes_hw_setiv_sdctr(ssh_cipher *ciph, const void *iv)
|
||||
{
|
||||
aes_ni_context *ctx = container_of(ciph, aes_ni_context, ciph);
|
||||
__m128i counter = _mm_loadu_si128(iv);
|
||||
@ -1426,7 +1426,7 @@ static FUNC_ISA void aes_hw_setiv_sdctr(ssh2_cipher *ciph, const void *iv)
|
||||
typedef __m128i (*aes_ni_fn)(__m128i v, const __m128i *keysched);
|
||||
|
||||
static FUNC_ISA inline void aes_cbc_ni_encrypt(
|
||||
ssh2_cipher *ciph, void *vblk, int blklen, aes_ni_fn encrypt)
|
||||
ssh_cipher *ciph, void *vblk, int blklen, aes_ni_fn encrypt)
|
||||
{
|
||||
aes_ni_context *ctx = container_of(ciph, aes_ni_context, ciph);
|
||||
|
||||
@ -1441,7 +1441,7 @@ static FUNC_ISA inline void aes_cbc_ni_encrypt(
|
||||
}
|
||||
|
||||
static FUNC_ISA inline void aes_cbc_ni_decrypt(
|
||||
ssh2_cipher *ciph, void *vblk, int blklen, aes_ni_fn decrypt)
|
||||
ssh_cipher *ciph, void *vblk, int blklen, aes_ni_fn decrypt)
|
||||
{
|
||||
aes_ni_context *ctx = container_of(ciph, aes_ni_context, ciph);
|
||||
|
||||
@ -1456,7 +1456,7 @@ static FUNC_ISA inline void aes_cbc_ni_decrypt(
|
||||
}
|
||||
|
||||
static FUNC_ISA inline void aes_sdctr_ni(
|
||||
ssh2_cipher *ciph, void *vblk, int blklen, aes_ni_fn encrypt)
|
||||
ssh_cipher *ciph, void *vblk, int blklen, aes_ni_fn encrypt)
|
||||
{
|
||||
aes_ni_context *ctx = container_of(ciph, aes_ni_context, ciph);
|
||||
|
||||
@ -1473,13 +1473,13 @@ static FUNC_ISA inline void aes_sdctr_ni(
|
||||
|
||||
#define NI_ENC_DEC(len) \
|
||||
static FUNC_ISA void aes##len##_cbc_hw_encrypt( \
|
||||
ssh2_cipher *ciph, void *vblk, int blklen) \
|
||||
ssh_cipher *ciph, void *vblk, int blklen) \
|
||||
{ aes_cbc_ni_encrypt(ciph, vblk, blklen, aes_ni_##len##_e); } \
|
||||
static FUNC_ISA void aes##len##_cbc_hw_decrypt( \
|
||||
ssh2_cipher *ciph, void *vblk, int blklen) \
|
||||
ssh_cipher *ciph, void *vblk, int blklen) \
|
||||
{ aes_cbc_ni_decrypt(ciph, vblk, blklen, aes_ni_##len##_d); } \
|
||||
static FUNC_ISA void aes##len##_sdctr_hw( \
|
||||
ssh2_cipher *ciph, void *vblk, int blklen) \
|
||||
ssh_cipher *ciph, void *vblk, int blklen) \
|
||||
{ aes_sdctr_ni(ciph, vblk, blklen, aes_ni_##len##_e); } \
|
||||
|
||||
NI_ENC_DEC(128)
|
||||
@ -1692,10 +1692,10 @@ typedef struct aes_neon_context aes_neon_context;
|
||||
struct aes_neon_context {
|
||||
uint8x16_t keysched_e[MAXROUNDKEYS], keysched_d[MAXROUNDKEYS], iv;
|
||||
|
||||
ssh2_cipher ciph;
|
||||
ssh_cipher ciph;
|
||||
};
|
||||
|
||||
static ssh2_cipher *aes_hw_new(const ssh2_cipheralg *alg)
|
||||
static ssh_cipher *aes_hw_new(const ssh_cipheralg *alg)
|
||||
{
|
||||
if (!aes_hw_available_cached())
|
||||
return NULL;
|
||||
@ -1705,14 +1705,14 @@ static ssh2_cipher *aes_hw_new(const ssh2_cipheralg *alg)
|
||||
return &ctx->ciph;
|
||||
}
|
||||
|
||||
static void aes_hw_free(ssh2_cipher *ciph)
|
||||
static void aes_hw_free(ssh_cipher *ciph)
|
||||
{
|
||||
aes_neon_context *ctx = container_of(ciph, aes_neon_context, ciph);
|
||||
smemclr(ctx, sizeof(*ctx));
|
||||
sfree(ctx);
|
||||
}
|
||||
|
||||
static void aes_hw_setkey(ssh2_cipher *ciph, const void *vkey)
|
||||
static void aes_hw_setkey(ssh_cipher *ciph, const void *vkey)
|
||||
{
|
||||
aes_neon_context *ctx = container_of(ciph, aes_neon_context, ciph);
|
||||
const unsigned char *key = (const unsigned char *)vkey;
|
||||
@ -1721,13 +1721,13 @@ static void aes_hw_setkey(ssh2_cipher *ciph, const void *vkey)
|
||||
ctx->keysched_e, ctx->keysched_d);
|
||||
}
|
||||
|
||||
static FUNC_ISA void aes_hw_setiv_cbc(ssh2_cipher *ciph, const void *iv)
|
||||
static FUNC_ISA void aes_hw_setiv_cbc(ssh_cipher *ciph, const void *iv)
|
||||
{
|
||||
aes_neon_context *ctx = container_of(ciph, aes_neon_context, ciph);
|
||||
ctx->iv = vld1q_u8(iv);
|
||||
}
|
||||
|
||||
static FUNC_ISA void aes_hw_setiv_sdctr(ssh2_cipher *ciph, const void *iv)
|
||||
static FUNC_ISA void aes_hw_setiv_sdctr(ssh_cipher *ciph, const void *iv)
|
||||
{
|
||||
aes_neon_context *ctx = container_of(ciph, aes_neon_context, ciph);
|
||||
uint8x16_t counter = vld1q_u8(iv);
|
||||
@ -1737,7 +1737,7 @@ static FUNC_ISA void aes_hw_setiv_sdctr(ssh2_cipher *ciph, const void *iv)
|
||||
typedef uint8x16_t (*aes_neon_fn)(uint8x16_t v, const uint8x16_t *keysched);
|
||||
|
||||
static FUNC_ISA inline void aes_cbc_neon_encrypt(
|
||||
ssh2_cipher *ciph, void *vblk, int blklen, aes_neon_fn encrypt)
|
||||
ssh_cipher *ciph, void *vblk, int blklen, aes_neon_fn encrypt)
|
||||
{
|
||||
aes_neon_context *ctx = container_of(ciph, aes_neon_context, ciph);
|
||||
|
||||
@ -1752,7 +1752,7 @@ static FUNC_ISA inline void aes_cbc_neon_encrypt(
|
||||
}
|
||||
|
||||
static FUNC_ISA inline void aes_cbc_neon_decrypt(
|
||||
ssh2_cipher *ciph, void *vblk, int blklen, aes_neon_fn decrypt)
|
||||
ssh_cipher *ciph, void *vblk, int blklen, aes_neon_fn decrypt)
|
||||
{
|
||||
aes_neon_context *ctx = container_of(ciph, aes_neon_context, ciph);
|
||||
|
||||
@ -1767,7 +1767,7 @@ static FUNC_ISA inline void aes_cbc_neon_decrypt(
|
||||
}
|
||||
|
||||
static FUNC_ISA inline void aes_sdctr_neon(
|
||||
ssh2_cipher *ciph, void *vblk, int blklen, aes_neon_fn encrypt)
|
||||
ssh_cipher *ciph, void *vblk, int blklen, aes_neon_fn encrypt)
|
||||
{
|
||||
aes_neon_context *ctx = container_of(ciph, aes_neon_context, ciph);
|
||||
|
||||
@ -1784,13 +1784,13 @@ static FUNC_ISA inline void aes_sdctr_neon(
|
||||
|
||||
#define NEON_ENC_DEC(len) \
|
||||
static FUNC_ISA void aes##len##_cbc_hw_encrypt( \
|
||||
ssh2_cipher *ciph, void *vblk, int blklen) \
|
||||
ssh_cipher *ciph, void *vblk, int blklen) \
|
||||
{ aes_cbc_neon_encrypt(ciph, vblk, blklen, aes_neon_##len##_e); } \
|
||||
static FUNC_ISA void aes##len##_cbc_hw_decrypt( \
|
||||
ssh2_cipher *ciph, void *vblk, int blklen) \
|
||||
ssh_cipher *ciph, void *vblk, int blklen) \
|
||||
{ aes_cbc_neon_decrypt(ciph, vblk, blklen, aes_neon_##len##_d); } \
|
||||
static FUNC_ISA void aes##len##_sdctr_hw( \
|
||||
ssh2_cipher *ciph, void *vblk, int blklen) \
|
||||
ssh_cipher *ciph, void *vblk, int blklen) \
|
||||
{ aes_sdctr_neon(ciph, vblk, blklen, aes_neon_##len##_e); } \
|
||||
|
||||
NEON_ENC_DEC(128)
|
||||
@ -1812,24 +1812,24 @@ bool aes_hw_available(void)
|
||||
return false;
|
||||
}
|
||||
|
||||
static ssh2_cipher *aes_hw_new(const ssh2_cipheralg *alg)
|
||||
static ssh_cipher *aes_hw_new(const ssh_cipheralg *alg)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define STUB_BODY { unreachable("Should never be called"); }
|
||||
|
||||
static void aes_hw_free(ssh2_cipher *ciph) STUB_BODY
|
||||
static void aes_hw_setkey(ssh2_cipher *ciph, const void *key) STUB_BODY
|
||||
static void aes_hw_setiv_cbc(ssh2_cipher *ciph, const void *iv) STUB_BODY
|
||||
static void aes_hw_setiv_sdctr(ssh2_cipher *ciph, const void *iv) STUB_BODY
|
||||
#define STUB_ENC_DEC(len) \
|
||||
static void aes##len##_cbc_hw_encrypt( \
|
||||
ssh2_cipher *ciph, void *vblk, int blklen) STUB_BODY \
|
||||
static void aes##len##_cbc_hw_decrypt( \
|
||||
ssh2_cipher *ciph, void *vblk, int blklen) STUB_BODY \
|
||||
static void aes##len##_sdctr_hw( \
|
||||
ssh2_cipher *ciph, void *vblk, int blklen) STUB_BODY
|
||||
static void aes_hw_free(ssh_cipher *ciph) STUB_BODY
|
||||
static void aes_hw_setkey(ssh_cipher *ciph, const void *key) STUB_BODY
|
||||
static void aes_hw_setiv_cbc(ssh_cipher *ciph, const void *iv) STUB_BODY
|
||||
static void aes_hw_setiv_sdctr(ssh_cipher *ciph, const void *iv) STUB_BODY
|
||||
#define STUB_ENC_DEC(len) \
|
||||
static void aes##len##_cbc_hw_encrypt( \
|
||||
ssh_cipher *ciph, void *vblk, int blklen) STUB_BODY \
|
||||
static void aes##len##_cbc_hw_decrypt( \
|
||||
ssh_cipher *ciph, void *vblk, int blklen) STUB_BODY \
|
||||
static void aes##len##_sdctr_hw( \
|
||||
ssh_cipher *ciph, void *vblk, int blklen) STUB_BODY
|
||||
|
||||
STUB_ENC_DEC(128)
|
||||
STUB_ENC_DEC(192)
|
||||
@ -1846,20 +1846,20 @@ void aes256_encrypt_pubkey(const void *key, void *blk, int len)
|
||||
{
|
||||
char iv[16];
|
||||
memset(iv, 0, 16);
|
||||
ssh2_cipher *cipher = ssh2_cipher_new(&ssh_aes256_cbc);
|
||||
ssh2_cipher_setkey(cipher, key);
|
||||
ssh2_cipher_setiv(cipher, iv);
|
||||
ssh2_cipher_encrypt(cipher, blk, len);
|
||||
ssh2_cipher_free(cipher);
|
||||
ssh_cipher *cipher = ssh_cipher_new(&ssh_aes256_cbc);
|
||||
ssh_cipher_setkey(cipher, key);
|
||||
ssh_cipher_setiv(cipher, iv);
|
||||
ssh_cipher_encrypt(cipher, blk, len);
|
||||
ssh_cipher_free(cipher);
|
||||
}
|
||||
|
||||
void aes256_decrypt_pubkey(const void *key, void *blk, int len)
|
||||
{
|
||||
char iv[16];
|
||||
memset(iv, 0, 16);
|
||||
ssh2_cipher *cipher = ssh2_cipher_new(&ssh_aes256_cbc);
|
||||
ssh2_cipher_setkey(cipher, key);
|
||||
ssh2_cipher_setiv(cipher, iv);
|
||||
ssh2_cipher_decrypt(cipher, blk, len);
|
||||
ssh2_cipher_free(cipher);
|
||||
ssh_cipher *cipher = ssh_cipher_new(&ssh_aes256_cbc);
|
||||
ssh_cipher_setkey(cipher, key);
|
||||
ssh_cipher_setiv(cipher, iv);
|
||||
ssh_cipher_decrypt(cipher, blk, len);
|
||||
ssh_cipher_free(cipher);
|
||||
}
|
||||
|
18
ssharcf.c
18
ssharcf.c
@ -9,7 +9,7 @@
|
||||
|
||||
typedef struct {
|
||||
unsigned char i, j, s[256];
|
||||
ssh2_cipher ciph;
|
||||
ssh_cipher ciph;
|
||||
} ArcfourContext;
|
||||
|
||||
static void arcfour_block(void *handle, void *vblk, int len)
|
||||
@ -62,14 +62,14 @@ static void arcfour_setkey(ArcfourContext *ctx, unsigned char const *key,
|
||||
* to leak data about the key.
|
||||
*/
|
||||
|
||||
static ssh2_cipher *arcfour_new(const ssh2_cipheralg *alg)
|
||||
static ssh_cipher *arcfour_new(const ssh_cipheralg *alg)
|
||||
{
|
||||
ArcfourContext *ctx = snew(ArcfourContext);
|
||||
ctx->ciph.vt = alg;
|
||||
return &ctx->ciph;
|
||||
}
|
||||
|
||||
static void arcfour_free(ssh2_cipher *cipher)
|
||||
static void arcfour_free(ssh_cipher *cipher)
|
||||
{
|
||||
ArcfourContext *ctx = container_of(cipher, ArcfourContext, ciph);
|
||||
smemclr(ctx, sizeof(*ctx));
|
||||
@ -85,25 +85,25 @@ static void arcfour_stir(ArcfourContext *ctx)
|
||||
sfree(junk);
|
||||
}
|
||||
|
||||
static void arcfour_ssh2_setiv(ssh2_cipher *cipher, const void *key)
|
||||
static void arcfour_ssh2_setiv(ssh_cipher *cipher, const void *key)
|
||||
{
|
||||
/* As a pure stream cipher, Arcfour has no IV separate from the key */
|
||||
}
|
||||
|
||||
static void arcfour_ssh2_setkey(ssh2_cipher *cipher, const void *key)
|
||||
static void arcfour_ssh2_setkey(ssh_cipher *cipher, const void *key)
|
||||
{
|
||||
ArcfourContext *ctx = container_of(cipher, ArcfourContext, ciph);
|
||||
arcfour_setkey(ctx, key, ctx->ciph.vt->padded_keybytes);
|
||||
arcfour_stir(ctx);
|
||||
}
|
||||
|
||||
static void arcfour_ssh2_block(ssh2_cipher *cipher, void *blk, int len)
|
||||
static void arcfour_ssh2_block(ssh_cipher *cipher, void *blk, int len)
|
||||
{
|
||||
ArcfourContext *ctx = container_of(cipher, ArcfourContext, ciph);
|
||||
arcfour_block(ctx, blk, len);
|
||||
}
|
||||
|
||||
const ssh2_cipheralg ssh_arcfour128_ssh2 = {
|
||||
const ssh_cipheralg ssh_arcfour128_ssh2 = {
|
||||
arcfour_new, arcfour_free, arcfour_ssh2_setiv, arcfour_ssh2_setkey,
|
||||
arcfour_ssh2_block, arcfour_ssh2_block, NULL, NULL,
|
||||
"arcfour128",
|
||||
@ -111,7 +111,7 @@ const ssh2_cipheralg ssh_arcfour128_ssh2 = {
|
||||
NULL
|
||||
};
|
||||
|
||||
const ssh2_cipheralg ssh_arcfour256_ssh2 = {
|
||||
const ssh_cipheralg ssh_arcfour256_ssh2 = {
|
||||
arcfour_new, arcfour_free, arcfour_ssh2_setiv, arcfour_ssh2_setkey,
|
||||
arcfour_ssh2_block, arcfour_ssh2_block, NULL, NULL,
|
||||
"arcfour256",
|
||||
@ -119,7 +119,7 @@ const ssh2_cipheralg ssh_arcfour256_ssh2 = {
|
||||
NULL
|
||||
};
|
||||
|
||||
static const ssh2_cipheralg *const arcfour_list[] = {
|
||||
static const ssh_cipheralg *const arcfour_list[] = {
|
||||
&ssh_arcfour256_ssh2,
|
||||
&ssh_arcfour128_ssh2,
|
||||
};
|
||||
|
135
sshblowf.c
135
sshblowf.c
@ -566,138 +566,115 @@ void blowfish_free_context(BlowfishContext *ctx)
|
||||
sfree(ctx);
|
||||
}
|
||||
|
||||
static void blowfish_iv(BlowfishContext *ctx, const void *viv)
|
||||
static void blowfish_iv_be(BlowfishContext *ctx, const void *viv)
|
||||
{
|
||||
const unsigned char *iv = (const unsigned char *)viv;
|
||||
ctx->iv0 = GET_32BIT_MSB_FIRST(iv);
|
||||
ctx->iv1 = GET_32BIT_MSB_FIRST(iv + 4);
|
||||
}
|
||||
|
||||
struct blowfish_ssh1_ctx {
|
||||
/* In SSH-1, need one key for each direction */
|
||||
BlowfishContext contexts[2];
|
||||
ssh1_cipher ciph;
|
||||
};
|
||||
|
||||
static ssh1_cipher *blowfish_ssh1_new(void)
|
||||
static void blowfish_iv_le(BlowfishContext *ctx, const void *viv)
|
||||
{
|
||||
struct blowfish_ssh1_ctx *ctx = snew(struct blowfish_ssh1_ctx);
|
||||
ctx->ciph.vt = &ssh1_blowfish;
|
||||
return &ctx->ciph;
|
||||
const unsigned char *iv = (const unsigned char *)viv;
|
||||
ctx->iv0 = GET_32BIT_LSB_FIRST(iv);
|
||||
ctx->iv1 = GET_32BIT_LSB_FIRST(iv + 4);
|
||||
}
|
||||
|
||||
static void blowfish_ssh1_free(ssh1_cipher *cipher)
|
||||
{
|
||||
struct blowfish_ssh1_ctx *ctx =
|
||||
container_of(cipher, struct blowfish_ssh1_ctx, ciph);
|
||||
smemclr(ctx, sizeof(*ctx));
|
||||
sfree(ctx);
|
||||
}
|
||||
|
||||
static void blowfish_ssh1_sesskey(ssh1_cipher *cipher, const void *key)
|
||||
{
|
||||
struct blowfish_ssh1_ctx *ctx =
|
||||
container_of(cipher, struct blowfish_ssh1_ctx, ciph);
|
||||
blowfish_setkey(&ctx->contexts[0], key, SSH1_SESSION_KEY_LENGTH);
|
||||
ctx->contexts[0].iv0 = ctx->contexts[0].iv1 = 0;
|
||||
ctx->contexts[1] = ctx->contexts[0]; /* structure copy */
|
||||
}
|
||||
|
||||
static void blowfish_ssh1_encrypt_blk(ssh1_cipher *cipher, void *blk, int len)
|
||||
{
|
||||
struct blowfish_ssh1_ctx *ctx =
|
||||
container_of(cipher, struct blowfish_ssh1_ctx, ciph);
|
||||
blowfish_lsb_encrypt_cbc(blk, len, ctx->contexts);
|
||||
}
|
||||
|
||||
static void blowfish_ssh1_decrypt_blk(ssh1_cipher *cipher, void *blk, int len)
|
||||
{
|
||||
struct blowfish_ssh1_ctx *ctx =
|
||||
container_of(cipher, struct blowfish_ssh1_ctx, ciph);
|
||||
blowfish_lsb_decrypt_cbc(blk, len, ctx->contexts+1);
|
||||
}
|
||||
|
||||
struct blowfish_ssh2_ctx {
|
||||
struct blowfish_ctx {
|
||||
BlowfishContext context;
|
||||
ssh2_cipher ciph;
|
||||
ssh_cipher ciph;
|
||||
};
|
||||
|
||||
static ssh2_cipher *blowfish_ssh2_new(const ssh2_cipheralg *alg)
|
||||
static ssh_cipher *blowfish_new(const ssh_cipheralg *alg)
|
||||
{
|
||||
struct blowfish_ssh2_ctx *ctx = snew(struct blowfish_ssh2_ctx);
|
||||
struct blowfish_ctx *ctx = snew(struct blowfish_ctx);
|
||||
ctx->ciph.vt = alg;
|
||||
return &ctx->ciph;
|
||||
}
|
||||
|
||||
static void blowfish_ssh2_free(ssh2_cipher *cipher)
|
||||
static void blowfish_free(ssh_cipher *cipher)
|
||||
{
|
||||
struct blowfish_ssh2_ctx *ctx =
|
||||
container_of(cipher, struct blowfish_ssh2_ctx, ciph);
|
||||
struct blowfish_ctx *ctx = container_of(cipher, struct blowfish_ctx, ciph);
|
||||
smemclr(ctx, sizeof(*ctx));
|
||||
sfree(ctx);
|
||||
}
|
||||
|
||||
static void blowfish_ssh2_setiv(ssh2_cipher *cipher, const void *iv)
|
||||
static void blowfish_ssh_setkey(ssh_cipher *cipher, const void *key)
|
||||
{
|
||||
struct blowfish_ssh2_ctx *ctx =
|
||||
container_of(cipher, struct blowfish_ssh2_ctx, ciph);
|
||||
blowfish_iv(&ctx->context, iv);
|
||||
}
|
||||
|
||||
static void blowfish_ssh2_setkey(ssh2_cipher *cipher, const void *key)
|
||||
{
|
||||
struct blowfish_ssh2_ctx *ctx =
|
||||
container_of(cipher, struct blowfish_ssh2_ctx, ciph);
|
||||
struct blowfish_ctx *ctx = container_of(cipher, struct blowfish_ctx, ciph);
|
||||
blowfish_setkey(&ctx->context, key, ctx->ciph.vt->padded_keybytes);
|
||||
}
|
||||
|
||||
static void blowfish_ssh2_encrypt_blk(ssh2_cipher *cipher, void *blk, int len)
|
||||
static void blowfish_ssh1_setiv(ssh_cipher *cipher, const void *iv)
|
||||
{
|
||||
struct blowfish_ssh2_ctx *ctx =
|
||||
container_of(cipher, struct blowfish_ssh2_ctx, ciph);
|
||||
struct blowfish_ctx *ctx = container_of(cipher, struct blowfish_ctx, ciph);
|
||||
blowfish_iv_le(&ctx->context, iv);
|
||||
}
|
||||
|
||||
static void blowfish_ssh2_setiv(ssh_cipher *cipher, const void *iv)
|
||||
{
|
||||
struct blowfish_ctx *ctx = container_of(cipher, struct blowfish_ctx, ciph);
|
||||
blowfish_iv_be(&ctx->context, iv);
|
||||
}
|
||||
|
||||
static void blowfish_ssh1_encrypt_blk(ssh_cipher *cipher, void *blk, int len)
|
||||
{
|
||||
struct blowfish_ctx *ctx = container_of(cipher, struct blowfish_ctx, ciph);
|
||||
blowfish_lsb_encrypt_cbc(blk, len, &ctx->context);
|
||||
}
|
||||
|
||||
static void blowfish_ssh1_decrypt_blk(ssh_cipher *cipher, void *blk, int len)
|
||||
{
|
||||
struct blowfish_ctx *ctx = container_of(cipher, struct blowfish_ctx, ciph);
|
||||
blowfish_lsb_decrypt_cbc(blk, len, &ctx->context);
|
||||
}
|
||||
|
||||
static void blowfish_ssh2_encrypt_blk(ssh_cipher *cipher, void *blk, int len)
|
||||
{
|
||||
struct blowfish_ctx *ctx = container_of(cipher, struct blowfish_ctx, ciph);
|
||||
blowfish_msb_encrypt_cbc(blk, len, &ctx->context);
|
||||
}
|
||||
|
||||
static void blowfish_ssh2_decrypt_blk(ssh2_cipher *cipher, void *blk, int len)
|
||||
static void blowfish_ssh2_decrypt_blk(ssh_cipher *cipher, void *blk, int len)
|
||||
{
|
||||
struct blowfish_ssh2_ctx *ctx =
|
||||
container_of(cipher, struct blowfish_ssh2_ctx, ciph);
|
||||
struct blowfish_ctx *ctx = container_of(cipher, struct blowfish_ctx, ciph);
|
||||
blowfish_msb_decrypt_cbc(blk, len, &ctx->context);
|
||||
}
|
||||
|
||||
static void blowfish_ssh2_sdctr(ssh2_cipher *cipher, void *blk, int len)
|
||||
static void blowfish_ssh2_sdctr(ssh_cipher *cipher, void *blk, int len)
|
||||
{
|
||||
struct blowfish_ssh2_ctx *ctx =
|
||||
container_of(cipher, struct blowfish_ssh2_ctx, ciph);
|
||||
struct blowfish_ctx *ctx = container_of(cipher, struct blowfish_ctx, ciph);
|
||||
blowfish_msb_sdctr(blk, len, &ctx->context);
|
||||
}
|
||||
|
||||
const ssh1_cipheralg ssh1_blowfish = {
|
||||
blowfish_ssh1_new, blowfish_ssh1_free,
|
||||
blowfish_ssh1_sesskey,
|
||||
const ssh_cipheralg ssh_blowfish_ssh1 = {
|
||||
blowfish_new, blowfish_free,
|
||||
blowfish_ssh1_setiv, blowfish_ssh_setkey,
|
||||
blowfish_ssh1_encrypt_blk, blowfish_ssh1_decrypt_blk,
|
||||
8, "Blowfish-128 CBC"
|
||||
NULL, NULL, NULL,
|
||||
8, 128, SSH1_SESSION_KEY_LENGTH, SSH_CIPHER_IS_CBC, "Blowfish-256 CBC",
|
||||
NULL
|
||||
};
|
||||
|
||||
const ssh2_cipheralg ssh_blowfish_ssh2 = {
|
||||
blowfish_ssh2_new, blowfish_ssh2_free,
|
||||
blowfish_ssh2_setiv, blowfish_ssh2_setkey,
|
||||
const ssh_cipheralg ssh_blowfish_ssh2 = {
|
||||
blowfish_new, blowfish_free,
|
||||
blowfish_ssh2_setiv, blowfish_ssh_setkey,
|
||||
blowfish_ssh2_encrypt_blk, blowfish_ssh2_decrypt_blk, NULL, NULL,
|
||||
"blowfish-cbc",
|
||||
8, 128, 16, SSH_CIPHER_IS_CBC, "Blowfish-128 CBC",
|
||||
NULL
|
||||
};
|
||||
|
||||
const ssh2_cipheralg ssh_blowfish_ssh2_ctr = {
|
||||
blowfish_ssh2_new, blowfish_ssh2_free,
|
||||
blowfish_ssh2_setiv, blowfish_ssh2_setkey,
|
||||
const ssh_cipheralg ssh_blowfish_ssh2_ctr = {
|
||||
blowfish_new, blowfish_free,
|
||||
blowfish_ssh2_setiv, blowfish_ssh_setkey,
|
||||
blowfish_ssh2_sdctr, blowfish_ssh2_sdctr, NULL, NULL,
|
||||
"blowfish-ctr",
|
||||
8, 256, 32, 0, "Blowfish-256 SDCTR",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const ssh2_cipheralg *const blowfish_list[] = {
|
||||
static const ssh_cipheralg *const blowfish_list[] = {
|
||||
&ssh_blowfish_ssh2_ctr,
|
||||
&ssh_blowfish_ssh2
|
||||
};
|
||||
|
6
sshbpp.h
6
sshbpp.h
@ -54,7 +54,7 @@ void ssh_bpp_free(BinaryPacketProtocol *bpp);
|
||||
|
||||
BinaryPacketProtocol *ssh1_bpp_new(LogContext *logctx);
|
||||
void ssh1_bpp_new_cipher(BinaryPacketProtocol *bpp,
|
||||
const ssh1_cipheralg *cipher,
|
||||
const ssh_cipheralg *cipher,
|
||||
const void *session_key);
|
||||
/* This is only called from outside the BPP in server mode; in client
|
||||
* mode the BPP detects compression start time automatically by
|
||||
@ -104,12 +104,12 @@ BinaryPacketProtocol *ssh2_bpp_new(
|
||||
LogContext *logctx, struct DataTransferStats *stats, bool is_server);
|
||||
void ssh2_bpp_new_outgoing_crypto(
|
||||
BinaryPacketProtocol *bpp,
|
||||
const ssh2_cipheralg *cipher, const void *ckey, const void *iv,
|
||||
const ssh_cipheralg *cipher, const void *ckey, const void *iv,
|
||||
const ssh2_macalg *mac, bool etm_mode, const void *mac_key,
|
||||
const ssh_compression_alg *compression, bool delayed_compression);
|
||||
void ssh2_bpp_new_incoming_crypto(
|
||||
BinaryPacketProtocol *bpp,
|
||||
const ssh2_cipheralg *cipher, const void *ckey, const void *iv,
|
||||
const ssh_cipheralg *cipher, const void *ckey, const void *iv,
|
||||
const ssh2_macalg *mac, bool etm_mode, const void *mac_key,
|
||||
const ssh_compression_alg *compression, bool delayed_compression);
|
||||
|
||||
|
26
sshccp.c
26
sshccp.c
@ -20,7 +20,7 @@
|
||||
* This has an intricate link between the cipher and the MAC. The
|
||||
* keying of both is done in by the cipher and setting of the IV is
|
||||
* done by the MAC. One cannot operate without the other. The
|
||||
* configuration of the ssh2_cipheralg structure ensures that the MAC is
|
||||
* configuration of the ssh_cipheralg structure ensures that the MAC is
|
||||
* set (and others ignored) if this cipher is chosen.
|
||||
*
|
||||
* This cipher also encrypts the length using a different
|
||||
@ -867,12 +867,12 @@ struct ccp_context {
|
||||
struct poly1305 mac;
|
||||
|
||||
BinarySink_IMPLEMENTATION;
|
||||
ssh2_cipher ciph;
|
||||
ssh_cipher ciph;
|
||||
ssh2_mac mac_if;
|
||||
};
|
||||
|
||||
static ssh2_mac *poly_ssh2_new(
|
||||
const ssh2_macalg *alg, ssh2_cipher *cipher)
|
||||
const ssh2_macalg *alg, ssh_cipher *cipher)
|
||||
{
|
||||
struct ccp_context *ctx = container_of(cipher, struct ccp_context, ciph);
|
||||
ctx->mac_if.vt = alg;
|
||||
@ -946,7 +946,7 @@ const ssh2_macalg ssh2_poly1305 = {
|
||||
16, 0, "Poly1305"
|
||||
};
|
||||
|
||||
static ssh2_cipher *ccp_new(const ssh2_cipheralg *alg)
|
||||
static ssh_cipher *ccp_new(const ssh_cipheralg *alg)
|
||||
{
|
||||
struct ccp_context *ctx = snew(struct ccp_context);
|
||||
BinarySink_INIT(ctx, poly_BinarySink_write);
|
||||
@ -955,7 +955,7 @@ static ssh2_cipher *ccp_new(const ssh2_cipheralg *alg)
|
||||
return &ctx->ciph;
|
||||
}
|
||||
|
||||
static void ccp_free(ssh2_cipher *cipher)
|
||||
static void ccp_free(ssh_cipher *cipher)
|
||||
{
|
||||
struct ccp_context *ctx = container_of(cipher, struct ccp_context, ciph);
|
||||
smemclr(&ctx->a_cipher, sizeof(ctx->a_cipher));
|
||||
@ -964,14 +964,14 @@ static void ccp_free(ssh2_cipher *cipher)
|
||||
sfree(ctx);
|
||||
}
|
||||
|
||||
static void ccp_iv(ssh2_cipher *cipher, const void *iv)
|
||||
static void ccp_iv(ssh_cipher *cipher, const void *iv)
|
||||
{
|
||||
/* struct ccp_context *ctx =
|
||||
container_of(cipher, struct ccp_context, ciph); */
|
||||
/* IV is set based on the sequence number */
|
||||
}
|
||||
|
||||
static void ccp_key(ssh2_cipher *cipher, const void *vkey)
|
||||
static void ccp_key(ssh_cipher *cipher, const void *vkey)
|
||||
{
|
||||
const unsigned char *key = (const unsigned char *)vkey;
|
||||
struct ccp_context *ctx = container_of(cipher, struct ccp_context, ciph);
|
||||
@ -981,13 +981,13 @@ static void ccp_key(ssh2_cipher *cipher, const void *vkey)
|
||||
chacha20_key(&ctx->b_cipher, key);
|
||||
}
|
||||
|
||||
static void ccp_encrypt(ssh2_cipher *cipher, void *blk, int len)
|
||||
static void ccp_encrypt(ssh_cipher *cipher, void *blk, int len)
|
||||
{
|
||||
struct ccp_context *ctx = container_of(cipher, struct ccp_context, ciph);
|
||||
chacha20_encrypt(&ctx->b_cipher, blk, len);
|
||||
}
|
||||
|
||||
static void ccp_decrypt(ssh2_cipher *cipher, void *blk, int len)
|
||||
static void ccp_decrypt(ssh_cipher *cipher, void *blk, int len)
|
||||
{
|
||||
struct ccp_context *ctx = container_of(cipher, struct ccp_context, ciph);
|
||||
chacha20_decrypt(&ctx->b_cipher, blk, len);
|
||||
@ -1010,7 +1010,7 @@ static void ccp_length_op(struct ccp_context *ctx, void *blk, int len,
|
||||
smemclr(iv, sizeof(iv));
|
||||
}
|
||||
|
||||
static void ccp_encrypt_length(ssh2_cipher *cipher, void *blk, int len,
|
||||
static void ccp_encrypt_length(ssh_cipher *cipher, void *blk, int len,
|
||||
unsigned long seq)
|
||||
{
|
||||
struct ccp_context *ctx = container_of(cipher, struct ccp_context, ciph);
|
||||
@ -1018,7 +1018,7 @@ static void ccp_encrypt_length(ssh2_cipher *cipher, void *blk, int len,
|
||||
chacha20_encrypt(&ctx->a_cipher, blk, len);
|
||||
}
|
||||
|
||||
static void ccp_decrypt_length(ssh2_cipher *cipher, void *blk, int len,
|
||||
static void ccp_decrypt_length(ssh_cipher *cipher, void *blk, int len,
|
||||
unsigned long seq)
|
||||
{
|
||||
struct ccp_context *ctx = container_of(cipher, struct ccp_context, ciph);
|
||||
@ -1026,7 +1026,7 @@ static void ccp_decrypt_length(ssh2_cipher *cipher, void *blk, int len,
|
||||
chacha20_decrypt(&ctx->a_cipher, blk, len);
|
||||
}
|
||||
|
||||
const ssh2_cipheralg ssh2_chacha20_poly1305 = {
|
||||
const ssh_cipheralg ssh2_chacha20_poly1305 = {
|
||||
|
||||
ccp_new,
|
||||
ccp_free,
|
||||
@ -1043,7 +1043,7 @@ const ssh2_cipheralg ssh2_chacha20_poly1305 = {
|
||||
&ssh2_poly1305
|
||||
};
|
||||
|
||||
static const ssh2_cipheralg *const ccp_list[] = {
|
||||
static const ssh_cipheralg *const ccp_list[] = {
|
||||
&ssh2_chacha20_poly1305
|
||||
};
|
||||
|
||||
|
161
sshdes.c
161
sshdes.c
@ -774,32 +774,18 @@ static void des_key(DESContext *context, const void *vkey)
|
||||
}
|
||||
|
||||
struct des3_ssh1_ctx {
|
||||
/* 3 cipher context for each direction */
|
||||
DESContext contexts[6];
|
||||
ssh1_cipher ciph;
|
||||
DESContext contexts[3];
|
||||
ssh_cipher ciph;
|
||||
};
|
||||
|
||||
struct des_ssh1_ctx {
|
||||
/* 1 cipher context for each direction */
|
||||
DESContext contexts[2];
|
||||
ssh1_cipher ciph;
|
||||
};
|
||||
|
||||
static ssh1_cipher *des3_ssh1_new(void)
|
||||
static ssh_cipher *des3_ssh1_new(const ssh_cipheralg *alg)
|
||||
{
|
||||
struct des3_ssh1_ctx *ctx = snew(struct des3_ssh1_ctx);
|
||||
ctx->ciph.vt = &ssh1_3des;
|
||||
ctx->ciph.vt = alg;
|
||||
return &ctx->ciph;
|
||||
}
|
||||
|
||||
static ssh1_cipher *des_ssh1_new(void)
|
||||
{
|
||||
struct des_ssh1_ctx *ctx = snew(struct des_ssh1_ctx);
|
||||
ctx->ciph.vt = &ssh1_des;
|
||||
return &ctx->ciph;
|
||||
}
|
||||
|
||||
static void des3_ssh1_free(ssh1_cipher *cipher)
|
||||
static void des3_ssh1_free(ssh_cipher *cipher)
|
||||
{
|
||||
struct des3_ssh1_ctx *ctx = container_of(
|
||||
cipher, struct des3_ssh1_ctx, ciph);
|
||||
@ -807,83 +793,65 @@ static void des3_ssh1_free(ssh1_cipher *cipher)
|
||||
sfree(ctx);
|
||||
}
|
||||
|
||||
static void des_ssh1_free(ssh1_cipher *cipher)
|
||||
{
|
||||
struct des_ssh1_ctx *ctx = container_of(
|
||||
cipher, struct des_ssh1_ctx, ciph);
|
||||
smemclr(ctx, sizeof(*ctx));
|
||||
sfree(ctx);
|
||||
}
|
||||
|
||||
static void des3_ssh1_sesskey(ssh1_cipher *cipher, const void *key)
|
||||
static void des3_ssh1_setkey(ssh_cipher *cipher, const void *key)
|
||||
{
|
||||
struct des3_ssh1_ctx *ctx = container_of(
|
||||
cipher, struct des3_ssh1_ctx, ciph);
|
||||
des3_key(ctx->contexts, key);
|
||||
des3_key(ctx->contexts+3, key);
|
||||
}
|
||||
|
||||
static void des3_ssh1_encrypt_blk(ssh1_cipher *cipher, void *blk, int len)
|
||||
static void des3_ssh1_setiv(ssh_cipher *cipher, const void *iv)
|
||||
{
|
||||
struct des3_ssh1_ctx *ctx = container_of(
|
||||
cipher, struct des3_ssh1_ctx, ciph);
|
||||
/* SSH-1's idea of triple-DES CBC is three actual instances of the
|
||||
* whole of DES-CBC, i.e. three separate CBC layers each with
|
||||
* their own IV. So in principle we ought to be able to accept 24
|
||||
* bytes of IV here. However, SSH-1 initialises all IVs to zero
|
||||
* anyway, so we fudge it by just setting them all the same. */
|
||||
for (int i = 0; i < 3; i++)
|
||||
des_iv(&ctx->contexts[i], iv);
|
||||
}
|
||||
|
||||
static void des3_ssh1_encrypt_blk(ssh_cipher *cipher, void *blk, int len)
|
||||
{
|
||||
struct des3_ssh1_ctx *ctx = container_of(
|
||||
cipher, struct des3_ssh1_ctx, ciph);
|
||||
des_3cbc_encrypt(blk, len, ctx->contexts);
|
||||
}
|
||||
|
||||
static void des3_ssh1_decrypt_blk(ssh1_cipher *cipher, void *blk, int len)
|
||||
static void des3_ssh1_decrypt_blk(ssh_cipher *cipher, void *blk, int len)
|
||||
{
|
||||
struct des3_ssh1_ctx *ctx = container_of(
|
||||
cipher, struct des3_ssh1_ctx, ciph);
|
||||
des_3cbc_decrypt(blk, len, ctx->contexts+3);
|
||||
}
|
||||
|
||||
static void des_ssh1_sesskey(ssh1_cipher *cipher, const void *key)
|
||||
{
|
||||
struct des_ssh1_ctx *ctx = container_of(
|
||||
cipher, struct des_ssh1_ctx, ciph);
|
||||
des_key(ctx->contexts, key);
|
||||
des_key(ctx->contexts+1, key);
|
||||
}
|
||||
|
||||
static void des_ssh1_encrypt_blk(ssh1_cipher *cipher, void *blk, int len)
|
||||
{
|
||||
struct des_ssh1_ctx *ctx = container_of(
|
||||
cipher, struct des_ssh1_ctx, ciph);
|
||||
des_cbc_encrypt(blk, len, ctx->contexts);
|
||||
}
|
||||
|
||||
static void des_ssh1_decrypt_blk(ssh1_cipher *cipher, void *blk, int len)
|
||||
{
|
||||
struct des_ssh1_ctx *ctx = container_of(
|
||||
cipher, struct des_ssh1_ctx, ciph);
|
||||
des_cbc_decrypt(blk, len, ctx->contexts+1);
|
||||
des_3cbc_decrypt(blk, len, ctx->contexts);
|
||||
}
|
||||
|
||||
struct des3_ssh2_ctx {
|
||||
DESContext contexts[3];
|
||||
ssh2_cipher ciph;
|
||||
ssh_cipher ciph;
|
||||
};
|
||||
|
||||
struct des_ssh2_ctx {
|
||||
struct des_ctx {
|
||||
DESContext context;
|
||||
ssh2_cipher ciph;
|
||||
ssh_cipher ciph;
|
||||
};
|
||||
|
||||
static ssh2_cipher *des3_ssh2_new(const ssh2_cipheralg *alg)
|
||||
static ssh_cipher *des3_ssh2_new(const ssh_cipheralg *alg)
|
||||
{
|
||||
struct des3_ssh2_ctx *ctx = snew(struct des3_ssh2_ctx);
|
||||
ctx->ciph.vt = alg;
|
||||
return &ctx->ciph;
|
||||
}
|
||||
|
||||
static ssh2_cipher *des_ssh2_new(const ssh2_cipheralg *alg)
|
||||
static ssh_cipher *des_new(const ssh_cipheralg *alg)
|
||||
{
|
||||
struct des_ssh2_ctx *ctx = snew(struct des_ssh2_ctx);
|
||||
struct des_ctx *ctx = snew(struct des_ctx);
|
||||
ctx->ciph.vt = alg;
|
||||
return &ctx->ciph;
|
||||
}
|
||||
|
||||
static void des3_ssh2_free(ssh2_cipher *cipher)
|
||||
static void des3_ssh2_free(ssh_cipher *cipher)
|
||||
{
|
||||
struct des3_ssh2_ctx *ctx = container_of(
|
||||
cipher, struct des3_ssh2_ctx, ciph);
|
||||
@ -891,15 +859,14 @@ static void des3_ssh2_free(ssh2_cipher *cipher)
|
||||
sfree(ctx);
|
||||
}
|
||||
|
||||
static void des_ssh2_free(ssh2_cipher *cipher)
|
||||
static void des_free(ssh_cipher *cipher)
|
||||
{
|
||||
struct des_ssh2_ctx *ctx = container_of(
|
||||
cipher, struct des_ssh2_ctx, ciph);
|
||||
struct des_ctx *ctx = container_of(cipher, struct des_ctx, ciph);
|
||||
smemclr(ctx, sizeof(*ctx));
|
||||
sfree(ctx);
|
||||
}
|
||||
|
||||
static void des3_ssh2_setiv(ssh2_cipher *cipher, const void *iv)
|
||||
static void des3_ssh2_setiv(ssh_cipher *cipher, const void *iv)
|
||||
{
|
||||
struct des3_ssh2_ctx *ctx = container_of(
|
||||
cipher, struct des3_ssh2_ctx, ciph);
|
||||
@ -908,59 +875,55 @@ static void des3_ssh2_setiv(ssh2_cipher *cipher, const void *iv)
|
||||
* CBC, so there's only one IV required, not three */
|
||||
}
|
||||
|
||||
static void des3_ssh2_setkey(ssh2_cipher *cipher, const void *key)
|
||||
static void des3_ssh2_setkey(ssh_cipher *cipher, const void *key)
|
||||
{
|
||||
struct des3_ssh2_ctx *ctx = container_of(
|
||||
cipher, struct des3_ssh2_ctx, ciph);
|
||||
des3_key(ctx->contexts, key);
|
||||
}
|
||||
|
||||
static void des_ssh2_setiv(ssh2_cipher *cipher, const void *iv)
|
||||
static void des_setiv(ssh_cipher *cipher, const void *iv)
|
||||
{
|
||||
struct des_ssh2_ctx *ctx = container_of(
|
||||
cipher, struct des_ssh2_ctx, ciph);
|
||||
struct des_ctx *ctx = container_of(cipher, struct des_ctx, ciph);
|
||||
des_iv(&ctx->context, iv);
|
||||
}
|
||||
|
||||
static void des_ssh2_setkey(ssh2_cipher *cipher, const void *key)
|
||||
static void des_setkey(ssh_cipher *cipher, const void *key)
|
||||
{
|
||||
struct des_ssh2_ctx *ctx = container_of(
|
||||
cipher, struct des_ssh2_ctx, ciph);
|
||||
struct des_ctx *ctx = container_of(cipher, struct des_ctx, ciph);
|
||||
des_key(&ctx->context, key);
|
||||
}
|
||||
|
||||
static void des3_ssh2_encrypt_blk(ssh2_cipher *cipher, void *blk, int len)
|
||||
static void des3_ssh2_encrypt_blk(ssh_cipher *cipher, void *blk, int len)
|
||||
{
|
||||
struct des3_ssh2_ctx *ctx = container_of(
|
||||
cipher, struct des3_ssh2_ctx, ciph);
|
||||
des_cbc3_encrypt(blk, len, ctx->contexts);
|
||||
}
|
||||
|
||||
static void des3_ssh2_decrypt_blk(ssh2_cipher *cipher, void *blk, int len)
|
||||
static void des3_ssh2_decrypt_blk(ssh_cipher *cipher, void *blk, int len)
|
||||
{
|
||||
struct des3_ssh2_ctx *ctx = container_of(
|
||||
cipher, struct des3_ssh2_ctx, ciph);
|
||||
des_cbc3_decrypt(blk, len, ctx->contexts);
|
||||
}
|
||||
|
||||
static void des3_ssh2_sdctr(ssh2_cipher *cipher, void *blk, int len)
|
||||
static void des3_ssh2_sdctr(ssh_cipher *cipher, void *blk, int len)
|
||||
{
|
||||
struct des3_ssh2_ctx *ctx = container_of(
|
||||
cipher, struct des3_ssh2_ctx, ciph);
|
||||
des_sdctr3(blk, len, ctx->contexts);
|
||||
}
|
||||
|
||||
static void des_ssh2_encrypt_blk(ssh2_cipher *cipher, void *blk, int len)
|
||||
static void des_encrypt_blk(ssh_cipher *cipher, void *blk, int len)
|
||||
{
|
||||
struct des_ssh2_ctx *ctx = container_of(
|
||||
cipher, struct des_ssh2_ctx, ciph);
|
||||
struct des_ctx *ctx = container_of(cipher, struct des_ctx, ciph);
|
||||
des_cbc_encrypt(blk, len, &ctx->context);
|
||||
}
|
||||
|
||||
static void des_ssh2_decrypt_blk(ssh2_cipher *cipher, void *blk, int len)
|
||||
static void des_decrypt_blk(ssh_cipher *cipher, void *blk, int len)
|
||||
{
|
||||
struct des_ssh2_ctx *ctx = container_of(
|
||||
cipher, struct des_ssh2_ctx, ciph);
|
||||
struct des_ctx *ctx = container_of(cipher, struct des_ctx, ciph);
|
||||
des_cbc_decrypt(blk, len, &ctx->context);
|
||||
}
|
||||
|
||||
@ -1070,7 +1033,7 @@ void des_decrypt_xdmauth(const void *keydata, void *blk, int len)
|
||||
des_cbc_decrypt(blk, len, &dc);
|
||||
}
|
||||
|
||||
const ssh2_cipheralg ssh_3des_ssh2 = {
|
||||
const ssh_cipheralg ssh_3des_ssh2 = {
|
||||
des3_ssh2_new, des3_ssh2_free, des3_ssh2_setiv, des3_ssh2_setkey,
|
||||
des3_ssh2_encrypt_blk, des3_ssh2_decrypt_blk, NULL, NULL,
|
||||
"3des-cbc",
|
||||
@ -1078,7 +1041,7 @@ const ssh2_cipheralg ssh_3des_ssh2 = {
|
||||
NULL
|
||||
};
|
||||
|
||||
const ssh2_cipheralg ssh_3des_ssh2_ctr = {
|
||||
const ssh_cipheralg ssh_3des_ssh2_ctr = {
|
||||
des3_ssh2_new, des3_ssh2_free, des3_ssh2_setiv, des3_ssh2_setkey,
|
||||
des3_ssh2_sdctr, des3_ssh2_sdctr, NULL, NULL,
|
||||
"3des-ctr",
|
||||
@ -1094,44 +1057,38 @@ const ssh2_cipheralg ssh_3des_ssh2_ctr = {
|
||||
* apparently aren't the only people to do so, so we sigh
|
||||
* and implement it anyway.
|
||||
*/
|
||||
const ssh2_cipheralg ssh_des_ssh2 = {
|
||||
des_ssh2_new, des_ssh2_free, des_ssh2_setiv, des_ssh2_setkey,
|
||||
des_ssh2_encrypt_blk, des_ssh2_decrypt_blk, NULL, NULL,
|
||||
const ssh_cipheralg ssh_des = {
|
||||
des_new, des_free, des_setiv, des_setkey,
|
||||
des_encrypt_blk, des_decrypt_blk, NULL, NULL,
|
||||
"des-cbc",
|
||||
8, 56, 8, SSH_CIPHER_IS_CBC, "single-DES CBC",
|
||||
NULL
|
||||
};
|
||||
|
||||
const ssh2_cipheralg ssh_des_sshcom_ssh2 = {
|
||||
des_ssh2_new, des_ssh2_free, des_ssh2_setiv, des_ssh2_setkey,
|
||||
des_ssh2_encrypt_blk, des_ssh2_decrypt_blk, NULL, NULL,
|
||||
const ssh_cipheralg ssh_des_sshcom_ssh2 = {
|
||||
des_new, des_free, des_setiv, des_setkey,
|
||||
des_encrypt_blk, des_decrypt_blk, NULL, NULL,
|
||||
"des-cbc@ssh.com",
|
||||
8, 56, 8, SSH_CIPHER_IS_CBC, "single-DES CBC",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const ssh2_cipheralg *const des3_list[] = {
|
||||
static const ssh_cipheralg *const des3_list[] = {
|
||||
&ssh_3des_ssh2_ctr,
|
||||
&ssh_3des_ssh2
|
||||
};
|
||||
|
||||
const ssh2_ciphers ssh2_3des = { lenof(des3_list), des3_list };
|
||||
|
||||
static const ssh2_cipheralg *const des_list[] = {
|
||||
&ssh_des_ssh2,
|
||||
static const ssh_cipheralg *const des_list[] = {
|
||||
&ssh_des,
|
||||
&ssh_des_sshcom_ssh2
|
||||
};
|
||||
|
||||
const ssh2_ciphers ssh2_des = { lenof(des_list), des_list };
|
||||
|
||||
const ssh1_cipheralg ssh1_3des = {
|
||||
des3_ssh1_new, des3_ssh1_free, des3_ssh1_sesskey,
|
||||
des3_ssh1_encrypt_blk, des3_ssh1_decrypt_blk,
|
||||
8, "triple-DES inner-CBC"
|
||||
};
|
||||
|
||||
const ssh1_cipheralg ssh1_des = {
|
||||
des_ssh1_new, des_ssh1_free, des_ssh1_sesskey,
|
||||
des_ssh1_encrypt_blk, des_ssh1_decrypt_blk,
|
||||
8, "single-DES CBC"
|
||||
const ssh_cipheralg ssh_3des_ssh1 = {
|
||||
des3_ssh1_new, des3_ssh1_free, des3_ssh1_setiv, des3_ssh1_setkey,
|
||||
des3_ssh1_encrypt_blk, des3_ssh1_decrypt_blk, NULL, NULL, NULL,
|
||||
8, 168, 24, SSH_CIPHER_IS_CBC, "triple-DES inner-CBC", NULL
|
||||
};
|
||||
|
3
sshmd5.c
3
sshmd5.c
@ -282,8 +282,7 @@ struct hmacmd5_context *hmacmd5_make_context(void)
|
||||
return ctx;
|
||||
}
|
||||
|
||||
static ssh2_mac *hmacmd5_ssh2_new(const ssh2_macalg *alg,
|
||||
ssh2_cipher *cipher)
|
||||
static ssh2_mac *hmacmd5_ssh2_new(const ssh2_macalg *alg, ssh_cipher *cipher)
|
||||
{
|
||||
struct hmacmd5_context *ctx = hmacmd5_make_context();
|
||||
ctx->mac.vt = alg;
|
||||
|
@ -256,8 +256,7 @@ struct hmacsha256 {
|
||||
ssh2_mac mac;
|
||||
};
|
||||
|
||||
static ssh2_mac *hmacsha256_new(
|
||||
const ssh2_macalg *alg, ssh2_cipher *cipher)
|
||||
static ssh2_mac *hmacsha256_new(const ssh2_macalg *alg, ssh_cipher *cipher)
|
||||
{
|
||||
struct hmacsha256 *ctx = snew(struct hmacsha256);
|
||||
ctx->mac.vt = alg;
|
||||
|
3
sshsha.c
3
sshsha.c
@ -285,8 +285,7 @@ struct hmacsha1 {
|
||||
ssh2_mac mac;
|
||||
};
|
||||
|
||||
static ssh2_mac *hmacsha1_new(
|
||||
const ssh2_macalg *alg, ssh2_cipher *cipher)
|
||||
static ssh2_mac *hmacsha1_new(const ssh2_macalg *alg, ssh_cipher *cipher)
|
||||
{
|
||||
struct hmacsha1 *ctx = snew(struct hmacsha1);
|
||||
ctx->mac.vt = alg;
|
||||
|
@ -779,15 +779,15 @@ class crypt(MyTestBase):
|
||||
|
||||
def vector(cipher, key, iv, plaintext, ciphertext):
|
||||
for suffix in "hw", "sw":
|
||||
c = ssh2_cipher_new("{}_{}".format(cipher, suffix))
|
||||
c = ssh_cipher_new("{}_{}".format(cipher, suffix))
|
||||
if c is None: return # skip test if HW AES not available
|
||||
ssh2_cipher_setkey(c, key)
|
||||
ssh2_cipher_setiv(c, iv)
|
||||
ssh_cipher_setkey(c, key)
|
||||
ssh_cipher_setiv(c, iv)
|
||||
self.assertEqualBin(
|
||||
ssh2_cipher_encrypt(c, plaintext), ciphertext)
|
||||
ssh2_cipher_setiv(c, iv)
|
||||
ssh_cipher_encrypt(c, plaintext), ciphertext)
|
||||
ssh_cipher_setiv(c, iv)
|
||||
self.assertEqualBin(
|
||||
ssh2_cipher_decrypt(c, ciphertext), plaintext)
|
||||
ssh_cipher_decrypt(c, ciphertext), plaintext)
|
||||
|
||||
# Tests of CBC mode.
|
||||
|
||||
@ -864,19 +864,19 @@ class crypt(MyTestBase):
|
||||
|
||||
def increment(keylen, suffix, iv):
|
||||
key = b'\xab' * (keylen//8)
|
||||
sdctr = ssh2_cipher_new("aes{}_ctr_{}".format(keylen, suffix))
|
||||
sdctr = ssh_cipher_new("aes{}_ctr_{}".format(keylen, suffix))
|
||||
if sdctr is None: return # skip test if HW AES not available
|
||||
ssh2_cipher_setkey(sdctr, key)
|
||||
cbc = ssh2_cipher_new("aes{}_{}".format(keylen, suffix))
|
||||
ssh2_cipher_setkey(cbc, key)
|
||||
ssh_cipher_setkey(sdctr, key)
|
||||
cbc = ssh_cipher_new("aes{}_{}".format(keylen, suffix))
|
||||
ssh_cipher_setkey(cbc, key)
|
||||
|
||||
ssh2_cipher_setiv(sdctr, iv)
|
||||
ec0 = ssh2_cipher_encrypt(sdctr, b'\x00' * 16)
|
||||
ec1 = ssh2_cipher_encrypt(sdctr, b'\x00' * 16)
|
||||
ssh2_cipher_setiv(cbc, b'\x00' * 16)
|
||||
dc0 = ssh2_cipher_decrypt(cbc, ec0)
|
||||
ssh2_cipher_setiv(cbc, b'\x00' * 16)
|
||||
dc1 = ssh2_cipher_decrypt(cbc, ec1)
|
||||
ssh_cipher_setiv(sdctr, iv)
|
||||
ec0 = ssh_cipher_encrypt(sdctr, b'\x00' * 16)
|
||||
ec1 = ssh_cipher_encrypt(sdctr, b'\x00' * 16)
|
||||
ssh_cipher_setiv(cbc, b'\x00' * 16)
|
||||
dc0 = ssh_cipher_decrypt(cbc, ec0)
|
||||
ssh_cipher_setiv(cbc, b'\x00' * 16)
|
||||
dc1 = ssh_cipher_decrypt(cbc, ec1)
|
||||
self.assertEqualBin(iv, dc0)
|
||||
return dc1
|
||||
|
||||
@ -922,15 +922,15 @@ class crypt(MyTestBase):
|
||||
decryptions = []
|
||||
|
||||
for suffix in "hw", "sw":
|
||||
c = ssh2_cipher_new("aes{:d}_{}".format(keylen, suffix))
|
||||
c = ssh_cipher_new("aes{:d}_{}".format(keylen, suffix))
|
||||
if c is None: continue
|
||||
ssh2_cipher_setkey(c, test_key[:keylen//8])
|
||||
ssh_cipher_setkey(c, test_key[:keylen//8])
|
||||
for chunklen in range(16, 16*12, 16):
|
||||
ssh2_cipher_setiv(c, test_iv)
|
||||
ssh_cipher_setiv(c, test_iv)
|
||||
decryption = b""
|
||||
for pos in range(0, len(test_ciphertext), chunklen):
|
||||
chunk = test_ciphertext[pos:pos+chunklen]
|
||||
decryption += ssh2_cipher_decrypt(c, chunk)
|
||||
decryption += ssh_cipher_decrypt(c, chunk)
|
||||
decryptions.append(decryption)
|
||||
|
||||
for d in decryptions:
|
||||
@ -1069,9 +1069,9 @@ class standard_test_vectors(MyTestBase):
|
||||
def testAES(self):
|
||||
def vector(cipher, key, plaintext, ciphertext):
|
||||
for suffix in "hw", "sw":
|
||||
c = ssh2_cipher_new("{}_{}".format(cipher, suffix))
|
||||
c = ssh_cipher_new("{}_{}".format(cipher, suffix))
|
||||
if c is None: return # skip test if HW AES not available
|
||||
ssh2_cipher_setkey(c, key)
|
||||
ssh_cipher_setkey(c, key)
|
||||
|
||||
# The AES test vectors are implicitly in ECB mode,
|
||||
# because they're testing the cipher primitive rather
|
||||
@ -1079,13 +1079,13 @@ class standard_test_vectors(MyTestBase):
|
||||
# using PuTTY's CBC setting, and clearing the IV to
|
||||
# all zeroes before each operation.
|
||||
|
||||
ssh2_cipher_setiv(c, b'\x00' * 16)
|
||||
ssh_cipher_setiv(c, b'\x00' * 16)
|
||||
self.assertEqualBin(
|
||||
ssh2_cipher_encrypt(c, plaintext), ciphertext)
|
||||
ssh_cipher_encrypt(c, plaintext), ciphertext)
|
||||
|
||||
ssh2_cipher_setiv(c, b'\x00' * 16)
|
||||
ssh_cipher_setiv(c, b'\x00' * 16)
|
||||
self.assertEqualBin(
|
||||
ssh2_cipher_decrypt(c, ciphertext), plaintext)
|
||||
ssh_cipher_decrypt(c, ciphertext), plaintext)
|
||||
|
||||
# The test vector from FIPS 197 appendix B. (This is also the
|
||||
# same key whose key setup phase is shown in detail in
|
||||
@ -1108,7 +1108,7 @@ class standard_test_vectors(MyTestBase):
|
||||
unhex('8ea2b7ca516745bfeafc49904b496089'))
|
||||
|
||||
def testDES(self):
|
||||
c = ssh2_cipher_new("des")
|
||||
c = ssh_cipher_new("des")
|
||||
def vector(key, plaintext, ciphertext):
|
||||
key = unhex(key)
|
||||
plaintext = unhex(plaintext)
|
||||
@ -1116,11 +1116,11 @@ class standard_test_vectors(MyTestBase):
|
||||
|
||||
# Similarly to above, we fake DES ECB by using DES CBC and
|
||||
# resetting the IV to zero all the time
|
||||
ssh2_cipher_setkey(c, key)
|
||||
ssh2_cipher_setiv(c, b'\x00' * 8)
|
||||
self.assertEqualBin(ssh2_cipher_encrypt(c, plaintext), ciphertext)
|
||||
ssh2_cipher_setiv(c, b'\x00' * 8)
|
||||
self.assertEqualBin(ssh2_cipher_decrypt(c, ciphertext), plaintext)
|
||||
ssh_cipher_setkey(c, key)
|
||||
ssh_cipher_setiv(c, b'\x00' * 8)
|
||||
self.assertEqualBin(ssh_cipher_encrypt(c, plaintext), ciphertext)
|
||||
ssh_cipher_setiv(c, b'\x00' * 8)
|
||||
self.assertEqualBin(ssh_cipher_decrypt(c, ciphertext), plaintext)
|
||||
|
||||
# Source: FIPS SP PUB 500-20
|
||||
|
||||
|
@ -129,7 +129,7 @@ def make_argword(arg, argtype, fnname, argindex, to_preserve):
|
||||
if typename == "uint" and isinstance(arg, numbers.Integral):
|
||||
return "0x{:x}".format(arg)
|
||||
if typename in {
|
||||
"hashalg", "macalg", "keyalg", "ssh1_cipheralg", "ssh2_cipheralg",
|
||||
"hashalg", "macalg", "keyalg", "cipheralg",
|
||||
"dh_group", "ecdh_alg", "rsaorder"}:
|
||||
arg = unicode_to_bytes(arg)
|
||||
if isinstance(arg, bytes) and b" " not in arg:
|
||||
|
166
testcrypt.c
166
testcrypt.c
@ -71,8 +71,7 @@ int random_byte(void)
|
||||
X(epoint, EdwardsPoint *, ecc_edwards_point_free(v)) \
|
||||
X(hash, ssh_hash *, ssh_hash_free(v)) \
|
||||
X(key, ssh_key *, ssh_key_free(v)) \
|
||||
X(ssh1cipher, ssh1_cipher *, ssh1_cipher_free(v)) \
|
||||
X(ssh2cipher, ssh2_cipher *, ssh2_cipher_free(v)) \
|
||||
X(cipher, ssh_cipher *, ssh_cipher_free(v)) \
|
||||
X(mac, ssh2_mac *, ssh2_mac_free(v)) \
|
||||
X(dh, dh_ctx *, dh_cleanup(v)) \
|
||||
X(ecdh, ecdh_key *, ssh_ecdhkex_freekey(v)) \
|
||||
@ -240,34 +239,16 @@ static const ssh_keyalg *get_keyalg(BinarySource *in)
|
||||
fatal_error("keyalg '%.*s': not found", PTRLEN_PRINTF(name));
|
||||
}
|
||||
|
||||
static const ssh1_cipheralg *get_ssh1_cipheralg(BinarySource *in)
|
||||
static const ssh_cipheralg *get_cipheralg(BinarySource *in)
|
||||
{
|
||||
static const struct {
|
||||
const char *key;
|
||||
const ssh1_cipheralg *value;
|
||||
} algs[] = {
|
||||
{"3des", &ssh1_3des},
|
||||
{"des", &ssh1_des},
|
||||
{"blowfish", &ssh1_blowfish},
|
||||
};
|
||||
|
||||
ptrlen name = get_word(in);
|
||||
for (size_t i = 0; i < lenof(algs); i++)
|
||||
if (ptrlen_eq_string(name, algs[i].key))
|
||||
return algs[i].value;
|
||||
|
||||
fatal_error("ssh1_cipheralg '%.*s': not found", PTRLEN_PRINTF(name));
|
||||
}
|
||||
|
||||
static const ssh2_cipheralg *get_ssh2_cipheralg(BinarySource *in)
|
||||
{
|
||||
static const struct {
|
||||
const char *key;
|
||||
const ssh2_cipheralg *value;
|
||||
const ssh_cipheralg *value;
|
||||
} algs[] = {
|
||||
{"3des_ctr", &ssh_3des_ssh2_ctr},
|
||||
{"3des", &ssh_3des_ssh2},
|
||||
{"des", &ssh_des_ssh2},
|
||||
{"3des_ssh2", &ssh_3des_ssh2},
|
||||
{"3des_ssh1", &ssh_3des_ssh1},
|
||||
{"des", &ssh_des},
|
||||
{"aes256_ctr", &ssh_aes256_sdctr},
|
||||
{"aes256_ctr_hw", &ssh_aes256_sdctr_hw},
|
||||
{"aes256_ctr_sw", &ssh_aes256_sdctr_sw},
|
||||
@ -286,8 +267,9 @@ static const ssh2_cipheralg *get_ssh2_cipheralg(BinarySource *in)
|
||||
{"aes128", &ssh_aes128_cbc},
|
||||
{"aes128_hw", &ssh_aes128_cbc_hw},
|
||||
{"aes128_sw", &ssh_aes128_cbc_sw},
|
||||
{"blowfish", &ssh_blowfish_ssh2_ctr},
|
||||
{"blowfish", &ssh_blowfish_ssh2},
|
||||
{"blowfish_ctr", &ssh_blowfish_ssh2_ctr},
|
||||
{"blowfish_ssh2", &ssh_blowfish_ssh2},
|
||||
{"blowfish_ssh1", &ssh_blowfish_ssh1},
|
||||
{"arcfour256", &ssh_arcfour256_ssh2},
|
||||
{"arcfour128", &ssh_arcfour128_ssh2},
|
||||
{"chacha20_poly1305", &ssh2_chacha20_poly1305},
|
||||
@ -298,7 +280,7 @@ static const ssh2_cipheralg *get_ssh2_cipheralg(BinarySource *in)
|
||||
if (ptrlen_eq_string(name, algs[i].key))
|
||||
return algs[i].value;
|
||||
|
||||
fatal_error("ssh2_cipheralg '%.*s': not found", PTRLEN_PRINTF(name));
|
||||
fatal_error("cipheralg '%.*s': not found", PTRLEN_PRINTF(name));
|
||||
}
|
||||
|
||||
static const ssh_kex *get_dh_group(BinarySource *in)
|
||||
@ -516,12 +498,12 @@ static void return_val_string_asciz(strbuf *out, char *s)
|
||||
return_val_string(out, sb);
|
||||
}
|
||||
|
||||
static void return_opt_val_ssh2cipher(strbuf *out, ssh2_cipher *c)
|
||||
static void return_opt_val_cipher(strbuf *out, ssh_cipher *c)
|
||||
{
|
||||
if (!c)
|
||||
strbuf_catf(out, "NULL\n");
|
||||
else
|
||||
return_val_ssh2cipher(out, c);
|
||||
return_val_cipher(out, c);
|
||||
}
|
||||
|
||||
static void handle_hello(BinarySource *in, strbuf *out)
|
||||
@ -639,112 +621,77 @@ strbuf *ssh_hash_final_wrapper(ssh_hash *h)
|
||||
#undef ssh_hash_final
|
||||
#define ssh_hash_final ssh_hash_final_wrapper
|
||||
|
||||
void ssh1_cipher_sesskey_wrapper(ssh1_cipher *c, ptrlen key)
|
||||
void ssh_cipher_setiv_wrapper(ssh_cipher *c, ptrlen key)
|
||||
{
|
||||
if (key.len != 32)
|
||||
fatal_error("ssh1_cipher_sesskey: needs exactly 32 bytes");
|
||||
ssh1_cipher_sesskey(c, key.ptr);
|
||||
if (key.len != ssh_cipher_alg(c)->blksize)
|
||||
fatal_error("ssh_cipher_setiv: needs exactly %d bytes",
|
||||
ssh_cipher_alg(c)->blksize);
|
||||
ssh_cipher_setiv(c, key.ptr);
|
||||
}
|
||||
#undef ssh1_cipher_sesskey
|
||||
#define ssh1_cipher_sesskey ssh1_cipher_sesskey_wrapper
|
||||
#undef ssh_cipher_setiv
|
||||
#define ssh_cipher_setiv ssh_cipher_setiv_wrapper
|
||||
|
||||
strbuf *ssh1_cipher_encrypt_wrapper(ssh1_cipher *c, ptrlen input)
|
||||
void ssh_cipher_setkey_wrapper(ssh_cipher *c, ptrlen key)
|
||||
{
|
||||
if (input.len % c->vt->blksize)
|
||||
fatal_error("ssh1_cipher_encrypt: needs a multiple of %d bytes",
|
||||
c->vt->blksize);
|
||||
if (key.len != ssh_cipher_alg(c)->padded_keybytes)
|
||||
fatal_error("ssh_cipher_setkey: needs exactly %d bytes",
|
||||
ssh_cipher_alg(c)->padded_keybytes);
|
||||
ssh_cipher_setkey(c, key.ptr);
|
||||
}
|
||||
#undef ssh_cipher_setkey
|
||||
#define ssh_cipher_setkey ssh_cipher_setkey_wrapper
|
||||
|
||||
strbuf *ssh_cipher_encrypt_wrapper(ssh_cipher *c, ptrlen input)
|
||||
{
|
||||
if (input.len % ssh_cipher_alg(c)->blksize)
|
||||
fatal_error("ssh_cipher_encrypt: needs a multiple of %d bytes",
|
||||
ssh_cipher_alg(c)->blksize);
|
||||
strbuf *sb = strbuf_new();
|
||||
put_datapl(sb, input);
|
||||
ssh1_cipher_encrypt(c, sb->u, sb->len);
|
||||
ssh_cipher_encrypt(c, sb->u, sb->len);
|
||||
return sb;
|
||||
}
|
||||
#undef ssh1_cipher_encrypt
|
||||
#define ssh1_cipher_encrypt ssh1_cipher_encrypt_wrapper
|
||||
#undef ssh_cipher_encrypt
|
||||
#define ssh_cipher_encrypt ssh_cipher_encrypt_wrapper
|
||||
|
||||
strbuf *ssh1_cipher_decrypt_wrapper(ssh1_cipher *c, ptrlen input)
|
||||
strbuf *ssh_cipher_decrypt_wrapper(ssh_cipher *c, ptrlen input)
|
||||
{
|
||||
if (input.len % c->vt->blksize)
|
||||
fatal_error("ssh1_cipher_decrypt: needs a multiple of %d bytes",
|
||||
c->vt->blksize);
|
||||
if (input.len % ssh_cipher_alg(c)->blksize)
|
||||
fatal_error("ssh_cipher_decrypt: needs a multiple of %d bytes",
|
||||
ssh_cipher_alg(c)->blksize);
|
||||
strbuf *sb = strbuf_new();
|
||||
put_datapl(sb, input);
|
||||
ssh1_cipher_decrypt(c, sb->u, sb->len);
|
||||
ssh_cipher_decrypt(c, sb->u, sb->len);
|
||||
return sb;
|
||||
}
|
||||
#undef ssh1_cipher_decrypt
|
||||
#define ssh1_cipher_decrypt ssh1_cipher_decrypt_wrapper
|
||||
#undef ssh_cipher_decrypt
|
||||
#define ssh_cipher_decrypt ssh_cipher_decrypt_wrapper
|
||||
|
||||
void ssh2_cipher_setiv_wrapper(ssh2_cipher *c, ptrlen key)
|
||||
{
|
||||
if (key.len != ssh2_cipher_alg(c)->blksize)
|
||||
fatal_error("ssh2_cipher_setiv: needs exactly %d bytes",
|
||||
ssh2_cipher_alg(c)->blksize);
|
||||
ssh2_cipher_setiv(c, key.ptr);
|
||||
}
|
||||
#undef ssh2_cipher_setiv
|
||||
#define ssh2_cipher_setiv ssh2_cipher_setiv_wrapper
|
||||
|
||||
void ssh2_cipher_setkey_wrapper(ssh2_cipher *c, ptrlen key)
|
||||
{
|
||||
if (key.len != ssh2_cipher_alg(c)->padded_keybytes)
|
||||
fatal_error("ssh2_cipher_setkey: needs exactly %d bytes",
|
||||
ssh2_cipher_alg(c)->padded_keybytes);
|
||||
ssh2_cipher_setkey(c, key.ptr);
|
||||
}
|
||||
#undef ssh2_cipher_setkey
|
||||
#define ssh2_cipher_setkey ssh2_cipher_setkey_wrapper
|
||||
|
||||
strbuf *ssh2_cipher_encrypt_wrapper(ssh2_cipher *c, ptrlen input)
|
||||
{
|
||||
if (input.len % ssh2_cipher_alg(c)->blksize)
|
||||
fatal_error("ssh2_cipher_encrypt: needs a multiple of %d bytes",
|
||||
ssh2_cipher_alg(c)->blksize);
|
||||
strbuf *sb = strbuf_new();
|
||||
put_datapl(sb, input);
|
||||
ssh2_cipher_encrypt(c, sb->u, sb->len);
|
||||
return sb;
|
||||
}
|
||||
#undef ssh2_cipher_encrypt
|
||||
#define ssh2_cipher_encrypt ssh2_cipher_encrypt_wrapper
|
||||
|
||||
strbuf *ssh2_cipher_decrypt_wrapper(ssh2_cipher *c, ptrlen input)
|
||||
{
|
||||
if (input.len % ssh2_cipher_alg(c)->blksize)
|
||||
fatal_error("ssh2_cipher_decrypt: needs a multiple of %d bytes",
|
||||
ssh2_cipher_alg(c)->blksize);
|
||||
strbuf *sb = strbuf_new();
|
||||
put_datapl(sb, input);
|
||||
ssh2_cipher_decrypt(c, sb->u, sb->len);
|
||||
return sb;
|
||||
}
|
||||
#undef ssh2_cipher_decrypt
|
||||
#define ssh2_cipher_decrypt ssh2_cipher_decrypt_wrapper
|
||||
|
||||
strbuf *ssh2_cipher_encrypt_length_wrapper(ssh2_cipher *c, ptrlen input,
|
||||
strbuf *ssh_cipher_encrypt_length_wrapper(ssh_cipher *c, ptrlen input,
|
||||
unsigned long seq)
|
||||
{
|
||||
if (input.len != 4)
|
||||
fatal_error("ssh2_cipher_encrypt_length: needs exactly 4 bytes");
|
||||
fatal_error("ssh_cipher_encrypt_length: needs exactly 4 bytes");
|
||||
strbuf *sb = strbuf_new();
|
||||
put_datapl(sb, input);
|
||||
ssh2_cipher_encrypt_length(c, sb->u, sb->len, seq);
|
||||
ssh_cipher_encrypt_length(c, sb->u, sb->len, seq);
|
||||
return sb;
|
||||
}
|
||||
#undef ssh2_cipher_encrypt_length
|
||||
#define ssh2_cipher_encrypt_length ssh2_cipher_encrypt_length_wrapper
|
||||
#undef ssh_cipher_encrypt_length
|
||||
#define ssh_cipher_encrypt_length ssh_cipher_encrypt_length_wrapper
|
||||
|
||||
strbuf *ssh2_cipher_decrypt_length_wrapper(ssh2_cipher *c, ptrlen input,
|
||||
strbuf *ssh_cipher_decrypt_length_wrapper(ssh_cipher *c, ptrlen input,
|
||||
unsigned long seq)
|
||||
{
|
||||
if (input.len % ssh2_cipher_alg(c)->blksize)
|
||||
fatal_error("ssh2_cipher_decrypt_length: needs exactly 4 bytes");
|
||||
if (input.len % ssh_cipher_alg(c)->blksize)
|
||||
fatal_error("ssh_cipher_decrypt_length: needs exactly 4 bytes");
|
||||
strbuf *sb = strbuf_new();
|
||||
put_datapl(sb, input);
|
||||
ssh2_cipher_decrypt_length(c, sb->u, sb->len, seq);
|
||||
ssh_cipher_decrypt_length(c, sb->u, sb->len, seq);
|
||||
return sb;
|
||||
}
|
||||
#undef ssh2_cipher_decrypt_length
|
||||
#define ssh2_cipher_decrypt_length ssh2_cipher_decrypt_length_wrapper
|
||||
#undef ssh_cipher_decrypt_length
|
||||
#define ssh_cipher_decrypt_length ssh_cipher_decrypt_length_wrapper
|
||||
|
||||
strbuf *ssh2_mac_genresult_wrapper(ssh2_mac *m)
|
||||
{
|
||||
@ -938,7 +885,7 @@ VALUE_TYPES(VALTYPE_TYPEDEF)
|
||||
return NULL; \
|
||||
return unwrap_value_##type(lookup_value(word))->vu_##type; \
|
||||
}
|
||||
OPTIONAL_PTR_FUNC(ssh2cipher)
|
||||
OPTIONAL_PTR_FUNC(cipher)
|
||||
OPTIONAL_PTR_FUNC(mpint)
|
||||
|
||||
typedef uintmax_t TD_uint;
|
||||
@ -951,8 +898,7 @@ typedef ssh_hash *TD_consumed_val_hash;
|
||||
typedef const ssh_hashalg *TD_hashalg;
|
||||
typedef const ssh2_macalg *TD_macalg;
|
||||
typedef const ssh_keyalg *TD_keyalg;
|
||||
typedef const ssh1_cipheralg *TD_ssh1_cipheralg;
|
||||
typedef const ssh2_cipheralg *TD_ssh2_cipheralg;
|
||||
typedef const ssh_cipheralg *TD_cipheralg;
|
||||
typedef const ssh_kex *TD_dh_group;
|
||||
typedef const ssh_kex *TD_ecdh_alg;
|
||||
typedef RsaSsh1Order TD_rsaorder;
|
||||
|
30
testcrypt.h
30
testcrypt.h
@ -121,11 +121,11 @@ FUNC1(val_string, ssh_hash_final, consumed_val_hash)
|
||||
FUNC2(void, ssh_hash_update, val_hash, val_string_ptrlen)
|
||||
|
||||
/*
|
||||
* The ssh2_mac abstraction. Note the optional ssh2_cipher parameter
|
||||
* The ssh2_mac abstraction. Note the optional ssh_cipher parameter
|
||||
* to ssh2_mac_new. Also, again, I've invented an ssh2_mac_update so
|
||||
* you can put data into the MAC.
|
||||
*/
|
||||
FUNC2(val_mac, ssh2_mac_new, macalg, opt_val_ssh2cipher)
|
||||
FUNC2(val_mac, ssh2_mac_new, macalg, opt_val_cipher)
|
||||
FUNC2(void, ssh2_mac_setkey, val_mac, val_string_ptrlen)
|
||||
FUNC1(void, ssh2_mac_start, val_mac)
|
||||
FUNC2(void, ssh2_mac_update, val_mac, val_string_ptrlen)
|
||||
@ -150,25 +150,17 @@ FUNC1(val_string_asciz, ssh_key_cache_str, val_key)
|
||||
FUNC2(uint, ssh_key_public_bits, keyalg, val_string_ptrlen)
|
||||
|
||||
/*
|
||||
* The ssh1_cipher abstraction. The in-place encrypt and decrypt
|
||||
* functions are wrapped to replace them with a pair that take one
|
||||
* The ssh_cipher abstraction. The in-place encrypt and decrypt
|
||||
* functions are wrapped to replace them with versions that take one
|
||||
* string and return a separate string.
|
||||
*/
|
||||
FUNC1(val_ssh1cipher, ssh1_cipher_new, ssh1_cipheralg)
|
||||
FUNC2(void, ssh1_cipher_sesskey, val_ssh1cipher, val_string_ptrlen)
|
||||
FUNC2(val_string, ssh1_cipher_encrypt, val_ssh1cipher, val_string_ptrlen)
|
||||
FUNC2(val_string, ssh1_cipher_decrypt, val_ssh1cipher, val_string_ptrlen)
|
||||
|
||||
/*
|
||||
* The ssh2_cipher abstraction, with similar modifications.
|
||||
*/
|
||||
FUNC1(opt_val_ssh2cipher, ssh2_cipher_new, ssh2_cipheralg)
|
||||
FUNC2(void, ssh2_cipher_setiv, val_ssh2cipher, val_string_ptrlen)
|
||||
FUNC2(void, ssh2_cipher_setkey, val_ssh2cipher, val_string_ptrlen)
|
||||
FUNC2(val_string, ssh2_cipher_encrypt, val_ssh2cipher, val_string_ptrlen)
|
||||
FUNC2(val_string, ssh2_cipher_decrypt, val_ssh2cipher, val_string_ptrlen)
|
||||
FUNC3(val_string, ssh2_cipher_encrypt_length, val_ssh2cipher, val_string_ptrlen, uint)
|
||||
FUNC3(val_string, ssh2_cipher_decrypt_length, val_ssh2cipher, val_string_ptrlen, uint)
|
||||
FUNC1(opt_val_cipher, ssh_cipher_new, cipheralg)
|
||||
FUNC2(void, ssh_cipher_setiv, val_cipher, val_string_ptrlen)
|
||||
FUNC2(void, ssh_cipher_setkey, val_cipher, val_string_ptrlen)
|
||||
FUNC2(val_string, ssh_cipher_encrypt, val_cipher, val_string_ptrlen)
|
||||
FUNC2(val_string, ssh_cipher_decrypt, val_cipher, val_string_ptrlen)
|
||||
FUNC3(val_string, ssh_cipher_encrypt_length, val_cipher, val_string_ptrlen, uint)
|
||||
FUNC3(val_string, ssh_cipher_decrypt_length, val_cipher, val_string_ptrlen, uint)
|
||||
|
||||
/*
|
||||
* Integer Diffie-Hellman.
|
||||
|
Loading…
Reference in New Issue
Block a user