Index: blowfish.tcl
===================================================================
RCS file: /cvsroot/tcllib/tcllib/modules/blowfish/blowfish.tcl,v
retrieving revision 1.7
diff -c -b -r1.7 blowfish.tcl
*** blowfish.tcl	2 Oct 2006 20:58:52 -0000	1.7
--- blowfish.tcl	11 Feb 2007 12:08:45 -0000
***************
*** 409,414 ****
--- 409,415 ----
      set P $state(P)
      set S $state(S)
      set cbc_mode [string equal "cbc" $state(M)]
+     set cfb_mode [string equal "cfb" $state(M)]
  
      if {[binary scan $state(I) II s0 s1] != 2} {
          return -code error "invalid initialization vector: must be 8 bytes"
***************
*** 431,444 ****
              set xl [expr {($xl & 0xffffffff) ^ $s0}]
              set xr [expr {($xr & 0xffffffff) ^ $s1}]
          }
          set d  [intEncrypt $P $S $xl $xr]
          if {$cbc_mode} {
              set s0 [lindex $d 0]
              set s1 [lindex $d 1]
          }
          append result [binary format I2 $d]
      }
!     if {$cbc_mode} {
          set state(I) [binary format II $s0 $s1]
      }
      return $result
--- 432,456 ----
              set xl [expr {($xl & 0xffffffff) ^ $s0}]
              set xr [expr {($xr & 0xffffffff) ^ $s1}]
          }
+         if ($cfb_mode) {
+         		set pl $xl
+         		set pr $xr
+         		set xl $s0
+         		set xr $s1
+         }
          set d  [intEncrypt $P $S $xl $xr]
          if {$cbc_mode} {
              set s0 [lindex $d 0]
              set s1 [lindex $d 1]
          }
+ 		    if {$cfb_mode} {
+ 		    	set s0 [expr [lindex $d 0] ^ $pl]
+ 		    	set s1 [expr [lindex $d 1] ^ $pr]
+ 					set d [list $s0 $s1]		    	
+ 		    }
          append result [binary format I2 $d]
      }
!     if {$cbc_mode || $cfb_mode} {
          set state(I) [binary format II $s0 $s1]
      }
      return $result
***************
*** 460,465 ****
--- 472,478 ----
      set P $state(P)
      set S $state(S)
      set cbc_mode [string equal "cbc" $state(M)]
+     set cfb_mode [string equal "cfb" $state(M)]
  
      if {[binary scan $state(I) II s0 s1] != 2} {
          return -code error "initialization vector must be 8 bytes"
***************
*** 480,486 ****
--- 493,509 ----
          }
          set xl [expr {$xl & 0xffffffff}]
          set xr [expr {$xr & 0xffffffff}]
+         if {$cfb_mode} {
+         	set cl $xl
+         	set cr $xr
+         	set xl $s0
+         	set xr $s1
+         }
+         if {$cfb_mode} {
+         	set d  [intEncrypt $P $S $xl $xr]
+         } else {
          	set d  [intDecrypt $P $S $xl $xr]
+         }
          if {$cbc_mode} {
              set d0 [lindex $d 0]
              set d1 [lindex $d 1]
***************
*** 489,494 ****
--- 512,525 ----
              set s0 $xl
              set s1 $xr
              append result [binary format II $c0 $c1]
+         } elseif {$cfb_mode} {
+         	 set d0 [lindex $d 0]
+         	 set d1 [lindex $d 1]
+            set c0 [expr {$d0 ^ $cl}]
+            set c1 [expr {$d1 ^ $cr}]
+            set s0 $cl
+            set s1 $cr
+            append result [binary format II $c0 $c1]
          } else {
              append result [binary format I2 $d]
          }
***************
*** 608,614 ****
      array set opts {-dir enc -mode cbc -key {} -in {} -out {} -hex 0 -pad \0}
      set opts(-chunksize) 4096
      set opts(-iv) [string repeat \0 8]
!     set modes {ecb cbc}
      set dirs  {encrypt decrypt}
      while {[string match -* [set option [lindex $args 0]]]} {
          switch -exact -- $option {
--- 639,645 ----
      array set opts {-dir enc -mode cbc -key {} -in {} -out {} -hex 0 -pad \0}
      set opts(-chunksize) 4096
      set opts(-iv) [string repeat \0 8]
!     set modes {ecb cbc cfb}
      set dirs  {encrypt decrypt}
      while {[string match -* [set option [lindex $args 0]]]} {
          switch -exact -- $option {
***************
*** 636,641 ****
--- 667,673 ----
          return -code error "no key provided: the -key option is required"
      }
      
+ 	  
      set r {}
      if {$opts(-in) == {}} {
  
***************
*** 645,650 ****
--- 677,683 ----
          }
  
          set data [lindex $args 0]
+         set inLength [string length $data]
  	      if {[string length $opts(-pad)] > 0} {
              set data [Pad [lindex $args 0] 8 $opts(-pad)]
          }
***************
*** 660,666 ****
              }
              Final $Key
          }
! 
          if {$opts(-out) != {}} {
              puts -nonewline $opts(-out) $r
              set r {}
--- 693,701 ----
              }
              Final $Key
          }
! 				if {$opts(-mode)=="cfb"} {
! 					set r [string range $r 0 [expr $inLength -1]]
! 				}
          if {$opts(-out) != {}} {
              puts -nonewline $opts(-out) $r
              set r {}
Index: blowfish.test
===================================================================
RCS file: /cvsroot/tcllib/tcllib/modules/blowfish/blowfish.test,v
retrieving revision 1.9
diff -c -b -r1.9 blowfish.test
*** blowfish.test	9 Oct 2006 21:41:40 -0000	1.9
--- blowfish.test	11 Feb 2007 12:08:45 -0000
***************
*** 170,175 ****
--- 170,177 ----
  set iv  [binary format H* FEDCBA9876543210]
  set plain [binary format H* \
                 37363534333231204E6F77206973207468652074696D6520666F722000000000]
+ set plainstream [binary format H* \
+                37363534333231204E6F77206973207468652074696D6520666F72200]
  
  foreach impl [implementations] {
      select_implementation $impl
***************
*** 189,194 ****
--- 191,214 ----
      reset_implementation
  }
  
+ foreach impl [implementations] {
+     select_implementation $impl
+     test blowfish-$impl-6.2 "blowfish cfb mode (impl $impl)" {
+         list [catch {
+             string toupper \
+                 [::blowfish::Hex \
+                      [::blowfish::blowfish \
+                           -dir enc \
+                           -mode cfb \
+                           -iv $iv \
+                           -key $key \
+                           $plainstream]]
+         } msg] $msg
+     } [list 0 \
+            E73214A2822139CAF26ECF6D2EB9E76E3DA3DE04D1517200519D57A6C3]
+     reset_implementation
+ }
+ 
  #cfb E73214A2822139CAF26ECF6D2EB9E76E3DA3DE04D1517200519D57A6C3
  #ofb E73214A2822139CA62B343CC5B65587310DD908D0C241B2263C2CF80DA
  
