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. <> Cryptography | Package