+/*
+ * SILC Crypto API for Blowfish
+ */
+
+/* Sets the key for the cipher. */
+
+SILC_CIPHER_API_SET_KEY(blowfish_cbc)
+{
+ blowfish_set_key((BlowfishContext *)context, (unsigned char *)key, keylen);
+ return TRUE;
+}
+
+/* Sets IV for the cipher. */
+
+SILC_CIPHER_API_SET_IV(blowfish_cbc)
+{
+
+}
+
+/* Initialize */
+
+SILC_CIPHER_API_INIT(blowfish_cbc)
+{
+ return silc_calloc(1, sizeof(BlowfishContext));
+}
+
+/* Unnitialize */
+
+SILC_CIPHER_API_UNINIT(blowfish_cbc)
+{
+ BlowfishContext *b = context;
+ memset(b, 0, sizeof(*b));
+ silc_free(b);
+}
+
+/* Encrypts with the cipher in CBC mode. Source and destination buffers
+ maybe one and same. */
+
+SILC_CIPHER_API_ENCRYPT(blowfish_cbc)
+{
+ SilcUInt32 tiv[4];
+ int i;
+
+ SILC_CBC_GET_IV(tiv, iv);
+
+ SILC_CBC_ENC_PRE(tiv, src);
+ blowfish_encrypt((BlowfishContext *)context, tiv, tiv, 16);
+ SILC_CBC_ENC_POST(tiv, dst, src);
+
+ for (i = 16; i < len; i += 16) {
+ SILC_CBC_ENC_PRE(tiv, src);
+ blowfish_encrypt((BlowfishContext *)context, tiv, tiv, 16);
+ SILC_CBC_ENC_POST(tiv, dst, src);
+ }
+
+ SILC_CBC_PUT_IV(tiv, iv);
+
+ return TRUE;
+}
+
+/* Decrypts with the cipher in CBC mode. Source and destination buffers
+ maybe one and same. */
+
+SILC_CIPHER_API_DECRYPT(blowfish_cbc)
+{
+ SilcUInt32 tmp[4], tmp2[4], tiv[4];
+ int i;
+
+ SILC_CBC_GET_IV(tiv, iv);
+
+ SILC_CBC_DEC_PRE(tmp, src);
+ blowfish_decrypt((BlowfishContext *)context, tmp, tmp2, 16);
+ SILC_CBC_DEC_POST(tmp2, dst, src, tmp, tiv);
+
+ for (i = 16; i < len; i += 16) {
+ SILC_CBC_DEC_PRE(tmp, src);
+ blowfish_decrypt((BlowfishContext *)context, tmp, tmp2, 16);
+ SILC_CBC_DEC_POST(tmp2, dst, src, tmp, tiv);
+ }
+
+ SILC_CBC_PUT_IV(tiv, iv);
+
+ return TRUE;
+}
+