aes

Difference between version 16 and 17 - 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 Federal
Information Processing Standards Publication 197, specifies the '''Rijndael'''block [cipher], which supercedes the [DES] cipher.



** See Also **
   [blowfish]:   

   [des]:   

   [rc4]:   

   [aes with critcl]:   A [C] implemenation of [AES] using [critcl].



** 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:


======
package require aes
aes::Accelerate 1
======


`aes::aes` automatically pads the input with with `NUL` characters so that its
length is an even multiple of 16.  Decrypting the encrypted value does not
automatically remove the extra padding characters.  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.


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 Tcllib 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:  The `[binary scan]` issues were already fixed in some earlier
version of the aes module, and they aren't related to the invalid output
problem reported above.  The example in the in the documentation uses too many
backslashes.  One backslash should be removed, like this:

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



** Page Authors **

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

<<categories>> Cryptography | Package