diff options
author | William Joye <wjoye@cfa.harvard.edu> | 2016-10-27 19:39:39 (GMT) |
---|---|---|
committer | William Joye <wjoye@cfa.harvard.edu> | 2016-10-27 19:39:39 (GMT) |
commit | ea28451286d3ea4a772fa174483f9a7a66bb1ab3 (patch) | |
tree | 6ee9d8a7848333a7ceeee3b13d492e40225f8b86 /tcllib/modules/blowfish | |
parent | b5ca09bae0d6a1edce939eea03594dd56383f2c8 (diff) | |
parent | 7c621da28f07e449ad90c387344f07a453927569 (diff) | |
download | blt-ea28451286d3ea4a772fa174483f9a7a66bb1ab3.zip blt-ea28451286d3ea4a772fa174483f9a7a66bb1ab3.tar.gz blt-ea28451286d3ea4a772fa174483f9a7a66bb1ab3.tar.bz2 |
Merge commit '7c621da28f07e449ad90c387344f07a453927569' as 'tcllib'
Diffstat (limited to 'tcllib/modules/blowfish')
-rw-r--r-- | tcllib/modules/blowfish/ChangeLog | 136 | ||||
-rw-r--r-- | tcllib/modules/blowfish/blowfish.bench | 66 | ||||
-rw-r--r-- | tcllib/modules/blowfish/blowfish.man | 164 | ||||
-rw-r--r-- | tcllib/modules/blowfish/blowfish.tcl | 724 | ||||
-rw-r--r-- | tcllib/modules/blowfish/blowfish.test | 315 | ||||
-rw-r--r-- | tcllib/modules/blowfish/pkgIndex.tcl | 5 |
6 files changed, 1410 insertions, 0 deletions
diff --git a/tcllib/modules/blowfish/ChangeLog b/tcllib/modules/blowfish/ChangeLog new file mode 100644 index 0000000..92da300 --- /dev/null +++ b/tcllib/modules/blowfish/ChangeLog @@ -0,0 +1,136 @@ +2013-02-01 Andreas Kupries <andreas_kupries@users.sourceforge.net> + + * + * Released and tagged Tcllib 1.15 ======================== + * + +2011-12-13 Andreas Kupries <andreas_kupries@users.sourceforge.net> + + * + * Released and tagged Tcllib 1.14 ======================== + * + +2011-01-24 Andreas Kupries <andreas_kupries@users.sourceforge.net> + + * + * Released and tagged Tcllib 1.13 ======================== + * + +2009-12-07 Andreas Kupries <andreas_kupries@users.sourceforge.net> + + * + * Released and tagged Tcllib 1.12 ======================== + * + +2008-12-12 Andreas Kupries <andreas_kupries@users.sourceforge.net> + + * + * Released and tagged Tcllib 1.11.1 ======================== + * + +2008-10-16 Andreas Kupries <andreas_kupries@users.sourceforge.net> + + * + * Released and tagged Tcllib 1.11 ======================== + * + +2007-09-17 Pat Thoyts <patthoyts@users.sourceforge.net> + + * blowfish.test: Fix default if -dir option is not specified it + defaults to 'enc' and this fails to match 'encrypt' and results in + the default operation being 'decrypt' + +2007-09-12 Andreas Kupries <andreas_kupries@users.sourceforge.net> + + * + * Released and tagged Tcllib 1.10 ======================== + * + +2007-08-20 Andreas Kupries <andreask@activestate.com> + + * blowfish.man: Version bumped to 1.0.3 due to bugfix at Mar 12. + * blowfish.tcl: + * pkgIndex.tcl: + +2007-03-19 Andreas Kupries <andreas_kupries@users.sourceforge.net> + + * blowfish.man: Fixed all warnings due to use of now deprecated + commands. Added a section about how to give feedback. + +2007-03-12 Pat Thoyts <patthoyts@users.sourceforge.net> + + * blowfish.tcl: Applied patch from bug #1664626 by Neil Madden to + the fix variable mis-naming in the Chunk command. + +2006-10-03 Andreas Kupries <andreas_kupries@users.sourceforge.net> + + * + * Released and tagged Tcllib 1.9 ======================== + * + +2006-10-02 Pat Thoyts <patthoyts@users.sourceforge.net> + + * blowfish.test: Document the padding and added -pad option + * blowfish.tcl: to turn off padding or change the pad char. + * blowfish.man: Increment the patchlevel. + * pkgIndex.tcl: + +2006-09-19 Pat Thoyts <patthoyts@users.sourceforge.net> + + * blowfish.tcl: Bug 1560822: hyphen handling. + * blowfish.test: Added test for hyphen handling. + * blowfish.man: Note -- for option termination. + * pkgIndex.tcl: Increment patchlevel. + +2006-01-22 Andreas Kupries <andreas_kupries@users.sourceforge.net> + + * blowfish.test: More boilerplate simplified via use of test support. + +2006-01-19 Andreas Kupries <andreas_kupries@users.sourceforge.net> + + * blowfish.test: Hooked into the new common test support code. + +2005-10-18 Andreas Kupries <andreask@activestate.com> + + * blowfish.bench: Extended with benchmarks for the keyschedule. + +2005-10-06 Andreas Kupries <andreas_kupries@users.sourceforge.net> + + * + * Released and tagged Tcllib 1.8 ======================== + * + +2005-09-04 Pat Thoyts <patthoyts@users.sourceforge.net> + + * blowfish.tcl: Added some performance enhancements. Added some + * blowfish.test: documentation for the API. Fix testing to test + * blowfish.man: each implementation. Checked with tcl 8.2. + * pkgIndex.tcl: + +2005-06-21 Andreas Kupries <andreas_kupries@users.sourceforge.net> + + * blowfish.man: Fixed a typo. + +2005-06-22 Pat Thoyts <patthoyts@users.sourceforge.net> + + * blowfish.man: new file + +2004-12-21 Pat Thoyts <patthoyts@users.sourceforge.net> + + * blowfish.tcl: Fixed bug in search for Trfcrypt (noticed by + Antirez). Added a Reset command to the programming API to permit + reuse of a key with a new initialization vector.. + +2004-12-07 Pat Thoyts <patthoyts@users.sourceforge.net> + + * blowfish.tcl: Add in support for Trfcrypt implementation. + * blowfish.test: Support variable key length and added tests. + +2004-12-06 Pat Thoyts <patthoyts@users.sourceforge.net> + + * blowfish.tcl: Imported Frank Pilhofer's pure-Tcl implementation + * blowfish.test: from the Tcler's wiki. Modified to remove the + Itcl code and to conform to the tcllib programming standards and + conventions. Test file includes standard test vectors. + + diff --git a/tcllib/modules/blowfish/blowfish.bench b/tcllib/modules/blowfish/blowfish.bench new file mode 100644 index 0000000..f3ece4e --- /dev/null +++ b/tcllib/modules/blowfish/blowfish.bench @@ -0,0 +1,66 @@ +# -*- tcl -*- +# Tcl Benchmark File +# +# This file contains a number of benchmarks for the 'blowfish' module. +# This allow developers to monitor/gauge/track package performance. +# +# (c) 2005 Andreas Kupries <andreas_kupries@users.sourceforge.net> + +# We need at least version 8.2 for the package and thus the +# benchmarks. + +if {![package vsatisfies [package provide Tcl] 8.2]} { + return +} + +# ### ### ### ######### ######### ######### ########################### +## Setting up the environment ... + +package forget blowfish +catch {namespace delete ::blowfish} +source [file join [file dirname [info script]] blowfish.tcl] + +set i [binary format H* 000000000000000] +set p [binary format H* 00112233445566778899aabbccddeeff] + +set k [binary format H* 000102030405060] +set c [binary format H* 69c4e0d86a7b0430d8cdb78070b4c55a] + +# ### ### ### ######### ######### ######### ########################### +## Benchmarks. + +bench -desc "BLOWFISH ECB encryption" -body { + blowfish::blowfish -mode ecb -dir enc -key $k -iv $i $p +} + +bench -desc "BLOWFISH ECB decryption" -body { + blowfish::blowfish -mode ecb -dir dec -key $k -iv $i $c +} + +bench -desc "BLOWFISH ECB encryption core" -pre { + set key [blowfish::Init ecb $k $i] +} -body { + blowfish::Encrypt $key $p +} -post { + blowfish::Final $key +} + +bench -desc "BLOWFISH ECB decryption core" -pre { + set key [blowfish::Init ecb $k $i] +} -body { + blowfish::Decrypt $key $c +} -post { + blowfish::Final $key +} + +bench -desc "BLOWFISH ECB keyschedule" -body { + blowfish::Final [blowfish::Init ecb $k $i] +} + +bench -desc "BLOWFISH CBC keyschedule" -body { + blowfish::Final [blowfish::Init cbc $k $i] +} + + +# ### ### ### ######### ######### ######### ########################### +## Complete diff --git a/tcllib/modules/blowfish/blowfish.man b/tcllib/modules/blowfish/blowfish.man new file mode 100644 index 0000000..8ee4627 --- /dev/null +++ b/tcllib/modules/blowfish/blowfish.man @@ -0,0 +1,164 @@ +[comment {-*- tcl -*- doctools manpage}] +[manpage_begin blowfish n 1.0.3] +[see_also 3des] +[see_also des] +[see_also rc4] +[keywords {block cipher}] +[keywords blowfish] +[keywords cryptography] +[keywords encryption] +[keywords security] +[copyright {2003, Pat Thoyts <patthoyts@users.sourceforge.net>}] +[moddesc {Blowfish Block Cipher}] +[titledesc {Implementation of the Blowfish block cipher}] +[category {Hashes, checksums, and encryption}] +[require Tcl 8.4] +[require blowfish [opt 1.0.4]] +[description] +[para] + +This package is an implementation in Tcl of the Blowfish algorithm +developed by Bruce Schneier [lb]1[rb]. Blowfish is a 64-bit block cipher +designed to operate quickly on 32 bit architectures and accepting a +variable key length. This implementation supports ECB and CBC mode +blowfish encryption. + +[section {COMMANDS}] + +[list_begin definitions] + +[call [cmd "::blowfish::blowfish"] \ + [opt [arg "-mode [lb]ecb|cbc[rb]"]] \ + [opt [arg "-dir [lb]encrypt|decrypt[rb]"]] \ + [arg "-key keydata"] \ + [opt [arg "-iv vector"]] \ + [opt [arg "-out channel"]] \ + [opt [arg "-chunksize size"]] \ + [opt [arg "-pad padchar"]] \ + [lb] [arg "-in channel"] | \ + [opt [arg "--"]] [arg "data"] [rb]] + +Perform the [package blowfish] algorithm on either the data provided +by the argument or on the data read from the [arg "-in"] channel. If +an [arg "-out"] channel is given then the result will be written to +this channel. + +[para] + +The [arg -key] option must be given. This parameter takes a binary +string of variable length and is used to generate the [package blowfish] +key schedule. You should be aware that creating a key +schedule is quite an expensive operation in blowfish so it is worth +reusing the key where possible. See [cmd Reset]. + +[para] + +The [arg -mode] and [arg -dir] options are optional and default to cbc +mode and encrypt respectively. The initialization vector [arg -iv] +takes an 8 byte binary argument which defaults to 8 zeros. +See [sectref "MODES OF OPERATION"] for more about available modes and +their uses. + +[para] + +Blowfish is a 64-bit block cipher. This means that the data must be +provided in units that are a multiple of 8 bytes. The [cmd blowfish] +command will by default add nul characters to pad the input data to a +multiple of 8 bytes if necessary. The programming api commands will +never add padding and instead will raise an error if the input is not +a multiple of the block size. The [arg -pad] option can be used to +change the padding character or to disable padding if the empty string +is provided as the argument. + +[list_end] + +[section "PROGRAMMING INTERFACE"] + +[list_begin definitions] + +[call [cmd "::blowfish::Init"] [arg "mode"] [arg "keydata"] [arg "iv"]] + +Construct a new blowfish key schedule using the specified key data and +the given initialization vector. The initialization vector is not used +with ECB mode but is important for CBC mode. +See [sectref "MODES OF OPERATION"] for details about cipher modes. + +[call [cmd "::blowfish::Encrypt"] [arg "Key"] [arg "data"]] + +Use a prepared key acquired by calling [cmd Init] to encrypt the +provided data. The data argument should be a binary array that is a +multiple of the block size of 8 bytes. The result is a binary +array the same size as the input of encrypted data. + +[call [cmd "::blowfish::Decrypt"] [arg "Key"] [arg "data"]] + +Decipher data using the key. Note that the same key may be used to +encrypt and decrypt data provided that the initialization vector is +reset appropriately for CBC mode. + +[call [cmd "::blowfish::Reset"] [arg "Key"] [arg "iv"]] + +Reset the initialization vector. This permits the programmer to re-use +a key and avoid the cost of re-generating the key schedule where the +same key data is being used multiple times. + +[call [cmd "::blowfish::Final"] [arg "Key"]] + +This should be called to clean up resources associated with [arg Key]. +Once this function has been called the key may not be used again. + +[list_end] + +[section "MODES OF OPERATION"] + +[list_begin definitions] + +[def "Electronic Code Book (ECB)"] +ECB is the basic mode of all block ciphers. Each block is encrypted +independently and so identical plain text will produce identical +output when encrypted with the same key. Any encryption errors will +only affect a single block however this is vulnerable to known +plaintext attacks. + +[def "Cipher Block Chaining (CBC)"] + +CBC mode uses the output of the last block encryption to affect the +current block. An initialization vector of the same size as the cipher +block size is used to handle the first block. The initialization +vector should be chosen randomly and transmitted as the first block of +the output. Errors in encryption affect the current block and the next +block after which the cipher will correct itself. CBC is the most +commonly used mode in software encryption. + +[list_end] + +[section "EXAMPLES"] + +[example { +% blowfish::blowfish -hex -mode ecb -dir encrypt -key secret01 "hello, world!" +d0d8f27e7a374b9e2dbd9938dd04195a +}] + +[example { + set Key [blowfish::Init cbc $eight_bytes_key_data $eight_byte_iv] + append ciphertext [blowfish::Encrypt $Key $plaintext] + append ciphertext [blowfish::Encrypt $Key $additional_plaintext] + blowfish::Final $Key +}] + +[section "REFERENCES"] + +[list_begin enumerated] + +[enum] + Schneier, B. "Applied Cryptography, 2nd edition", 1996, + ISBN 0-471-11709-9, pub. John Wiley & Sons. + +[list_end] + +[section AUTHORS] +Frank Pilhofer, Pat Thoyts + +[vset CATEGORY blowfish] +[include ../doctools2base/include/feedback.inc] +[manpage_end] diff --git a/tcllib/modules/blowfish/blowfish.tcl b/tcllib/modules/blowfish/blowfish.tcl new file mode 100644 index 0000000..2610ae1 --- /dev/null +++ b/tcllib/modules/blowfish/blowfish.tcl @@ -0,0 +1,724 @@ +# blowfish.tcl - +# +# Pure-Tcl implementation of the Blowfish algorithm. +# +# See http://www.schneier.com/blowfish.html for information about the +# Blowfish algorithm. +# +# The implementation is derived from Paul Kocher's implementation, +# available at http://www.schneier.com/blowfish-download.html +# +# Copyright (C) 2004 Frank Pilhofer +# Copyright (C) 2004 Pat Thoyts <patthoyts@users.sourceforge.net> +# +# ------------------------------------------------------------------------- +# See the file "license.terms" for information on usage and redistribution +# of this file, and for a DISCLAIMER OF ALL WARRANTIES. +# ------------------------------------------------------------------------- +# + +package require Tcl 8.2 + +namespace eval blowfish { + variable uid + if {![info exists uid]} { set uid 0 } + + variable accel + array set accel {trf 0} + + namespace export blowfish + + variable ORIG_P { + 0x243F6A88 0x85A308D3 0x13198A2E 0x03707344 + 0xA4093822 0x299F31D0 0x082EFA98 0xEC4E6C89 + 0x452821E6 0x38D01377 0xBE5466CF 0x34E90C6C + 0xC0AC29B7 0xC97C50DD 0x3F84D5B5 0xB5470917 + 0x9216D5D9 0x8979FB1B + } + + variable ORIG_S { + 0xD1310BA6 0x98DFB5AC 0x2FFD72DB 0xD01ADFB7 + 0xB8E1AFED 0x6A267E96 0xBA7C9045 0xF12C7F99 + 0x24A19947 0xB3916CF7 0x0801F2E2 0x858EFC16 + 0x636920D8 0x71574E69 0xA458FEA3 0xF4933D7E + 0x0D95748F 0x728EB658 0x718BCD58 0x82154AEE + 0x7B54A41D 0xC25A59B5 0x9C30D539 0x2AF26013 + 0xC5D1B023 0x286085F0 0xCA417918 0xB8DB38EF + 0x8E79DCB0 0x603A180E 0x6C9E0E8B 0xB01E8A3E + 0xD71577C1 0xBD314B27 0x78AF2FDA 0x55605C60 + 0xE65525F3 0xAA55AB94 0x57489862 0x63E81440 + 0x55CA396A 0x2AAB10B6 0xB4CC5C34 0x1141E8CE + 0xA15486AF 0x7C72E993 0xB3EE1411 0x636FBC2A + 0x2BA9C55D 0x741831F6 0xCE5C3E16 0x9B87931E + 0xAFD6BA33 0x6C24CF5C 0x7A325381 0x28958677 + 0x3B8F4898 0x6B4BB9AF 0xC4BFE81B 0x66282193 + 0x61D809CC 0xFB21A991 0x487CAC60 0x5DEC8032 + 0xEF845D5D 0xE98575B1 0xDC262302 0xEB651B88 + 0x23893E81 0xD396ACC5 0x0F6D6FF3 0x83F44239 + 0x2E0B4482 0xA4842004 0x69C8F04A 0x9E1F9B5E + 0x21C66842 0xF6E96C9A 0x670C9C61 0xABD388F0 + 0x6A51A0D2 0xD8542F68 0x960FA728 0xAB5133A3 + 0x6EEF0B6C 0x137A3BE4 0xBA3BF050 0x7EFB2A98 + 0xA1F1651D 0x39AF0176 0x66CA593E 0x82430E88 + 0x8CEE8619 0x456F9FB4 0x7D84A5C3 0x3B8B5EBE + 0xE06F75D8 0x85C12073 0x401A449F 0x56C16AA6 + 0x4ED3AA62 0x363F7706 0x1BFEDF72 0x429B023D + 0x37D0D724 0xD00A1248 0xDB0FEAD3 0x49F1C09B + 0x075372C9 0x80991B7B 0x25D479D8 0xF6E8DEF7 + 0xE3FE501A 0xB6794C3B 0x976CE0BD 0x04C006BA + 0xC1A94FB6 0x409F60C4 0x5E5C9EC2 0x196A2463 + 0x68FB6FAF 0x3E6C53B5 0x1339B2EB 0x3B52EC6F + 0x6DFC511F 0x9B30952C 0xCC814544 0xAF5EBD09 + 0xBEE3D004 0xDE334AFD 0x660F2807 0x192E4BB3 + 0xC0CBA857 0x45C8740F 0xD20B5F39 0xB9D3FBDB + 0x5579C0BD 0x1A60320A 0xD6A100C6 0x402C7279 + 0x679F25FE 0xFB1FA3CC 0x8EA5E9F8 0xDB3222F8 + 0x3C7516DF 0xFD616B15 0x2F501EC8 0xAD0552AB + 0x323DB5FA 0xFD238760 0x53317B48 0x3E00DF82 + 0x9E5C57BB 0xCA6F8CA0 0x1A87562E 0xDF1769DB + 0xD542A8F6 0x287EFFC3 0xAC6732C6 0x8C4F5573 + 0x695B27B0 0xBBCA58C8 0xE1FFA35D 0xB8F011A0 + 0x10FA3D98 0xFD2183B8 0x4AFCB56C 0x2DD1D35B + 0x9A53E479 0xB6F84565 0xD28E49BC 0x4BFB9790 + 0xE1DDF2DA 0xA4CB7E33 0x62FB1341 0xCEE4C6E8 + 0xEF20CADA 0x36774C01 0xD07E9EFE 0x2BF11FB4 + 0x95DBDA4D 0xAE909198 0xEAAD8E71 0x6B93D5A0 + 0xD08ED1D0 0xAFC725E0 0x8E3C5B2F 0x8E7594B7 + 0x8FF6E2FB 0xF2122B64 0x8888B812 0x900DF01C + 0x4FAD5EA0 0x688FC31C 0xD1CFF191 0xB3A8C1AD + 0x2F2F2218 0xBE0E1777 0xEA752DFE 0x8B021FA1 + 0xE5A0CC0F 0xB56F74E8 0x18ACF3D6 0xCE89E299 + 0xB4A84FE0 0xFD13E0B7 0x7CC43B81 0xD2ADA8D9 + 0x165FA266 0x80957705 0x93CC7314 0x211A1477 + 0xE6AD2065 0x77B5FA86 0xC75442F5 0xFB9D35CF + 0xEBCDAF0C 0x7B3E89A0 0xD6411BD3 0xAE1E7E49 + 0x00250E2D 0x2071B35E 0x226800BB 0x57B8E0AF + 0x2464369B 0xF009B91E 0x5563911D 0x59DFA6AA + 0x78C14389 0xD95A537F 0x207D5BA2 0x02E5B9C5 + 0x83260376 0x6295CFA9 0x11C81968 0x4E734A41 + 0xB3472DCA 0x7B14A94A 0x1B510052 0x9A532915 + 0xD60F573F 0xBC9BC6E4 0x2B60A476 0x81E67400 + 0x08BA6FB5 0x571BE91F 0xF296EC6B 0x2A0DD915 + 0xB6636521 0xE7B9F9B6 0xFF34052E 0xC5855664 + 0x53B02D5D 0xA99F8FA1 0x08BA4799 0x6E85076A + 0x4B7A70E9 0xB5B32944 0xDB75092E 0xC4192623 + 0xAD6EA6B0 0x49A7DF7D 0x9CEE60B8 0x8FEDB266 + 0xECAA8C71 0x699A17FF 0x5664526C 0xC2B19EE1 + 0x193602A5 0x75094C29 0xA0591340 0xE4183A3E + 0x3F54989A 0x5B429D65 0x6B8FE4D6 0x99F73FD6 + 0xA1D29C07 0xEFE830F5 0x4D2D38E6 0xF0255DC1 + 0x4CDD2086 0x8470EB26 0x6382E9C6 0x021ECC5E + 0x09686B3F 0x3EBAEFC9 0x3C971814 0x6B6A70A1 + 0x687F3584 0x52A0E286 0xB79C5305 0xAA500737 + 0x3E07841C 0x7FDEAE5C 0x8E7D44EC 0x5716F2B8 + 0xB03ADA37 0xF0500C0D 0xF01C1F04 0x0200B3FF + 0xAE0CF51A 0x3CB574B2 0x25837A58 0xDC0921BD + 0xD19113F9 0x7CA92FF6 0x94324773 0x22F54701 + 0x3AE5E581 0x37C2DADC 0xC8B57634 0x9AF3DDA7 + 0xA9446146 0x0FD0030E 0xECC8C73E 0xA4751E41 + 0xE238CD99 0x3BEA0E2F 0x3280BBA1 0x183EB331 + 0x4E548B38 0x4F6DB908 0x6F420D03 0xF60A04BF + 0x2CB81290 0x24977C79 0x5679B072 0xBCAF89AF + 0xDE9A771F 0xD9930810 0xB38BAE12 0xDCCF3F2E + 0x5512721F 0x2E6B7124 0x501ADDE6 0x9F84CD87 + 0x7A584718 0x7408DA17 0xBC9F9ABC 0xE94B7D8C + 0xEC7AEC3A 0xDB851DFA 0x63094366 0xC464C3D2 + 0xEF1C1847 0x3215D908 0xDD433B37 0x24C2BA16 + 0x12A14D43 0x2A65C451 0x50940002 0x133AE4DD + 0x71DFF89E 0x10314E55 0x81AC77D6 0x5F11199B + 0x043556F1 0xD7A3C76B 0x3C11183B 0x5924A509 + 0xF28FE6ED 0x97F1FBFA 0x9EBABF2C 0x1E153C6E + 0x86E34570 0xEAE96FB1 0x860E5E0A 0x5A3E2AB3 + 0x771FE71C 0x4E3D06FA 0x2965DCB9 0x99E71D0F + 0x803E89D6 0x5266C825 0x2E4CC978 0x9C10B36A + 0xC6150EBA 0x94E2EA78 0xA5FC3C53 0x1E0A2DF4 + 0xF2F74EA7 0x361D2B3D 0x1939260F 0x19C27960 + 0x5223A708 0xF71312B6 0xEBADFE6E 0xEAC31F66 + 0xE3BC4595 0xA67BC883 0xB17F37D1 0x018CFF28 + 0xC332DDEF 0xBE6C5AA5 0x65582185 0x68AB9802 + 0xEECEA50F 0xDB2F953B 0x2AEF7DAD 0x5B6E2F84 + 0x1521B628 0x29076170 0xECDD4775 0x619F1510 + 0x13CCA830 0xEB61BD96 0x0334FE1E 0xAA0363CF + 0xB5735C90 0x4C70A239 0xD59E9E0B 0xCBAADE14 + 0xEECC86BC 0x60622CA7 0x9CAB5CAB 0xB2F3846E + 0x648B1EAF 0x19BDF0CA 0xA02369B9 0x655ABB50 + 0x40685A32 0x3C2AB4B3 0x319EE9D5 0xC021B8F7 + 0x9B540B19 0x875FA099 0x95F7997E 0x623D7DA8 + 0xF837889A 0x97E32D77 0x11ED935F 0x16681281 + 0x0E358829 0xC7E61FD6 0x96DEDFA1 0x7858BA99 + 0x57F584A5 0x1B227263 0x9B83C3FF 0x1AC24696 + 0xCDB30AEB 0x532E3054 0x8FD948E4 0x6DBC3128 + 0x58EBF2EF 0x34C6FFEA 0xFE28ED61 0xEE7C3C73 + 0x5D4A14D9 0xE864B7E3 0x42105D14 0x203E13E0 + 0x45EEE2B6 0xA3AAABEA 0xDB6C4F15 0xFACB4FD0 + 0xC742F442 0xEF6ABBB5 0x654F3B1D 0x41CD2105 + 0xD81E799E 0x86854DC7 0xE44B476A 0x3D816250 + 0xCF62A1F2 0x5B8D2646 0xFC8883A0 0xC1C7B6A3 + 0x7F1524C3 0x69CB7492 0x47848A0B 0x5692B285 + 0x095BBF00 0xAD19489D 0x1462B174 0x23820E00 + 0x58428D2A 0x0C55F5EA 0x1DADF43E 0x233F7061 + 0x3372F092 0x8D937E41 0xD65FECF1 0x6C223BDB + 0x7CDE3759 0xCBEE7460 0x4085F2A7 0xCE77326E + 0xA6078084 0x19F8509E 0xE8EFD855 0x61D99735 + 0xA969A7AA 0xC50C06C2 0x5A04ABFC 0x800BCADC + 0x9E447A2E 0xC3453484 0xFDD56705 0x0E1E9EC9 + 0xDB73DBD3 0x105588CD 0x675FDA79 0xE3674340 + 0xC5C43465 0x713E38D8 0x3D28F89E 0xF16DFF20 + 0x153E21E7 0x8FB03D4A 0xE6E39F2B 0xDB83ADF7 + 0xE93D5A68 0x948140F7 0xF64C261C 0x94692934 + 0x411520F7 0x7602D4F7 0xBCF46B2E 0xD4A20068 + 0xD4082471 0x3320F46A 0x43B7D4B7 0x500061AF + 0x1E39F62E 0x97244546 0x14214F74 0xBF8B8840 + 0x4D95FC1D 0x96B591AF 0x70F4DDD3 0x66A02F45 + 0xBFBC09EC 0x03BD9785 0x7FAC6DD0 0x31CB8504 + 0x96EB27B3 0x55FD3941 0xDA2547E6 0xABCA0A9A + 0x28507825 0x530429F4 0x0A2C86DA 0xE9B66DFB + 0x68DC1462 0xD7486900 0x680EC0A4 0x27A18DEE + 0x4F3FFEA2 0xE887AD8C 0xB58CE006 0x7AF4D6B6 + 0xAACE1E7C 0xD3375FEC 0xCE78A399 0x406B2A42 + 0x20FE9E35 0xD9F385B9 0xEE39D7AB 0x3B124E8B + 0x1DC9FAF7 0x4B6D1856 0x26A36631 0xEAE397B2 + 0x3A6EFA74 0xDD5B4332 0x6841E7F7 0xCA7820FB + 0xFB0AF54E 0xD8FEB397 0x454056AC 0xBA489527 + 0x55533A3A 0x20838D87 0xFE6BA9B7 0xD096954B + 0x55A867BC 0xA1159A58 0xCCA92963 0x99E1DB33 + 0xA62A4A56 0x3F3125F9 0x5EF47E1C 0x9029317C + 0xFDF8E802 0x04272F70 0x80BB155C 0x05282CE3 + 0x95C11548 0xE4C66D22 0x48C1133F 0xC70F86DC + 0x07F9C9EE 0x41041F0F 0x404779A4 0x5D886E17 + 0x325F51EB 0xD59BC0D1 0xF2BCC18F 0x41113564 + 0x257B7834 0x602A9C60 0xDFF8E8A3 0x1F636C1B + 0x0E12B4C2 0x02E1329E 0xAF664FD1 0xCAD18115 + 0x6B2395E0 0x333E92E1 0x3B240B62 0xEEBEB922 + 0x85B2A20E 0xE6BA0D99 0xDE720C8C 0x2DA2F728 + 0xD0127845 0x95B794FD 0x647D0862 0xE7CCF5F0 + 0x5449A36F 0x877D48FA 0xC39DFD27 0xF33E8D1E + 0x0A476341 0x992EFF74 0x3A6F6EAB 0xF4F8FD37 + 0xA812DC60 0xA1EBDDF8 0x991BE14C 0xDB6E6B0D + 0xC67B5510 0x6D672C37 0x2765D43B 0xDCD0E804 + 0xF1290DC7 0xCC00FFA3 0xB5390F92 0x690FED0B + 0x667B9FFB 0xCEDB7D9C 0xA091CF0B 0xD9155EA3 + 0xBB132F88 0x515BAD24 0x7B9479BF 0x763BD6EB + 0x37392EB3 0xCC115979 0x8026E297 0xF42E312D + 0x6842ADA7 0xC66A2B3B 0x12754CCC 0x782EF11C + 0x6A124237 0xB79251E7 0x06A1BBE6 0x4BFB6350 + 0x1A6B1018 0x11CAEDFA 0x3D25BDD8 0xE2E1C3C9 + 0x44421659 0x0A121386 0xD90CEC6E 0xD5ABEA2A + 0x64AF674E 0xDA86A85F 0xBEBFE988 0x64E4C3FE + 0x9DBC8057 0xF0F7C086 0x60787BF8 0x6003604D + 0xD1FD8346 0xF6381FB0 0x7745AE04 0xD736FCCC + 0x83426B33 0xF01EAB71 0xB0804187 0x3C005E5F + 0x77A057BE 0xBDE8AE24 0x55464299 0xBF582E61 + 0x4E58F48F 0xF2DDFDA2 0xF474EF38 0x8789BDC2 + 0x5366F9C3 0xC8B38E74 0xB475F255 0x46FCD9B9 + 0x7AEB2661 0x8B1DDF84 0x846A0E79 0x915F95E2 + 0x466E598E 0x20B45770 0x8CD55591 0xC902DE4C + 0xB90BACE1 0xBB8205D0 0x11A86248 0x7574A99E + 0xB77F19B6 0xE0A9DC09 0x662D09A1 0xC4324633 + 0xE85A1F02 0x09F0BE8C 0x4A99A025 0x1D6EFE10 + 0x1AB93D1D 0x0BA5A4DF 0xA186F20F 0x2868F169 + 0xDCB7DA83 0x573906FE 0xA1E2CE9B 0x4FCD7F52 + 0x50115E01 0xA70683FA 0xA002B5C4 0x0DE6D027 + 0x9AF88C27 0x773F8641 0xC3604C06 0x61A806B5 + 0xF0177A28 0xC0F586E0 0x006058AA 0x30DC7D62 + 0x11E69ED7 0x2338EA63 0x53C2DD94 0xC2C21634 + 0xBBCBEE56 0x90BCB6DE 0xEBFC7DA1 0xCE591D76 + 0x6F05E409 0x4B7C0188 0x39720A3D 0x7C927C24 + 0x86E3725F 0x724D9DB9 0x1AC15BB4 0xD39EB8FC + 0xED545578 0x08FCA5B5 0xD83D7CD3 0x4DAD0FC4 + 0x1E50EF5E 0xB161E6F8 0xA28514D9 0x6C51133C + 0x6FD5C7E7 0x56E14EC4 0x362ABFCE 0xDDC6C837 + 0xD79A3234 0x92638212 0x670EFA8E 0x406000E0 + 0x3A39CE37 0xD3FAF5CF 0xABC27737 0x5AC52D1B + 0x5CB0679E 0x4FA33742 0xD3822740 0x99BC9BBE + 0xD5118E9D 0xBF0F7315 0xD62D1C7E 0xC700C47B + 0xB78C1B6B 0x21A19045 0xB26EB1BE 0x6A366EB4 + 0x5748AB2F 0xBC946E79 0xC6A376D2 0x6549C2C8 + 0x530FF8EE 0x468DDE7D 0xD5730A1D 0x4CD04DC6 + 0x2939BBDB 0xA9BA4650 0xAC9526E8 0xBE5EE304 + 0xA1FAD5F0 0x6A2D519A 0x63EF8CE2 0x9A86EE22 + 0xC089C2B8 0x43242EF6 0xA51E03AA 0x9CF2D0A4 + 0x83C061BA 0x9BE96A4D 0x8FE51550 0xBA645BD6 + 0x2826A2F9 0xA73A3AE1 0x4BA99586 0xEF5562E9 + 0xC72FEFD3 0xF752F7DA 0x3F046F69 0x77FA0A59 + 0x80E4A915 0x87B08601 0x9B09E6AD 0x3B3EE593 + 0xE990FD5A 0x9E34D797 0x2CF0B7D9 0x022B8B51 + 0x96D5AC3A 0x017DA67D 0xD1CF3ED6 0x7C7D2D28 + 0x1F9F25CF 0xADF2B89B 0x5AD6B472 0x5A88F54C + 0xE029AC71 0xE019A5E6 0x47B0ACFD 0xED93FA9B + 0xE8D3C48D 0x283B57CC 0xF8D56629 0x79132E28 + 0x785F0191 0xED756055 0xF7960E44 0xE3D35E8C + 0x15056DD4 0x88F46DBA 0x03A16125 0x0564F0BD + 0xC3EB9E15 0x3C9057A2 0x97271AEC 0xA93A072A + 0x1B3F6D9B 0x1E6321F5 0xF59C66FB 0x26DCF319 + 0x7533D928 0xB155FDF5 0x03563482 0x8ABA3CBB + 0x28517711 0xC20AD9F8 0xABCC5167 0xCCAD925F + 0x4DE81751 0x3830DC8E 0x379D5862 0x9320F991 + 0xEA7A90C2 0xFB3E7BCE 0x5121CE64 0x774FBE32 + 0xA8B6E37E 0xC3293D46 0x48DE5369 0x6413E680 + 0xA2AE0810 0xDD6DB224 0x69852DFD 0x09072166 + 0xB39A460A 0x6445C0DD 0x586CDECF 0x1C20C8AE + 0x5BBEF7DD 0x1B588D40 0xCCD2017F 0x6BB4E3BB + 0xDDA26A7E 0x3A59FF45 0x3E350A44 0xBCB4CDD5 + 0x72EACEA8 0xFA6484BB 0x8D6612AE 0xBF3C6F47 + 0xD29BE463 0x542F5D9E 0xAEC2771B 0xF64E6370 + 0x740E0D8D 0xE75B1357 0xF8721671 0xAF537D5D + 0x4040CB08 0x4EB4E2CC 0x34D2466A 0x0115AF84 + 0xE1B00428 0x95983A1D 0x06B89FB4 0xCE6EA048 + 0x6F3F3B82 0x3520AB82 0x011A1D4B 0x277227F8 + 0x611560B1 0xE7933FDC 0xBB3A792B 0x344525BD + 0xA08839E1 0x51CE794B 0x2F32C9B7 0xA01FBAC9 + 0xE01CC87E 0xBCC7D1F6 0xCF0111C3 0xA1E8AAC7 + 0x1A908749 0xD44FBD9A 0xD0DADECB 0xD50ADA38 + 0x0339C32A 0xC6913667 0x8DF9317C 0xE0B12B4F + 0xF79E59B7 0x43F5BB3A 0xF2D519FF 0x27D9459C + 0xBF97222C 0x15E6FC2A 0x0F91FC71 0x9B941525 + 0xFAE59361 0xCEB69CEB 0xC2A86459 0x12BAA8D1 + 0xB6C1075E 0xE3056A0C 0x10D25065 0xCB03A442 + 0xE0EC6E0E 0x1698DB3B 0x4C98A0BE 0x3278E964 + 0x9F1F9532 0xE0D392DF 0xD3A0342B 0x8971F21E + 0x1B0A7441 0x4BA3348C 0xC5BE7120 0xC37632D8 + 0xDF359F8D 0x9B992F2E 0xE60B6F47 0x0FE3F11D + 0xE54CDA54 0x1EDAD891 0xCE6279CF 0xCD3E7E6F + 0x1618B166 0xFD2C1D05 0x848FD2C5 0xF6FB2299 + 0xF523F357 0xA6327623 0x93A83531 0x56CCCD02 + 0xACF08162 0x5A75EBB5 0x6E163697 0x88D273CC + 0xDE966292 0x81B949D0 0x4C50901B 0x71C65614 + 0xE6C6C7BD 0x327A140A 0x45E1D006 0xC3F27B9A + 0xC9AA53FD 0x62A80F00 0xBB25BFE2 0x35BDD2F6 + 0x71126905 0xB2040222 0xB6CBCF7C 0xCD769C2B + 0x53113EC0 0x1640E3D3 0x38ABBD60 0x2547ADF0 + 0xBA38209C 0xF746CE76 0x77AFA1C5 0x20756060 + 0x85CBFE4E 0x8AE88DD8 0x7AAAF9B0 0x4CF9AA7E + 0x1948C25C 0x02FB8A8C 0x01C36AE4 0xD6EBE1F9 + 0x90D4F869 0xA65CDEA0 0x3F09252D 0xC208E69F + 0xB74E6132 0xCE77E25B 0x578FDFE3 0x3AC372E6 + } +} + +proc ::blowfish::intEncrypt {P S xl xr} { + for {set i 0} {$i < 16} {incr i} { + set xl [expr {$xl ^ [lindex $P $i]}] + + set S0a [lindex $S [expr { ($xl >> 24) & 0xff}]] + set S1b [lindex $S [expr {(($xl >> 16) & 0xff) + 256}]] + set S2c [lindex $S [expr {(($xl >> 8) & 0xff) + 512}]] + set S3d [lindex $S [expr { ($xl & 0xff) + 768}]] + set xr [expr {(((($S0a + $S1b) ^ $S2c) + $S3d) & 0xffffffff) ^ $xr}] + + set temp $xl ; set xl $xr ; set xr $temp + } + + set temp $xl ; set xl $xr ; set xr $temp + return [list [expr {$xl ^ [lindex $P 17]}] [expr {$xr ^ [lindex $P 16]}]] +} + +proc ::blowfish::intDecrypt {P S xl xr} { + for {set i 17} {$i > 1} {incr i -1} { + set xl [expr {$xl ^ [lindex $P $i]}] + + set S0a [lindex $S [expr { ($xl >> 24) & 0xff}]] + set S1b [lindex $S [expr {(($xl >> 16) & 0xff) + 256}]] + set S2c [lindex $S [expr {(($xl >> 8) & 0xff) + 512}]] + set S3d [lindex $S [expr { ($xl & 0xff) + 768}]] + set xr [expr {(((($S0a + $S1b) ^ $S2c) + $S3d) & 0xffffffff) ^ $xr}] + + set temp $xl ; set xl $xr ; set xr $temp + } + + set temp $xl ; set xl $xr ; set xr $temp + return [list [expr {$xl ^ [lindex $P 0]}] [expr {$xr ^ [lindex $P 1]}]] +} + +proc ::blowfish::Init {mode key iv} { + variable ORIG_S + variable ORIG_P + variable uid + + set S $ORIG_S + set P [list] + + set kl [string length $key] + binary scan $key c* kc + + set j 0 + for {set i 0} {$i < 18} {incr i} { + set data 0 + for {set k 0} {$k < 4} {incr k} { + set data [expr {(($data << 8) | ([lindex $kc $j] & 0xff)) & 0xffffffff}] + if {[incr j] >= $kl} { + set j 0 + } + } + set OPi [lindex $ORIG_P $i] + lappend P [expr {$OPi ^ $data}] + } + + set datal 0 + set datar 0 + + for {set i 0} {$i < 18} {incr i} { + set ed [intEncrypt $P $S $datal $datar] + set datal [lindex $ed 0] + set datar [lindex $ed 1] + set P [lreplace $P $i [incr i] $datal $datar] + } + + for {set i 0} {$i < 4} {incr i} { + for {set j 0} {$j < 256} {incr j 2} { + set ed [intEncrypt $P $S $datal $datar] + set datal [lindex $ed 0] + set datar [lindex $ed 1] + set t [expr {$i * 256 + $j}] + set S [lreplace $S $t [incr t] $datal $datar] + } + } + + set token [namespace current]::[incr uid] + variable $token + upvar #0 $token state + array set state [list P $P S $S M $mode I $iv] + return $token +} + +proc ::blowfish::Reset {token iv} { + upvar #0 $token state + set state(I) $iv + return +} + +proc ::blowfish::Final {token} { + # PRAGMA: nocheck + variable $token + unset $token +} + +proc ::blowfish::EncryptBlock {token block} { + upvar #0 $token state + if {[binary scan $block II xl xr] != 2} { + error "block must be 8 bytes" + } + set xl [expr {$xl & 0xffffffff}] + set xr [expr {$xr & 0xffffffff}] + set d [intEncrypt $state(P) $state(S) $xl $xr] + return [binary format I2 $d] +} + +proc ::blowfish::Encrypt {Key data} { + upvar #0 $Key state + set P $state(P) + set S $state(S) + set cbc_mode [string equal "cbc" $state(M)] + + if {[binary scan $state(I) II s0 s1] != 2} { + return -code error "invalid initialization vector: must be 8 bytes" + } + + set len [string length $data] + if {($len % 8) != 0} { + return -code error "invalid block size: blocks must be 8 bytes" + } + + set s0 [expr {$s0 & 0xffffffff}] + set s1 [expr {$s1 & 0xffffffff}] + + set result "" + for {set i 0} {$i < $len} {incr i 8} { + if {[binary scan $data @[set i]II xl xr] != 2} { + return -code error "oops" + } + if {$cbc_mode} { + 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 +} + +proc ::blowfish::DecryptBlock {Key block} { + upvar #0 $Key state + if {[binary scan $block II xl xr] != 2} { + return -code error "invalid block size: block must be 8 bytes" + } + set xl [expr {$xl & 0xffffffff}] + set xr [expr {$xr & 0xffffffff}] + set d [intDecrypt $state(P) $state(S) $xl $xr] + return [binary format I2 $d] +} + +proc ::blowfish::Decrypt {token data} { + upvar #0 $token state + set P $state(P) + set S $state(S) + set cbc_mode [string equal "cbc" $state(M)] + + if {[binary scan $state(I) II s0 s1] != 2} { + return -code error "initialization vector must be 8 bytes" + } + + set len [string length $data] + if {($len % 8) != 0} { + return -code error "block size invalid" + } + + set s0 [expr {$s0 & 0xffffffff}] + set s1 [expr {$s1 & 0xffffffff}] + + set result "" + for {set i 0} {$i < $len} {incr i 8} { + if {[binary scan $data @[set i]II xl xr] != 2} { + error "oops" + } + set xl [expr {$xl & 0xffffffff}] + set xr [expr {$xr & 0xffffffff}] + set d [intDecrypt $P $S $xl $xr] + if {$cbc_mode} { + set d0 [lindex $d 0] + set d1 [lindex $d 1] + set c0 [expr {$d0 ^ $s0}] + set c1 [expr {$d1 ^ $s1}] + set s0 $xl + set s1 $xr + append result [binary format II $c0 $c1] + } else { + append result [binary format I2 $d] + } + } + if {$cbc_mode} { + set state(I) [binary format II $s0 $s1] + } + return $result +} + + +# ------------------------------------------------------------------------- +# Fileevent handler for chunked file reading. +# +proc ::blowfish::Chunk {Key in {out {}} {chunksize 4096} {pad \0}} { + upvar #0 $Key state + + if {[eof $in]} { + fileevent $in readable {} + set state(reading) 0 + } + + set data [read $in $chunksize] + # FIX ME: we should ony pad after eof + if {[string length $pad] > 0} { + set data [Pad $data 8] + } + + if {$out == {}} { + append state(output) [$state(cmd) $Key $data] + } else { + puts -nonewline $out [$state(cmd) $Key $data] + } +} + +# ------------------------------------------------------------------------- + +# LoadAccelerator -- +# +# This package can make use of a number of compiled extensions to +# accelerate the digest computation. This procedure manages the +# use of these extensions within the package. During normal usage +# this should not be called, but the test package manipulates the +# list of enabled accelerators. +# +proc ::blowfish::LoadAccelerator {name} { + variable accel + set r 0 + switch -exact -- $name { + trf { + if {![catch {package require Trfcrypt}]} { + set block [string repeat \0 8] + set r [expr {![catch {::blowfish -dir enc -mode ecb -key $block $block} msg]}] + } + } + default { + return -code error "invalid accelerator package:\ + must be one of [join [array names accel] {, }]" + } + } + set accel($name) $r +} + +# ------------------------------------------------------------------------- + +proc ::blowfish::Hex {data} { + binary scan $data H* r + return $r +} + +proc ::blowfish::SetOneOf {lst item} { + set ndx [lsearch -glob $lst "${item}*"] + if {$ndx == -1} { + set err [join $lst ", "] + return -code error "invalid mode \"$item\": must be one of $err" + } + return [lindex $lst $ndx] +} + +proc ::blowfish::CheckSize {what size thing} { + if {[string length $thing] != $size} { + return -code error "invalid value for $what: must be $size bytes long" + } + return $thing +} + +proc ::blowfish::CheckPad {char} { + if {[string length $char] > 1} { + return -code error "invalid value: should be a char or empty string" + } + return $char +} + +proc ::blowfish::Pad {data blocksize {fill \0}} { + set len [string length $data] + if {$len == 0} { + set data [string repeat $fill $blocksize] + } elseif {($len % $blocksize) != 0} { + set pad [expr {$blocksize - ($len % $blocksize)}] + append data [string repeat $fill $pad] + } + return $data +} + +# Description: +# Pop the nth element off a list. Used in options processing. +# +proc ::blowfish::Pop {varname {nth 0}} { + upvar $varname args + set r [lindex $args $nth] + set args [lreplace $args $nth $nth] + return $r +} + +proc ::blowfish::blowfish {args} { + variable accel + array set opts {-dir encrypt -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 { + -mode { set opts(-mode) [SetOneOf $modes [Pop args 1]] } + -dir { set opts(-dir) [SetOneOf $dirs [Pop args 1]] } + -iv { set opts(-iv) [CheckSize -iv 8 [Pop args 1]] } + -key { set opts(-key) [Pop args 1] } + -in { set opts(-in) [Pop args 1] } + -out { set opts(-out) [Pop args 1] } + -chunksize { set opts(-chunksize) [Pop args 1] } + -hex { set opts(-hex) 1 } + -pad { set opts(-pad) [CheckPad [Pop args 1]] } + -- { Pop args; break } + default { + if {[string length $opts(-in)] == 0 && [llength $args] == 1} break + set err [join [lsort [array names opts]] ", "] + return -code error "bad option \"$option\":\ + must be one of $err" + } + } + Pop args + } + + if {$opts(-key) == {}} { + return -code error "no key provided: the -key option is required" + } + + set r {} + if {$opts(-in) == {}} { + + if {[llength $args] != 1} { + return -code error "wrong \# args:\ + should be \"blowfish ?options...? -key keydata plaintext\"" + } + + set data [lindex $args 0] + if {[string length $opts(-pad)] > 0} { + set data [Pad [lindex $args 0] 8 $opts(-pad)] + } + if {$accel(trf)} { + set r [::blowfish -dir $opts(-dir) -mode $opts(-mode) \ + -key $opts(-key) -iv $opts(-iv) -- $data] + } else { + set Key [Init $opts(-mode) $opts(-key) $opts(-iv)] + if {[string equal $opts(-dir) "encrypt"]} { + set r [Encrypt $Key $data] + } else { + set r [Decrypt $Key $data] + } + Final $Key + } + + if {$opts(-out) != {}} { + puts -nonewline $opts(-out) $r + set r {} + } + + } else { + + if {[llength $args] != 0} { + return -code error "wrong \# args:\ + should be \"blowfish ?options...? -key keydata -in channel\"" + } + + set Key [Init $opts(-mode) $opts(-key) $opts(-iv)] + upvar $Key state + set state(reading) 1 + if {[string equal $opts(-dir) "encrypt"]} { + set state(cmd) Encrypt + } else { + set state(cmd) Decrypt + } + set state(output) "" + fileevent $opts(-in) readable \ + [list [namespace origin Chunk] \ + $Key $opts(-in) $opts(-out) $opts(-chunksize) $opts(-pad)] + if {[info commands ::tkwait] != {}} { + tkwait variable [subst $Key](reading) + } else { + vwait [subst $Key](reading) + } + if {$opts(-out) == {}} { + set r $state(output) + } + Final $Key + + } + + if {$opts(-hex)} { + set r [Hex $r] + } + return $r +} + +# ------------------------------------------------------------------------- + +# Try and load a compiled extension to help. +namespace eval ::blowfish { + variable e {} + foreach e {trf} { + if {[LoadAccelerator $e]} break + } + unset e +} + +package provide blowfish 1.0.4 + +# ------------------------------------------------------------------------- +# +# Local Variables: +# mode: tcl +# indent-tabs-mode: nil +# End: diff --git a/tcllib/modules/blowfish/blowfish.test b/tcllib/modules/blowfish/blowfish.test new file mode 100644 index 0000000..a09e91d --- /dev/null +++ b/tcllib/modules/blowfish/blowfish.test @@ -0,0 +1,315 @@ +# blowfish.test - Copyright (C) 2004 Pat Thoyts <patthoyts@users.sf.net> +# +# $Id: blowfish.test,v 1.11 2007/09/17 14:19:07 patthoyts Exp $ + +# ------------------------------------------------------------------------- + +source [file join \ + [file dirname [file dirname [file join [pwd] [info script]]]] \ + devtools testutilities.tcl] + +testsNeedTcl 8.2 +testsNeedTcltest 1.0 + +testing { + useLocal blowfish.tcl blowfish +} + +# ------------------------------------------------------------------------- +# Handle multiple implementation testing +# +array set preserve [array get ::blowfish::accel] + +proc implementations {} { + variable ::blowfish::accel + foreach {a v} [array get accel] {if {$v} {lappend r $a}} + lappend r tcl; set r +} + +proc select_implementation {impl} { + variable ::blowfish::accel + foreach e [array names accel] { set accel($e) 0 } + if {[string compare "tcl" $impl] != 0} { + set accel($impl) 1 + } +} + +proc reset_implementation {} { + variable ::blowfish::accel + array set accel [array get ::preserve] +} + +# ------------------------------------------------------------------------- +# Report versions +# +if {[::blowfish::LoadAccelerator trf]} { + puts "> Trf based" +} +puts "> pure Tcl" + +# ------------------------------------------------------------------------- +# Now the package specific tests.... +# ------------------------------------------------------------------------- + +# ------------------------------------------------------------------------- + +#test blowfish-1.0 {blowfish basic command options} { +# list [catch {::blowfish::blowfish} msg] \ +# [string match "wrong # args*" $msg] +# +#} {1 1} + +# ------------------------------------------------------------------------- + +# Test vectors from http://www.schneier.com/code/vectors.txt + +set vectors { + 0000000000000000 0000000000000000 4EF997456198DD78 + FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF 51866FD5B85ECB8A + 3000000000000000 1000000000000001 7D856F9A613063F2 + 1111111111111111 1111111111111111 2466DD878B963C9D + 0123456789ABCDEF 1111111111111111 61F9C3802281B096 + 1111111111111111 0123456789ABCDEF 7D0CC630AFDA1EC7 + 0000000000000000 0000000000000000 4EF997456198DD78 + FEDCBA9876543210 0123456789ABCDEF 0ACEAB0FC6A0A28D + 7CA110454A1A6E57 01A1D6D039776742 59C68245EB05282B + 0131D9619DC1376E 5CD54CA83DEF57DA B1B8CC0B250F09A0 + 07A1133E4A0B2686 0248D43806F67172 1730E5778BEA1DA4 + 3849674C2602319E 51454B582DDF440A A25E7856CF2651EB + 04B915BA43FEB5B6 42FD443059577FA2 353882B109CE8F1A + 0113B970FD34F2CE 059B5E0851CF143A 48F4D0884C379918 + 0170F175468FB5E6 0756D8E0774761D2 432193B78951FC98 + 43297FAD38E373FE 762514B829BF486A 13F04154D69D1AE5 + 07A7137045DA2A16 3BDD119049372802 2EEDDA93FFD39C79 + 04689104C2FD3B2F 26955F6835AF609A D887E0393C2DA6E3 + 37D06BB516CB7546 164D5E404F275232 5F99D04F5B163969 + 1F08260D1AC2465E 6B056E18759F5CCA 4A057A3B24D3977B + 584023641ABA6176 004BD6EF09176062 452031C1E4FADA8E + 025816164629B007 480D39006EE762F2 7555AE39F59B87BD + 49793EBC79B3258F 437540C8698F3CFA 53C55F9CB49FC019 + 4FB05E1515AB73A7 072D43A077075292 7A8E7BFA937E89A3 + 49E95D6D4CA229BF 02FE55778117F12A CF9C5D7A4986ADB5 + 018310DC409B26D6 1D9D5C5018F728C2 D1ABB290658BC778 + 1C587F1C13924FEF 305532286D6F295A 55CB3774D13EF201 + 0101010101010101 0123456789ABCDEF FA34EC4847B268B2 + 1F1F1F1F0E0E0E0E 0123456789ABCDEF A790795108EA3CAE + E0FEE0FEF1FEF1FE 0123456789ABCDEF C39E072D9FAC631D + 0000000000000000 FFFFFFFFFFFFFFFF 014933E0CDAFF6E4 + FFFFFFFFFFFFFFFF 0000000000000000 F21E9A77B71C49BC + 0123456789ABCDEF 0000000000000000 245946885754369A + FEDCBA9876543210 FFFFFFFFFFFFFFFF 6B5C5A9C5D9E0A5A +} + +set n 0 +foreach impl [implementations] { + select_implementation $impl + foreach {key plain cipher} $vectors { + test blowfish-$impl-2.$n "blowfish ecb test vector $n (impl $impl)" { + list [catch { + string toupper \ + [::blowfish::Hex \ + [::blowfish::blowfish -mode ecb -dir enc \ + -key [binary format H* $key] \ + [binary format H* $plain]]] + } msg] $msg + } [list 0 $cipher] + incr n + } + reset_implementation +} + +set vectors { + F9AD597C49DB005E F0 + E91D21C1D961A6D6 F0E1 + E9C2B70A1BC65CF3 F0E1D2 + BE1E639408640F05 F0E1D2C3 + B39E44481BDB1E6E F0E1D2C3B4 + 9457AA83B1928C0D F0E1D2C3B4A5 + 8BB77032F960629D F0E1D2C3B4A596 + E87A244E2CC85E82 F0E1D2C3B4A59687 + 15750E7A4F4EC577 F0E1D2C3B4A5968778 + 122BA70B3AB64AE0 F0E1D2C3B4A596877869 + 3A833C9AFFC537F6 F0E1D2C3B4A5968778695A + 9409DA87A90F6BF2 F0E1D2C3B4A5968778695A4B + 884F80625060B8B4 F0E1D2C3B4A5968778695A4B3C + 1F85031C19E11968 F0E1D2C3B4A5968778695A4B3C2D + 79D9373A714CA34F F0E1D2C3B4A5968778695A4B3C2D1E + 93142887EE3BE15C F0E1D2C3B4A5968778695A4B3C2D1E0F + 03429E838CE2D14B F0E1D2C3B4A5968778695A4B3C2D1E0F00 + A4299E27469FF67B F0E1D2C3B4A5968778695A4B3C2D1E0F0011 + AFD5AED1C1BC96A8 F0E1D2C3B4A5968778695A4B3C2D1E0F001122 + 10851C0E3858DA9F F0E1D2C3B4A5968778695A4B3C2D1E0F00112233 + E6F51ED79B9DB21F F0E1D2C3B4A5968778695A4B3C2D1E0F0011223344 + 64A6E14AFD36B46F F0E1D2C3B4A5968778695A4B3C2D1E0F001122334455 + 80C7D7D45A5479AD F0E1D2C3B4A5968778695A4B3C2D1E0F00112233445566 + 05044B62FA52D080 F0E1D2C3B4A5968778695A4B3C2D1E0F0011223344556677 +} + +set plain [binary format H* FEDCBA9876543210] +foreach impl [implementations] { + select_implementation $impl + set n 0 + foreach {cipher key} $vectors { + test blowfish-$impl-4.$n "blowfish ecb test variable length key (impl $impl)" { + list [catch { + string toupper \ + [::blowfish::Hex \ + [::blowfish::blowfish \ + -mode ecb \ + -dir enc \ + -key [binary format H* $key] \ + $plain]] + } msg] $msg + } [list 0 $cipher] + incr n + } + reset_implementation +} + +set key [binary format H* 0123456789ABCDEFF0E1D2C3B4A59687] +set iv [binary format H* FEDCBA9876543210] +set plain [binary format H* \ + 37363534333231204E6F77206973207468652074696D6520666F722000000000] + +foreach impl [implementations] { + select_implementation $impl + test blowfish-$impl-6.1 "blowfish cbc mode (impl $impl)" { + list [catch { + string toupper \ + [::blowfish::Hex \ + [::blowfish::blowfish \ + -dir enc \ + -mode cbc \ + -iv $iv \ + -key $key \ + $plain]] + } msg] $msg + } [list 0 \ + 6B77B4D63006DEE605B156E27403979358DEB9E7154616D959F1652BD5FF92CC] + reset_implementation +} + +#cfb E73214A2822139CAF26ECF6D2EB9E76E3DA3DE04D1517200519D57A6C3 +#ofb E73214A2822139CA62B343CC5B65587310DD908D0C241B2263C2CF80DA + +foreach impl [implementations] { + select_implementation $impl + + test blowfish-$impl-7.1 {test reset of initialization vector on cbc mode} { + list [catch { + set iv [string repeat \x00 8] + set pt "01234567abcdefgh01234567" + set tok [blowfish::Init cbc secret $iv] + set ct1 [blowfish::Encrypt $tok $pt] + blowfish::Reset $tok $iv + set ct2 [blowfish::Encrypt $tok $pt] + blowfish::Final $tok + string equal $ct1 $ct2 + } msg] $msg + } {0 1} + + test blowfish-$impl-7.2 {test reset of initialization vector on cbc mode} { + list [catch { + set pt "01234567abcdefgh01234567" + set tok [blowfish::Init cbc secret [string repeat \x00 8]] + set ct1 [blowfish::Encrypt $tok $pt] + blowfish::Reset $tok [string repeat \x01 8] + set ct2 [blowfish::Encrypt $tok $pt] + blowfish::Final $tok + string equal $ct1 $ct2 + } msg] $msg + } {0 0} + + test blowfish-$impl-8.0 {check hyphen in crypt data} { + list [catch { + set key "uP/AD/oGb6q/" + set text "ececho cleardata" + set cipher [blowfish::blowfish -mode ecb -key $key -dir encrypt $text] + set plain [blowfish::blowfish -mode ecb -key $key -dir decrypt $cipher] + string compare $plain $text + } msg] $msg + } {0 0} + + test blowfish-$impl-8.1 {check hyphen in plaintext} { + list [catch { + set key "uP/AD/oGb6q/" + set text "-cecho cleardata" + set cipher [blowfish::blowfish -mode ecb -key $key -dir encrypt $text] + set plain [blowfish::blowfish -mode ecb -key $key -dir decrypt $cipher] + string compare $plain $text + } msg] $msg + } {0 0} + + test blowfish-$impl-8.2 {check hyphen in key} { + list [catch { + set key "-P/AD/oGb6q/" + set text "ececho cleardata" + set cipher [blowfish::blowfish -mode ecb -key $key -dir encrypt $text] + set plain [blowfish::blowfish -mode ecb -key $key -dir decrypt $cipher] + string compare $plain $text + } msg] $msg + } {0 0} + + test blowfish-$impl-8.3 {check option termination} { + list [catch { + set key "uP/AD/oGb6q/" + set text "ececho cleardata" + set cipher [blowfish::blowfish -mode ecb -key $key -dir encrypt -- $text] + set plain [blowfish::blowfish -mode ecb -key $key -dir decrypt -- $cipher] + string compare $plain $text + } msg] $msg + } {0 0} + + test blowfish-$impl-9.0 {check -pad option} { + list [catch { + set key "uP/AD/oGb6q/" + set text "01234" + set cipher [blowfish::blowfish -mode ecb -hex -key $key \ + -dir encrypt -pad a -- $text] + } msg] $msg + } {0 8927243c2d7d568c} + + test blowfish-$impl-9.1 {check -pad option} { + list [catch { + set key "uP/AD/oGb6q/" + set text "01234" + set cipher [blowfish::blowfish -mode ecb -hex -key $key \ + -dir encrypt -pad { } -- $text] + } msg] $msg + } {0 3fc711286b8eca79} + + test blowfish-$impl-9.2 {check -pad option} { + list [catch { + set key "uP/AD/oGb6q/" + set text "01234" + set cipher [blowfish::blowfish -mode ecb -hex -key $key \ + -dir encrypt -pad "" -- $text] + } msg] \ + [expr { + [string equal $msg \ + {invalid block size: blocks must be 8 bytes}] \ + || [string equal $msg \ + {can not encrypt incomplete block at end of input}]}] + } {1 1} + + test blowfish-$impl-9.3 {check -dir option default is encrypt} { + list [catch { + set key "04B915BA43FEB5B6" + set text "42FD443059577FA2" + set cipher [blowfish::blowfish -mode ecb -pad "" -hex\ + -key [binary format H* $key]\ + -- [binary format H* $text]] + } msg] $msg + } {0 353882b109ce8f1a} + + reset_implementation +} + +# ------------------------------------------------------------------------- + +testsuiteCleanup + +# Local variables: +# mode: tcl +# indent-tabs-mode: nil +# End: diff --git a/tcllib/modules/blowfish/pkgIndex.tcl b/tcllib/modules/blowfish/pkgIndex.tcl new file mode 100644 index 0000000..d9db123 --- /dev/null +++ b/tcllib/modules/blowfish/pkgIndex.tcl @@ -0,0 +1,5 @@ +if {![package vsatisfies [package provide Tcl] 8.2]} { + # PRAGMA: returnok + return +} +package ifneeded blowfish 1.0.4 [list source [file join $dir blowfish.tcl]] |