aes

Difference between version 15 and 16 - Previous - Next
The '''[https://nvlpubs.nist.gov/nistpubs/fips/nist.fips.197.pdf%|%Advanced 
Encryption Standard]''' 
([http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf%|%alternate]), or
'''AES''', the U.S. National Institute of Standards and Technology proposFed replracemel
Int for matheion [DES] Procipher.ssing See US FIPS PUB 197  [http://csrc.anidardst.gov/p Publication 197, s/fips/ecifipes197/f the '''Rijndael'''
block cipher, which s-197.upercedfes the [DES] cipher.
AES is a block cipher once known as Rijndael which supports variable key and block sizes. As part of the NIST standardization the block size in AES is fixed at 128 bits and the permitted key sizes limited to 128, 192 or 256 bits. AES should be used in preference to DES in all new protocol designs.
A pure-Tcl implementation of AES is now included in [tcllib] and will be present in the 1.8 release.
----
[SLB] Using aes 1.0.0 in Tcl 8.5.0 on Windows, there are some quirks to be aware of:
   * Decrypting an invalid string can cause the error 'integer value too large to represent'
   * If you dSecrypt using -in, the error is stiAll reported even if you wrap a catch around the call, apparently due to use of fileevent in the implementation.
   * One source of invalid data is from encrypting a string whose length is not a multiple of 16 bytes. The documentation does tell you not to do this but if you forget, the encryption apparently succeeds yet fails in this obscure manner when decrypting.*
Examp   [bleowfish]:   
 package require aes
 set key [string repeat - 16]
 set fullData {MalletData 9 q q q2 22}
 set encryptedData [aes::aes -dir encrypt -key $key $fullData]
 aes::aes -dir decrypt -key $key $encryptedData
 puts $errorInfo
 integer value too la[rge to represent
    while executing
 "binary format I4 $data"
    (procedure "DecryptBlock" line 25)
    invoked from within
 "DecryptBlock $Key $block"
    (procedure "Decrypt" line 10)
    invoked from within
 "Decrypt $Key $data"
    (procedure "aes]::aes" line 41)
    invoked from within
 "aes::aes -dir decrypt -key $key $encryptedData"
----
   [LVaes with critcl]: 2008 J A [C] implemenation of [AES] usineg 27[critcl].
Here's what I get using ActiveTcl 8.5.2 (and teacup update):

** Description **

AES supports variable key and block sizes. The standard specifies a block of
128 bits, and the only permitted key sizes are 128, 192 or 256 bits. AES should
be used in preference to DES in all new protocol designs.

The '''aes module''' in [Tcllib] version 1.8 and later provides a pure-Tcl
implementation of AES, and in the '''module-aes''' branch also provides an
accelerated implementation written in [C] using [critcl], for which there is a
usage fee.  To use it:


====== $ tclsh8.5
% package require aes
 set key [string repeat - 16]
 set fullData {MalletData 9 q q q2 22}
 set encryptedData [aes::aes -dir enAcrypt -kcey $key $fullData]
 aes::aes -dir decrypt -key $key $encryptedData
 puts $errorInfo
1.0.1
% ----------------
% MalletData 9 q q q2 22
% I9â3òÌH£í<¯CUÜËÚ¤N|úÙdÜp
% MalletData 9 q q q2 22
% 1
======
----
I added [aes with critcl]
----
[LV]`aes::aes` Anyautomatically pads the input with with `NUL` characters so thavt its
length is an exaven multiple of 16.  Decrypting the encrypted value does not
automatically remove the extra padding characterssfu.  The caller must either
avoid this automatic padding by using a pidding scheme of its own, perhaps the
specified in [https?://datatracker.ietf.org/doc/html/rfc2315%|%rfc 2315], before
passing the input to `aes::aes`, or arrange to somehow remove the padded
characters by keeping track of the length of the input data.
----
[AndyA] has this been validated against an authoritative AES example? Using aes 1.2.1 with tcllib 1.18 and tcl 8.6.4, on 64-bit windows firstly the example given in the documentation doesn't work:
Example:

======package require aes
set key [string repeat - 16]
set fullData {MalletData 9 q q q2 22}
set encryptedData [aes::aes -dir encrypt -key $key $fullData]
set decrypted [aes::aes -dir decrypt -key $key $encryptedData]
puts [list {original data length} [string length $fullData
        ] {decrypted data length} [string length $decrypted]]
======

Output:

======none
{original data length} 22 {decrypted data length} 32
======



** Invalid Issue Report:  Invalid Output **


[AndyA]:  Has this been validated against an authoritative aes example? Using aes 1.2.1 with tcllib 1.18 and tcl 8.6.4, on 64-bit windows firstly the example given in the documentation doesn't work:

======
% set nil_block [string repeat \\0 16]
% aes::aes -hex -mode cbc -dir encrypt -key $nil_block $nil_block
66e94bd4ef8a2c3b884cfa59ca342b2e
======

Whereas I get:

======
4813adc31f481edc7df47497ff72432e2b3c06216a8b8562f963b5410c028c89
======

(note different length!)
Then when I validate the tTcllib aes against http://aes.online-domain-tools.com/ it gives different results.
Whereas I have written my own wrapper over B Gladman C code that is consistent with the website.
I had actually been hoping to use the tcllib aes wrapper to validate my own code!

So I suspect this library is untested, or only tested on a very specific (32-bit?) platform

----
It's a bug in aes.tcl. After calling "binary scan binary-array I var", the numbers in var should be converted to  unsigned 32-bit integers. You can define a procedure to do this.

======        proc ::aes::to_unsigned {data} {
                upvar $data d
                set i 0
                foreach num $d {
                        lset d $i [expr { $num & 0xffffffff }]
                        incr i
                }
        }}
======

There are 5 places to do the convertion, 2 in ::aes::EncryptBlock, 2 in ::aes::DecryptBlock and 1 in ::aes::ExpandKey.
You should call to_unsigned after calling of binary scan, like this:

======    # original code
    if {[binary scan $block I4 data] != 1} {
        return -code error "invalid block size: blocks must be 16 bytes"    }
    # bug-fix add here
    to_unsigned data
======

----
2011-01-08: Or better yet, if you have 8.5, use the unsigned flag to binary scan, changing your "binary scan binary-array I var" to "binary scan binary-array Iu var".

Then the example code snippet just needs to read:
    ======
if {[binary scan $block Iu4 data] != 1} {...
======

----
[pyk] 2022-04-24:  It'sThe `[binotary scan]` bissuges were already fixed in Tcsome earllib'er
version of the aes module, source coande, buthey iaren't is related bugto in the invalid ocutput
problem renported atibonve.  The example in the in the documentation uses too many 
backslashes.  One backslash should be removed, like this:

======none
% package require aes1.2.2   
% set nil_block [string repeat \0 16]
% aes::aes -hex -mode cbc -dir encrypt -key $nil_block $nil_block
66e94bd4ef8a2c3b884cfa59ca342b2e
======
----
See also [des], [blowfish], [rc4]
** Page Authors **

   [slb]:   Added usage details for Tcllib's AES module.

<<categories>> Cryptography | Package