#define F(x) Fprime( ((x>>24)&0xFF), ((x>>16)&0xFF), ((x>>8)&0xFF), (x&0xFF) )
#define ROUND(n) ( xL ^= P[n], t = xL, xL = F(xL) ^ xR, xR = t )
-static void blowfish_encrypt(word32 xL, word32 xR, word32 *output,
- BlowfishContext *ctx) {
+static void blowfish_encrypt(word32 xL, word32 xR, word32 * output,
+ BlowfishContext * ctx)
+{
word32 *S0 = ctx->S0;
word32 *S1 = ctx->S1;
word32 *S2 = ctx->S2;
output[1] = xL;
}
-static void blowfish_decrypt(word32 xL, word32 xR, word32 *output,
- BlowfishContext *ctx) {
+static void blowfish_decrypt(word32 xL, word32 xR, word32 * output,
+ BlowfishContext * ctx)
+{
word32 *S0 = ctx->S0;
word32 *S1 = ctx->S1;
word32 *S2 = ctx->S2;
}
static void blowfish_lsb_encrypt_cbc(unsigned char *blk, int len,
- BlowfishContext *ctx) {
+ BlowfishContext * ctx)
+{
word32 xL, xR, out[2], iv0, iv1;
assert((len & 7) == 0);
- iv0 = ctx->iv0; iv1 = ctx->iv1;
+ iv0 = ctx->iv0;
+ iv1 = ctx->iv1;
while (len > 0) {
- xL = GET_32BIT_LSB_FIRST(blk);
- xR = GET_32BIT_LSB_FIRST(blk+4);
- iv0 ^= xL;
- iv1 ^= xR;
- blowfish_encrypt(iv0, iv1, out, ctx);
- iv0 = out[0];
- iv1 = out[1];
- PUT_32BIT_LSB_FIRST(blk, iv0);
- PUT_32BIT_LSB_FIRST(blk+4, iv1);
- blk += 8;
- len -= 8;
+ xL = GET_32BIT_LSB_FIRST(blk);
+ xR = GET_32BIT_LSB_FIRST(blk + 4);
+ iv0 ^= xL;
+ iv1 ^= xR;
+ blowfish_encrypt(iv0, iv1, out, ctx);
+ iv0 = out[0];
+ iv1 = out[1];
+ PUT_32BIT_LSB_FIRST(blk, iv0);
+ PUT_32BIT_LSB_FIRST(blk + 4, iv1);
+ blk += 8;
+ len -= 8;
}
- ctx->iv0 = iv0; ctx->iv1 = iv1;
+ ctx->iv0 = iv0;
+ ctx->iv1 = iv1;
}
static void blowfish_lsb_decrypt_cbc(unsigned char *blk, int len,
- BlowfishContext *ctx) {
+ BlowfishContext * ctx)
+{
word32 xL, xR, out[2], iv0, iv1;
assert((len & 7) == 0);
- iv0 = ctx->iv0; iv1 = ctx->iv1;
+ iv0 = ctx->iv0;
+ iv1 = ctx->iv1;
while (len > 0) {
- xL = GET_32BIT_LSB_FIRST(blk);
- xR = GET_32BIT_LSB_FIRST(blk+4);
- blowfish_decrypt(xL, xR, out, ctx);
- iv0 ^= out[0];
- iv1 ^= out[1];
- PUT_32BIT_LSB_FIRST(blk, iv0);
- PUT_32BIT_LSB_FIRST(blk+4, iv1);
- iv0 = xL;
- iv1 = xR;
- blk += 8;
- len -= 8;
+ xL = GET_32BIT_LSB_FIRST(blk);
+ xR = GET_32BIT_LSB_FIRST(blk + 4);
+ blowfish_decrypt(xL, xR, out, ctx);
+ iv0 ^= out[0];
+ iv1 ^= out[1];
+ PUT_32BIT_LSB_FIRST(blk, iv0);
+ PUT_32BIT_LSB_FIRST(blk + 4, iv1);
+ iv0 = xL;
+ iv1 = xR;
+ blk += 8;
+ len -= 8;
}
- ctx->iv0 = iv0; ctx->iv1 = iv1;
+ ctx->iv0 = iv0;
+ ctx->iv1 = iv1;
}
static void blowfish_msb_encrypt_cbc(unsigned char *blk, int len,
- BlowfishContext *ctx) {
+ BlowfishContext * ctx)
+{
word32 xL, xR, out[2], iv0, iv1;
assert((len & 7) == 0);
- iv0 = ctx->iv0; iv1 = ctx->iv1;
+ iv0 = ctx->iv0;
+ iv1 = ctx->iv1;
while (len > 0) {
- xL = GET_32BIT_MSB_FIRST(blk);
- xR = GET_32BIT_MSB_FIRST(blk+4);
- iv0 ^= xL;
- iv1 ^= xR;
- blowfish_encrypt(iv0, iv1, out, ctx);
- iv0 = out[0];
- iv1 = out[1];
- PUT_32BIT_MSB_FIRST(blk, iv0);
- PUT_32BIT_MSB_FIRST(blk+4, iv1);
- blk += 8;
- len -= 8;
+ xL = GET_32BIT_MSB_FIRST(blk);
+ xR = GET_32BIT_MSB_FIRST(blk + 4);
+ iv0 ^= xL;
+ iv1 ^= xR;
+ blowfish_encrypt(iv0, iv1, out, ctx);
+ iv0 = out[0];
+ iv1 = out[1];
+ PUT_32BIT_MSB_FIRST(blk, iv0);
+ PUT_32BIT_MSB_FIRST(blk + 4, iv1);
+ blk += 8;
+ len -= 8;
}
- ctx->iv0 = iv0; ctx->iv1 = iv1;
+ ctx->iv0 = iv0;
+ ctx->iv1 = iv1;
}
static void blowfish_msb_decrypt_cbc(unsigned char *blk, int len,
- BlowfishContext *ctx) {
+ BlowfishContext * ctx)
+{
word32 xL, xR, out[2], iv0, iv1;
assert((len & 7) == 0);
- iv0 = ctx->iv0; iv1 = ctx->iv1;
+ iv0 = ctx->iv0;
+ iv1 = ctx->iv1;
while (len > 0) {
- xL = GET_32BIT_MSB_FIRST(blk);
- xR = GET_32BIT_MSB_FIRST(blk+4);
- blowfish_decrypt(xL, xR, out, ctx);
- iv0 ^= out[0];
- iv1 ^= out[1];
- PUT_32BIT_MSB_FIRST(blk, iv0);
- PUT_32BIT_MSB_FIRST(blk+4, iv1);
- iv0 = xL;
- iv1 = xR;
- blk += 8;
- len -= 8;
+ xL = GET_32BIT_MSB_FIRST(blk);
+ xR = GET_32BIT_MSB_FIRST(blk + 4);
+ blowfish_decrypt(xL, xR, out, ctx);
+ iv0 ^= out[0];
+ iv1 ^= out[1];
+ PUT_32BIT_MSB_FIRST(blk, iv0);
+ PUT_32BIT_MSB_FIRST(blk + 4, iv1);
+ iv0 = xL;
+ iv1 = xR;
+ blk += 8;
+ len -= 8;
}
- ctx->iv0 = iv0; ctx->iv1 = iv1;
+ ctx->iv0 = iv0;
+ ctx->iv1 = iv1;
}
-static void blowfish_setkey(BlowfishContext *ctx,
- const unsigned char *key, short keybytes) {
+static void blowfish_setkey(BlowfishContext * ctx,
+ const unsigned char *key, short keybytes)
+{
word32 *S0 = ctx->S0;
word32 *S1 = ctx->S1;
word32 *S2 = ctx->S2;
int i;
for (i = 0; i < 18; i++) {
- P[i] = parray[i];
- P[i] ^= ((word32)(unsigned char)(key[ (i*4+0) % keybytes ])) << 24;
- P[i] ^= ((word32)(unsigned char)(key[ (i*4+1) % keybytes ])) << 16;
- P[i] ^= ((word32)(unsigned char)(key[ (i*4+2) % keybytes ])) << 8;
- P[i] ^= ((word32)(unsigned char)(key[ (i*4+3) % keybytes ]));
+ P[i] = parray[i];
+ P[i] ^=
+ ((word32) (unsigned char) (key[(i * 4 + 0) % keybytes])) << 24;
+ P[i] ^=
+ ((word32) (unsigned char) (key[(i * 4 + 1) % keybytes])) << 16;
+ P[i] ^=
+ ((word32) (unsigned char) (key[(i * 4 + 2) % keybytes])) << 8;
+ P[i] ^= ((word32) (unsigned char) (key[(i * 4 + 3) % keybytes]));
}
for (i = 0; i < 256; i++) {
- S0[i] = sbox0[i];
- S1[i] = sbox1[i];
- S2[i] = sbox2[i];
- S3[i] = sbox3[i];
+ S0[i] = sbox0[i];
+ S1[i] = sbox1[i];
+ S2[i] = sbox2[i];
+ S3[i] = sbox3[i];
}
str[0] = str[1] = 0;
for (i = 0; i < 18; i += 2) {
- blowfish_encrypt(str[0], str[1], str, ctx);
- P[i] = str[0]; P[i+1] = str[1];
+ blowfish_encrypt(str[0], str[1], str, ctx);
+ P[i] = str[0];
+ P[i + 1] = str[1];
}
for (i = 0; i < 256; i += 2) {
- blowfish_encrypt(str[0], str[1], str, ctx);
- S0[i] = str[0]; S0[i+1] = str[1];
+ blowfish_encrypt(str[0], str[1], str, ctx);
+ S0[i] = str[0];
+ S0[i + 1] = str[1];
}
for (i = 0; i < 256; i += 2) {
- blowfish_encrypt(str[0], str[1], str, ctx);
- S1[i] = str[0]; S1[i+1] = str[1];
+ blowfish_encrypt(str[0], str[1], str, ctx);
+ S1[i] = str[0];
+ S1[i + 1] = str[1];
}
for (i = 0; i < 256; i += 2) {
- blowfish_encrypt(str[0], str[1], str, ctx);
- S2[i] = str[0]; S2[i+1] = str[1];
+ blowfish_encrypt(str[0], str[1], str, ctx);
+ S2[i] = str[0];
+ S2[i + 1] = str[1];
}
for (i = 0; i < 256; i += 2) {
- blowfish_encrypt(str[0], str[1], str, ctx);
- S3[i] = str[0]; S3[i+1] = str[1];
+ blowfish_encrypt(str[0], str[1], str, ctx);
+ S3[i] = str[0];
+ S3[i + 1] = str[1];
}
}
/* -- Interface with PuTTY -- */
#define SSH_SESSION_KEY_LENGTH 32
-static BlowfishContext ectx, dctx;
-static void blowfish_cskey(unsigned char *key)
+static void *blowfish_make_context(void)
{
- blowfish_setkey(&ectx, key, 16);
- logevent("Initialised Blowfish client->server encryption");
+ return snew(BlowfishContext);
}
-static void blowfish_sckey(unsigned char *key)
+static void *blowfish_ssh1_make_context(void)
{
- blowfish_setkey(&dctx, key, 16);
- logevent("Initialised Blowfish server->client encryption");
+ /* In SSH1, need one key for each direction */
+ return snewn(2, BlowfishContext);
}
-static void blowfish_csiv(unsigned char *key)
+static void blowfish_free_context(void *handle)
{
- ectx.iv0 = GET_32BIT_MSB_FIRST(key);
- ectx.iv1 = GET_32BIT_MSB_FIRST(key+4);
+ sfree(handle);
}
-static void blowfish_sciv(unsigned char *key)
+static void blowfish_key(void *handle, unsigned char *key)
{
- dctx.iv0 = GET_32BIT_MSB_FIRST(key);
- dctx.iv1 = GET_32BIT_MSB_FIRST(key+4);
+ BlowfishContext *ctx = (BlowfishContext *)handle;
+ blowfish_setkey(ctx, key, 16);
}
-static void blowfish_sesskey(unsigned char *key)
+static void blowfish_iv(void *handle, unsigned char *key)
{
- blowfish_setkey(&ectx, key, SSH_SESSION_KEY_LENGTH);
- ectx.iv0 = 0;
- ectx.iv1 = 0;
- dctx = ectx;
- logevent("Initialised Blowfish encryption");
+ BlowfishContext *ctx = (BlowfishContext *)handle;
+ ctx->iv0 = GET_32BIT_MSB_FIRST(key);
+ ctx->iv1 = GET_32BIT_MSB_FIRST(key + 4);
}
-static void blowfish_ssh1_encrypt_blk(unsigned char *blk, int len)
+static void blowfish_sesskey(void *handle, unsigned char *key)
{
- blowfish_lsb_encrypt_cbc(blk, len, &ectx);
+ BlowfishContext *ctx = (BlowfishContext *)handle;
+ blowfish_setkey(ctx, key, SSH_SESSION_KEY_LENGTH);
+ ctx->iv0 = 0;
+ ctx->iv1 = 0;
+ ctx[1] = ctx[0]; /* structure copy */
}
-static void blowfish_ssh1_decrypt_blk(unsigned char *blk, int len)
+static void blowfish_ssh1_encrypt_blk(void *handle, unsigned char *blk,
+ int len)
{
- blowfish_lsb_decrypt_cbc(blk, len, &dctx);
+ BlowfishContext *ctx = (BlowfishContext *)handle;
+ blowfish_lsb_encrypt_cbc(blk, len, ctx);
}
-static void blowfish_ssh2_encrypt_blk(unsigned char *blk, int len)
+static void blowfish_ssh1_decrypt_blk(void *handle, unsigned char *blk,
+ int len)
{
- blowfish_msb_encrypt_cbc(blk, len, &ectx);
+ BlowfishContext *ctx = (BlowfishContext *)handle;
+ blowfish_lsb_decrypt_cbc(blk, len, ctx+1);
}
-static void blowfish_ssh2_decrypt_blk(unsigned char *blk, int len)
+static void blowfish_ssh2_encrypt_blk(void *handle, unsigned char *blk,
+ int len)
{
- blowfish_msb_decrypt_cbc(blk, len, &dctx);
+ BlowfishContext *ctx = (BlowfishContext *)handle;
+ blowfish_msb_encrypt_cbc(blk, len, ctx);
}
-struct ssh_cipher ssh_blowfish_ssh1 = {
- blowfish_sesskey,
- blowfish_csiv, blowfish_cskey,
- blowfish_sciv, blowfish_sckey,
- blowfish_ssh1_encrypt_blk,
- blowfish_ssh1_decrypt_blk,
- "blowfish-cbc",
- 8, 256
+static void blowfish_ssh2_decrypt_blk(void *handle, unsigned char *blk,
+ int len)
+{
+ BlowfishContext *ctx = (BlowfishContext *)handle;
+ blowfish_msb_decrypt_cbc(blk, len, ctx);
+}
+
+const struct ssh_cipher ssh_blowfish_ssh1 = {
+ blowfish_ssh1_make_context, blowfish_free_context, blowfish_sesskey,
+ blowfish_ssh1_encrypt_blk, blowfish_ssh1_decrypt_blk,
+ 8, "Blowfish"
};
-struct ssh_cipher ssh_blowfish_ssh2 = {
- blowfish_sesskey,
- blowfish_csiv, blowfish_cskey,
- blowfish_sciv, blowfish_sckey,
- blowfish_ssh2_encrypt_blk,
- blowfish_ssh2_decrypt_blk,
+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-cbc",
- 8, 128
+ 8, 128, "Blowfish"
+};
+
+static const struct ssh2_cipher *const blowfish_list[] = {
+ &ssh_blowfish_ssh2
+};
+
+const struct ssh2_ciphers ssh2_blowfish = {
+ sizeof(blowfish_list) / sizeof(*blowfish_list),
+ blowfish_list
};