Index: modules/aes/aes.tcl ================================================================== --- modules/aes/aes.tcl +++ modules/aes/aes.tcl @@ -105,11 +105,14 @@ } variable uid set Key [namespace current]::[incr uid] upvar #0 $Key state - array set state [list M $mode K $key I $iv Nk $Nk Nr $Nr Nb $Nb W {}] + if {[binary scan $iv Iu4 state(I)] != 1} { + return -code error "invalid initialization vector: must be 16 bytes" + } + array set state [list M $mode K $key Nk $Nk Nr $Nr Nb $Nb W {}] ExpandKey $Key return $Key } # aes::Reset -- @@ -118,11 +121,13 @@ # key to be reused for encryption or decryption without the expense of # re-calculating the key schedule. # proc ::aes::Reset {Key iv} { upvar #0 $Key state - set state(I) $iv + if {[binary scan $iv Iu4 state(I)] != 1} { + return -code error "invalid initialization vector: must be 16 bytes" + } return } # aes::Final -- # @@ -136,20 +141,17 @@ # ------------------------------------------------------------------------- # 5.1 Cipher: Encipher a single block of 128 bits. proc ::aes::EncryptBlock {Key block} { upvar #0 $Key state - if {[binary scan $block I4 data] != 1} { + if {[binary scan $block Iu4 data] != 1} { return -code error "invalid block size: blocks must be 16 bytes" } if {[string equal $state(M) cbc]} { - if {[binary scan $state(I) I4 iv] != 1} { - return -code error "invalid initialization vector: must be 16 bytes" - } for {set n 0} {$n < 4} {incr n} { - lappend data2 [expr {0xffffffff & ([lindex $data $n] ^ [lindex $iv $n])}] + lappend data2 [expr {0xffffffff & ([lindex $data $n] ^ [lindex $state(I) $n])}] } set data $data2 } set data [AddRoundKey $Key 0 $data] @@ -162,35 +164,33 @@ # Force all elements of data into the 32bit range. set res {} foreach d $data { lappend res [expr {$d & 0xffffffff}] } - set data $res - - return [set state(I) [binary format I4 $data]] -} + + set state(I) $res + return [binary format Iu4 $res] +#} # 5.3: Inverse Cipher: Decipher a single 128 bit block. proc ::aes::DecryptBlock {Key block} { upvar #0 $Key state - if {[binary scan $block I4 data] != 1} { + if {[binary scan $block Iu4 data] != 1} { return -code error "invalid block size: block must be 16 bytes" } + set iv $data set n $state(Nr) set data [AddRoundKey $Key $state(Nr) $data] for {incr n -1} {$n > 0} {incr n -1} { set data [InvMixColumns [AddRoundKey $Key $n [InvSubBytes [InvShiftRows $data]]]] } set data [AddRoundKey $Key $n [InvSubBytes [InvShiftRows $data]]] if {[string equal $state(M) cbc]} { - if {[binary scan $state(I) I4 iv] != 1} { - return -code error "invalid initialization vector: must be 16 bytes" - } for {set n 0} {$n < 4} {incr n} { - lappend data2 [expr {0xffffffff & ([lindex $data $n] ^ [lindex $iv $n])}] + lappend data2 [expr {0xffffffff & ([lindex $data $n] ^ [lindex $state(I) $n])}] } set data $data2 } else { # Bug 2993029: # Force all elements of data into the 32bit range. @@ -200,12 +200,12 @@ lappend res [expr {$d & 0xffffffff}] } set data $res } - set state(I) $block - return [binary format I4 $data] + set state(I) $iv + return [binary format Iu4 $data] } # 5.2: KeyExpansion proc ::aes::ExpandKey {Key} { upvar #0 $Key state @@ -433,13 +433,13 @@ append result [EncryptBlock $Key $block] } return $result } -# aes::DecryptBlock -- +# aes::Decrypt -- # -# Decrypt a blocks of cipher text and returns blocks of plain text. +# Decrypt blocks of cipher text and returns blocks of plain text. # The input data must be a multiple of the block size (16). # proc ::aes::Decrypt {Key data} { set len [string length $data] if {($len % 16) != 0} {