+static void blowfish_msb_decrypt_cbc(unsigned char *blk, int len,
+ BlowfishContext * ctx)
+{
+ word32 xL, xR, out[2], iv0, iv1;
+
+ assert((len & 7) == 0);
+
+ 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;
+ }
+
+ ctx->iv0 = iv0;
+ ctx->iv1 = iv1;
+}
+
+static void blowfish_msb_sdctr(unsigned char *blk, int len,
+ BlowfishContext * ctx)
+{
+ word32 b[2], iv0, iv1, tmp;
+
+ assert((len & 7) == 0);
+
+ iv0 = ctx->iv0;
+ iv1 = ctx->iv1;
+
+ while (len > 0) {
+ blowfish_encrypt(iv0, iv1, b, ctx);
+ tmp = GET_32BIT_MSB_FIRST(blk);
+ PUT_32BIT_MSB_FIRST(blk, tmp ^ b[0]);
+ tmp = GET_32BIT_MSB_FIRST(blk + 4);
+ PUT_32BIT_MSB_FIRST(blk + 4, tmp ^ b[1]);
+ if ((iv1 = (iv1 + 1) & 0xffffffff) == 0)
+ iv0 = (iv0 + 1) & 0xffffffff;
+ blk += 8;
+ len -= 8;
+ }
+
+ ctx->iv0 = iv0;
+ ctx->iv1 = iv1;
+}
+
+static void blowfish_setkey(BlowfishContext * ctx,
+ const unsigned char *key, short keybytes)
+{