1
0
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:
Simon Tatham 2019-01-17 18:06:08 +00:00
parent 20930e7d0c
commit 986508a570
22 changed files with 465 additions and 611 deletions

6
defs.h
View File

@ -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;

View File

@ -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
View File

@ -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;

View File

@ -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) */

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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

View File

@ -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) {

View File

@ -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
View File

@ -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);
}

View File

@ -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,
};

View File

@ -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
};

View File

@ -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);

View File

@ -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
View File

@ -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
};

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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:

View File

@ -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;

View File

@ -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.