No cipher uses this facility yet, but one shortly will.
/*
* OpenSSH encrypt-then-MAC mode: the packet length is
- * unencrypted.
+ * unencrypted, unless the cipher supports length encryption.
*/
for (st->i = st->len = 0; st->i < 4; st->i++) {
while ((*datalen) == 0)
st->pktin->data[st->i] = *(*data)++;
(*datalen)--;
}
- st->len = toint(GET_32BIT(st->pktin->data));
+ /* Cipher supports length decryption, so do it */
+ if (ssh->sccipher && (ssh->sccipher->flags & SSH_CIPHER_SEPARATE_LENGTH)) {
+ /* Keep the packet the same though, so the MAC passes */
+ unsigned char len[4];
+ memcpy(len, st->pktin->data, 4);
+ ssh->sccipher->decrypt_length(ssh->sc_cipher_ctx, len, 4, st->incoming_sequence);
+ st->len = toint(GET_32BIT(len));
+ } else {
+ st->len = toint(GET_32BIT(st->pktin->data));
+ }
/*
* _Completely_ silly lengths should be stomped on before they
for (i = 0; i < padding; i++)
pkt->data[pkt->length + i] = random_byte();
PUT_32BIT(pkt->data, pkt->length + padding - 4);
+
+ /* Encrypt length if the scheme requires it */
+ if (ssh->cscipher && (ssh->cscipher->flags & SSH_CIPHER_SEPARATE_LENGTH)) {
+ ssh->cscipher->encrypt_length(ssh->cs_cipher_ctx, pkt->data, 4,
+ ssh->v2_outgoing_sequence);
+ }
+
if (ssh->csmac && ssh->csmac_etm) {
/*
* OpenSSH-defined encrypt-then-MAC protocol.
void (*setkey) (void *, unsigned char *key);/* for SSH-2 */
void (*encrypt) (void *, unsigned char *blk, int len);
void (*decrypt) (void *, unsigned char *blk, int len);
+ /* Ignored unless SSH_CIPHER_SEPARATE_LENGTH flag set */
+ void (*encrypt_length) (void *, unsigned char *blk, int len, unsigned long seq);
+ void (*decrypt_length) (void *, unsigned char *blk, int len, unsigned long seq);
const char *name;
int blksize;
int keylen;
unsigned int flags;
#define SSH_CIPHER_IS_CBC 1
+#define SSH_CIPHER_SEPARATE_LENGTH 2
const char *text_name;
/* If set, this takes priority over other MAC. */
const struct ssh_mac *required_mac;
static const struct ssh2_cipher ssh_aes128_ctr = {
aes_make_context, aes_free_context, aes_iv, aes128_key,
- aes_ssh2_sdctr, aes_ssh2_sdctr,
+ aes_ssh2_sdctr, aes_ssh2_sdctr, NULL, NULL,
"aes128-ctr",
16, 128, 0, "AES-128 SDCTR",
NULL
static const struct ssh2_cipher ssh_aes192_ctr = {
aes_make_context, aes_free_context, aes_iv, aes192_key,
- aes_ssh2_sdctr, aes_ssh2_sdctr,
+ aes_ssh2_sdctr, aes_ssh2_sdctr, NULL, NULL,
"aes192-ctr",
16, 192, 0, "AES-192 SDCTR",
NULL
static const struct ssh2_cipher ssh_aes256_ctr = {
aes_make_context, aes_free_context, aes_iv, aes256_key,
- aes_ssh2_sdctr, aes_ssh2_sdctr,
+ aes_ssh2_sdctr, aes_ssh2_sdctr, NULL, NULL,
"aes256-ctr",
16, 256, 0, "AES-256 SDCTR",
NULL
static const struct ssh2_cipher ssh_aes128 = {
aes_make_context, aes_free_context, aes_iv, aes128_key,
- aes_ssh2_encrypt_blk, aes_ssh2_decrypt_blk,
+ aes_ssh2_encrypt_blk, aes_ssh2_decrypt_blk, NULL, NULL,
"aes128-cbc",
16, 128, SSH_CIPHER_IS_CBC, "AES-128 CBC",
NULL
static const struct ssh2_cipher ssh_aes192 = {
aes_make_context, aes_free_context, aes_iv, aes192_key,
- aes_ssh2_encrypt_blk, aes_ssh2_decrypt_blk,
+ aes_ssh2_encrypt_blk, aes_ssh2_decrypt_blk, NULL, NULL,
"aes192-cbc",
16, 192, SSH_CIPHER_IS_CBC, "AES-192 CBC",
NULL
static const struct ssh2_cipher ssh_aes256 = {
aes_make_context, aes_free_context, aes_iv, aes256_key,
- aes_ssh2_encrypt_blk, aes_ssh2_decrypt_blk,
+ aes_ssh2_encrypt_blk, aes_ssh2_decrypt_blk, NULL, NULL,
"aes256-cbc",
16, 256, SSH_CIPHER_IS_CBC, "AES-256 CBC",
NULL
static const struct ssh2_cipher ssh_rijndael_lysator = {
aes_make_context, aes_free_context, aes_iv, aes256_key,
- aes_ssh2_encrypt_blk, aes_ssh2_decrypt_blk,
+ aes_ssh2_encrypt_blk, aes_ssh2_decrypt_blk, NULL, NULL,
"rijndael-cbc@lysator.liu.se",
16, 256, SSH_CIPHER_IS_CBC, "AES-256 CBC",
NULL
const struct ssh2_cipher ssh_arcfour128_ssh2 = {
arcfour_make_context, arcfour_free_context, arcfour_iv, arcfour128_key,
- arcfour_block, arcfour_block,
+ arcfour_block, arcfour_block, NULL, NULL,
"arcfour128",
1, 128, 0, "Arcfour-128",
NULL
const struct ssh2_cipher ssh_arcfour256_ssh2 = {
arcfour_make_context, arcfour_free_context, arcfour_iv, arcfour256_key,
- arcfour_block, arcfour_block,
+ arcfour_block, arcfour_block, NULL, NULL,
"arcfour256",
1, 256, 0, "Arcfour-256",
NULL
static const struct ssh2_cipher ssh_blowfish_ssh2 = {
blowfish_make_context, blowfish_free_context, blowfish_iv, blowfish_key,
- blowfish_ssh2_encrypt_blk, blowfish_ssh2_decrypt_blk,
+ blowfish_ssh2_encrypt_blk, blowfish_ssh2_decrypt_blk, NULL, NULL,
"blowfish-cbc",
8, 128, SSH_CIPHER_IS_CBC, "Blowfish-128 CBC",
NULL
static const struct ssh2_cipher ssh_blowfish_ssh2_ctr = {
blowfish_make_context, blowfish_free_context, blowfish_iv, blowfish256_key,
- blowfish_ssh2_sdctr, blowfish_ssh2_sdctr,
+ blowfish_ssh2_sdctr, blowfish_ssh2_sdctr, NULL, NULL,
"blowfish-ctr",
8, 256, 0, "Blowfish-256 SDCTR",
NULL
static const struct ssh2_cipher ssh_3des_ssh2 = {
des3_make_context, des3_free_context, des3_iv, des3_key,
- des3_ssh2_encrypt_blk, des3_ssh2_decrypt_blk,
+ des3_ssh2_encrypt_blk, des3_ssh2_decrypt_blk, NULL, NULL,
"3des-cbc",
8, 168, SSH_CIPHER_IS_CBC, "triple-DES CBC",
NULL
static const struct ssh2_cipher ssh_3des_ssh2_ctr = {
des3_make_context, des3_free_context, des3_iv, des3_key,
- des3_ssh2_sdctr, des3_ssh2_sdctr,
+ des3_ssh2_sdctr, des3_ssh2_sdctr, NULL, NULL,
"3des-ctr",
8, 168, 0, "triple-DES SDCTR",
NULL
*/
static const struct ssh2_cipher ssh_des_ssh2 = {
des_make_context, des3_free_context, des3_iv, des_key,
- des_ssh2_encrypt_blk, des_ssh2_decrypt_blk,
+ des_ssh2_encrypt_blk, des_ssh2_decrypt_blk, NULL, NULL,
"des-cbc",
8, 56, SSH_CIPHER_IS_CBC, "single-DES CBC",
NULL
static const struct ssh2_cipher ssh_des_sshcom_ssh2 = {
des_make_context, des3_free_context, des3_iv, des_key,
- des_ssh2_encrypt_blk, des_ssh2_decrypt_blk,
+ des_ssh2_encrypt_blk, des_ssh2_decrypt_blk, NULL, NULL,
"des-cbc@ssh.com",
8, 56, SSH_CIPHER_IS_CBC, "single-DES CBC",
NULL