From 7aff1e4cb053394db57c2814d5fe1e6493e0cc75 Mon Sep 17 00:00:00 2001 From: watcherhd Date: Sat, 26 Nov 2011 14:19:43 +0000 Subject: Project folders rename part 2 git-svn-id: http://miranda-plugins.googlecode.com/svn/trunk@214 e753b5eb-9565-29b2-b5c5-2cc6f99dfbcb --- CryptoPP/!whatsnew.txt | 34 + CryptoPP/GPGw/GnuPGw.dep | 141 + CryptoPP/GPGw/GnuPGw.dsp | 158 + CryptoPP/GPGw/GnuPGw.mak | 191 + CryptoPP/GPGw/Release/GnuPGw.dll | Bin 0 -> 13824 bytes CryptoPP/GPGw/Release/GnuPGw.map | 259 ++ CryptoPP/GPGw/commonheaders.c | 42 + CryptoPP/GPGw/commonheaders.h | 79 + CryptoPP/GPGw/gnupgw.dsw | 29 + CryptoPP/GPGw/gpg.c | 366 ++ CryptoPP/GPGw/gpg.h | 40 + CryptoPP/GPGw/gpgw.msp | 110 + CryptoPP/GPGw/keys.c | 67 + CryptoPP/GPGw/keys.h | 13 + CryptoPP/GPGw/language.c | 27 + CryptoPP/GPGw/language.h | 29 + CryptoPP/GPGw/main.c | 369 ++ CryptoPP/GPGw/passdialog.c | 29 + CryptoPP/GPGw/passdialog.h | 8 + CryptoPP/GPGw/passphrases.c | 50 + CryptoPP/GPGw/passphrases.h | 10 + CryptoPP/GPGw/pipeexec.c | 134 + CryptoPP/GPGw/pipeexec.h | 24 + CryptoPP/GPGw/resource.h | 21 + CryptoPP/GPGw/resource.rc | 112 + CryptoPP/GPGw/size.h | 21 + CryptoPP/GPGw/tools.c | 191 + CryptoPP/GPGw/tools.h | 25 + CryptoPP/GPGw/userdialog.c | 81 + CryptoPP/GPGw/userdialog.h | 6 + CryptoPP/PGPw/PGPsdkW.dep | 43 + CryptoPP/PGPw/PGPsdkW.dsp | 122 + CryptoPP/PGPw/PGPsdkW.dsw | 29 + CryptoPP/PGPw/PGPsdkW.mak | 220 + CryptoPP/PGPw/Release6/PGPsdkW6.dll | Bin 0 -> 8192 bytes CryptoPP/PGPw/Release6/PGPsdkW6.map | 213 + CryptoPP/PGPw/Release8/PGPsdkW8.dll | Bin 0 -> 8192 bytes CryptoPP/PGPw/Release8/PGPsdkW8.map | 216 + CryptoPP/PGPw/commonheaders.cpp | 5 + CryptoPP/PGPw/commonheaders.h | 64 + CryptoPP/PGPw/main.cpp | 584 +++ CryptoPP/PGPw/sdk6/include/pgpBase.h | 270 ++ CryptoPP/PGPw/sdk6/include/pgpBigNum.h | 208 + CryptoPP/PGPw/sdk6/include/pgpCBC.h | 93 + CryptoPP/PGPw/sdk6/include/pgpCFB.h | 127 + CryptoPP/PGPw/sdk6/include/pgpConfig.h | 96 + CryptoPP/PGPw/sdk6/include/pgpEncode.h | 301 ++ CryptoPP/PGPw/sdk6/include/pgpErrors.h | 305 ++ CryptoPP/PGPw/sdk6/include/pgpFeatures.h | 176 + CryptoPP/PGPw/sdk6/include/pgpGroups.h | 322 ++ CryptoPP/PGPw/sdk6/include/pgpHMAC.h | 75 + CryptoPP/PGPw/sdk6/include/pgpHash.h | 95 + CryptoPP/PGPw/sdk6/include/pgpKeyServer.h | 360 ++ CryptoPP/PGPw/sdk6/include/pgpKeys.h | 879 ++++ CryptoPP/PGPw/sdk6/include/pgpMemoryMgr.h | 235 ++ CryptoPP/PGPw/sdk6/include/pgpOptionList.h | 452 ++ CryptoPP/PGPw/sdk6/include/pgpPFLConfig.h | 51 + CryptoPP/PGPw/sdk6/include/pgpPFLErrors.h | 97 + CryptoPP/PGPw/sdk6/include/pgpPubTypes.h | 276 ++ CryptoPP/PGPw/sdk6/include/pgpPublicKey.h | 213 + CryptoPP/PGPw/sdk6/include/pgpRandomPool.h | 49 + CryptoPP/PGPw/sdk6/include/pgpSDKPrefs.h | 74 + CryptoPP/PGPw/sdk6/include/pgpSockets.h | 476 +++ CryptoPP/PGPw/sdk6/include/pgpSymmetricCipher.h | 122 + CryptoPP/PGPw/sdk6/include/pgpTLS.h | 316 ++ CryptoPP/PGPw/sdk6/include/pgpUserInterface.h | 290 ++ CryptoPP/PGPw/sdk6/include/pgpUtilities.h | 231 ++ CryptoPP/PGPw/sdk6/lib/PGP_SDK.lib | Bin 0 -> 99772 bytes CryptoPP/PGPw/sdk6/lib/PGPsdkNL.lib | Bin 0 -> 28718 bytes CryptoPP/PGPw/sdk6/lib/PGPsdkUI.lib | Bin 0 -> 11824 bytes CryptoPP/PGPw/sdk8/include/pflTypes.h | 52 + CryptoPP/PGPw/sdk8/include/pgpAPIAdapter.h | 186 + CryptoPP/PGPw/sdk8/include/pgpBER.h | 175 + CryptoPP/PGPw/sdk8/include/pgpBase.h | 451 ++ CryptoPP/PGPw/sdk8/include/pgpBigNum.h | 177 + CryptoPP/PGPw/sdk8/include/pgpCBC.h | 82 + CryptoPP/PGPw/sdk8/include/pgpCFB.h | 115 + CryptoPP/PGPw/sdk8/include/pgpConfig.h | 96 + CryptoPP/PGPw/sdk8/include/pgpEC.h | 78 + CryptoPP/PGPw/sdk8/include/pgpEncode.h | 306 ++ CryptoPP/PGPw/sdk8/include/pgpErrors.h | 393 ++ CryptoPP/PGPw/sdk8/include/pgpFeatures.h | 143 + CryptoPP/PGPw/sdk8/include/pgpGroups.h | 315 ++ CryptoPP/PGPw/sdk8/include/pgpHMAC.h | 67 + CryptoPP/PGPw/sdk8/include/pgpHash.h | 86 + CryptoPP/PGPw/sdk8/include/pgpHashWords.h | 40 + CryptoPP/PGPw/sdk8/include/pgpIKE.h | 784 ++++ CryptoPP/PGPw/sdk8/include/pgpKeyServer.h | 339 ++ CryptoPP/PGPw/sdk8/include/pgpKeys.h | 831 ++++ CryptoPP/PGPw/sdk8/include/pgpLDAP.h | 722 ++++ CryptoPP/PGPw/sdk8/include/pgpMemoryMgr.h | 220 + CryptoPP/PGPw/sdk8/include/pgpOptionList.h | 542 +++ CryptoPP/PGPw/sdk8/include/pgpPFLConfig.h | 52 + CryptoPP/PGPw/sdk8/include/pgpPFLErrors.h | 116 + CryptoPP/PGPw/sdk8/include/pgpPubTypes.h | 350 ++ CryptoPP/PGPw/sdk8/include/pgpPublicKey.h | 207 + CryptoPP/PGPw/sdk8/include/pgpRandomPool.h | 46 + CryptoPP/PGPw/sdk8/include/pgpReconstruct.h | 117 + CryptoPP/PGPw/sdk8/include/pgpSECSH.h | 308 ++ CryptoPP/PGPw/sdk8/include/pgpSKEP.h | 120 + CryptoPP/PGPw/sdk8/include/pgpShare.h | 80 + CryptoPP/PGPw/sdk8/include/pgpShareFile.h | 95 + CryptoPP/PGPw/sdk8/include/pgpSockets.h | 464 +++ CryptoPP/PGPw/sdk8/include/pgpSymmetricCipher.h | 114 + CryptoPP/PGPw/sdk8/include/pgpTLS.h | 336 ++ CryptoPP/PGPw/sdk8/include/pgpUserInterface.h | 284 ++ CryptoPP/PGPw/sdk8/include/pgpUtilities.h | 464 +++ CryptoPP/PGPw/sdk8/lib/PGPsdk.lib | Bin 0 -> 151794 bytes CryptoPP/PGPw/sdk8/lib/PGPsdkNL.lib | Bin 0 -> 50356 bytes CryptoPP/PGPw/sdk8/lib/PGPsdkUI.lib | Bin 0 -> 14694 bytes CryptoPP/base16.cpp | 64 + CryptoPP/base16.h | 53 + CryptoPP/base64.cpp | 96 + CryptoPP/base64.h | 58 + CryptoPP/commonheaders.cpp | 125 + CryptoPP/commonheaders.h | 200 + CryptoPP/cpp_cntx.cpp | 184 + CryptoPP/cpp_gpgw.cpp | 334 ++ CryptoPP/cpp_gzip.cpp | 57 + CryptoPP/cpp_keys.cpp | 199 + CryptoPP/cpp_misc.cpp | 97 + CryptoPP/cpp_pgpw.cpp | 324 ++ CryptoPP/cpp_rsam.cpp | 1074 +++++ CryptoPP/cpp_rsam.h | 45 + CryptoPP/cpp_rsau.cpp | 258 ++ CryptoPP/cpp_rsau.h | 101 + CryptoPP/cpp_svcs.cpp | 345 ++ CryptoPP/crypto/3desval.dat | 3 + CryptoPP/crypto/3way.cpp | 139 + CryptoPP/crypto/3way.h | 53 + CryptoPP/crypto/3wayval.dat | 5 + CryptoPP/crypto/Doxyfile | 1147 ++++++ CryptoPP/crypto/GNUmakefile | 158 + CryptoPP/crypto/License.txt | 68 + CryptoPP/crypto/Readme.txt | 414 ++ CryptoPP/crypto/adhoc.cpp | 17 + CryptoPP/crypto/adhoc.cpp.copied | 1 + CryptoPP/crypto/adhoc.cpp.proto | 17 + CryptoPP/crypto/adler32.cpp | 77 + CryptoPP/crypto/adler32.h | 27 + CryptoPP/crypto/aes.h | 16 + CryptoPP/crypto/algebra.cpp | 340 ++ CryptoPP/crypto/algebra.h | 285 ++ CryptoPP/crypto/algparam.cpp | 42 + CryptoPP/crypto/algparam.h | 360 ++ CryptoPP/crypto/arc4.cpp | 120 + CryptoPP/crypto/arc4.h | 71 + CryptoPP/crypto/argnames.h | 76 + CryptoPP/crypto/asn.cpp | 595 +++ CryptoPP/crypto/asn.h | 369 ++ CryptoPP/crypto/base32.cpp | 39 + CryptoPP/crypto/base32.h | 38 + CryptoPP/crypto/base64.cpp | 42 + CryptoPP/crypto/base64.h | 36 + CryptoPP/crypto/basecode.cpp | 238 ++ CryptoPP/crypto/basecode.h | 86 + CryptoPP/crypto/bench.cpp | 344 ++ CryptoPP/crypto/bench.h | 11 + CryptoPP/crypto/bench2.cpp | 327 ++ CryptoPP/crypto/bfinit.cpp | 277 ++ CryptoPP/crypto/blowfish.cpp | 99 + CryptoPP/crypto/blowfish.h | 46 + CryptoPP/crypto/blumshub.cpp | 63 + CryptoPP/crypto/blumshub.h | 53 + CryptoPP/crypto/camellia.cpp | 537 +++ CryptoPP/crypto/camellia.dat | 45 + CryptoPP/crypto/camellia.h | 48 + CryptoPP/crypto/cast.cpp | 296 ++ CryptoPP/crypto/cast.h | 91 + CryptoPP/crypto/cast128v.dat | 11 + CryptoPP/crypto/cast256v.dat | 11 + CryptoPP/crypto/casts.cpp | 545 +++ CryptoPP/crypto/cbcmac.cpp | 63 + CryptoPP/crypto/cbcmac.h | 51 + CryptoPP/crypto/channels.cpp | 309 ++ CryptoPP/crypto/channels.h | 123 + CryptoPP/crypto/config.h | 454 ++ CryptoPP/crypto/cpu.cpp | 199 + CryptoPP/crypto/cpu.h | 260 ++ CryptoPP/crypto/crc.cpp | 160 + CryptoPP/crypto/crc.h | 41 + CryptoPP/crypto/cryptdll.dsp | 561 +++ CryptoPP/crypto/cryptest.dsp | 431 ++ CryptoPP/crypto/cryptest.dsw | 74 + CryptoPP/crypto/cryptlib.cpp | 721 ++++ CryptoPP/crypto/cryptlib.dep | 1968 +++++++++ CryptoPP/crypto/cryptlib.dsp | 1155 ++++++ CryptoPP/crypto/cryptlib.h | 1608 ++++++++ CryptoPP/crypto/cryptlib.mak | 1942 +++++++++ CryptoPP/crypto/cryptlib_9.vcproj | 5012 +++++++++++++++++++++++ CryptoPP/crypto/cryptlib_bds.cpp | 10 + CryptoPP/crypto/crypto54msvc6.patch | 241 ++ CryptoPP/crypto/cryptopp.rc | 104 + CryptoPP/crypto/datatest.cpp | 564 +++ CryptoPP/crypto/default.cpp | 258 ++ CryptoPP/crypto/default.h | 104 + CryptoPP/crypto/des.cpp | 449 ++ CryptoPP/crypto/des.h | 144 + CryptoPP/crypto/descert.dat | 171 + CryptoPP/crypto/dessp.cpp | 95 + CryptoPP/crypto/dh.cpp | 19 + CryptoPP/crypto/dh.h | 99 + CryptoPP/crypto/dh1024.dat | 1 + CryptoPP/crypto/dh2.cpp | 22 + CryptoPP/crypto/dh2.h | 58 + CryptoPP/crypto/dh2048.dat | 1 + CryptoPP/crypto/dlie1024.dat | 1 + CryptoPP/crypto/dlie2048.dat | 1 + CryptoPP/crypto/dll.cpp | 146 + CryptoPP/crypto/dll.h | 68 + CryptoPP/crypto/dlltest.cpp | 206 + CryptoPP/crypto/dlltest.dsp | 90 + CryptoPP/crypto/dmac.h | 91 + CryptoPP/crypto/dsa.cpp | 119 + CryptoPP/crypto/dsa.h | 35 + CryptoPP/crypto/dsa1024.dat | 1 + CryptoPP/crypto/dsa1024b.dat | 1 + CryptoPP/crypto/dsa512.dat | 1 + CryptoPP/crypto/ec2n.cpp | 288 ++ CryptoPP/crypto/ec2n.h | 113 + CryptoPP/crypto/eccrypto.cpp | 650 +++ CryptoPP/crypto/eccrypto.h | 280 ++ CryptoPP/crypto/ecp.cpp | 473 +++ CryptoPP/crypto/ecp.h | 126 + CryptoPP/crypto/elgamal.cpp | 17 + CryptoPP/crypto/elgamal.h | 121 + CryptoPP/crypto/elgc1024.dat | 1 + CryptoPP/crypto/emsa2.cpp | 34 + CryptoPP/crypto/emsa2.h | 86 + CryptoPP/crypto/eprecomp.cpp | 117 + CryptoPP/crypto/eprecomp.h | 73 + CryptoPP/crypto/esig1023.dat | 1 + CryptoPP/crypto/esig1536.dat | 1 + CryptoPP/crypto/esig2046.dat | 1 + CryptoPP/crypto/esign.cpp | 210 + CryptoPP/crypto/esign.h | 128 + CryptoPP/crypto/factory.h | 128 + CryptoPP/crypto/files.cpp | 212 + CryptoPP/crypto/files.h | 97 + CryptoPP/crypto/filters.cpp | 999 +++++ CryptoPP/crypto/filters.h | 761 ++++ CryptoPP/crypto/fips140.cpp | 84 + CryptoPP/crypto/fips140.h | 59 + CryptoPP/crypto/fipsalgt.cpp | 1290 ++++++ CryptoPP/crypto/fipstest.cpp | 616 +++ CryptoPP/crypto/fltrimpl.h | 64 + CryptoPP/crypto/gf256.cpp | 34 + CryptoPP/crypto/gf256.h | 66 + CryptoPP/crypto/gf2_32.cpp | 99 + CryptoPP/crypto/gf2_32.h | 66 + CryptoPP/crypto/gf2n.cpp | 879 ++++ CryptoPP/crypto/gf2n.h | 367 ++ CryptoPP/crypto/gfpcrypt.cpp | 275 ++ CryptoPP/crypto/gfpcrypt.h | 536 +++ CryptoPP/crypto/gost.cpp | 123 + CryptoPP/crypto/gost.h | 58 + CryptoPP/crypto/gostval.dat | 23 + CryptoPP/crypto/gzip.cpp | 99 + CryptoPP/crypto/gzip.h | 65 + CryptoPP/crypto/haval.cpp | 276 ++ CryptoPP/crypto/haval.h | 63 + CryptoPP/crypto/havalcer.dat | 23 + CryptoPP/crypto/hex.cpp | 44 + CryptoPP/crypto/hex.h | 36 + CryptoPP/crypto/hmac.cpp | 86 + CryptoPP/crypto/hmac.h | 61 + CryptoPP/crypto/hrtimer.cpp | 139 + CryptoPP/crypto/hrtimer.h | 65 + CryptoPP/crypto/ida.cpp | 421 ++ CryptoPP/crypto/ida.h | 152 + CryptoPP/crypto/idea.cpp | 192 + CryptoPP/crypto/idea.h | 61 + CryptoPP/crypto/ideaval.dat | 11 + CryptoPP/crypto/integer.cpp | 4237 +++++++++++++++++++ CryptoPP/crypto/integer.h | 418 ++ CryptoPP/crypto/iterhash.cpp | 150 + CryptoPP/crypto/iterhash.h | 114 + CryptoPP/crypto/lubyrack.h | 141 + CryptoPP/crypto/luc.cpp | 210 + CryptoPP/crypto/luc.h | 236 ++ CryptoPP/crypto/luc1024.dat | 1 + CryptoPP/crypto/luc2048.dat | 1 + CryptoPP/crypto/lucc1024.dat | 1 + CryptoPP/crypto/lucc512.dat | 1 + CryptoPP/crypto/lucd1024.dat | 4 + CryptoPP/crypto/lucd512.dat | 2 + CryptoPP/crypto/lucs1024.dat | 1 + CryptoPP/crypto/lucs512.dat | 1 + CryptoPP/crypto/mars.cpp | 210 + CryptoPP/crypto/mars.h | 54 + CryptoPP/crypto/marss.cpp | 139 + CryptoPP/crypto/marsval.dat | 9 + CryptoPP/crypto/md2.cpp | 120 + CryptoPP/crypto/md2.h | 46 + CryptoPP/crypto/md4.cpp | 110 + CryptoPP/crypto/md4.h | 35 + CryptoPP/crypto/md5.cpp | 118 + CryptoPP/crypto/md5.h | 33 + CryptoPP/crypto/md5mac.cpp | 166 + CryptoPP/crypto/md5mac.h | 38 + CryptoPP/crypto/mdc.h | 72 + CryptoPP/crypto/misc.cpp | 98 + CryptoPP/crypto/misc.h | 1119 +++++ CryptoPP/crypto/modarith.h | 158 + CryptoPP/crypto/modes.cpp | 209 + CryptoPP/crypto/modes.h | 451 ++ CryptoPP/crypto/modexppc.h | 34 + CryptoPP/crypto/mqueue.cpp | 174 + CryptoPP/crypto/mqueue.h | 98 + CryptoPP/crypto/mqv.cpp | 13 + CryptoPP/crypto/mqv.h | 141 + CryptoPP/crypto/mqv1024.dat | 1 + CryptoPP/crypto/mqv2048.dat | 1 + CryptoPP/crypto/nbtheory.cpp | 1134 +++++ CryptoPP/crypto/nbtheory.h | 137 + CryptoPP/crypto/network.cpp | 550 +++ CryptoPP/crypto/network.h | 235 ++ CryptoPP/crypto/nr.h | 6 + CryptoPP/crypto/nr1024.dat | 1 + CryptoPP/crypto/nr2048.dat | 1 + CryptoPP/crypto/oaep.cpp | 97 + CryptoPP/crypto/oaep.h | 42 + CryptoPP/crypto/oids.h | 112 + CryptoPP/crypto/osrng.cpp | 171 + CryptoPP/crypto/osrng.h | 153 + CryptoPP/crypto/panama.cpp | 505 +++ CryptoPP/crypto/panama.h | 144 + CryptoPP/crypto/pch.cpp | 1 + CryptoPP/crypto/pch.h | 21 + CryptoPP/crypto/pkcspad.cpp | 124 + CryptoPP/crypto/pkcspad.h | 94 + CryptoPP/crypto/polynomi.cpp | 577 +++ CryptoPP/crypto/polynomi.h | 459 +++ CryptoPP/crypto/pssr.cpp | 145 + CryptoPP/crypto/pssr.h | 66 + CryptoPP/crypto/pubkey.cpp | 157 + CryptoPP/crypto/pubkey.h | 1678 ++++++++ CryptoPP/crypto/pwdbased.h | 213 + CryptoPP/crypto/queue.cpp | 564 +++ CryptoPP/crypto/queue.h | 141 + CryptoPP/crypto/rabi1024.dat | 1 + CryptoPP/crypto/rabi2048.dat | 1 + CryptoPP/crypto/rabin.cpp | 221 + CryptoPP/crypto/rabin.h | 107 + CryptoPP/crypto/randpool.cpp | 61 + CryptoPP/crypto/randpool.h | 33 + CryptoPP/crypto/rc2.cpp | 118 + CryptoPP/crypto/rc2.h | 72 + CryptoPP/crypto/rc2val.dat | 48 + CryptoPP/crypto/rc5.cpp | 79 + CryptoPP/crypto/rc5.h | 54 + CryptoPP/crypto/rc5val.dat | 5 + CryptoPP/crypto/rc6.cpp | 96 + CryptoPP/crypto/rc6.h | 54 + CryptoPP/crypto/rc6val.dat | 17 + CryptoPP/crypto/rdtables.cpp | 697 ++++ CryptoPP/crypto/regtest.cpp | 89 + CryptoPP/crypto/resource.h | 15 + CryptoPP/crypto/rijndael.cpp | 722 ++++ CryptoPP/crypto/rijndael.dat | 9 + CryptoPP/crypto/rijndael.h | 61 + CryptoPP/crypto/ripemd.cpp | 803 ++++ CryptoPP/crypto/ripemd.h | 49 + CryptoPP/crypto/rng.cpp | 155 + CryptoPP/crypto/rng.h | 77 + CryptoPP/crypto/rsa.cpp | 304 ++ CryptoPP/crypto/rsa.h | 174 + CryptoPP/crypto/rsa1024.dat | 32 + CryptoPP/crypto/rsa2048.dat | 61 + CryptoPP/crypto/rsa400pb.dat | 10 + CryptoPP/crypto/rsa400pv.dat | 41 + CryptoPP/crypto/rsa512a.dat | 35 + CryptoPP/crypto/rw.cpp | 196 + CryptoPP/crypto/rw.h | 92 + CryptoPP/crypto/rw1024.dat | 1 + CryptoPP/crypto/rw2048.dat | 1 + CryptoPP/crypto/safer.cpp | 153 + CryptoPP/crypto/safer.h | 86 + CryptoPP/crypto/saferval.dat | 16 + CryptoPP/crypto/salsa.cpp | 564 +++ CryptoPP/crypto/salsa.h | 43 + CryptoPP/crypto/seal.cpp | 217 + CryptoPP/crypto/seal.h | 44 + CryptoPP/crypto/secblock.h | 500 +++ CryptoPP/crypto/seckey.h | 211 + CryptoPP/crypto/serpent.cpp | 123 + CryptoPP/crypto/serpent.h | 52 + CryptoPP/crypto/serpentp.h | 434 ++ CryptoPP/crypto/serpentv.dat | 9 + CryptoPP/crypto/sha.cpp | 553 +++ CryptoPP/crypto/sha.h | 61 + CryptoPP/crypto/shacal2.cpp | 140 + CryptoPP/crypto/shacal2.h | 54 + CryptoPP/crypto/shacal2v.dat | 14 + CryptoPP/crypto/shark.cpp | 141 + CryptoPP/crypto/shark.h | 69 + CryptoPP/crypto/sharkbox.cpp | 4166 +++++++++++++++++++ CryptoPP/crypto/sharkval.dat | 7 + CryptoPP/crypto/simple.cpp | 14 + CryptoPP/crypto/simple.h | 209 + CryptoPP/crypto/skipjack.cpp | 202 + CryptoPP/crypto/skipjack.dat | 1 + CryptoPP/crypto/skipjack.h | 60 + CryptoPP/crypto/smartptr.h | 223 + CryptoPP/crypto/socketft.cpp | 531 +++ CryptoPP/crypto/socketft.h | 224 + CryptoPP/crypto/sosemanuk.cpp | 710 ++++ CryptoPP/crypto/sosemanuk.h | 40 + CryptoPP/crypto/square.cpp | 174 + CryptoPP/crypto/square.h | 58 + CryptoPP/crypto/squaretb.cpp | 582 +++ CryptoPP/crypto/squareva.dat | 8 + CryptoPP/crypto/stdcpp.h | 27 + CryptoPP/crypto/strciphr.cpp | 256 ++ CryptoPP/crypto/strciphr.h | 306 ++ CryptoPP/crypto/tea.cpp | 147 + CryptoPP/crypto/tea.h | 132 + CryptoPP/crypto/test.cpp | 855 ++++ CryptoPP/crypto/tftables.cpp | 317 ++ CryptoPP/crypto/tiger.cpp | 269 ++ CryptoPP/crypto/tiger.h | 29 + CryptoPP/crypto/tigertab.cpp | 529 +++ CryptoPP/crypto/trdlocal.cpp | 73 + CryptoPP/crypto/trdlocal.h | 44 + CryptoPP/crypto/trunhash.h | 48 + CryptoPP/crypto/ttmac.cpp | 338 ++ CryptoPP/crypto/ttmac.h | 38 + CryptoPP/crypto/twofish.cpp | 168 + CryptoPP/crypto/twofish.h | 59 + CryptoPP/crypto/twofishv.dat | 9 + CryptoPP/crypto/usage.dat | 81 + CryptoPP/crypto/validat1.cpp | 1352 ++++++ CryptoPP/crypto/validat2.cpp | 758 ++++ CryptoPP/crypto/validat3.cpp | 693 ++++ CryptoPP/crypto/validate.h | 78 + CryptoPP/crypto/vmac.cpp | 820 ++++ CryptoPP/crypto/vmac.h | 77 + CryptoPP/crypto/wait.cpp | 397 ++ CryptoPP/crypto/wait.h | 208 + CryptoPP/crypto/wake.cpp | 125 + CryptoPP/crypto/wake.h | 86 + CryptoPP/crypto/whrlpool.cpp | 706 ++++ CryptoPP/crypto/whrlpool.h | 26 + CryptoPP/crypto/winpipes.cpp | 205 + CryptoPP/crypto/winpipes.h | 142 + CryptoPP/crypto/words.h | 103 + CryptoPP/crypto/x64masm.asm | 1896 +++++++++ CryptoPP/crypto/xormac.h | 179 + CryptoPP/crypto/xtr.cpp | 100 + CryptoPP/crypto/xtr.h | 215 + CryptoPP/crypto/xtrcrypt.cpp | 108 + CryptoPP/crypto/xtrcrypt.h | 54 + CryptoPP/crypto/xtrdh171.dat | 3 + CryptoPP/crypto/xtrdh342.dat | 5 + CryptoPP/crypto/zdeflate.cpp | 791 ++++ CryptoPP/crypto/zdeflate.h | 121 + CryptoPP/crypto/zinflate.cpp | 621 +++ CryptoPP/crypto/zinflate.h | 149 + CryptoPP/crypto/zlib.cpp | 90 + CryptoPP/crypto/zlib.h | 58 + CryptoPP/cryptopp.dep | 80 + CryptoPP/cryptopp.dsp | 233 ++ CryptoPP/cryptopp.dsw | 44 + CryptoPP/cryptopp.h | 216 + CryptoPP/cryptopp.mak | 420 ++ CryptoPP/cryptopp_9.sln | 28 + CryptoPP/cryptopp_9.vcproj | 656 +++ CryptoPP/dllloader.cpp | 280 ++ CryptoPP/dllloader.h | 8 + CryptoPP/gettime.cpp | 29 + CryptoPP/gettime.h | 8 + CryptoPP/main.cpp | 87 + CryptoPP/mmi.cpp | 88 + CryptoPP/mmi.h | 22 + CryptoPP/readme.txt | 103 + CryptoPP/resource.h | 17 + CryptoPP/resource.rc | 39 + CryptoPP/utf8.cpp | 149 + CryptoPP/utf8.h | 9 + CryptoPP/version.h | 16 + CryptoPP/version.rc | 41 + 481 files changed, 109024 insertions(+) create mode 100644 CryptoPP/!whatsnew.txt create mode 100644 CryptoPP/GPGw/GnuPGw.dep create mode 100644 CryptoPP/GPGw/GnuPGw.dsp create mode 100644 CryptoPP/GPGw/GnuPGw.mak create mode 100644 CryptoPP/GPGw/Release/GnuPGw.dll create mode 100644 CryptoPP/GPGw/Release/GnuPGw.map create mode 100644 CryptoPP/GPGw/commonheaders.c create mode 100644 CryptoPP/GPGw/commonheaders.h create mode 100644 CryptoPP/GPGw/gnupgw.dsw create mode 100644 CryptoPP/GPGw/gpg.c create mode 100644 CryptoPP/GPGw/gpg.h create mode 100644 CryptoPP/GPGw/gpgw.msp create mode 100644 CryptoPP/GPGw/keys.c create mode 100644 CryptoPP/GPGw/keys.h create mode 100644 CryptoPP/GPGw/language.c create mode 100644 CryptoPP/GPGw/language.h create mode 100644 CryptoPP/GPGw/main.c create mode 100644 CryptoPP/GPGw/passdialog.c create mode 100644 CryptoPP/GPGw/passdialog.h create mode 100644 CryptoPP/GPGw/passphrases.c create mode 100644 CryptoPP/GPGw/passphrases.h create mode 100644 CryptoPP/GPGw/pipeexec.c create mode 100644 CryptoPP/GPGw/pipeexec.h create mode 100644 CryptoPP/GPGw/resource.h create mode 100644 CryptoPP/GPGw/resource.rc create mode 100644 CryptoPP/GPGw/size.h create mode 100644 CryptoPP/GPGw/tools.c create mode 100644 CryptoPP/GPGw/tools.h create mode 100644 CryptoPP/GPGw/userdialog.c create mode 100644 CryptoPP/GPGw/userdialog.h create mode 100644 CryptoPP/PGPw/PGPsdkW.dep create mode 100644 CryptoPP/PGPw/PGPsdkW.dsp create mode 100644 CryptoPP/PGPw/PGPsdkW.dsw create mode 100644 CryptoPP/PGPw/PGPsdkW.mak create mode 100644 CryptoPP/PGPw/Release6/PGPsdkW6.dll create mode 100644 CryptoPP/PGPw/Release6/PGPsdkW6.map create mode 100644 CryptoPP/PGPw/Release8/PGPsdkW8.dll create mode 100644 CryptoPP/PGPw/Release8/PGPsdkW8.map create mode 100644 CryptoPP/PGPw/commonheaders.cpp create mode 100644 CryptoPP/PGPw/commonheaders.h create mode 100644 CryptoPP/PGPw/main.cpp create mode 100644 CryptoPP/PGPw/sdk6/include/pgpBase.h create mode 100644 CryptoPP/PGPw/sdk6/include/pgpBigNum.h create mode 100644 CryptoPP/PGPw/sdk6/include/pgpCBC.h create mode 100644 CryptoPP/PGPw/sdk6/include/pgpCFB.h create mode 100644 CryptoPP/PGPw/sdk6/include/pgpConfig.h create mode 100644 CryptoPP/PGPw/sdk6/include/pgpEncode.h create mode 100644 CryptoPP/PGPw/sdk6/include/pgpErrors.h create mode 100644 CryptoPP/PGPw/sdk6/include/pgpFeatures.h create mode 100644 CryptoPP/PGPw/sdk6/include/pgpGroups.h create mode 100644 CryptoPP/PGPw/sdk6/include/pgpHMAC.h create mode 100644 CryptoPP/PGPw/sdk6/include/pgpHash.h create mode 100644 CryptoPP/PGPw/sdk6/include/pgpKeyServer.h create mode 100644 CryptoPP/PGPw/sdk6/include/pgpKeys.h create mode 100644 CryptoPP/PGPw/sdk6/include/pgpMemoryMgr.h create mode 100644 CryptoPP/PGPw/sdk6/include/pgpOptionList.h create mode 100644 CryptoPP/PGPw/sdk6/include/pgpPFLConfig.h create mode 100644 CryptoPP/PGPw/sdk6/include/pgpPFLErrors.h create mode 100644 CryptoPP/PGPw/sdk6/include/pgpPubTypes.h create mode 100644 CryptoPP/PGPw/sdk6/include/pgpPublicKey.h create mode 100644 CryptoPP/PGPw/sdk6/include/pgpRandomPool.h create mode 100644 CryptoPP/PGPw/sdk6/include/pgpSDKPrefs.h create mode 100644 CryptoPP/PGPw/sdk6/include/pgpSockets.h create mode 100644 CryptoPP/PGPw/sdk6/include/pgpSymmetricCipher.h create mode 100644 CryptoPP/PGPw/sdk6/include/pgpTLS.h create mode 100644 CryptoPP/PGPw/sdk6/include/pgpUserInterface.h create mode 100644 CryptoPP/PGPw/sdk6/include/pgpUtilities.h create mode 100644 CryptoPP/PGPw/sdk6/lib/PGP_SDK.lib create mode 100644 CryptoPP/PGPw/sdk6/lib/PGPsdkNL.lib create mode 100644 CryptoPP/PGPw/sdk6/lib/PGPsdkUI.lib create mode 100644 CryptoPP/PGPw/sdk8/include/pflTypes.h create mode 100644 CryptoPP/PGPw/sdk8/include/pgpAPIAdapter.h create mode 100644 CryptoPP/PGPw/sdk8/include/pgpBER.h create mode 100644 CryptoPP/PGPw/sdk8/include/pgpBase.h create mode 100644 CryptoPP/PGPw/sdk8/include/pgpBigNum.h create mode 100644 CryptoPP/PGPw/sdk8/include/pgpCBC.h create mode 100644 CryptoPP/PGPw/sdk8/include/pgpCFB.h create mode 100644 CryptoPP/PGPw/sdk8/include/pgpConfig.h create mode 100644 CryptoPP/PGPw/sdk8/include/pgpEC.h create mode 100644 CryptoPP/PGPw/sdk8/include/pgpEncode.h create mode 100644 CryptoPP/PGPw/sdk8/include/pgpErrors.h create mode 100644 CryptoPP/PGPw/sdk8/include/pgpFeatures.h create mode 100644 CryptoPP/PGPw/sdk8/include/pgpGroups.h create mode 100644 CryptoPP/PGPw/sdk8/include/pgpHMAC.h create mode 100644 CryptoPP/PGPw/sdk8/include/pgpHash.h create mode 100644 CryptoPP/PGPw/sdk8/include/pgpHashWords.h create mode 100644 CryptoPP/PGPw/sdk8/include/pgpIKE.h create mode 100644 CryptoPP/PGPw/sdk8/include/pgpKeyServer.h create mode 100644 CryptoPP/PGPw/sdk8/include/pgpKeys.h create mode 100644 CryptoPP/PGPw/sdk8/include/pgpLDAP.h create mode 100644 CryptoPP/PGPw/sdk8/include/pgpMemoryMgr.h create mode 100644 CryptoPP/PGPw/sdk8/include/pgpOptionList.h create mode 100644 CryptoPP/PGPw/sdk8/include/pgpPFLConfig.h create mode 100644 CryptoPP/PGPw/sdk8/include/pgpPFLErrors.h create mode 100644 CryptoPP/PGPw/sdk8/include/pgpPubTypes.h create mode 100644 CryptoPP/PGPw/sdk8/include/pgpPublicKey.h create mode 100644 CryptoPP/PGPw/sdk8/include/pgpRandomPool.h create mode 100644 CryptoPP/PGPw/sdk8/include/pgpReconstruct.h create mode 100644 CryptoPP/PGPw/sdk8/include/pgpSECSH.h create mode 100644 CryptoPP/PGPw/sdk8/include/pgpSKEP.h create mode 100644 CryptoPP/PGPw/sdk8/include/pgpShare.h create mode 100644 CryptoPP/PGPw/sdk8/include/pgpShareFile.h create mode 100644 CryptoPP/PGPw/sdk8/include/pgpSockets.h create mode 100644 CryptoPP/PGPw/sdk8/include/pgpSymmetricCipher.h create mode 100644 CryptoPP/PGPw/sdk8/include/pgpTLS.h create mode 100644 CryptoPP/PGPw/sdk8/include/pgpUserInterface.h create mode 100644 CryptoPP/PGPw/sdk8/include/pgpUtilities.h create mode 100644 CryptoPP/PGPw/sdk8/lib/PGPsdk.lib create mode 100644 CryptoPP/PGPw/sdk8/lib/PGPsdkNL.lib create mode 100644 CryptoPP/PGPw/sdk8/lib/PGPsdkUI.lib create mode 100644 CryptoPP/base16.cpp create mode 100644 CryptoPP/base16.h create mode 100644 CryptoPP/base64.cpp create mode 100644 CryptoPP/base64.h create mode 100644 CryptoPP/commonheaders.cpp create mode 100644 CryptoPP/commonheaders.h create mode 100644 CryptoPP/cpp_cntx.cpp create mode 100644 CryptoPP/cpp_gpgw.cpp create mode 100644 CryptoPP/cpp_gzip.cpp create mode 100644 CryptoPP/cpp_keys.cpp create mode 100644 CryptoPP/cpp_misc.cpp create mode 100644 CryptoPP/cpp_pgpw.cpp create mode 100644 CryptoPP/cpp_rsam.cpp create mode 100644 CryptoPP/cpp_rsam.h create mode 100644 CryptoPP/cpp_rsau.cpp create mode 100644 CryptoPP/cpp_rsau.h create mode 100644 CryptoPP/cpp_svcs.cpp create mode 100644 CryptoPP/crypto/3desval.dat create mode 100644 CryptoPP/crypto/3way.cpp create mode 100644 CryptoPP/crypto/3way.h create mode 100644 CryptoPP/crypto/3wayval.dat create mode 100644 CryptoPP/crypto/Doxyfile create mode 100644 CryptoPP/crypto/GNUmakefile create mode 100644 CryptoPP/crypto/License.txt create mode 100644 CryptoPP/crypto/Readme.txt create mode 100644 CryptoPP/crypto/adhoc.cpp create mode 100644 CryptoPP/crypto/adhoc.cpp.copied create mode 100644 CryptoPP/crypto/adhoc.cpp.proto create mode 100644 CryptoPP/crypto/adler32.cpp create mode 100644 CryptoPP/crypto/adler32.h create mode 100644 CryptoPP/crypto/aes.h create mode 100644 CryptoPP/crypto/algebra.cpp create mode 100644 CryptoPP/crypto/algebra.h create mode 100644 CryptoPP/crypto/algparam.cpp create mode 100644 CryptoPP/crypto/algparam.h create mode 100644 CryptoPP/crypto/arc4.cpp create mode 100644 CryptoPP/crypto/arc4.h create mode 100644 CryptoPP/crypto/argnames.h create mode 100644 CryptoPP/crypto/asn.cpp create mode 100644 CryptoPP/crypto/asn.h create mode 100644 CryptoPP/crypto/base32.cpp create mode 100644 CryptoPP/crypto/base32.h create mode 100644 CryptoPP/crypto/base64.cpp create mode 100644 CryptoPP/crypto/base64.h create mode 100644 CryptoPP/crypto/basecode.cpp create mode 100644 CryptoPP/crypto/basecode.h create mode 100644 CryptoPP/crypto/bench.cpp create mode 100644 CryptoPP/crypto/bench.h create mode 100644 CryptoPP/crypto/bench2.cpp create mode 100644 CryptoPP/crypto/bfinit.cpp create mode 100644 CryptoPP/crypto/blowfish.cpp create mode 100644 CryptoPP/crypto/blowfish.h create mode 100644 CryptoPP/crypto/blumshub.cpp create mode 100644 CryptoPP/crypto/blumshub.h create mode 100644 CryptoPP/crypto/camellia.cpp create mode 100644 CryptoPP/crypto/camellia.dat create mode 100644 CryptoPP/crypto/camellia.h create mode 100644 CryptoPP/crypto/cast.cpp create mode 100644 CryptoPP/crypto/cast.h create mode 100644 CryptoPP/crypto/cast128v.dat create mode 100644 CryptoPP/crypto/cast256v.dat create mode 100644 CryptoPP/crypto/casts.cpp create mode 100644 CryptoPP/crypto/cbcmac.cpp create mode 100644 CryptoPP/crypto/cbcmac.h create mode 100644 CryptoPP/crypto/channels.cpp create mode 100644 CryptoPP/crypto/channels.h create mode 100644 CryptoPP/crypto/config.h create mode 100644 CryptoPP/crypto/cpu.cpp create mode 100644 CryptoPP/crypto/cpu.h create mode 100644 CryptoPP/crypto/crc.cpp create mode 100644 CryptoPP/crypto/crc.h create mode 100644 CryptoPP/crypto/cryptdll.dsp create mode 100644 CryptoPP/crypto/cryptest.dsp create mode 100644 CryptoPP/crypto/cryptest.dsw create mode 100644 CryptoPP/crypto/cryptlib.cpp create mode 100644 CryptoPP/crypto/cryptlib.dep create mode 100644 CryptoPP/crypto/cryptlib.dsp create mode 100644 CryptoPP/crypto/cryptlib.h create mode 100644 CryptoPP/crypto/cryptlib.mak create mode 100644 CryptoPP/crypto/cryptlib_9.vcproj create mode 100644 CryptoPP/crypto/cryptlib_bds.cpp create mode 100644 CryptoPP/crypto/crypto54msvc6.patch create mode 100644 CryptoPP/crypto/cryptopp.rc create mode 100644 CryptoPP/crypto/datatest.cpp create mode 100644 CryptoPP/crypto/default.cpp create mode 100644 CryptoPP/crypto/default.h create mode 100644 CryptoPP/crypto/des.cpp create mode 100644 CryptoPP/crypto/des.h create mode 100644 CryptoPP/crypto/descert.dat create mode 100644 CryptoPP/crypto/dessp.cpp create mode 100644 CryptoPP/crypto/dh.cpp create mode 100644 CryptoPP/crypto/dh.h create mode 100644 CryptoPP/crypto/dh1024.dat create mode 100644 CryptoPP/crypto/dh2.cpp create mode 100644 CryptoPP/crypto/dh2.h create mode 100644 CryptoPP/crypto/dh2048.dat create mode 100644 CryptoPP/crypto/dlie1024.dat create mode 100644 CryptoPP/crypto/dlie2048.dat create mode 100644 CryptoPP/crypto/dll.cpp create mode 100644 CryptoPP/crypto/dll.h create mode 100644 CryptoPP/crypto/dlltest.cpp create mode 100644 CryptoPP/crypto/dlltest.dsp create mode 100644 CryptoPP/crypto/dmac.h create mode 100644 CryptoPP/crypto/dsa.cpp create mode 100644 CryptoPP/crypto/dsa.h create mode 100644 CryptoPP/crypto/dsa1024.dat create mode 100644 CryptoPP/crypto/dsa1024b.dat create mode 100644 CryptoPP/crypto/dsa512.dat create mode 100644 CryptoPP/crypto/ec2n.cpp create mode 100644 CryptoPP/crypto/ec2n.h create mode 100644 CryptoPP/crypto/eccrypto.cpp create mode 100644 CryptoPP/crypto/eccrypto.h create mode 100644 CryptoPP/crypto/ecp.cpp create mode 100644 CryptoPP/crypto/ecp.h create mode 100644 CryptoPP/crypto/elgamal.cpp create mode 100644 CryptoPP/crypto/elgamal.h create mode 100644 CryptoPP/crypto/elgc1024.dat create mode 100644 CryptoPP/crypto/emsa2.cpp create mode 100644 CryptoPP/crypto/emsa2.h create mode 100644 CryptoPP/crypto/eprecomp.cpp create mode 100644 CryptoPP/crypto/eprecomp.h create mode 100644 CryptoPP/crypto/esig1023.dat create mode 100644 CryptoPP/crypto/esig1536.dat create mode 100644 CryptoPP/crypto/esig2046.dat create mode 100644 CryptoPP/crypto/esign.cpp create mode 100644 CryptoPP/crypto/esign.h create mode 100644 CryptoPP/crypto/factory.h create mode 100644 CryptoPP/crypto/files.cpp create mode 100644 CryptoPP/crypto/files.h create mode 100644 CryptoPP/crypto/filters.cpp create mode 100644 CryptoPP/crypto/filters.h create mode 100644 CryptoPP/crypto/fips140.cpp create mode 100644 CryptoPP/crypto/fips140.h create mode 100644 CryptoPP/crypto/fipsalgt.cpp create mode 100644 CryptoPP/crypto/fipstest.cpp create mode 100644 CryptoPP/crypto/fltrimpl.h create mode 100644 CryptoPP/crypto/gf256.cpp create mode 100644 CryptoPP/crypto/gf256.h create mode 100644 CryptoPP/crypto/gf2_32.cpp create mode 100644 CryptoPP/crypto/gf2_32.h create mode 100644 CryptoPP/crypto/gf2n.cpp create mode 100644 CryptoPP/crypto/gf2n.h create mode 100644 CryptoPP/crypto/gfpcrypt.cpp create mode 100644 CryptoPP/crypto/gfpcrypt.h create mode 100644 CryptoPP/crypto/gost.cpp create mode 100644 CryptoPP/crypto/gost.h create mode 100644 CryptoPP/crypto/gostval.dat create mode 100644 CryptoPP/crypto/gzip.cpp create mode 100644 CryptoPP/crypto/gzip.h create mode 100644 CryptoPP/crypto/haval.cpp create mode 100644 CryptoPP/crypto/haval.h create mode 100644 CryptoPP/crypto/havalcer.dat create mode 100644 CryptoPP/crypto/hex.cpp create mode 100644 CryptoPP/crypto/hex.h create mode 100644 CryptoPP/crypto/hmac.cpp create mode 100644 CryptoPP/crypto/hmac.h create mode 100644 CryptoPP/crypto/hrtimer.cpp create mode 100644 CryptoPP/crypto/hrtimer.h create mode 100644 CryptoPP/crypto/ida.cpp create mode 100644 CryptoPP/crypto/ida.h create mode 100644 CryptoPP/crypto/idea.cpp create mode 100644 CryptoPP/crypto/idea.h create mode 100644 CryptoPP/crypto/ideaval.dat create mode 100644 CryptoPP/crypto/integer.cpp create mode 100644 CryptoPP/crypto/integer.h create mode 100644 CryptoPP/crypto/iterhash.cpp create mode 100644 CryptoPP/crypto/iterhash.h create mode 100644 CryptoPP/crypto/lubyrack.h create mode 100644 CryptoPP/crypto/luc.cpp create mode 100644 CryptoPP/crypto/luc.h create mode 100644 CryptoPP/crypto/luc1024.dat create mode 100644 CryptoPP/crypto/luc2048.dat create mode 100644 CryptoPP/crypto/lucc1024.dat create mode 100644 CryptoPP/crypto/lucc512.dat create mode 100644 CryptoPP/crypto/lucd1024.dat create mode 100644 CryptoPP/crypto/lucd512.dat create mode 100644 CryptoPP/crypto/lucs1024.dat create mode 100644 CryptoPP/crypto/lucs512.dat create mode 100644 CryptoPP/crypto/mars.cpp create mode 100644 CryptoPP/crypto/mars.h create mode 100644 CryptoPP/crypto/marss.cpp create mode 100644 CryptoPP/crypto/marsval.dat create mode 100644 CryptoPP/crypto/md2.cpp create mode 100644 CryptoPP/crypto/md2.h create mode 100644 CryptoPP/crypto/md4.cpp create mode 100644 CryptoPP/crypto/md4.h create mode 100644 CryptoPP/crypto/md5.cpp create mode 100644 CryptoPP/crypto/md5.h create mode 100644 CryptoPP/crypto/md5mac.cpp create mode 100644 CryptoPP/crypto/md5mac.h create mode 100644 CryptoPP/crypto/mdc.h create mode 100644 CryptoPP/crypto/misc.cpp create mode 100644 CryptoPP/crypto/misc.h create mode 100644 CryptoPP/crypto/modarith.h create mode 100644 CryptoPP/crypto/modes.cpp create mode 100644 CryptoPP/crypto/modes.h create mode 100644 CryptoPP/crypto/modexppc.h create mode 100644 CryptoPP/crypto/mqueue.cpp create mode 100644 CryptoPP/crypto/mqueue.h create mode 100644 CryptoPP/crypto/mqv.cpp create mode 100644 CryptoPP/crypto/mqv.h create mode 100644 CryptoPP/crypto/mqv1024.dat create mode 100644 CryptoPP/crypto/mqv2048.dat create mode 100644 CryptoPP/crypto/nbtheory.cpp create mode 100644 CryptoPP/crypto/nbtheory.h create mode 100644 CryptoPP/crypto/network.cpp create mode 100644 CryptoPP/crypto/network.h create mode 100644 CryptoPP/crypto/nr.h create mode 100644 CryptoPP/crypto/nr1024.dat create mode 100644 CryptoPP/crypto/nr2048.dat create mode 100644 CryptoPP/crypto/oaep.cpp create mode 100644 CryptoPP/crypto/oaep.h create mode 100644 CryptoPP/crypto/oids.h create mode 100644 CryptoPP/crypto/osrng.cpp create mode 100644 CryptoPP/crypto/osrng.h create mode 100644 CryptoPP/crypto/panama.cpp create mode 100644 CryptoPP/crypto/panama.h create mode 100644 CryptoPP/crypto/pch.cpp create mode 100644 CryptoPP/crypto/pch.h create mode 100644 CryptoPP/crypto/pkcspad.cpp create mode 100644 CryptoPP/crypto/pkcspad.h create mode 100644 CryptoPP/crypto/polynomi.cpp create mode 100644 CryptoPP/crypto/polynomi.h create mode 100644 CryptoPP/crypto/pssr.cpp create mode 100644 CryptoPP/crypto/pssr.h create mode 100644 CryptoPP/crypto/pubkey.cpp create mode 100644 CryptoPP/crypto/pubkey.h create mode 100644 CryptoPP/crypto/pwdbased.h create mode 100644 CryptoPP/crypto/queue.cpp create mode 100644 CryptoPP/crypto/queue.h create mode 100644 CryptoPP/crypto/rabi1024.dat create mode 100644 CryptoPP/crypto/rabi2048.dat create mode 100644 CryptoPP/crypto/rabin.cpp create mode 100644 CryptoPP/crypto/rabin.h create mode 100644 CryptoPP/crypto/randpool.cpp create mode 100644 CryptoPP/crypto/randpool.h create mode 100644 CryptoPP/crypto/rc2.cpp create mode 100644 CryptoPP/crypto/rc2.h create mode 100644 CryptoPP/crypto/rc2val.dat create mode 100644 CryptoPP/crypto/rc5.cpp create mode 100644 CryptoPP/crypto/rc5.h create mode 100644 CryptoPP/crypto/rc5val.dat create mode 100644 CryptoPP/crypto/rc6.cpp create mode 100644 CryptoPP/crypto/rc6.h create mode 100644 CryptoPP/crypto/rc6val.dat create mode 100644 CryptoPP/crypto/rdtables.cpp create mode 100644 CryptoPP/crypto/regtest.cpp create mode 100644 CryptoPP/crypto/resource.h create mode 100644 CryptoPP/crypto/rijndael.cpp create mode 100644 CryptoPP/crypto/rijndael.dat create mode 100644 CryptoPP/crypto/rijndael.h create mode 100644 CryptoPP/crypto/ripemd.cpp create mode 100644 CryptoPP/crypto/ripemd.h create mode 100644 CryptoPP/crypto/rng.cpp create mode 100644 CryptoPP/crypto/rng.h create mode 100644 CryptoPP/crypto/rsa.cpp create mode 100644 CryptoPP/crypto/rsa.h create mode 100644 CryptoPP/crypto/rsa1024.dat create mode 100644 CryptoPP/crypto/rsa2048.dat create mode 100644 CryptoPP/crypto/rsa400pb.dat create mode 100644 CryptoPP/crypto/rsa400pv.dat create mode 100644 CryptoPP/crypto/rsa512a.dat create mode 100644 CryptoPP/crypto/rw.cpp create mode 100644 CryptoPP/crypto/rw.h create mode 100644 CryptoPP/crypto/rw1024.dat create mode 100644 CryptoPP/crypto/rw2048.dat create mode 100644 CryptoPP/crypto/safer.cpp create mode 100644 CryptoPP/crypto/safer.h create mode 100644 CryptoPP/crypto/saferval.dat create mode 100644 CryptoPP/crypto/salsa.cpp create mode 100644 CryptoPP/crypto/salsa.h create mode 100644 CryptoPP/crypto/seal.cpp create mode 100644 CryptoPP/crypto/seal.h create mode 100644 CryptoPP/crypto/secblock.h create mode 100644 CryptoPP/crypto/seckey.h create mode 100644 CryptoPP/crypto/serpent.cpp create mode 100644 CryptoPP/crypto/serpent.h create mode 100644 CryptoPP/crypto/serpentp.h create mode 100644 CryptoPP/crypto/serpentv.dat create mode 100644 CryptoPP/crypto/sha.cpp create mode 100644 CryptoPP/crypto/sha.h create mode 100644 CryptoPP/crypto/shacal2.cpp create mode 100644 CryptoPP/crypto/shacal2.h create mode 100644 CryptoPP/crypto/shacal2v.dat create mode 100644 CryptoPP/crypto/shark.cpp create mode 100644 CryptoPP/crypto/shark.h create mode 100644 CryptoPP/crypto/sharkbox.cpp create mode 100644 CryptoPP/crypto/sharkval.dat create mode 100644 CryptoPP/crypto/simple.cpp create mode 100644 CryptoPP/crypto/simple.h create mode 100644 CryptoPP/crypto/skipjack.cpp create mode 100644 CryptoPP/crypto/skipjack.dat create mode 100644 CryptoPP/crypto/skipjack.h create mode 100644 CryptoPP/crypto/smartptr.h create mode 100644 CryptoPP/crypto/socketft.cpp create mode 100644 CryptoPP/crypto/socketft.h create mode 100644 CryptoPP/crypto/sosemanuk.cpp create mode 100644 CryptoPP/crypto/sosemanuk.h create mode 100644 CryptoPP/crypto/square.cpp create mode 100644 CryptoPP/crypto/square.h create mode 100644 CryptoPP/crypto/squaretb.cpp create mode 100644 CryptoPP/crypto/squareva.dat create mode 100644 CryptoPP/crypto/stdcpp.h create mode 100644 CryptoPP/crypto/strciphr.cpp create mode 100644 CryptoPP/crypto/strciphr.h create mode 100644 CryptoPP/crypto/tea.cpp create mode 100644 CryptoPP/crypto/tea.h create mode 100644 CryptoPP/crypto/test.cpp create mode 100644 CryptoPP/crypto/tftables.cpp create mode 100644 CryptoPP/crypto/tiger.cpp create mode 100644 CryptoPP/crypto/tiger.h create mode 100644 CryptoPP/crypto/tigertab.cpp create mode 100644 CryptoPP/crypto/trdlocal.cpp create mode 100644 CryptoPP/crypto/trdlocal.h create mode 100644 CryptoPP/crypto/trunhash.h create mode 100644 CryptoPP/crypto/ttmac.cpp create mode 100644 CryptoPP/crypto/ttmac.h create mode 100644 CryptoPP/crypto/twofish.cpp create mode 100644 CryptoPP/crypto/twofish.h create mode 100644 CryptoPP/crypto/twofishv.dat create mode 100644 CryptoPP/crypto/usage.dat create mode 100644 CryptoPP/crypto/validat1.cpp create mode 100644 CryptoPP/crypto/validat2.cpp create mode 100644 CryptoPP/crypto/validat3.cpp create mode 100644 CryptoPP/crypto/validate.h create mode 100644 CryptoPP/crypto/vmac.cpp create mode 100644 CryptoPP/crypto/vmac.h create mode 100644 CryptoPP/crypto/wait.cpp create mode 100644 CryptoPP/crypto/wait.h create mode 100644 CryptoPP/crypto/wake.cpp create mode 100644 CryptoPP/crypto/wake.h create mode 100644 CryptoPP/crypto/whrlpool.cpp create mode 100644 CryptoPP/crypto/whrlpool.h create mode 100644 CryptoPP/crypto/winpipes.cpp create mode 100644 CryptoPP/crypto/winpipes.h create mode 100644 CryptoPP/crypto/words.h create mode 100644 CryptoPP/crypto/x64masm.asm create mode 100644 CryptoPP/crypto/xormac.h create mode 100644 CryptoPP/crypto/xtr.cpp create mode 100644 CryptoPP/crypto/xtr.h create mode 100644 CryptoPP/crypto/xtrcrypt.cpp create mode 100644 CryptoPP/crypto/xtrcrypt.h create mode 100644 CryptoPP/crypto/xtrdh171.dat create mode 100644 CryptoPP/crypto/xtrdh342.dat create mode 100644 CryptoPP/crypto/zdeflate.cpp create mode 100644 CryptoPP/crypto/zdeflate.h create mode 100644 CryptoPP/crypto/zinflate.cpp create mode 100644 CryptoPP/crypto/zinflate.h create mode 100644 CryptoPP/crypto/zlib.cpp create mode 100644 CryptoPP/crypto/zlib.h create mode 100644 CryptoPP/cryptopp.dep create mode 100644 CryptoPP/cryptopp.dsp create mode 100644 CryptoPP/cryptopp.dsw create mode 100644 CryptoPP/cryptopp.h create mode 100644 CryptoPP/cryptopp.mak create mode 100644 CryptoPP/cryptopp_9.sln create mode 100644 CryptoPP/cryptopp_9.vcproj create mode 100644 CryptoPP/dllloader.cpp create mode 100644 CryptoPP/dllloader.h create mode 100644 CryptoPP/gettime.cpp create mode 100644 CryptoPP/gettime.h create mode 100644 CryptoPP/main.cpp create mode 100644 CryptoPP/mmi.cpp create mode 100644 CryptoPP/mmi.h create mode 100644 CryptoPP/readme.txt create mode 100644 CryptoPP/resource.h create mode 100644 CryptoPP/resource.rc create mode 100644 CryptoPP/utf8.cpp create mode 100644 CryptoPP/utf8.h create mode 100644 CryptoPP/version.h create mode 100644 CryptoPP/version.rc (limited to 'CryptoPP') diff --git a/CryptoPP/!whatsnew.txt b/CryptoPP/!whatsnew.txt new file mode 100644 index 0000000..a5931a1 --- /dev/null +++ b/CryptoPP/!whatsnew.txt @@ -0,0 +1,34 @@ + +Verison 1.0.4.4 [22-05-2009] + + +Verison 1.0.4.3 [18-05-2009] + +[*] memory leak fixes +[+] rsa_get_hash +[*] new format private key +[+] functions for export/import keys + + +Verison 1.0.4.2 [07-05-2009] + +[*] serious memory corrupting fixed +[*] some security fixes +[*] the principle of operation with contexts is changed +[+] rsa_set_timeout + + +Verison 1.0.4.1 [04-05-2009] + +[*] memory leak fixes +[*] base16 & base64 fixes +[+] RSA/AES feature in Native mode +[+] gpg_set_tmp + + +Verison 1.0.4.0 [28-04-2009] + +[*] GPG empty password fixed +[*] export utf8 string function +[*] native-mode decode null-terminate string fixed +[+] RSA/AES Secure File Transfer diff --git a/CryptoPP/GPGw/GnuPGw.dep b/CryptoPP/GPGw/GnuPGw.dep new file mode 100644 index 0000000..4c922be --- /dev/null +++ b/CryptoPP/GPGw/GnuPGw.dep @@ -0,0 +1,141 @@ +# Microsoft Developer Studio Generated Dependency File, included by GnuPGw.mak + +.\commonheaders.c : \ + "..\version.h"\ + ".\commonheaders.h"\ + ".\gpg.h"\ + ".\keys.h"\ + ".\language.h"\ + ".\passdialog.h"\ + ".\passphrases.h"\ + ".\pipeexec.h"\ + ".\size.h"\ + ".\tools.h"\ + ".\userdialog.h"\ + + +.\gpg.c : \ + "..\version.h"\ + ".\commonheaders.h"\ + ".\gpg.h"\ + ".\keys.h"\ + ".\language.h"\ + ".\passdialog.h"\ + ".\passphrases.h"\ + ".\pipeexec.h"\ + ".\size.h"\ + ".\tools.h"\ + ".\userdialog.h"\ + + +.\keys.c : \ + "..\version.h"\ + ".\commonheaders.h"\ + ".\gpg.h"\ + ".\keys.h"\ + ".\language.h"\ + ".\passdialog.h"\ + ".\passphrases.h"\ + ".\pipeexec.h"\ + ".\size.h"\ + ".\tools.h"\ + ".\userdialog.h"\ + + +.\language.c : \ + "..\version.h"\ + ".\commonheaders.h"\ + ".\gpg.h"\ + ".\keys.h"\ + ".\language.h"\ + ".\passdialog.h"\ + ".\passphrases.h"\ + ".\pipeexec.h"\ + ".\size.h"\ + ".\tools.h"\ + ".\userdialog.h"\ + + +.\main.c : \ + "..\version.h"\ + ".\commonheaders.h"\ + ".\gpg.h"\ + ".\keys.h"\ + ".\language.h"\ + ".\passdialog.h"\ + ".\passphrases.h"\ + ".\pipeexec.h"\ + ".\size.h"\ + ".\tools.h"\ + ".\userdialog.h"\ + + +.\passdialog.c : \ + "..\version.h"\ + ".\commonheaders.h"\ + ".\gpg.h"\ + ".\keys.h"\ + ".\language.h"\ + ".\passdialog.h"\ + ".\passphrases.h"\ + ".\pipeexec.h"\ + ".\size.h"\ + ".\tools.h"\ + ".\userdialog.h"\ + + +.\passphrases.c : \ + "..\version.h"\ + ".\commonheaders.h"\ + ".\gpg.h"\ + ".\keys.h"\ + ".\language.h"\ + ".\passdialog.h"\ + ".\passphrases.h"\ + ".\pipeexec.h"\ + ".\size.h"\ + ".\tools.h"\ + ".\userdialog.h"\ + + +.\pipeexec.c : \ + "..\version.h"\ + ".\commonheaders.h"\ + ".\gpg.h"\ + ".\keys.h"\ + ".\language.h"\ + ".\passdialog.h"\ + ".\passphrases.h"\ + ".\pipeexec.h"\ + ".\size.h"\ + ".\tools.h"\ + ".\userdialog.h"\ + + +.\tools.c : \ + "..\version.h"\ + ".\commonheaders.h"\ + ".\gpg.h"\ + ".\keys.h"\ + ".\language.h"\ + ".\passdialog.h"\ + ".\passphrases.h"\ + ".\pipeexec.h"\ + ".\size.h"\ + ".\tools.h"\ + ".\userdialog.h"\ + + +.\userdialog.c : \ + "..\version.h"\ + ".\commonheaders.h"\ + ".\gpg.h"\ + ".\keys.h"\ + ".\language.h"\ + ".\passdialog.h"\ + ".\passphrases.h"\ + ".\pipeexec.h"\ + ".\size.h"\ + ".\tools.h"\ + ".\userdialog.h"\ + diff --git a/CryptoPP/GPGw/GnuPGw.dsp b/CryptoPP/GPGw/GnuPGw.dsp new file mode 100644 index 0000000..1ce65c2 --- /dev/null +++ b/CryptoPP/GPGw/GnuPGw.dsp @@ -0,0 +1,158 @@ +# Microsoft Developer Studio Project File - Name="GnuPGw" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=GnuPGw - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "GnuPGw.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "GnuPGw.mak" CFG="GnuPGw - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "GnuPGw - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "GnuPGw___Win32_Release" +# PROP BASE Intermediate_Dir "GnuPGw___Win32_Release" +# PROP BASE Ignore_Export_Lib 1 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /Gi /GX /O2 /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O1 /Ob2 /Yu"commonheaders.h" /FD /c +# SUBTRACT CPP /Fr +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x417 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib shell32.lib gdi32.lib msimg32.lib comdlg32.lib advapi32.lib msvcrt.lib /nologo /base:"0x46100000" /dll /map /machine:I386 /filealign:0x200 +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 kernel32.lib user32.lib shell32.lib gdi32.lib msimg32.lib comdlg32.lib advapi32.lib msvcrt.lib /nologo /base:"0x46100000" /dll /map /machine:I386 /filealign:0x200 +# SUBTRACT LINK32 /pdb:none /debug +# Begin Target + +# Name "GnuPGw - Win32 Release" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\commonheaders.c +# ADD CPP /Yc"commonheaders.h" +# End Source File +# Begin Source File + +SOURCE=.\gpg.c +# End Source File +# Begin Source File + +SOURCE=.\keys.c +# End Source File +# Begin Source File + +SOURCE=.\language.c +# End Source File +# Begin Source File + +SOURCE=.\main.c +# End Source File +# Begin Source File + +SOURCE=.\passdialog.c +# End Source File +# Begin Source File + +SOURCE=.\passphrases.c +# End Source File +# Begin Source File + +SOURCE=.\pipeexec.c +# End Source File +# Begin Source File + +SOURCE=.\tools.c +# End Source File +# Begin Source File + +SOURCE=.\userdialog.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\commonheaders.h +# End Source File +# Begin Source File + +SOURCE=.\gpg.h +# End Source File +# Begin Source File + +SOURCE=.\keys.h +# End Source File +# Begin Source File + +SOURCE=.\language.h +# End Source File +# Begin Source File + +SOURCE=.\passdialog.h +# End Source File +# Begin Source File + +SOURCE=.\passphrases.h +# End Source File +# Begin Source File + +SOURCE=.\pipeexec.h +# End Source File +# Begin Source File + +SOURCE=.\resource.h +# End Source File +# Begin Source File + +SOURCE=.\size.h +# End Source File +# Begin Source File + +SOURCE=.\userdialog.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# End Group +# End Target +# End Project diff --git a/CryptoPP/GPGw/GnuPGw.mak b/CryptoPP/GPGw/GnuPGw.mak new file mode 100644 index 0000000..225c4fc --- /dev/null +++ b/CryptoPP/GPGw/GnuPGw.mak @@ -0,0 +1,191 @@ +# Microsoft Developer Studio Generated NMAKE File, Based on GnuPGw.dsp +!IF "$(CFG)" == "" +CFG=GnuPGw - Win32 Release +!MESSAGE No configuration specified. Defaulting to GnuPGw - Win32 Release. +!ENDIF + +!IF "$(CFG)" != "GnuPGw - Win32 Release" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "GnuPGw.mak" CFG="GnuPGw - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "GnuPGw - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF + +OUTDIR=.\Release +INTDIR=.\Release +# Begin Custom Macros +OutDir=.\Release +# End Custom Macros + +ALL : "$(OUTDIR)\GnuPGw.dll" + + +CLEAN : + -@erase "$(INTDIR)\commonheaders.obj" + -@erase "$(INTDIR)\GnuPGw.pch" + -@erase "$(INTDIR)\gpg.obj" + -@erase "$(INTDIR)\keys.obj" + -@erase "$(INTDIR)\language.obj" + -@erase "$(INTDIR)\main.obj" + -@erase "$(INTDIR)\passdialog.obj" + -@erase "$(INTDIR)\passphrases.obj" + -@erase "$(INTDIR)\pipeexec.obj" + -@erase "$(INTDIR)\resource.res" + -@erase "$(INTDIR)\tools.obj" + -@erase "$(INTDIR)\userdialog.obj" + -@erase "$(INTDIR)\vc60.idb" + -@erase "$(OUTDIR)\GnuPGw.dll" + -@erase "$(OUTDIR)\GnuPGw.exp" + -@erase "$(OUTDIR)\GnuPGw.map" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +CPP_PROJ=/nologo /MD /W3 /GX /O1 /Ob2 /Fp"$(INTDIR)\GnuPGw.pch" /Yu"commonheaders.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c + +.c{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +MTL=midl.exe +MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 +RSC=rc.exe +RSC_PROJ=/l 0x419 /fo"$(INTDIR)\resource.res" /d "NDEBUG" +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\GnuPGw.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +LINK32_FLAGS=kernel32.lib user32.lib shell32.lib gdi32.lib msimg32.lib comdlg32.lib advapi32.lib msvcrt.lib /nologo /base:"0x46100000" /dll /incremental:no /pdb:"$(OUTDIR)\GnuPGw.pdb" /map:"$(INTDIR)\GnuPGw.map" /machine:I386 /out:"$(OUTDIR)\GnuPGw.dll" /implib:"$(OUTDIR)\GnuPGw.lib" /filealign:0x200 +LINK32_OBJS= \ + "$(INTDIR)\commonheaders.obj" \ + "$(INTDIR)\gpg.obj" \ + "$(INTDIR)\keys.obj" \ + "$(INTDIR)\language.obj" \ + "$(INTDIR)\main.obj" \ + "$(INTDIR)\passdialog.obj" \ + "$(INTDIR)\passphrases.obj" \ + "$(INTDIR)\pipeexec.obj" \ + "$(INTDIR)\tools.obj" \ + "$(INTDIR)\userdialog.obj" \ + "$(INTDIR)\resource.res" + +"$(OUTDIR)\GnuPGw.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + + +!IF "$(NO_EXTERNAL_DEPS)" != "1" +!IF EXISTS("GnuPGw.dep") +!INCLUDE "GnuPGw.dep" +!ELSE +!MESSAGE Warning: cannot find "GnuPGw.dep" +!ENDIF +!ENDIF + + +!IF "$(CFG)" == "GnuPGw - Win32 Release" +SOURCE=.\commonheaders.c +CPP_SWITCHES=/nologo /MD /W3 /GX /O1 /Ob2 /Fp"$(INTDIR)\GnuPGw.pch" /Yc"commonheaders.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c + +"$(INTDIR)\commonheaders.obj" "$(INTDIR)\GnuPGw.pch" : $(SOURCE) "$(INTDIR)" + $(CPP) @<< + $(CPP_SWITCHES) $(SOURCE) +<< + + +SOURCE=.\gpg.c + +"$(INTDIR)\gpg.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\GnuPGw.pch" + + +SOURCE=.\keys.c + +"$(INTDIR)\keys.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\GnuPGw.pch" + + +SOURCE=.\language.c + +"$(INTDIR)\language.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\GnuPGw.pch" + + +SOURCE=.\main.c + +"$(INTDIR)\main.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\GnuPGw.pch" + + +SOURCE=.\passdialog.c + +"$(INTDIR)\passdialog.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\GnuPGw.pch" + + +SOURCE=.\passphrases.c + +"$(INTDIR)\passphrases.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\GnuPGw.pch" + + +SOURCE=.\pipeexec.c + +"$(INTDIR)\pipeexec.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\GnuPGw.pch" + + +SOURCE=.\tools.c + +"$(INTDIR)\tools.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\GnuPGw.pch" + + +SOURCE=.\userdialog.c + +"$(INTDIR)\userdialog.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\GnuPGw.pch" + + +SOURCE=.\resource.rc + +"$(INTDIR)\resource.res" : $(SOURCE) "$(INTDIR)" + $(RSC) $(RSC_PROJ) $(SOURCE) + + + +!ENDIF + diff --git a/CryptoPP/GPGw/Release/GnuPGw.dll b/CryptoPP/GPGw/Release/GnuPGw.dll new file mode 100644 index 0000000..7dba65e Binary files /dev/null and b/CryptoPP/GPGw/Release/GnuPGw.dll differ diff --git a/CryptoPP/GPGw/Release/GnuPGw.map b/CryptoPP/GPGw/Release/GnuPGw.map new file mode 100644 index 0000000..ec55dd6 --- /dev/null +++ b/CryptoPP/GPGw/Release/GnuPGw.map @@ -0,0 +1,259 @@ + GnuPGw + + Timestamp is 49fdd7b0 (Sun May 03 21:43:12 2009) + + Preferred load address is 46100000 + + Start Length Name Class + 0001:00000000 00001976H .text CODE + 0002:00000000 000000e0H .idata$5 DATA + 0002:000000e0 00000064H .idata$2 DATA + 0002:00000144 00000014H .idata$3 DATA + 0002:00000158 000000e0H .idata$4 DATA + 0002:00000238 00000314H .idata$6 DATA + 0002:00000550 0000017fH .edata DATA + 0003:00000000 000006c0H .data DATA + 0003:000006c0 00000e60H .bss DATA + 0004:00000000 00000088H .rsrc$01 DATA + 0004:00000090 000002a0H .rsrc$02 DATA + + Address Publics by Value Rva+Base Lib:Object + + 0001:00000000 _LogMessage 46101000 f commonheaders.obj + 0001:0000004b _detectKeys 4610104b f gpg.obj + 0001:00000157 _gpgListPublicKeys 46101157 f gpg.obj + 0001:00000225 _gpgListSecretKeys 46101225 f gpg.obj + 0001:000002f3 _gpgDetectUserID 461012f3 f gpg.obj + 0001:000004a3 _gpgEncrypt 461014a3 f gpg.obj + 0001:00000611 _gpgDecrypt 46101611 f gpg.obj + 0001:00000791 _initKeyUserIDs 46101791 f keys.obj + 0001:000007a7 _updateKeyUserIDs 461017a7 f keys.obj + 0001:00000880 _releaseKeyUserIDs 46101880 f keys.obj + 0001:00000893 _getKeyUserID 46101893 f keys.obj + 0001:000008a8 _getKeyUserIDCount 461018a8 f keys.obj + 0001:000008b4 __gpg_init 461018b4 f main.obj + 0001:000008e4 __gpg_done 461018e4 f main.obj + 0001:000008fd __gpg_open_keyrings 461018fd f main.obj + 0001:0000096b __gpg_close_keyrings 4610196b f main.obj + 0001:0000096f __gpg_get_error 4610196f f main.obj + 0001:00000972 __gpg_set_log 46101972 f main.obj + 0001:00000999 __gpg_set_tmp 46101999 f main.obj + 0001:000009c9 __gpg_get_passphrases 461019c9 f main.obj + 0001:00000a71 __gpg_set_passphrases 46101a71 f main.obj + 0001:00000b0f __gpg_encrypt 46101b0f f main.obj + 0001:00000b8f __gpg_decrypt 46101b8f f main.obj + 0001:00000dfb __gpg_size_keyid 46101dfb f main.obj + 0001:00000dff __gpg_select_keyid 46101dff f main.obj + 0001:00000e4c _GetRegValue 46101e4c f main.obj + 0001:00000eb4 _GetEnvValue 46101eb4 f main.obj + 0001:00000ef1 _ShowSelectExecDlg 46101ef1 f main.obj + 0001:00000fb0 _ShowSelectHomeDlg 46101fb0 f main.obj + 0001:0000108c _dllmain@12 4610208c f main.obj + 0001:0000109b _PassphraseDialogProcedure@16 4610209b f passdialog.obj + 0001:00001109 _initPassphrases 46102109 f passphrases.obj + 0001:00001118 _releasePassphrases 46102118 f passphrases.obj + 0001:00001161 _addPassphrase 46102161 f passphrases.obj + 0001:000011c7 _getPassphrase 461021c7 f passphrases.obj + 0001:00001210 _isWindowsNT 46102210 f pipeexec.obj + 0001:00001254 _storeOutput 46102254 f pipeexec.obj + 0001:000012aa _pxExecute 461022aa f pipeexec.obj + 0001:00001498 _replace 46102498 f tools.obj + 0001:00001517 _getNextPart 46102517 f tools.obj + 0001:0000156c _appendText 4610256c f tools.obj + 0001:000015bb _existsFile 461025bb f tools.obj + 0001:000015e3 _existsPath 461025e3 f tools.obj + 0001:0000160b _writeToFile 4610260b f tools.obj + 0001:00001694 _readFromFile 46102694 f tools.obj + 0001:0000171c _getTemporaryFileName 4610271c f tools.obj + 0001:00001733 _UserIdDialogProcedure@16 46102733 f userdialog.obj + 0001:0000186e _RefreshListView 4610286e f userdialog.obj + 0001:00001914 _GetOpenFileNameA@4 46102914 f comdlg32:comdlg32.dll + 0001:0000191a _strcat 4610291a f msvcrt:MSVCRT.dll + 0001:00001920 _strcpy 46102920 f msvcrt:MSVCRT.dll + 0001:00001926 _strcmp 46102926 f msvcrt:MSVCRT.dll + 0001:0000192c _strlen 4610292c f msvcrt:MSVCRT.dll + 0001:00001940 __alloca_probe 46102940 f msvcrt:chkstk.obj + 0001:00001940 __chkstk 46102940 f msvcrt:chkstk.obj + 0001:00001970 _memset 46102970 f msvcrt:MSVCRT.dll + 0002:00000000 __imp__RegCloseKey@4 46103000 advapi32:ADVAPI32.dll + 0002:00000004 __imp__RegOpenKeyA@12 46103004 advapi32:ADVAPI32.dll + 0002:00000008 __imp__SetSecurityDescriptorDacl@16 46103008 advapi32:ADVAPI32.dll + 0002:0000000c __imp__InitializeSecurityDescriptor@8 4610300c advapi32:ADVAPI32.dll + 0002:00000010 __imp__RegQueryValueExA@24 46103010 advapi32:ADVAPI32.dll + 0002:00000014 \177ADVAPI32_NULL_THUNK_DATA 46103014 advapi32:ADVAPI32.dll + 0002:00000018 __imp__PeekNamedPipe@24 46103018 kernel32:KERNEL32.dll + 0002:0000001c __imp__WaitForSingleObject@8 4610301c kernel32:KERNEL32.dll + 0002:00000020 __imp__WriteFile@20 46103020 kernel32:KERNEL32.dll + 0002:00000024 __imp__GetExitCodeProcess@8 46103024 kernel32:KERNEL32.dll + 0002:00000028 __imp__CreateProcessA@40 46103028 kernel32:KERNEL32.dll + 0002:0000002c __imp__ReadFile@20 4610302c kernel32:KERNEL32.dll + 0002:00000030 __imp__CloseHandle@4 46103030 kernel32:KERNEL32.dll + 0002:00000034 __imp__CreatePipe@16 46103034 kernel32:KERNEL32.dll + 0002:00000038 __imp__GetFileAttributesA@4 46103038 kernel32:KERNEL32.dll + 0002:0000003c __imp__GetTempFileNameA@16 4610303c kernel32:KERNEL32.dll + 0002:00000040 __imp__GetVersionExA@4 46103040 kernel32:KERNEL32.dll + 0002:00000044 __imp__GetEnvironmentVariableA@12 46103044 kernel32:KERNEL32.dll + 0002:00000048 __imp__LocalFree@4 46103048 kernel32:KERNEL32.dll + 0002:0000004c __imp__LocalAlloc@8 4610304c kernel32:KERNEL32.dll + 0002:00000050 __imp__GetStartupInfoA@4 46103050 kernel32:KERNEL32.dll + 0002:00000054 __imp__GetTempPathA@8 46103054 kernel32:KERNEL32.dll + 0002:00000058 \177KERNEL32_NULL_THUNK_DATA 46103058 kernel32:KERNEL32.dll + 0002:0000005c __imp__free 4610305c msvcrt:MSVCRT.dll + 0002:00000060 __imp__fseek 46103060 msvcrt:MSVCRT.dll + 0002:00000064 __imp__ftell 46103064 msvcrt:MSVCRT.dll + 0002:00000068 __imp__fread 46103068 msvcrt:MSVCRT.dll + 0002:0000006c __imp__fwrite 4610306c msvcrt:MSVCRT.dll + 0002:00000070 __imp__strncat 46103070 msvcrt:MSVCRT.dll + 0002:00000074 __imp__memmove 46103074 msvcrt:MSVCRT.dll + 0002:00000078 __imp__strchr 46103078 msvcrt:MSVCRT.dll + 0002:0000007c __imp__strncpy 4610307c msvcrt:MSVCRT.dll + 0002:00000080 __imp__memset 46103080 msvcrt:MSVCRT.dll + 0002:00000084 __imp__realloc 46103084 msvcrt:MSVCRT.dll + 0002:00000088 __imp__strcat 46103088 msvcrt:MSVCRT.dll + 0002:0000008c __imp__strcpy 4610308c msvcrt:MSVCRT.dll + 0002:00000090 __imp__fclose 46103090 msvcrt:MSVCRT.dll + 0002:00000094 __imp__fputs 46103094 msvcrt:MSVCRT.dll + 0002:00000098 __imp__fopen 46103098 msvcrt:MSVCRT.dll + 0002:0000009c __imp__strcmp 4610309c msvcrt:MSVCRT.dll + 0002:000000a0 __imp__malloc 461030a0 msvcrt:MSVCRT.dll + 0002:000000a4 __imp__remove 461030a4 msvcrt:MSVCRT.dll + 0002:000000a8 __imp__strstr 461030a8 msvcrt:MSVCRT.dll + 0002:000000ac __imp__strncmp 461030ac msvcrt:MSVCRT.dll + 0002:000000b0 __imp__strlen 461030b0 msvcrt:MSVCRT.dll + 0002:000000b4 \177MSVCRT_NULL_THUNK_DATA 461030b4 msvcrt:MSVCRT.dll + 0002:000000b8 __imp__DialogBoxParamA@20 461030b8 user32:USER32.dll + 0002:000000bc __imp__SetDlgItemTextA@12 461030bc user32:USER32.dll + 0002:000000c0 __imp__EndDialog@8 461030c0 user32:USER32.dll + 0002:000000c4 __imp__GetDlgItemTextA@16 461030c4 user32:USER32.dll + 0002:000000c8 __imp__EnableWindow@8 461030c8 user32:USER32.dll + 0002:000000cc __imp__GetDlgItem@8 461030cc user32:USER32.dll + 0002:000000d0 __imp__SendMessageA@16 461030d0 user32:USER32.dll + 0002:000000d4 \177USER32_NULL_THUNK_DATA 461030d4 user32:USER32.dll + 0002:000000d8 __imp__GetOpenFileNameA@4 461030d8 comdlg32:comdlg32.dll + 0002:000000dc \177comdlg32_NULL_THUNK_DATA 461030dc comdlg32:comdlg32.dll + 0002:000000e0 __IMPORT_DESCRIPTOR_KERNEL32 461030e0 kernel32:KERNEL32.dll + 0002:000000f4 __IMPORT_DESCRIPTOR_USER32 461030f4 user32:USER32.dll + 0002:00000108 __IMPORT_DESCRIPTOR_comdlg32 46103108 comdlg32:comdlg32.dll + 0002:0000011c __IMPORT_DESCRIPTOR_ADVAPI32 4610311c advapi32:ADVAPI32.dll + 0002:00000130 __IMPORT_DESCRIPTOR_MSVCRT 46103130 msvcrt:MSVCRT.dll + 0002:00000144 __NULL_IMPORT_DESCRIPTOR 46103144 kernel32:KERNEL32.dll + 0003:00000000 _szModuleName 46104000 commonheaders.obj + 0003:00000004 _szVersionStr 46104004 commonheaders.obj + 0003:00000008 _txtbeginpgpmessage 46104008 commonheaders.obj + 0003:0000000c _txtendpgpmessage 4610400c commonheaders.obj + 0003:00000010 ??_C@_0BK@JOKF@?9?9?9?9?9END?5PGP?5MESSAGE?9?9?9?9?9?$AA@ 46104010 commonheaders.obj + 0003:0000002c ??_C@_0BM@JJIG@?9?9?9?9?9BEGIN?5PGP?5MESSAGE?9?9?9?9?9?$AA@ 4610402c commonheaders.obj + 0003:00000048 ??_C@_0BE@LAIP@GnuPG?5DLL?5?$CI1?40?44?41?$CJ?$AA@ 46104048 commonheaders.obj + 0003:0000005c ??_C@_05KOGF@GnuPG?$AA@ 4610405c commonheaders.obj + 0003:00000064 ??_C@_01FCOA@?5?$AA@ 46104064 commonheaders.obj + 0003:00000068 ??_C@_01FNLH@a?$AA@ 46104068 commonheaders.obj + 0003:0000006c _txtgpgargslistpublickeys 4610406c gpg.obj + 0003:00000070 _txtgpgargslistsecretkeys 46104070 gpg.obj + 0003:00000074 _txtgpgargsimportpublickey 46104074 gpg.obj + 0003:00000078 _txtgpgargsexportpublickey 46104078 gpg.obj + 0003:0000007c _txtgpgargsdetectuserid 4610407c gpg.obj + 0003:00000080 _txtgpgargsencrypt 46104080 gpg.obj + 0003:00000084 _txtgpgargsdecrypt 46104084 gpg.obj + 0003:00000088 _txtpub 46104088 gpg.obj + 0003:0000008c _txtsec 4610408c gpg.obj + 0003:00000090 _txtcrlf 46104090 gpg.obj + 0003:00000094 _txtcolon 46104094 gpg.obj + 0003:00000098 _txtquotationmark 46104098 gpg.obj + 0003:0000009c _txtgpgcolon 4610409c gpg.obj + 0003:000000a0 _txtplainfile 461040a0 gpg.obj + 0003:000000a4 _txtcipherfile 461040a4 gpg.obj + 0003:000000a8 _txtuserid 461040a8 gpg.obj + 0003:000000ac _txtkeyfile 461040ac gpg.obj + 0003:000000b0 _txthome 461040b0 gpg.obj + 0003:000000b4 _txtidseparator 461040b4 gpg.obj + 0003:000000b8 ??_C@_02GIEM@?0?5?$AA@ 461040b8 gpg.obj + 0003:000000bc ??_C@_06HJED@?$CFhome?$CF?$AA@ 461040bc gpg.obj + 0003:000000c4 ??_C@_09KME@?$CFkeyfile?$CF?$AA@ 461040c4 gpg.obj + 0003:000000d0 ??_C@_08OBEK@?$CFuserid?$CF?$AA@ 461040d0 gpg.obj + 0003:000000dc ??_C@_0N@OPDF@?$CFcipherfile?$CF?$AA@ 461040dc gpg.obj + 0003:000000ec ??_C@_0M@MB@?$CFplainfile?$CF?$AA@ 461040ec gpg.obj + 0003:000000f8 ??_C@_04GMI@gpg?3?$AA@ 461040f8 gpg.obj + 0003:00000100 ??_C@_01HMO@?$CC?$AA@ 46104100 gpg.obj + 0003:00000104 ??_C@_01PKAG@?3?$AA@ 46104104 gpg.obj + 0003:00000108 ??_C@_02PIMC@?$AN?6?$AA@ 46104108 gpg.obj + 0003:0000010c ??_C@_03CLEA@sec?$AA@ 4610410c gpg.obj + 0003:00000110 ??_C@_03BNEF@pub?$AA@ 46104110 gpg.obj + 0003:00000114 ??_C@_0FL@MOKP@?9?9homedir?5?$CC?$CFhome?$CF?$CC?5?9?9yes?5?9?9passp@ 46104114 gpg.obj + 0003:00000170 ??_C@_0IK@JPKD@?9?9homedir?5?$CC?$CFhome?$CF?$CC?5?9?9batch?5?9?9yes@ 46104170 gpg.obj + 0003:000001fc ??_C@_0DE@MKBK@?9?9homedir?5?$CC?$CFhome?$CF?$CC?5?9?9batch?5?9?9dec@ 461041fc gpg.obj + 0003:00000230 ??_C@_0FH@ECPM@?9?9homedir?5?$CC?$CFhome?$CF?$CC?5?9?9batch?5?9?9yes@ 46104230 gpg.obj + 0003:00000288 ??_C@_0CI@MMOA@?9?9homedir?5?$CC?$CFhome?$CF?$CC?5?9?9import?5?$CC?$CFke@ 46104288 gpg.obj + 0003:000002b0 ??_C@_0DD@DLMD@?9?9homedir?5?$CC?$CFhome?$CF?$CC?5?9?9with?9colon?5@ 461042b0 gpg.obj + 0003:000002e4 ??_C@_0DD@DFNM@?9?9homedir?5?$CC?$CFhome?$CF?$CC?5?9?9with?9colon?5@ 461042e4 gpg.obj + 0003:00000318 ??_C@_04BBGP@?2x3a?$AA@ 46104318 gpg.obj + 0003:00000320 ??_C@_04DKNC@?$DO?$DO?$DO?5?$AA@ 46104320 gpg.obj + 0003:00000328 ??_C@_0BB@JNKM@list?5public?5keys?$AA@ 46104328 gpg.obj + 0003:0000033c ??_C@_01BJG@?6?$AA@ 4610433c gpg.obj + 0003:00000340 ??_C@_0BB@JDLD@list?5secret?5keys?$AA@ 46104340 gpg.obj + 0003:00000354 ??_C@_0P@LHID@detect?5user?5id?$AA@ 46104354 gpg.obj + 0003:00000364 ??_C@_07CGOE@encrypt?$AA@ 46104364 gpg.obj + 0003:0000036c ??_C@_07BLJA@decrypt?$AA@ 4610436c gpg.obj + 0003:00000374 _txtlistpublickeysfailed 46104374 language.obj + 0003:00000378 _txtlistsecretkeysfailed 46104378 language.obj + 0003:0000037c _txtwarning 4610437c language.obj + 0003:00000380 _txterror 46104380 language.obj + 0003:00000384 _txtdetectuseridfailed 46104384 language.obj + 0003:00000388 _txtunknownuserid 46104388 language.obj + 0003:0000038c _txtencryptfailed 4610438c language.obj + 0003:00000390 ??_C@_0CP@IGDB@Could?5not?5encrypt?5the?5message?4?5I@ 46104390 language.obj + 0003:000003c0 ??_C@_0BA@BMKJ@Unknown?5User?5ID?$AA@ 461043c0 language.obj + 0003:000003d0 ??_C@_0GH@PFNF@You?5received?5an?5encrypted?5messag@ 461043d0 language.obj + 0003:00000438 ??_C@_0BF@MLAH@GnuPG?5Plugin?5?9?5Error?$AA@ 46104438 language.obj + 0003:00000450 ??_C@_0BH@MLOA@GnuPG?5Plugin?5?9?5Warning?$AA@ 46104450 language.obj + 0003:00000468 ??_C@_0DE@HEGN@Could?5not?5generate?5a?5list?5of?5the@ 46104468 language.obj + 0003:0000049c ??_C@_0DE@LKHI@Could?5not?5generate?5a?5list?5of?5the@ 4610449c language.obj + 0003:000004d0 ??_C@_01FFCO@?$AC?$AA@ 461044d0 main.obj + 0003:000004d4 ??_C@_01KKJH@?$AB?$AA@ 461044d4 main.obj + 0003:000004d8 ??_C@_01FEHD@?$AN?$AA@ 461044d8 main.obj + 0003:000004dc ??_C@_0BI@DIOP@Select?5GnuPG?5executable?$AA@ 461044dc main.obj + 0003:000004f4 ??_C@_0DI@KIMG@GnuPG?5executable?5?$CIgpg?4exe?$CJ?$AAgpg?4e@ 461044f4 main.obj + 0003:0000052c ??_C@_08GIFB@?2gpg?4exe?$AA@ 4610452c main.obj + 0003:00000538 ??_C@_0BC@PKCH@Install?5Directory?$AA@ 46104538 main.obj + 0003:0000054c ??_C@_0L@KPLK@gpgProgram?$AA@ 4610454c main.obj + 0003:00000558 ??_C@_0BD@FFCB@Software?2GNU?2GnuPG?$AA@ 46104558 main.obj + 0003:0000056c ??_C@_0BE@JBON@Open?5Public?5Keyring?$AA@ 4610456c main.obj + 0003:00000580 ??_C@_0EA@FLAI@Public?5key?5rings?5?$CIpubring?4gpg?$CJ?$AAp@ 46104580 main.obj + 0003:000005c0 ??_C@_06OEPH@?2gnupg?$AA@ 461045c0 main.obj + 0003:000005c8 ??_C@_07DBHH@APPDATA?$AA@ 461045c8 main.obj + 0003:000005d0 ??_C@_07DAJH@HomeDir?$AA@ 461045d0 main.obj + 0003:000005d8 ??_C@_09IHAA@GNUPGHOME?$AA@ 461045d8 main.obj + 0003:000005e4 ??_C@_08PBHE@output?3?6?$AA@ 461045e4 pipeexec.obj + 0003:000005f0 ??_C@_0BG@BFBG@create?5process?5failed?$AA@ 461045f0 pipeexec.obj + 0003:00000608 ??_C@_04IGAC@?9?9?9?5?$AA@ 46104608 pipeexec.obj + 0003:00000610 ??_C@_0BD@CKEI@create?5pipe?5failed?$AA@ 46104610 pipeexec.obj + 0003:00000624 ??_C@_0O@FMDH@commandline?3?6?$AA@ 46104624 pipeexec.obj + 0003:00000638 _escsequence 46104638 tools.obj + 0003:00000650 _escsequencecount 46104650 tools.obj + 0003:00000654 ??_C@_01POCP@?7?$AA@ 46104654 tools.obj + 0003:00000658 ??_C@_02NLPO@?2t?$AA@ 46104658 tools.obj + 0003:0000065c ??_C@_02CEIM@?2r?$AA@ 4610465c tools.obj + 0003:00000660 ??_C@_02HDBI@?2n?$AA@ 46104660 tools.obj + 0003:00000664 ??_C@_0L@JBPC@filename?3?6?$AA@ 46104664 tools.obj + 0003:00000670 ??_C@_0O@HMCP@write?5to?5file?$AA@ 46104670 tools.obj + 0003:00000680 ??_C@_02NGAF@wb?$AA@ 46104680 tools.obj + 0003:00000684 ??_C@_03MOIF@gpg?$AA@ 46104684 tools.obj + 0003:00000688 ??_C@_0P@EGMO@read?5from?5file?$AA@ 46104688 tools.obj + 0003:00000698 ??_C@_02JKAF@rb?$AA@ 46104698 tools.obj + 0003:000006ac ??_C@_07GIAA@User?5ID?$AA@ 461046ac userdialog.obj + 0003:000006b4 ??_C@_06LGJA@Key?5ID?$AA@ 461046b4 userdialog.obj + 0003:000006c0 ??_C@_00A@?$AA@ 461046c0 gpg.obj + 0003:000007cc _passphrasecount 461047cc + 0003:000007d0 _passphrases 461047d0 + 0003:000007e0 _dlgpassphrase 461047e0 + 0003:000008e0 _keyuseridcount 461048e0 + 0003:000008e8 _keyuserids 461048e8 + 0003:00000900 _gpgHomeDirectory 46104900 + 0003:00000b00 _gpgExecutable 46104b00 + 0003:00000d00 _g_hInst 46104d00 + 0003:00000d20 _logfile 46104d20 + 0003:00001120 _temporarydirectory 46105120 + + entry point at 0000:00000000 + + Static symbols + diff --git a/CryptoPP/GPGw/commonheaders.c b/CryptoPP/GPGw/commonheaders.c new file mode 100644 index 0000000..5404e4e --- /dev/null +++ b/CryptoPP/GPGw/commonheaders.c @@ -0,0 +1,42 @@ +#include "commonheaders.h" + +LPCSTR szModuleName = MODULENAME; +LPCSTR szVersionStr = MODULENAME" DLL ("__VERSION_STRING")"; +HINSTANCE g_hInst; + +char temporarydirectory[fullfilenamesize]; +char logfile[fullfilenamesize]; +/* +char *txtbeginpgppublickeyblock="-----BEGIN PGP PUBLIC KEY BLOCK-----"; +char *txtendpgppublickeyblock="-----END PGP PUBLIC KEY BLOCK-----"; +*/ +char *txtbeginpgpmessage="-----BEGIN PGP MESSAGE-----"; +char *txtendpgpmessage="-----END PGP MESSAGE-----"; + + +void __cdecl ErrorMessage(const char *alevel, const char *atext, const char *ahint) +{ + char buffer[errormessagesize]; + + strcpy(buffer, atext); + strcat(buffer, " "); + strcat(buffer, ahint); + MessageBox(NULL, buffer, alevel, MB_OK); +} + + +void __cdecl LogMessage(const char *astart, const char *atext, const char *aend) +{ + FILE *log; + + if(logfile[0]=='\0') return; + + log=fopen(logfile, "a"); + if(log!=NULL) + { + fputs(astart, log); + fputs(atext, log); + fputs(aend, log); + fclose(log); + } +} diff --git a/CryptoPP/GPGw/commonheaders.h b/CryptoPP/GPGw/commonheaders.h new file mode 100644 index 0000000..4ae6e15 --- /dev/null +++ b/CryptoPP/GPGw/commonheaders.h @@ -0,0 +1,79 @@ +// Windows API + +#pragma once +#define _WIN32_IE 0x0500 +//#define WIN32_LEAN_AND_MEAN +//#pragma warning(disable: 4078) + +#include +//#include +#include +#include +#include +#include "..\version.h" + +// gnupg plugin +#include "resource.h" +#include "size.h" +#include "language.h" +#include "pipeexec.h" +#include "gpg.h" +#include "tools.h" +#include "passphrases.h" +#include "passdialog.h" +#include "userdialog.h" +#include "keys.h" + +// debug makro +#define debugout(mtext) MessageBox(NULL, (mtext), "GnuPG Plugin - Debug", MB_OK) + +// passphrase typ +struct passphrase +{ + char keyuserid[keyuseridsize]; + char passphrase[passphrasesize]; +}; + +extern struct passphrase *passphrases; +extern int passphrasecount; + +extern char temporarydirectory[fullfilenamesize]; +extern char logfile[fullfilenamesize]; + +extern char *txtbeginpgppublickeyblock; +extern char *txtendpgppublickeyblock; +extern char *txtbeginpgpmessage; +extern char *txtendpgpmessage; + +#ifdef _MSC_VER +//#pragma comment(linker,"/merge:.rdata=.text") +#pragma comment(linker,"/entry:dllmain") +#pragma comment(linker,"/nodefaultlib") +#pragma comment(linker,"/subsystem:windows") +#pragma optimize("gsy", on) +#endif + +#define MODULENAME "GnuPG" + +extern LPCSTR szModuleName; +extern LPCSTR szVersionStr; +extern HINSTANCE g_hInst; + +#define DLLEXPORT __declspec(dllexport) + +extern DLLEXPORT int __cdecl _gpg_init(void); +extern DLLEXPORT int __cdecl _gpg_done(void); +extern DLLEXPORT int __cdecl _gpg_open_keyrings(LPSTR,LPSTR); +extern DLLEXPORT int __cdecl _gpg_close_keyrings(void); +extern DLLEXPORT void __cdecl _gpg_set_log(LPCSTR); +extern DLLEXPORT void __cdecl _gpg_set_tmp(LPCSTR); +extern DLLEXPORT LPSTR __cdecl _gpg_get_error(void); +extern DLLEXPORT int __cdecl _gpg_size_keyid(void); +extern DLLEXPORT int __cdecl _gpg_select_keyid(HWND,LPSTR); +extern DLLEXPORT LPSTR __cdecl _gpg_encrypt(LPCSTR,LPCSTR); +extern DLLEXPORT LPSTR __cdecl _gpg_decrypt(LPCSTR); +extern DLLEXPORT LPSTR __cdecl _gpg_get_passphrases(); +extern DLLEXPORT void __cdecl _gpg_set_passphrases(LPCSTR); + +void __cdecl ErrorMessage(const char *alevel, const char *atext, const char *ahint); +void __cdecl LogMessage(const char *astart, const char *atext, const char *aend); diff --git a/CryptoPP/GPGw/gnupgw.dsw b/CryptoPP/GPGw/gnupgw.dsw new file mode 100644 index 0000000..1c2166c --- /dev/null +++ b/CryptoPP/GPGw/gnupgw.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "GnuPGw"=.\GnuPGw.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CryptoPP/GPGw/gpg.c b/CryptoPP/GPGw/gpg.c new file mode 100644 index 0000000..354e455 --- /dev/null +++ b/CryptoPP/GPGw/gpg.c @@ -0,0 +1,366 @@ +#include "commonheaders.h" +#include + +char *txtgpgargslistpublickeys= + "--homedir \"%home%\"" + " --with-colon" // felder durch : voneinander abgetrennt + " --list-public-keys"; // oeffentliche schluessel auflisten +char *txtgpgargslistsecretkeys= + "--homedir \"%home%\"" + " --with-colon" + " --list-secret-keys"; // geheime schluessel auflisten +char *txtgpgargsimportpublickey= + "--homedir \"%home%\"" + " --import \"%keyfile%\""; // schluessel importieren +char *txtgpgargsexportpublickey= + "--homedir \"%home%\"" + " --batch" + " --yes" // abfragen mit ja beantworten + " --armor" // ausgabe als text + " --comment \"\"" // kommentar unterdruecken ("Comment: For info see http://www.gnupg.org") + " --no-version" // ausgabe der version unterdruecken ("Version: GnuPG v1.0.6 (MingW32)") + " --export \"%userid%\""; // export des schluessels %userid% +char *txtgpgargsdetectuserid= + "--homedir \"%home%\"" + " --batch" // interaktion verhindern (daraus folgt fehler) + " --decrypt \"%cipherfile%\""; // datei %cipherfile% entschluesseln +char *txtgpgargsencrypt= + "--homedir \"%home%\"" + " --batch" + " --yes" // abfragen mit ja beantworten + " --armor" // textausgabe + " --comment \"\"" // kein kommentar hinzufuegen + " --no-version" // keine versions informationen hinzufuegen + " --recipient \"%userid%\"" // %userid% des empfaengers + " --output \"%cipherfile%\"" // ausgabe in datei %cipherfile% + " --encrypt \"%plainfile%\""; // eingabe kommt aus %plainfile% +char *txtgpgargsdecrypt= + "--homedir \"%home%\"" + " --yes" // abfragen mit ja beantworten + " --passphrase-fd 0" // passphrase von stdin + " --output \"%plainfile%\"" // ausgabe in datei %plainfile% + " --decrypt \"%cipherfile%\""; // eingabe kommt aus %cipherfile% + +// oeffentliche zeichenketten +char gpgExecutable[argumentsize]; +char gpgHomeDirectory[argumentsize]; + + +// zeichenketten fuer den internen gebrauch +char *txtpub="pub"; +char *txtsec="sec"; +char *txtcrlf="\r\n"; +char *txtcolon=":"; +char *txtquotationmark="\""; +char *txtgpgcolon="gpg:"; +char *txtplainfile="%plainfile%"; +char *txtcipherfile="%cipherfile%"; +char *txtuserid="%userid%"; +char *txtkeyfile="%keyfile%"; +char *txthome="%home%"; +char *txtidseparator=", "; + + +void assembleCommandLine(char *aresult, const char *aexecutable, const char *aargs) +{ + strcpy(aresult, aexecutable); + strcat(aresult, " "); + strcat(aresult, aargs); +} + + +void detectKeys(char *aresult, char *aoutput, const char *alabel) +{ + char line[linesize]; + char part[linesize]; + char *linepos; + char *partpos; + long i; + + strcpy(aresult, ""); + linepos=aoutput; + + do + { + linepos=getNextPart(line, linepos, txtcrlf); + if(linepos==NULL) break; + + partpos=line; + partpos=getNextPart(part, partpos, txtcolon); + + if(strcmp(part, alabel)==0) + for(i=1; i<=10; i++) + { + partpos=getNextPart(part, partpos, txtcolon); + + switch(i) + { + case 4: + strcat(aresult, part); + strcat(aresult, txtidseparator); + break; + case 9: + strcat(aresult, part); + strcat(aresult, txtcrlf); + break; + } + } + } + while(linepos!=NULL); + + replace(aresult, "\\x3a", ":"); +} + + +gpgResult gpgListPublicKeys(char *aresult) +{ + pxResult pxresult; + char commandline[commandlinesize]; + DWORD exitcode; + char *output; + + LogMessage(">>> ", "list public keys", "\n"); + output=(char *)malloc(1); + strcpy(output, ""); + assembleCommandLine(commandline, gpgExecutable, txtgpgargslistpublickeys); + replace(commandline, txthome, gpgHomeDirectory); + pxresult=pxExecute(commandline, "", &output, &exitcode); + + if((pxresult!=pxSuccess)||(exitcode!=0)) + { + free(output); + return gpgExecuteFailed; + } + + detectKeys(aresult, output, txtpub); + + free(output); + return gpgSuccess; +} + + +gpgResult gpgListSecretKeys(char *aresult) +{ + pxResult pxresult; + char commandline[commandlinesize]; + DWORD exitcode; + char *output; + + LogMessage(">>> ", "list secret keys", "\n"); + output=(char *)malloc(1); + strcpy(output, ""); + assembleCommandLine(commandline, gpgExecutable, txtgpgargslistsecretkeys); + replace(commandline, txthome, gpgHomeDirectory); + pxresult=pxExecute(commandline, "", &output, &exitcode); + + if((pxresult!=pxSuccess)||(exitcode!=0)) + { + free(output); + return gpgExecuteFailed; + } + + detectKeys(aresult, output, txtsec); + + free(output); + return gpgSuccess; +} + + +gpgResult gpgImportPublicKey(const char *akey) +{ + pxResult pxresult; + char commandline[commandlinesize]; + char filename[fullfilenamesize]; + DWORD exitcode; + char *output; + + LogMessage(">>> ", "import public key", "\n"); + if(! writeToFile(filename, akey)) return gpgWriteToFileFailed; + + output=(char *)malloc(1); + strcpy(output, ""); + assembleCommandLine(commandline, gpgExecutable, txtgpgargsimportpublickey); + replace(commandline, txtkeyfile, filename); + replace(commandline, txthome, gpgHomeDirectory); + pxresult=pxExecute(commandline, "", &output, &exitcode); + remove(filename); + free(output); + + if((pxresult!=pxSuccess)||(exitcode!=0)) + return gpgExecuteFailed; + + return gpgSuccess; +} + + +gpgResult gpgExportPublicKey(char *aresult, const char *auserid) +{ + pxResult pxresult; + char commandline[commandlinesize]; + DWORD exitcode; + char *output; + + LogMessage(">>> ", "export public key", "\n"); + output=(char *)malloc(1); + strcpy(output, ""); + assembleCommandLine(commandline, gpgExecutable, txtgpgargsexportpublickey); + replace(commandline, txtuserid, auserid); + replace(commandline, txthome, gpgHomeDirectory); + pxresult=pxExecute(commandline, "", &output, &exitcode); + + if((pxresult!=pxSuccess)||(exitcode!=0)) + { + strcpy(aresult, ""); + free(output); + return gpgExecuteFailed; + } + + strcpy(aresult, output); + + free(output); + return gpgSuccess; +} + + +gpgResult gpgDetectUserID(char *aresult, const char *aciphertext) +{ + pxResult pxresult; + char commandline[commandlinesize]; + char filename[fullfilenamesize]; + char line[linesize]; + char part[linesize]; + char *linepos; + char *partpos; + DWORD exitcode; + char *output; + + LogMessage(">>> ", "detect user id", "\n"); + strcpy(aresult, ""); + + if(! writeToFile(filename, aciphertext)) + return gpgWriteToFileFailed; + + output=(char *)malloc(1); + strcpy(output, ""); + assembleCommandLine(commandline, gpgExecutable, txtgpgargsdetectuserid); + replace(commandline, txtcipherfile, filename); + replace(commandline, txthome, gpgHomeDirectory); + pxresult=pxExecute(commandline, "", &output, &exitcode); + remove(filename); + + if((pxresult!=pxSuccess)&&(pxresult!=pxSuccessExitCodeInvalid)) + { + free(output); + return gpgExecuteFailed; + } + + linepos=output; + + do + { + linepos=getNextPart(line, linepos, txtcrlf); + if(strncmp(line, txtgpgcolon, strlen(txtgpgcolon))!=0 && strstr(line, txtgpgcolon)==0) + { + partpos=line; + partpos=getNextPart(part, partpos, txtquotationmark); + getNextPart(part, partpos, txtquotationmark); + linepos=NULL; + } + } + while(linepos!=NULL); + strcpy(aresult, part); + + free(output); + return gpgSuccess; +} + + +gpgResult gpgEncrypt(char *aresult, const char *auserid, const char *aplaintext) +{ + pxResult pxresult; + char commandline[commandlinesize]; + char plainfile[fullfilenamesize]; + char cipherfile[fullfilenamesize]; + DWORD exitcode; + char *output; + + LogMessage(">>> ", "encrypt", "\n"); + strcpy(aresult, ""); + + if(! writeToFile(plainfile, aplaintext)) + return gpgWriteToFileFailed; + + output=(char *)malloc(1); + strcpy(output, ""); + getTemporaryFileName(cipherfile); + assembleCommandLine(commandline, gpgExecutable, txtgpgargsencrypt); + replace(commandline, txtcipherfile, cipherfile); + replace(commandline, txtplainfile, plainfile); + replace(commandline, txtuserid, auserid); + replace(commandline, txthome, gpgHomeDirectory); + pxresult=pxExecute(commandline, "", &output, &exitcode); + remove(plainfile); + free(output); + + if((pxresult!=pxSuccess)||(exitcode!=0)) + { + remove(cipherfile); + return gpgExecuteFailed; + } + + if(! readFromFile(aresult, cipherfile)) + { + remove(cipherfile); + return gpgReadFromFileFailed; + } + + remove(cipherfile); + return gpgSuccess; +} + + +gpgResult gpgDecrypt(char *aresult, const char *aciphertext, const char *apassphrase) +{ + pxResult pxresult; + char commandline[commandlinesize]; + char plainfile[fullfilenamesize]; + char cipherfile[fullfilenamesize]; + char passphrase[linesize]; + DWORD exitcode; + char *output; + + LogMessage(">>> ", "decrypt", "\n"); + strcpy(aresult, ""); + + if(! writeToFile(cipherfile, aciphertext)) + return gpgWriteToFileFailed; + + output=(char *)malloc(1); + strcpy(output, ""); + getTemporaryFileName(plainfile); + assembleCommandLine(commandline, gpgExecutable, txtgpgargsdecrypt); + replace(commandline, txtcipherfile, cipherfile); + replace(commandline, txtplainfile, plainfile); + replace(commandline, txthome, gpgHomeDirectory); + strcpy(passphrase, apassphrase); + strcat(passphrase, txtcrlf); + pxresult=pxExecute(commandline, passphrase, &output, &exitcode); + remove(cipherfile); + free(output); + + if((pxresult!=pxSuccess)||(exitcode!=0)) + { + remove(plainfile); + return gpgExecuteFailed; + } + + if(! readFromFile(aresult, plainfile)) + { + remove(plainfile); + return gpgReadFromFileFailed; + } + + remove(plainfile); + return gpgSuccess; +} + diff --git a/CryptoPP/GPGw/gpg.h b/CryptoPP/GPGw/gpg.h new file mode 100644 index 0000000..5a06071 --- /dev/null +++ b/CryptoPP/GPGw/gpg.h @@ -0,0 +1,40 @@ +#ifndef __GPG_H__ +#define __GPG_H__ + +typedef enum +{ + gpgSuccess, + gpgUnknownError, + gpgWriteToFileFailed, + gpgReadFromFileFailed, + gpgExecuteFailed +} +gpgResult; + +// konstanten fuer die initialisierung der parameter +extern char *txtgpgargslistpublickeys; +extern char *txtgpgargslistsecretkeys; +extern char *txtgpgargsimportpublickey; +extern char *txtgpgargsexportpublickey; +extern char *txtgpgargsdetectuserid; +extern char *txtgpgargsencrypt; +extern char *txtgpgargsdecrypt; + +// sonstige konstanten +extern char *txtcrlf; +extern char *txtidseparator; + +// zeichenketten +extern char gpgExecutable[]; +extern char gpgHomeDirectory[]; + +// funktionsprototypen +gpgResult gpgListPublicKeys(char *aresult); +gpgResult gpgListSecretKeys(char *aresult); +gpgResult gpgImportPublicKey(const char *akey); +gpgResult gpgExportPublicKey(char *aresult, const char *auserid); +gpgResult gpgDetectUserID(char *aresult, const char *aciphertext); +gpgResult gpgEncrypt(char *aresult, const char *auserid, const char *aplaintext); +gpgResult gpgDecrypt(char *aresult, const char *aciphertext, const char *apassphrase); + +#endif // __GPG_H__ diff --git a/CryptoPP/GPGw/gpgw.msp b/CryptoPP/GPGw/gpgw.msp new file mode 100644 index 0000000..36a8cee --- /dev/null +++ b/CryptoPP/GPGw/gpgw.msp @@ -0,0 +1,110 @@ +[Project] +name=gpgw +type=2 +defaultConfig=1 + + +[Debug] +// compiler +workingDirectory= +arguments= +intermediateFilesDirectory=Debug +outputFilesDirectory=Debug +compilerPreprocessor= +extraCompilerOptions= +compilerIncludeDirectory= +noWarning=0 +defaultWarning=0 +allWarning=1 +extraWarning=0 +isoWarning=0 +warningsAsErrors=0 +debugType=1 +debugLevel=2 +exceptionEnabled=1 +runtimeTypeEnabled=1 +optimizeLevel=0 + +// linker +libraryPath= +outputFilename=Debug\gpgw.dll +libraries=comdlg32 +extraLinkerOptions= +ignoreStartupFile=0 +ignoreDefaultLibs=0 +stripExecutableFile=0 + +// archive +extraArchiveOptions= + +//resource +resourcePreprocessor= +resourceIncludeDirectory= +extraResourceOptions= + +[Release] +// compiler +workingDirectory= +arguments= +intermediateFilesDirectory=Release +outputFilesDirectory=Release +compilerPreprocessor= +extraCompilerOptions= +compilerIncludeDirectory= +noWarning=0 +defaultWarning=0 +allWarning=1 +extraWarning=0 +isoWarning=0 +warningAsErrors=0 +debugType=0 +debugLevel=1 +exceptionEnabled=0 +runtimeTypeEnabled=0 +optimizeLevel=4 + +// linker +libraryPath= +outputFilename=Release\gpgw.dll +libraries=comdlg32 +extraLinkerOptions= +ignoreStartupFile=0 +ignoreDefaultLibs=0 +stripExecutableFile=1 + +// archive +extraArchiveOptions= + +//resource +resourcePreprocessor= +resourceIncludeDirectory= +extraResourceOptions= + +[Source] +1=commonheaders.c +2=gpg.c +3=keys.c +4=language.c +5=main.c +6=passdialog.c +7=passphrases.c +8=pipeexec.c +9=tools.c +10=userdialog.c +[Header] +1=commonheaders.h +2=gpg.h +3=keys.h +4=language.h +5=passdialog.h +6=passphrases.h +7=pipeexec.h +8=resource.h +9=size.h +10=tools.h +11=userdialog.h +[Resource] +1=resource.rc +[Other] +[History] +pipeexec.c,1120 diff --git a/CryptoPP/GPGw/keys.c b/CryptoPP/GPGw/keys.c new file mode 100644 index 0000000..4cfbe4f --- /dev/null +++ b/CryptoPP/GPGw/keys.c @@ -0,0 +1,67 @@ +#include "commonheaders.h" + +typedef char tkeyuserid[keyuseridsize]; + +tkeyuserid *keyuserids[2]; +int keyuseridcount[2]; + + +void initKeyUserIDs(const int atype) +{ + keyuseridcount[atype]=0; + keyuserids[atype]=NULL; +} + + +void updateKeyUserIDs(const int atype) +{ + char *pos; + gpgResult gpgresult; + char buffer[largebuffersize]; + char keyuserid[keyuseridsize]; + + releaseKeyUserIDs(atype); + initKeyUserIDs(atype); + + ZeroMemory(buffer, sizeof(buffer)); + if(atype==publickeyuserid) gpgresult=gpgListPublicKeys(buffer); + else gpgresult=gpgListSecretKeys(buffer); + + if(gpgresult!=gpgSuccess) + { +// if(atype==publickeyuserid) ErrorMessage(txterror, txtlistpublickeysfailed, txtverifyoptions); +// else ErrorMessage(txterror, txtlistsecretkeysfailed, txtverifyoptions); + return; + } + + for(pos=buffer; pos!=NULL; ) + { + pos=getNextPart(keyuserid, pos, txtcrlf); + + if(pos!=NULL) + { + keyuseridcount[atype]++; + keyuserids[atype]=realloc(keyuserids[atype], sizeof(tkeyuserid)*keyuseridcount[atype]); + strcpy(keyuserids[atype][keyuseridcount[atype]-1], keyuserid); + } + } +} + + +void releaseKeyUserIDs(const int atype) +{ + free(keyuserids[atype]); +} + + +char *getKeyUserID(const int atype, const int aindex) +{ + return keyuserids[atype][aindex]; +} + + +int getKeyUserIDCount(const int atype) +{ + return keyuseridcount[atype]; +} + diff --git a/CryptoPP/GPGw/keys.h b/CryptoPP/GPGw/keys.h new file mode 100644 index 0000000..394c6c0 --- /dev/null +++ b/CryptoPP/GPGw/keys.h @@ -0,0 +1,13 @@ +#ifndef __KEYS_H__ +#define __KEYS_H__ + +#define publickeyuserid 0 +#define secretkeyuserid 1 + +void initKeyUserIDs(const int atype); +void updateKeyUserIDs(const int atype); +void releaseKeyUserIDs(const int atype); +char *getKeyUserID(const int atype, const int aindex); +int getKeyUserIDCount(const int atype); + +#endif // __KEYS_H__ diff --git a/CryptoPP/GPGw/language.c b/CryptoPP/GPGw/language.c new file mode 100644 index 0000000..4997711 --- /dev/null +++ b/CryptoPP/GPGw/language.c @@ -0,0 +1,27 @@ +#include "commonheaders.h" + +//char *txtverifyoptions="Please verify your settings in M->Options->Plugins->GnuPG and GnuPG Advanced."; /*lang*/ +//char *txtinvalidexecutable="The GnuPG Plugin requires the GnuPG executable \"gpg.exe\"."; /*lang*/ +//char *txtinvaliduserid="Could not obtain the GnuPG user id."; /*lang*/ +//char *txtexportpublickeyfailed="The export of your public key failed."; /*lang*/ +//char *txtimportpublickeyfailed="The import of the key failed."; /*lang*/ +char *txtlistpublickeysfailed="Could not generate a list of the public GnuPG keys."; /*lang*/ +char *txtlistsecretkeysfailed="Could not generate a list of the secret GnuPG keys."; /*lang*/ +//char *txtplugins="Plugins"; /*lang*/ +//char *txtgnupgplugin="GnuPG Plugin"; /*lang*/ +//char *txtexecutablefiles="Executable Files"; /*lang*/ +//char *txtselectexecutable="Select GnuPG Executable"; /*lang*/ +char *txtwarning="GnuPG Plugin - Warning"; /*lang*/ +char *txterror="GnuPG Plugin - Error"; /*lang*/ +//char *txtnone=""; /*lang*/ +//char *txtuseencryption="Use GnuPG Encryption"; /*lang*/ +//char *txtsendpublickey="Send GnuPG Key"; /*lang*/ +//char *txtpublickeyreceived="You received a public key."; /*lang*/ +//char *txtpublickeyreceivedstored="You received a public key. It was added to your keyring."; /*lang*/ +char *txtdetectuseridfailed="You received an encrypted message. Could not detect the user id of the public key, used to encrypt it."; /*lang*/ +char *txtunknownuserid="Unknown User ID"; /*lang*/ +char *txtencryptfailed="Could not encrypt the message. It wasn't sent."; /*lang*/ +//char *txtoptions="GnuPG"; /*lang*/ +//char *txtexpertoptions="GnuPG Advanced"; /*lang*/ + + diff --git a/CryptoPP/GPGw/language.h b/CryptoPP/GPGw/language.h new file mode 100644 index 0000000..6c3548b --- /dev/null +++ b/CryptoPP/GPGw/language.h @@ -0,0 +1,29 @@ +#ifndef __TEXT_H__ +#define __TEXT_H__ + +// textkonstanten, die uebersetzt werden muessen +extern char *txtverifyoptions; +extern char *txtinvalidexecutable; +extern char *txtinvaliduserid; +extern char *txtexportpublickeyfailed; +extern char *txtimportpublickeyfailed; +extern char *txtlistpublickeysfailed; +extern char *txtlistsecretkeysfailed; +extern char *txtplugins; +extern char *txtgnupgplugin; +extern char *txtexecutablefiles; +extern char *txtselectexecutable; +extern char *txtwarning; +extern char *txterror; +extern char *txtnone; +extern char *txtuseencryption; +extern char *txtsendpublickey; +extern char *txtpublickeyreceived; +extern char *txtpublickeyreceivedstored; +extern char *txtdetectuseridfailed; +extern char *txtunknownuserid; +extern char *txtencryptfailed; +extern char *txtoptions; +extern char *txtexpertoptions; + +#endif // __TEXT_H__ diff --git a/CryptoPP/GPGw/main.c b/CryptoPP/GPGw/main.c new file mode 100644 index 0000000..766d491 --- /dev/null +++ b/CryptoPP/GPGw/main.c @@ -0,0 +1,369 @@ +#include "commonheaders.h" + + +BOOL ShowSelectExecDlg(LPSTR); +BOOL ShowSelectHomeDlg(LPSTR); + + +int __cdecl _gpg_init() +{ + GetTempPath(sizeof(temporarydirectory),temporarydirectory); + logfile[0]='\0'; + initPassphrases(); + initKeyUserIDs(publickeyuserid); + initKeyUserIDs(secretkeyuserid); + return 1; +} + + +int __cdecl _gpg_done() +{ + releaseKeyUserIDs(secretkeyuserid); + releaseKeyUserIDs(publickeyuserid); + releasePassphrases(); + return 1; +} + + +int __cdecl _gpg_open_keyrings(LPSTR ExecPath, LPSTR HomePath) +{ + if( !ExecPath || (!*ExecPath && !ShowSelectExecDlg(ExecPath)) ) { + return 0; + } + if( !HomePath || (!*HomePath && !ShowSelectHomeDlg(HomePath)) ) { + return 0; + } + if( !existsFile(ExecPath) ) { +// ErrorMessage(txtwarning, txtinvalidexecutable, txtverifyoptions); + return 0; + } + strcpy(gpgExecutable, ExecPath); + strcpy(gpgHomeDirectory, HomePath); + updateKeyUserIDs(publickeyuserid); + updateKeyUserIDs(secretkeyuserid); + return 1; +} + + +int __cdecl _gpg_close_keyrings() +{ + return 1; +} + + +LPSTR __cdecl _gpg_get_error() +{ + return 0; +} + + +void __cdecl _gpg_set_log(LPCSTR LogPath) +{ + if(LogPath) strncpy(logfile,LogPath,sizeof(logfile)); + else logfile[0]='\0'; +} + + +void __cdecl _gpg_set_tmp(LPCSTR TmpPath) +{ + if(TmpPath) strncpy(temporarydirectory,TmpPath,sizeof(temporarydirectory)); + else GetTempPath(sizeof(temporarydirectory),temporarydirectory); +} + + +LPSTR __cdecl _gpg_get_passphrases() +{ + size_t i; char *b, x; + + b = (char *) LocalAlloc(LPTR,(keyuseridsize+passphrasesize)*passphrasecount+1); *b = '\0'; + + for(i=0; i<(size_t)passphrasecount; i++) { + strcat(b,passphrases[i].keyuserid); strcat(b,"\x01"); + strcat(b,passphrases[i].passphrase); strcat(b,"\x02"); + } + + // encrypt + for(i=0; i2 ) { + x = b[i] ^ ( (i&0x7f) ^ 13); + if( x>2 ) b[i]=x; + } + + return b; +} + + +void __cdecl _gpg_set_passphrases(LPCSTR buffer) +{ + size_t i, l = strlen(buffer); char *t, *p, *b, x; + + if( !l ) return; + + b = (char *) LocalAlloc(LPTR,l+1); + strcpy(b, buffer); + + // decrypt + for(i=0; i2 ) { + x = b[i] ^ ( (i&0x7f) ^ 13); + if( x>2 ) b[i]=x; + } + + while(*b) { + t = strchr(b, '\x02'); + if(t) { + *t = '\0'; + p = strchr(b, '\x01'); + *p = '\0'; + addPassphrase(b, p+1); + t++; + } + b = t; + } + LocalFree(b); +} + + +LPSTR __cdecl _gpg_encrypt(LPCSTR message, LPCSTR keyid) +{ + char buffer[ciphertextsize]; + char *encmessage = 0; + int encmessagelen; + gpgResult gpgresult; + + if(strlen(keyid)) + { + ZeroMemory(buffer, sizeof(buffer)); + gpgresult=gpgEncrypt(buffer, keyid, message); + + if(gpgresult!=gpgSuccess) + { +// ErrorMessage(txterror, txtencryptfailed, txtverifyoptions); + return 0; + } + encmessagelen = strlen(buffer)+1; + encmessage = (char *) LocalAlloc(LPTR,encmessagelen); + MoveMemory(encmessage, buffer, encmessagelen); + } + + return encmessage; +} + + +LPSTR __cdecl _gpg_decrypt(LPCSTR message) +{ + char buffer[ciphertextsize]; + char plaintext[plaintextsize]; + char keyuserid[keyuseridsize]; + char *begin, *end; + int dlgresult; + BOOL useridvalid; + char *storedpassphrase; + char passphrase[passphrasesize]; + char *decmessage = 0; + int decmessagelen; + gpgResult gpgresult; + + begin=strstr(message, txtbeginpgpmessage); + end=strstr(message, txtendpgpmessage); + + if((begin!=NULL)&&(end!=NULL)) + { + strcpy(buffer, ""); + strncat(buffer, begin, end-begin+strlen(txtendpgpmessage)); + replace(buffer, "\r", ""); + replace(buffer, "\n", txtcrlf); + + ZeroMemory(keyuserid, sizeof(keyuserid)); + gpgresult=gpgDetectUserID(keyuserid, buffer); + storedpassphrase=NULL; + + if(gpgresult!=gpgSuccess) + { +// ErrorMessage(txtwarning, txtdetectuseridfailed, txtverifyoptions); + strcpy(keyuserid, txtunknownuserid); + useridvalid=FALSE; + } + else + { + storedpassphrase=getPassphrase(keyuserid); + useridvalid=TRUE; + } + + if(storedpassphrase!=NULL) + { + strcpy(passphrase, storedpassphrase); + ZeroMemory(plaintext, sizeof(plaintext)); + gpgresult=gpgDecrypt(plaintext, buffer, passphrase); + } + else gpgresult=gpgUnknownError; + + dlgresult=IDOK; + while((gpgresult!=gpgSuccess)&&(dlgresult!=IDCANCEL)) + { + dlgresult=DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_PASSPHRASE), NULL, PassphraseDialogProcedure, (LPARAM)keyuserid); + + if(dlgresult==IDOK) + { + strcpy(passphrase, dlgpassphrase); + ZeroMemory(dlgpassphrase, passphrasesize); + strcat(passphrase, txtcrlf); + ZeroMemory(plaintext, sizeof(plaintext)); + gpgresult=gpgDecrypt(plaintext, buffer, passphrase); + } + } + + if(gpgresult==gpgSuccess) + { + strcpy(buffer, plaintext); + } + + if( gpgresult==gpgSuccess && useridvalid==TRUE) + addPassphrase(keyuserid, passphrase); + + ZeroMemory(passphrase, sizeof(passphrase)); + + decmessagelen = strlen(buffer)+1; + decmessage = (char *) LocalAlloc(LPTR,decmessagelen); + MoveMemory(decmessage, buffer, decmessagelen); + } + + return decmessage; +} + + +int __cdecl _gpg_size_keyid() +{ + return keyidsize; +} + + +int __cdecl _gpg_select_keyid(HWND hdlg, LPSTR keyid) +{ + int dlgresult; + + ZeroMemory(keyid, keyidsize); + dlgresult=DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_SELECTKEY), hdlg, UserIdDialogProcedure, (LPARAM)keyid); + + if(dlgresult!=IDOK) + ZeroMemory(keyid, keyidsize); + + return (dlgresult==IDOK); +} + + +void noBackslash(LPSTR path) { + LPSTR ptr; + ptr = path + strlen(path) - 1; + if( *ptr=='\\' ) *ptr = '\0'; +} + + +static char buf[MAX_PATH]; + + +LPSTR GetRegValue(HKEY hKey , LPCSTR szPath, LPCSTR szName){ + DWORD len=MAX_PATH,type; + LPSTR ret=0; + + RegOpenKey(hKey,szPath,&hKey); + if( RegQueryValueEx(hKey,szName,NULL,&type,(LPBYTE)&buf,&len)==ERROR_SUCCESS ){ + noBackslash((LPSTR)&buf); + ret = (LPSTR)&buf; + } + RegCloseKey(hKey); + + return ret; +} + + +LPSTR GetEnvValue(LPCSTR szName){ + LPSTR ret=0; + + if( GetEnvironmentVariable(szName, buf, MAX_PATH) > 0 ) { + noBackslash((LPSTR)&buf); + ret = (LPSTR)&buf; + } + + return ret; +} + + +BOOL ShowSelectExecDlg(LPSTR path) +{ + OPENFILENAME ofn; + ZeroMemory(&ofn,sizeof(ofn)); + + ofn.lpstrFile = GetRegValue(HKEY_CURRENT_USER,"Software\\GNU\\GnuPG","gpgProgram"); + if( ofn.lpstrFile && existsFile(ofn.lpstrFile) ) { + strcpy(path, ofn.lpstrFile); + return TRUE; + } + ofn.lpstrFile = GetRegValue(HKEY_LOCAL_MACHINE,"Software\\GNU\\GnuPG","Install Directory"); + if( ofn.lpstrFile ) { + strcat(ofn.lpstrFile,"\\gpg.exe"); + if( existsFile(ofn.lpstrFile) ) { + strcpy(path, ofn.lpstrFile); + return TRUE; + } + } + + ofn.lStructSize = sizeof(ofn); + ofn.nMaxFile = MAX_PATH; + ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_NONETWORKBUTTON; + + ofn.lpstrFile = path; + ofn.lpstrFilter = "GnuPG executable (gpg.exe)\0gpg.exe\0All files (*.*)\0*.*\0"; + ofn.lpstrTitle = "Select GnuPG executable"; + if (!GetOpenFileName(&ofn)) return FALSE; + + return TRUE; +} + + +BOOL ShowSelectHomeDlg(LPSTR path) +{ + int i; + OPENFILENAME ofn; + + ofn.lpstrFile = GetEnvValue("GNUPGHOME"); + if( ofn.lpstrFile && existsPath(ofn.lpstrFile) ) { + strcpy(path, ofn.lpstrFile); + return TRUE; + } + ofn.lpstrFile = GetRegValue(HKEY_CURRENT_USER,"Software\\GNU\\GnuPG","HomeDir"); + if( ofn.lpstrFile && existsPath(ofn.lpstrFile) ) { + strcpy(path, ofn.lpstrFile); + return TRUE; + } + ofn.lpstrFile = GetEnvValue("APPDATA"); + if( ofn.lpstrFile ) { + strcat(ofn.lpstrFile,"\\gnupg"); + if( existsPath(ofn.lpstrFile) ) { + strcpy(path, ofn.lpstrFile); + return TRUE; + } + } + + ofn.lStructSize = sizeof(ofn); + ofn.nMaxFile = MAX_PATH; + ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_NONETWORKBUTTON; + + ofn.lpstrFile = path; + ofn.lpstrFilter = "Public key rings (pubring.gpg)\0pubring.gpg\0All files (*.*)\0*.*\0"; + ofn.lpstrTitle = "Open Public Keyring"; + if (!GetOpenFileName(&ofn)) return FALSE; + + for(i=strlen(path);i && path[i]!='\\';i--); + path[i] = 0; + + return TRUE; +} + + +// dllmain +BOOL WINAPI dllmain(HINSTANCE hInst, DWORD dwReason, LPVOID lpVoid) { + g_hInst = hInst; + return TRUE; +} + diff --git a/CryptoPP/GPGw/passdialog.c b/CryptoPP/GPGw/passdialog.c new file mode 100644 index 0000000..cbba113 --- /dev/null +++ b/CryptoPP/GPGw/passdialog.c @@ -0,0 +1,29 @@ +#include "commonheaders.h" + +char dlgpassphrase[passphrasesize]; + + +BOOL CALLBACK PassphraseDialogProcedure(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam) +{ + switch(msg) + { + case WM_INITDIALOG: + SetDlgItemText(hdlg, IDC_USERID, (char *)lparam); + break; + case WM_COMMAND: + switch(LOWORD(wparam)) + { + case IDOK: + ZeroMemory(dlgpassphrase, sizeof(dlgpassphrase)); + GetDlgItemText(hdlg, IDC_PASSPHRASE, dlgpassphrase, sizeof(dlgpassphrase)); + case IDCANCEL: + EndDialog(hdlg, wparam); + return TRUE; + break; + } + break; + } + + return FALSE; +} + diff --git a/CryptoPP/GPGw/passdialog.h b/CryptoPP/GPGw/passdialog.h new file mode 100644 index 0000000..b59f421 --- /dev/null +++ b/CryptoPP/GPGw/passdialog.h @@ -0,0 +1,8 @@ +#ifndef __PASSDIALOG_H__ +#define __PASSDIALOG_H__ + +extern char dlgpassphrase[]; + +BOOL CALLBACK PassphraseDialogProcedure(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam); + +#endif // __PASSDIALOG_H__ diff --git a/CryptoPP/GPGw/passphrases.c b/CryptoPP/GPGw/passphrases.c new file mode 100644 index 0000000..5e93936 --- /dev/null +++ b/CryptoPP/GPGw/passphrases.c @@ -0,0 +1,50 @@ +#include "commonheaders.h" + +// globale variablen +struct passphrase *passphrases; +int passphrasecount; + + +void initPassphrases(void) +{ + passphrasecount=0; + passphrases=NULL; +} + + +void releasePassphrases(void) +{ + int i; + + for(i=0; i0); +} + + +pxResult pxExecute(char *acommandline, char *ainput, char **aoutput, LPDWORD aexitcode) +{ + BOOL success; + STARTUPINFO startupinfo; + SECURITY_ATTRIBUTES securityattributes; + SECURITY_DESCRIPTOR securitydescriptor; + PROCESS_INFORMATION processinformation; + HANDLE newstdin, newstdout, readstdout, writestdin; + char *inputpos; + DWORD transfered; + int size; + + LogMessage("commandline:\n", acommandline, "\n"); + + ZeroMemory(&securityattributes, sizeof(securityattributes)); + securityattributes.nLength=sizeof(SECURITY_ATTRIBUTES); + securityattributes.bInheritHandle=TRUE; + + if(isWindowsNT()) + { + InitializeSecurityDescriptor(&securitydescriptor, SECURITY_DESCRIPTOR_REVISION); + SetSecurityDescriptorDacl(&securitydescriptor, TRUE, NULL, FALSE); + securityattributes.lpSecurityDescriptor=&securitydescriptor; + } + else securityattributes.lpSecurityDescriptor=NULL; + + success=CreatePipe(&newstdin, &writestdin ,&securityattributes ,0); + if(! success) + { + LogMessage("--- ", "create pipe failed", "\n"); + return pxCreatePipeFailed; + } + + success=CreatePipe(&readstdout, &newstdout, &securityattributes, 0); + if(! success) + { + LogMessage("--- ", "create pipe failed", "\n"); + CloseHandle(newstdin); + CloseHandle(writestdin); + return pxCreatePipeFailed; + } + + GetStartupInfo(&startupinfo); + startupinfo.dwFlags=STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW; + startupinfo.wShowWindow=SW_HIDE; + startupinfo.hStdOutput=newstdout; + startupinfo.hStdError=newstdout; + startupinfo.hStdInput=newstdin; + + success=CreateProcess(NULL, acommandline, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &startupinfo, &processinformation); + + if(! success) + { + LogMessage("--- ", "create process failed", "\n"); + CloseHandle(newstdin); + CloseHandle(writestdin); + CloseHandle(newstdout); + CloseHandle(readstdout); + return pxCreateProcessFailed; + } + + inputpos=ainput; + + while(TRUE) + { + success=GetExitCodeProcess(processinformation.hProcess, aexitcode); + if((success)&&(*aexitcode!=STILL_ACTIVE)) break; + + storeOutput(readstdout, aoutput); + + if(*inputpos!='\0') size=1; + else size=0; + + success=WriteFile(writestdin, inputpos, size, &transfered, NULL); + + inputpos+=transfered; + } + + storeOutput(readstdout, aoutput); + WaitForSingleObject(processinformation.hProcess, INFINITE); + + LogMessage("output:\n", *aoutput, ""); + + CloseHandle(processinformation.hThread); + CloseHandle(processinformation.hProcess); + CloseHandle(newstdin); + CloseHandle(newstdout); + CloseHandle(readstdout); + CloseHandle(writestdin); + + return pxSuccess; +} + diff --git a/CryptoPP/GPGw/pipeexec.h b/CryptoPP/GPGw/pipeexec.h new file mode 100644 index 0000000..241e071 --- /dev/null +++ b/CryptoPP/GPGw/pipeexec.h @@ -0,0 +1,24 @@ +#ifndef __PIPEEXEC_H__ +#define __PIPEEXEC_H__ + +#include + +// typen +typedef enum +{ + pxSuccess, + pxSuccessExitCodeInvalid, + pxCreatePipeFailed, + pxDuplicateHandleFailed, + pxCloseHandleFailed, + pxCreateProcessFailed, + pxThreadWaitFailed, + pxReadFileFailed, + pxBufferOverflow +} +pxResult; + +pxResult pxExecute(char *acommandline, char *ainput, char **aoutput, LPDWORD aexitcode); + +#endif // __PIPEEXEC_H__ + diff --git a/CryptoPP/GPGw/resource.h b/CryptoPP/GPGw/resource.h new file mode 100644 index 0000000..af5efe2 --- /dev/null +++ b/CryptoPP/GPGw/resource.h @@ -0,0 +1,21 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by resource.rc +// +#define IDD_PASSPHRASE 101 +#define IDD_SELECTKEY 102 +#define IDC_PASSPHRASE 1000 +#define IDC_USERID 1001 +#define IDC_KEYLIST 1002 +#define IDC_REFRESH 1003 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 103 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1004 +#define _APS_NEXT_SYMED_VALUE 103 +#endif +#endif diff --git a/CryptoPP/GPGw/resource.rc b/CryptoPP/GPGw/resource.rc new file mode 100644 index 0000000..53968a5 --- /dev/null +++ b/CryptoPP/GPGw/resource.rc @@ -0,0 +1,112 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Neutral resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) +#ifdef _WIN32 +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL +#pragma code_page(1251) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_PASSPHRASE DIALOG 0, 0, 238, 46 +STYLE DS_SYSMODAL | DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "GnuPG Plugin - Passphrase" +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "Enter passphrase for the secret key of user:", IDC_STATIC,6,4,168,8 + LTEXT "User ID",IDC_USERID,6,14,168,8 + EDITTEXT IDC_PASSPHRASE,6,24,168,12,ES_PASSWORD | ES_AUTOHSCROLL + DEFPUSHBUTTON "Ok",IDOK,181,7,50,14 + PUSHBUTTON "Cancel",IDCANCEL,181,24,50,14 +END + +IDD_SELECTKEY DIALOGEX 0, 0, 272, 208 +STYLE DS_SYSMODAL | DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "GnuPG Plugin - Select public key" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "",IDC_KEYLIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SORTASCENDING | + LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,7,7,258,174 + PUSHBUTTON "Refresh",IDC_REFRESH,7,187,50,14 + DEFPUSHBUTTON "Ok",IDOK,154,187,50,14 + PUSHBUTTON "Cancel",IDCANCEL,215,187,50,14 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_SELECTKEY, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 265 + TOPMARGIN, 7 + BOTTOMMARGIN, 201 + END +END +#endif // APSTUDIO_INVOKED + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // Neutral resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/CryptoPP/GPGw/size.h b/CryptoPP/GPGw/size.h new file mode 100644 index 0000000..e9382f7 --- /dev/null +++ b/CryptoPP/GPGw/size.h @@ -0,0 +1,21 @@ +#ifndef __SIZE_H__ +#define __SIZE_H__ + +// array groessen +#define contactsize 256 +#define passphrasesize 256 +#define errormessagesize 512 +#define keybuffersize 8192 +#define fullfilenamesize 1024 +#define argumentsize 512 +#define commandlinesize 2048 +#define linesize 512 +#define filenamesize L_tmpnam +#define ciphertextsize 16384 +#define plaintextsize 16384 +#define plugintagsize 128 +#define keyuseridsize 512 +#define keyidsize 80 +#define largebuffersize 16384 + +#endif // __SIZE_H__ diff --git a/CryptoPP/GPGw/tools.c b/CryptoPP/GPGw/tools.c new file mode 100644 index 0000000..ee7adde --- /dev/null +++ b/CryptoPP/GPGw/tools.c @@ -0,0 +1,191 @@ +#include "commonheaders.h" + +// escape sequence type +struct escapesequence +{ + char *sequence; + char *code; +}; + +// supported escape sequences +struct escapesequence escsequence[]= +{ + {"\\n", "\n"}, + {"\\r", "\r"}, + {"\\t", "\t"} +}; + +// number of supported escape sequences +int escsequencecount=sizeof(escsequence)/sizeof(struct escapesequence); + + +void replace(char *atext, const char *apattern, const char *areplacement) +{ + char *pos, *last; + long textsize; + long patternsize; + long replacementsize; + + pos=atext; + patternsize=strlen(apattern); + replacementsize=strlen(areplacement); + + do + { + // textstelle suchen + last=pos; + pos=strstr(pos, apattern); + // etwas gefunden? + if(pos==NULL) break; + + // laenge des textes ermitteln + textsize=strlen(last); + // platz schaffen + memmove(pos+replacementsize, pos+patternsize, textsize-((pos-last)+patternsize)+1); + // ersetzen + strncpy(pos, areplacement, replacementsize); + pos+=replacementsize; + } + while(pos!=NULL); +} + + +char *getNextPart(char *aresult, char *atext, const char *aseparator) +{ + char *pos; + + strcpy(aresult, ""); + pos=strstr(atext, aseparator); + + if(pos!=NULL) + { + strncat(aresult, atext, pos-atext); + pos+=strlen(aseparator); + } + else strcpy(aresult, atext); + + return pos; +} + + +void getLastPart(char *aresult, char *atext) +{ + strcpy(aresult, atext); +} + + +void appendText(char **abuffer, const char *atext, int atextsize) +{ + int size; + + if(*abuffer==NULL) size=0; + else size=strlen(*abuffer); + size++; // abschliessende 0 + if(atextsize==0) atextsize=strlen(atext); + size+=atextsize; + + *abuffer=(char *)realloc(*abuffer, size); + strncat(*abuffer, atext, atextsize); +} + + +BOOL existsFile(const char *afilename) +{ + int attr; + + if(strlen(afilename)==0) return FALSE; + + attr = GetFileAttributes(afilename); + + return ( (attr!=-1) && ((attr&FILE_ATTRIBUTE_DIRECTORY)==0)); +} + + +BOOL existsPath(const char *apathname) +{ + int attr; + + if(strlen(apathname)==0) return FALSE; + + attr = GetFileAttributes(apathname); + + return ( (attr!=-1) && (attr&FILE_ATTRIBUTE_DIRECTORY) ); +} + + +BOOL writeToFile(char *afilename, const char *atext) +{ + FILE *handle; + size_t written; + size_t length; + + getTemporaryFileName(afilename); + + handle=fopen(afilename, "wb"); + + if(handle==NULL) + { + LogMessage("--- ", "write to file", "\n"); + LogMessage("filename:\n", afilename, "\n"); + return FALSE; + } + + length=strlen(atext); + written=fwrite(atext, sizeof(char), length, handle); + + if(written!=length) return FALSE; + + fclose(handle); + return TRUE; +} + + +BOOL readFromFile(char *aresult, const char *afilename) +{ + FILE *handle; + size_t filesize; + size_t read; + + handle=fopen(afilename, "rb"); + if(handle==NULL) + { + LogMessage("--- ", "read from file", "\n"); + LogMessage("filename:\n", afilename, "\n"); + return FALSE; + } + + fseek(handle, 0, SEEK_END); + filesize=ftell(handle); + fseek(handle, 0, SEEK_SET); + + read=fread(aresult, sizeof(char), filesize, handle); + if(read!=filesize) return FALSE; + + fclose(handle); + return TRUE; +} + + +void getTemporaryFileName(char *aresult) +{ + GetTempFileName(temporarydirectory,"gpg",0,aresult); +} + + +void quoteEscapeSequences(char *atext) +{ + int i; + + for(i=0; i +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=PGPsdkW - Win32 Release6 +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "PGPsdkW.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "PGPsdkW.mak" CFG="PGPsdkW - Win32 Release6" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "PGPsdkW - Win32 Release6" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "PGPsdkW - Win32 Release8" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "PGPsdkW - Win32 Release6" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "PGPsdkW___Win32_Release6" +# PROP BASE Intermediate_Dir "PGPsdkW___Win32_Release6" +# PROP BASE Ignore_Export_Lib 1 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release6" +# PROP Intermediate_Dir "Release6" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /Gi /O1 /I "sdk6/include" /D PGP_WIN32=0x658 /YX"commonheaders.h" /FD /c +# ADD CPP /nologo /MD /W3 /Gi /GX /O1 /I "sdk6/include" /D PGP_WIN32=0x658 /Yu"commonheaders.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x417 /d "NDEBUG" +# ADD RSC /l 0x417 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 delayimp.lib pgp_sdk.lib pgpsdknl.lib pgpsdkui.lib kernel32.lib user32.lib shell32.lib gdi32.lib msimg32.lib comdlg32.lib msvcrt.lib /nologo /base:"0x46600000" /dll /map /machine:I386 /pdb:"Release6/PGPsdkW6.pdb" /out:"Release6/PGPsdkW6.dll" /libpath:"sdk6/lib" /filealign:0x200 /delayload:pgp_sdk.dll /delayload:pgpsdkui.dll +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 delayimp.lib pgp_sdk.lib pgpsdknl.lib pgpsdkui.lib kernel32.lib user32.lib shell32.lib gdi32.lib msimg32.lib comdlg32.lib msvcrt.lib /nologo /base:"0x46600000" /dll /map /machine:I386 /pdb:"Release6/PGPsdkW6.pdb" /out:"Release6/PGPsdkW6.dll" /libpath:"sdk6/lib" /filealign:0x200 /delayload:pgp_sdk.dll /delayload:pgpsdkui.dll +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "PGPsdkW - Win32 Release8" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "PGPsdkW___Win32_Release8" +# PROP BASE Intermediate_Dir "PGPsdkW___Win32_Release8" +# PROP BASE Ignore_Export_Lib 1 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release8" +# PROP Intermediate_Dir "Release8" +# PROP Ignore_Export_Lib 1 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /Gi /O1 /I "sdk8/include" /D PGP_WIN32=0x800 /YX"commonheaders.h" /FD /c +# ADD CPP /nologo /MD /W3 /Gi /GX /O1 /I "sdk8/include" /D PGP_WIN32=0x800 /Yu"commonheaders.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x417 /d "NDEBUG" +# ADD RSC /l 0x417 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 delayimp.lib pgpsdk.lib pgpsdknl.lib pgpsdkui.lib kernel32.lib user32.lib shell32.lib gdi32.lib msimg32.lib comdlg32.lib msvcrt.lib /nologo /base:"0x46800000" /dll /map /machine:I386 /pdb:"Release8/PGPsdkW8.pdb" /out:"Release8/PGPsdkW8.dll" /libpath:"sdk8/lib" /filealign:0x200 /delayload:pgp_sdk.dll /delayload:pgpsdkui.dll +# SUBTRACT BASE LINK32 /pdb:none +# ADD LINK32 delayimp.lib pgpsdk.lib pgpsdknl.lib pgpsdkui.lib kernel32.lib user32.lib shell32.lib gdi32.lib msimg32.lib comdlg32.lib msvcrt.lib /nologo /base:"0x46800000" /dll /map /machine:I386 /pdb:"Release8/PGPsdkW8.pdb" /out:"Release8/PGPsdkW8.dll" /libpath:"sdk8/lib" /filealign:0x200 /delayload:pgpsdk.dll /delayload:pgpsdkui.dll +# SUBTRACT LINK32 /pdb:none + +!ENDIF + +# Begin Target + +# Name "PGPsdkW - Win32 Release6" +# Name "PGPsdkW - Win32 Release8" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\commonheaders.cpp +# ADD CPP /Yc"commonheaders.h" +# End Source File +# Begin Source File + +SOURCE=.\main.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\commonheaders.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/CryptoPP/PGPw/PGPsdkW.dsw b/CryptoPP/PGPw/PGPsdkW.dsw new file mode 100644 index 0000000..443b854 --- /dev/null +++ b/CryptoPP/PGPw/PGPsdkW.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "PGPsdkW"=.\PGPsdkW.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CryptoPP/PGPw/PGPsdkW.mak b/CryptoPP/PGPw/PGPsdkW.mak new file mode 100644 index 0000000..86459e7 --- /dev/null +++ b/CryptoPP/PGPw/PGPsdkW.mak @@ -0,0 +1,220 @@ +# Microsoft Developer Studio Generated NMAKE File, Based on PGPsdkW.dsp +!IF "$(CFG)" == "" +CFG=PGPsdkW - Win32 Release6 +!MESSAGE No configuration specified. Defaulting to PGPsdkW - Win32 Release6. +!ENDIF + +!IF "$(CFG)" != "PGPsdkW - Win32 Release6" && "$(CFG)" != "PGPsdkW - Win32 Release8" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "PGPsdkW.mak" CFG="PGPsdkW - Win32 Release6" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "PGPsdkW - Win32 Release6" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "PGPsdkW - Win32 Release8" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF + +!IF "$(CFG)" == "PGPsdkW - Win32 Release6" + +OUTDIR=.\Release6 +INTDIR=.\Release6 +# Begin Custom Macros +OutDir=.\Release6 +# End Custom Macros + +ALL : "$(OUTDIR)\PGPsdkW6.dll" + + +CLEAN : + -@erase "$(INTDIR)\commonheaders.obj" + -@erase "$(INTDIR)\main.obj" + -@erase "$(INTDIR)\PGPsdkW.pch" + -@erase "$(INTDIR)\vc60.idb" + -@erase "$(OUTDIR)\PGPsdkW6.dll" + -@erase "$(OUTDIR)\PGPsdkW6.exp" + -@erase "$(OUTDIR)\PGPsdkW6.map" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +CPP_PROJ=/nologo /MD /W3 /Gi /GX /O1 /I "sdk6/include" /D PGP_WIN32=0x658 /Fp"$(INTDIR)\PGPsdkW.pch" /Yu"commonheaders.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c + +.c{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +MTL=midl.exe +MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 +RSC=rc.exe +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\PGPsdkW.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +LINK32_FLAGS=delayimp.lib pgp_sdk.lib pgpsdknl.lib pgpsdkui.lib kernel32.lib user32.lib shell32.lib gdi32.lib msimg32.lib comdlg32.lib msvcrt.lib /nologo /base:"0x46600000" /dll /incremental:no /pdb:"$(OUTDIR)\PGPsdkW6.pdb" /map:"$(INTDIR)\PGPsdkW6.map" /machine:I386 /out:"$(OUTDIR)\PGPsdkW6.dll" /implib:"$(OUTDIR)\PGPsdkW6.lib" /libpath:"sdk6/lib" /filealign:0x200 /delayload:pgp_sdk.dll /delayload:pgpsdkui.dll +LINK32_OBJS= \ + "$(INTDIR)\commonheaders.obj" \ + "$(INTDIR)\main.obj" + +"$(OUTDIR)\PGPsdkW6.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "PGPsdkW - Win32 Release8" + +OUTDIR=.\Release8 +INTDIR=.\Release8 +# Begin Custom Macros +OutDir=.\Release8 +# End Custom Macros + +ALL : "$(OUTDIR)\PGPsdkW8.dll" + + +CLEAN : + -@erase "$(INTDIR)\commonheaders.obj" + -@erase "$(INTDIR)\main.obj" + -@erase "$(INTDIR)\PGPsdkW.pch" + -@erase "$(INTDIR)\vc60.idb" + -@erase "$(OUTDIR)\PGPsdkW8.dll" + -@erase "$(OUTDIR)\PGPsdkW8.exp" + -@erase "$(OUTDIR)\PGPsdkW8.map" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +CPP_PROJ=/nologo /MD /W3 /Gi /GX /O1 /I "sdk8/include" /D PGP_WIN32=0x800 /Fp"$(INTDIR)\PGPsdkW.pch" /Yu"commonheaders.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c + +.c{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +MTL=midl.exe +MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 +RSC=rc.exe +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\PGPsdkW.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +LINK32_FLAGS=delayimp.lib pgpsdk.lib pgpsdknl.lib pgpsdkui.lib kernel32.lib user32.lib shell32.lib gdi32.lib msimg32.lib comdlg32.lib msvcrt.lib /nologo /base:"0x46800000" /dll /incremental:no /pdb:"$(OUTDIR)\PGPsdkW8.pdb" /map:"$(INTDIR)\PGPsdkW8.map" /machine:I386 /out:"$(OUTDIR)\PGPsdkW8.dll" /implib:"$(OUTDIR)\PGPsdkW8.lib" /libpath:"sdk8/lib" /filealign:0x200 /delayload:pgpsdk.dll /delayload:pgpsdkui.dll +LINK32_OBJS= \ + "$(INTDIR)\commonheaders.obj" \ + "$(INTDIR)\main.obj" + +"$(OUTDIR)\PGPsdkW8.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + + +!IF "$(NO_EXTERNAL_DEPS)" != "1" +!IF EXISTS("PGPsdkW.dep") +!INCLUDE "PGPsdkW.dep" +!ELSE +!MESSAGE Warning: cannot find "PGPsdkW.dep" +!ENDIF +!ENDIF + + +!IF "$(CFG)" == "PGPsdkW - Win32 Release6" || "$(CFG)" == "PGPsdkW - Win32 Release8" +SOURCE=.\commonheaders.cpp + +!IF "$(CFG)" == "PGPsdkW - Win32 Release6" + +CPP_SWITCHES=/nologo /MD /W3 /Gi /GX /O1 /I "sdk6/include" /D PGP_WIN32=0x658 /Fp"$(INTDIR)\PGPsdkW.pch" /Yc"commonheaders.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c + +"$(INTDIR)\commonheaders.obj" "$(INTDIR)\PGPsdkW.pch" : $(SOURCE) "$(INTDIR)" + $(CPP) @<< + $(CPP_SWITCHES) $(SOURCE) +<< + + +!ELSEIF "$(CFG)" == "PGPsdkW - Win32 Release8" + +CPP_SWITCHES=/nologo /MD /W3 /Gi /GX /O1 /I "sdk8/include" /D PGP_WIN32=0x800 /Fp"$(INTDIR)\PGPsdkW.pch" /Yc"commonheaders.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c + +"$(INTDIR)\commonheaders.obj" "$(INTDIR)\PGPsdkW.pch" : $(SOURCE) "$(INTDIR)" + $(CPP) @<< + $(CPP_SWITCHES) $(SOURCE) +<< + + +!ENDIF + +SOURCE=.\main.cpp + +"$(INTDIR)\main.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\PGPsdkW.pch" + + + +!ENDIF + diff --git a/CryptoPP/PGPw/Release6/PGPsdkW6.dll b/CryptoPP/PGPw/Release6/PGPsdkW6.dll new file mode 100644 index 0000000..90a7a2a Binary files /dev/null and b/CryptoPP/PGPw/Release6/PGPsdkW6.dll differ diff --git a/CryptoPP/PGPw/Release6/PGPsdkW6.map b/CryptoPP/PGPw/Release6/PGPsdkW6.map new file mode 100644 index 0000000..6f9fa45 --- /dev/null +++ b/CryptoPP/PGPw/Release6/PGPsdkW6.map @@ -0,0 +1,213 @@ + PGPsdkW6 + + Timestamp is 45ddf356 (Thu Feb 22 22:47:34 2007) + + Preferred load address is 46600000 + + Start Length Name Class + 0001:00000000 0000003cH .idata$5 CODE + 0001:00000040 0000003eH .rdata CODE + 0001:00000080 00000d81H .text CODE + 0001:00000e04 00000040H .didat$2 CODE + 0001:00000e44 00000020H .didat$3 CODE + 0001:00000e64 000000a0H .didat$4 CODE + 0001:00000f04 000002ceH .didat$6 CODE + 0001:000011d4 000000a0H .didat$7 CODE + 0001:00001274 0000003cH .idata$2 CODE + 0001:000012b0 00000014H .idata$3 CODE + 0001:000012c4 0000003cH .idata$4 CODE + 0001:00001300 000000e0H .idata$6 CODE + 0001:000013e0 00000172H .edata CODE + 0002:00000000 00000090H .data DATA + 0002:00000090 000000a0H .didat$5 DATA + 0002:00000130 00000050H .bss DATA + + Address Publics by Value Rva+Base Lib:Object + + 0001:00000000 __imp__LocalAlloc@8 46601000 kernel32:KERNEL32.dll + 0001:00000004 __imp__LocalFree@4 46601004 kernel32:KERNEL32.dll + 0001:00000008 __imp__lstrlenA@4 46601008 kernel32:KERNEL32.dll + 0001:0000000c __imp__GetLastError@0 4660100c kernel32:KERNEL32.dll + 0001:00000010 __imp__RaiseException@16 46601010 kernel32:KERNEL32.dll + 0001:00000014 __imp__InterlockedExchange@8 46601014 kernel32:KERNEL32.dll + 0001:00000018 __imp__LoadLibraryA@4 46601018 kernel32:KERNEL32.dll + 0001:0000001c __imp__FreeLibrary@4 4660101c kernel32:KERNEL32.dll + 0001:00000020 __imp__GetProcAddress@8 46601020 kernel32:KERNEL32.dll + 0001:00000024 \177KERNEL32_NULL_THUNK_DATA 46601024 kernel32:KERNEL32.dll + 0001:00000028 __imp___except_handler3 46601028 msvcrt:MSVCRT.dll + 0001:0000002c __imp__memmove 4660102c msvcrt:MSVCRT.dll + 0001:00000030 \177MSVCRT_NULL_THUNK_DATA 46601030 msvcrt:MSVCRT.dll + 0001:00000034 __imp__MessageBoxA@16 46601034 user32:USER32.dll + 0001:00000038 \177USER32_NULL_THUNK_DATA 46601038 user32:USER32.dll + 0001:00000060 __sz_PGP_SDK 46601060 pgp_sdk:PGP_SDK.dll + 0001:00000070 __sz_PGPsdkUI 46601070 pgpsdkui:PGPsdkUI.dll + 0001:00000080 ?ClearPGPError@@YAXXZ 46601080 f main.obj + 0001:00000089 ?CheckPGPError@@YA_NH@Z 46601089 f main.obj + 0001:000000b5 __pgp_init 466010b5 f main.obj + 0001:000001be __pgp_done 466011be f main.obj + 0001:00000271 __pgp_open_keyrings 46601271 f main.obj + 0001:00000297 __pgp_close_keyrings 46601297 f main.obj + 0001:000002b2 __pgp_get_version 466012b2 f main.obj + 0001:000002b8 __pgp_get_error 466012b8 f main.obj + 0001:000002be __pgp_encrypt_keydb 466012be f main.obj + 0001:000003dc __pgp_decrypt_keydb 466013dc f main.obj + 0001:00000528 ?_pgp_import_key@@YAHPAPAUPGPKeySet@@PBD@Z 46601528 f main.obj + 0001:00000566 __pgp_encrypt_key 46601566 f main.obj + 0001:00000683 __pgp_decrypt_key 46601683 f main.obj + 0001:0000080b __pgp_size_keyid 4660180b f main.obj + 0001:0000080f __pgp_select_keyid 4660180f f main.obj + 0001:000008fb ?dllmain@@YGHPAUHINSTANCE__@@KPAX@Z 466018fb f main.obj + 0001:0000090a __imp_load__PGPGetErrorString 4660190a pgp_sdk:PGP_SDK.dll + 0001:00000916 __tailMerge_PGP_SDK 46601916 pgp_sdk:PGP_SDK.dll + 0001:00000924 _PGPGetErrorString 46601924 pgp_sdk:PGP_SDK.dll + 0001:0000092a __imp_load__PGPGetSDKVersion 4660192a pgp_sdk:PGP_SDK.dll + 0001:00000936 _PGPGetSDKVersion 46601936 pgp_sdk:PGP_SDK.dll + 0001:0000093c __imp_load__PGPNewContext 4660193c pgp_sdk:PGP_SDK.dll + 0001:00000948 _PGPNewContext 46601948 pgp_sdk:PGP_SDK.dll + 0001:0000094e __imp_load__PGPsdkInit 4660194e pgp_sdk:PGP_SDK.dll + 0001:0000095a _PGPsdkInit 4660195a pgp_sdk:PGP_SDK.dll + 0001:00000960 __imp_load__PGPsdkCleanup 46601960 pgp_sdk:PGP_SDK.dll + 0001:0000096c _PGPsdkCleanup 4660196c pgp_sdk:PGP_SDK.dll + 0001:00000972 __imp_load__PGPFreeContext 46601972 pgp_sdk:PGP_SDK.dll + 0001:0000097e _PGPFreeContext 4660197e pgp_sdk:PGP_SDK.dll + 0001:00000984 __imp_load__PGPFreeKeySet 46601984 pgp_sdk:PGP_SDK.dll + 0001:00000990 _PGPFreeKeySet 46601990 pgp_sdk:PGP_SDK.dll + 0001:00000996 __imp_load__PGPFreeData 46601996 pgp_sdk:PGP_SDK.dll + 0001:000009a2 _PGPFreeData 466019a2 pgp_sdk:PGP_SDK.dll + 0001:000009a8 __imp_load__PGPOpenDefaultKeyRings 466019a8 pgp_sdk:PGP_SDK.dll + 0001:000009b4 _PGPOpenDefaultKeyRings 466019b4 pgp_sdk:PGP_SDK.dll + 0001:000009ba __imp_load__PGPFreeFilter 466019ba pgp_sdk:PGP_SDK.dll + 0001:000009c6 _PGPFreeFilter 466019c6 pgp_sdk:PGP_SDK.dll + 0001:000009cc __imp_load__PGPEncode 466019cc pgp_sdk:PGP_SDK.dll + 0001:000009d8 _PGPEncode 466019d8 pgp_sdk:PGP_SDK.dll + 0001:000009de __imp_load__PGPOInputBuffer 466019de pgp_sdk:PGP_SDK.dll + 0001:000009ea _PGPOInputBuffer 466019ea pgp_sdk:PGP_SDK.dll + 0001:000009f0 __imp_load__PGPOArmorOutput 466019f0 pgp_sdk:PGP_SDK.dll + 0001:000009fc _PGPOArmorOutput 466019fc pgp_sdk:PGP_SDK.dll + 0001:00000a02 __imp_load__PGPOAllocatedOutputBuffer 46601a02 pgp_sdk:PGP_SDK.dll + 0001:00000a0e _PGPOAllocatedOutputBuffer 46601a0e pgp_sdk:PGP_SDK.dll + 0001:00000a14 __imp_load__PGPOEncryptToKeySet 46601a14 pgp_sdk:PGP_SDK.dll + 0001:00000a20 _PGPOEncryptToKeySet 46601a20 pgp_sdk:PGP_SDK.dll + 0001:00000a26 __imp_load__PGPOVersionString 46601a26 pgp_sdk:PGP_SDK.dll + 0001:00000a32 _PGPOVersionString 46601a32 pgp_sdk:PGP_SDK.dll + 0001:00000a38 __imp_load__PGPOLastOption 46601a38 pgp_sdk:PGP_SDK.dll + 0001:00000a44 _PGPOLastOption 46601a44 pgp_sdk:PGP_SDK.dll + 0001:00000a4a __imp_load__PGPFilterKeySet 46601a4a pgp_sdk:PGP_SDK.dll + 0001:00000a56 _PGPFilterKeySet 46601a56 pgp_sdk:PGP_SDK.dll + 0001:00000a5c __imp_load__PGPNewKeyIDFilter 46601a5c pgp_sdk:PGP_SDK.dll + 0001:00000a68 _PGPNewKeyIDFilter 46601a68 pgp_sdk:PGP_SDK.dll + 0001:00000a6e __imp_load__PGPDecode 46601a6e pgp_sdk:PGP_SDK.dll + 0001:00000a7a _PGPDecode 46601a7a pgp_sdk:PGP_SDK.dll + 0001:00000a80 __imp_load__PGPOKeySetRef 46601a80 pgp_sdk:PGP_SDK.dll + 0001:00000a8c _PGPOKeySetRef 46601a8c pgp_sdk:PGP_SDK.dll + 0001:00000a92 __imp_load__PGPOPassphrase 46601a92 pgp_sdk:PGP_SDK.dll + 0001:00000a9e _PGPOPassphrase 46601a9e pgp_sdk:PGP_SDK.dll + 0001:00000aa4 __imp_load__PGPImportKeySet 46601aa4 pgp_sdk:PGP_SDK.dll + 0001:00000ab0 _PGPImportKeySet 46601ab0 pgp_sdk:PGP_SDK.dll + 0001:00000ab6 __imp_load__PGPCountKeys 46601ab6 pgp_sdk:PGP_SDK.dll + 0001:00000ac2 _PGPCountKeys 46601ac2 pgp_sdk:PGP_SDK.dll + 0001:00000ac8 __imp_load__PGPFreeKeyIter 46601ac8 pgp_sdk:PGP_SDK.dll + 0001:00000ad4 _PGPFreeKeyIter 46601ad4 pgp_sdk:PGP_SDK.dll + 0001:00000ada __imp_load__PGPFreeKeyList 46601ada pgp_sdk:PGP_SDK.dll + 0001:00000ae6 _PGPFreeKeyList 46601ae6 pgp_sdk:PGP_SDK.dll + 0001:00000aec __imp_load__PGPGetKeyIDString 46601aec pgp_sdk:PGP_SDK.dll + 0001:00000af8 _PGPGetKeyIDString 46601af8 pgp_sdk:PGP_SDK.dll + 0001:00000afe __imp_load__PGPGetKeyIDFromKey 46601afe pgp_sdk:PGP_SDK.dll + 0001:00000b0a _PGPGetKeyIDFromKey 46601b0a pgp_sdk:PGP_SDK.dll + 0001:00000b10 __imp_load__PGPKeyIterNext 46601b10 pgp_sdk:PGP_SDK.dll + 0001:00000b1c _PGPKeyIterNext 46601b1c pgp_sdk:PGP_SDK.dll + 0001:00000b22 __imp_load__PGPNewKeyIter 46601b22 pgp_sdk:PGP_SDK.dll + 0001:00000b2e _PGPNewKeyIter 46601b2e pgp_sdk:PGP_SDK.dll + 0001:00000b34 __imp_load__PGPOrderKeySet 46601b34 pgp_sdk:PGP_SDK.dll + 0001:00000b40 _PGPOrderKeySet 46601b40 pgp_sdk:PGP_SDK.dll + 0001:00000b46 __imp_load__PGPsdkUILibInit 46601b46 pgpsdkui:PGPsdkUI.dll + 0001:00000b52 __tailMerge_PGPsdkUI 46601b52 pgpsdkui:PGPsdkUI.dll + 0001:00000b60 _PGPsdkUILibInit 46601b60 pgpsdkui:PGPsdkUI.dll + 0001:00000b66 __imp_load__PGPsdkUILibCleanup 46601b66 pgpsdkui:PGPsdkUI.dll + 0001:00000b72 _PGPsdkUILibCleanup 46601b72 pgpsdkui:PGPsdkUI.dll + 0001:00000b78 __imp_load__PGPPassphraseDialog 46601b78 pgpsdkui:PGPsdkUI.dll + 0001:00000b84 _PGPPassphraseDialog 46601b84 pgpsdkui:PGPsdkUI.dll + 0001:00000b8a __imp_load__PGPOUIOutputPassphrase 46601b8a pgpsdkui:PGPsdkUI.dll + 0001:00000b96 _PGPOUIOutputPassphrase 46601b96 pgpsdkui:PGPsdkUI.dll + 0001:00000b9c __imp_load__PGPRecipientDialog 46601b9c pgpsdkui:PGPsdkUI.dll + 0001:00000ba8 _PGPRecipientDialog 46601ba8 pgpsdkui:PGPsdkUI.dll + 0001:00000bae __imp_load__PGPOUIParentWindowHandle 46601bae pgpsdkui:PGPsdkUI.dll + 0001:00000bba _PGPOUIParentWindowHandle 46601bba pgpsdkui:PGPsdkUI.dll + 0001:00000bc0 __imp_load__PGPOUIWindowTitle 46601bc0 pgpsdkui:PGPsdkUI.dll + 0001:00000bcc _PGPOUIWindowTitle 46601bcc pgpsdkui:PGPsdkUI.dll + 0001:00000be0 __except_handler3 46601be0 f msvcrt:MSVCRT.dll + 0001:00000be6 ___delayLoadHelper@8 46601be6 f delayimp:delayhlp.obj + 0001:00000e04 __DELAY_IMPORT_DESCRIPTOR_PGP_SDK 46601e04 pgp_sdk:PGP_SDK.dll + 0001:00000e24 __DELAY_IMPORT_DESCRIPTOR_PGPsdkUI 46601e24 pgpsdkui:PGPsdkUI.dll + 0001:00000e44 __NULL_DELAY_IMPORT_DESCRIPTOR 46601e44 pgp_sdk:PGP_SDK.dll + 0001:00000ee0 \177PGP_SDK_NULL_THUNK_DATA_DLN 46601ee0 pgp_sdk:PGP_SDK.dll + 0001:00000f00 \177PGPsdkUI_NULL_THUNK_DATA_DLN 46601f00 pgpsdkui:PGPsdkUI.dll + 0001:000011d8 \177PGP_SDK_NULL_THUNK_DATA_DLB 466021d8 pgp_sdk:PGP_SDK.dll + 0001:00001258 \177PGPsdkUI_NULL_THUNK_DATA_DLB 46602258 pgpsdkui:PGPsdkUI.dll + 0001:00001274 __IMPORT_DESCRIPTOR_KERNEL32 46602274 kernel32:KERNEL32.dll + 0001:00001288 __IMPORT_DESCRIPTOR_USER32 46602288 user32:USER32.dll + 0001:0000129c __IMPORT_DESCRIPTOR_MSVCRT 4660229c msvcrt:MSVCRT.dll + 0001:000012b0 __NULL_IMPORT_DESCRIPTOR 466022b0 kernel32:KERNEL32.dll + 0002:00000000 ?szModuleName@@3PBDB 46603000 commonheaders.obj + 0002:00000004 ?szVersionStr@@3PBDB 46603004 commonheaders.obj + 0002:00000008 ??_C@_0BG@HGBA@PGPsdk?5DLL?5?$CI1?40?41?411?$CJ?$AA@ 46603008 commonheaders.obj + 0002:00000020 ??_C@_06DDFD@PGPsdk?$AA@ 46603020 commonheaders.obj + 0002:00000028 ??_C@_0EB@DOFC@You?5selected?5more?5than?5one?5key?4?5@ 46603028 main.obj + 0002:0000006c ??_C@_0BF@LLHL@Select?5Contact?8s?5Key?$AA@ 4660306c main.obj + 0002:00000090 __imp__PGPGetErrorString 46603090 pgp_sdk:PGP_SDK.dll + 0002:00000094 __imp__PGPGetSDKVersion 46603094 pgp_sdk:PGP_SDK.dll + 0002:00000098 __imp__PGPNewContext 46603098 pgp_sdk:PGP_SDK.dll + 0002:0000009c __imp__PGPsdkInit 4660309c pgp_sdk:PGP_SDK.dll + 0002:000000a0 __imp__PGPsdkCleanup 466030a0 pgp_sdk:PGP_SDK.dll + 0002:000000a4 __imp__PGPFreeContext 466030a4 pgp_sdk:PGP_SDK.dll + 0002:000000a8 __imp__PGPFreeKeySet 466030a8 pgp_sdk:PGP_SDK.dll + 0002:000000ac __imp__PGPFreeData 466030ac pgp_sdk:PGP_SDK.dll + 0002:000000b0 __imp__PGPOpenDefaultKeyRings 466030b0 pgp_sdk:PGP_SDK.dll + 0002:000000b4 __imp__PGPFreeFilter 466030b4 pgp_sdk:PGP_SDK.dll + 0002:000000b8 __imp__PGPEncode 466030b8 pgp_sdk:PGP_SDK.dll + 0002:000000bc __imp__PGPOInputBuffer 466030bc pgp_sdk:PGP_SDK.dll + 0002:000000c0 __imp__PGPOArmorOutput 466030c0 pgp_sdk:PGP_SDK.dll + 0002:000000c4 __imp__PGPOAllocatedOutputBuffer 466030c4 pgp_sdk:PGP_SDK.dll + 0002:000000c8 __imp__PGPOEncryptToKeySet 466030c8 pgp_sdk:PGP_SDK.dll + 0002:000000cc __imp__PGPOVersionString 466030cc pgp_sdk:PGP_SDK.dll + 0002:000000d0 __imp__PGPOLastOption 466030d0 pgp_sdk:PGP_SDK.dll + 0002:000000d4 __imp__PGPFilterKeySet 466030d4 pgp_sdk:PGP_SDK.dll + 0002:000000d8 __imp__PGPNewKeyIDFilter 466030d8 pgp_sdk:PGP_SDK.dll + 0002:000000dc __imp__PGPDecode 466030dc pgp_sdk:PGP_SDK.dll + 0002:000000e0 __imp__PGPOKeySetRef 466030e0 pgp_sdk:PGP_SDK.dll + 0002:000000e4 __imp__PGPOPassphrase 466030e4 pgp_sdk:PGP_SDK.dll + 0002:000000e8 __imp__PGPImportKeySet 466030e8 pgp_sdk:PGP_SDK.dll + 0002:000000ec __imp__PGPCountKeys 466030ec pgp_sdk:PGP_SDK.dll + 0002:000000f0 __imp__PGPFreeKeyIter 466030f0 pgp_sdk:PGP_SDK.dll + 0002:000000f4 __imp__PGPFreeKeyList 466030f4 pgp_sdk:PGP_SDK.dll + 0002:000000f8 __imp__PGPGetKeyIDString 466030f8 pgp_sdk:PGP_SDK.dll + 0002:000000fc __imp__PGPGetKeyIDFromKey 466030fc pgp_sdk:PGP_SDK.dll + 0002:00000100 __imp__PGPKeyIterNext 46603100 pgp_sdk:PGP_SDK.dll + 0002:00000104 __imp__PGPNewKeyIter 46603104 pgp_sdk:PGP_SDK.dll + 0002:00000108 __imp__PGPOrderKeySet 46603108 pgp_sdk:PGP_SDK.dll + 0002:0000010c \177PGP_SDK_NULL_THUNK_DATA_DLA 4660310c pgp_sdk:PGP_SDK.dll + 0002:00000110 __imp__PGPsdkUILibCleanup 46603110 pgpsdkui:PGPsdkUI.dll + 0002:00000114 __imp__PGPPassphraseDialog 46603114 pgpsdkui:PGPsdkUI.dll + 0002:00000118 __imp__PGPOUIOutputPassphrase 46603118 pgpsdkui:PGPsdkUI.dll + 0002:0000011c __imp__PGPRecipientDialog 4660311c pgpsdkui:PGPsdkUI.dll + 0002:00000120 __imp__PGPOUIParentWindowHandle 46603120 pgpsdkui:PGPsdkUI.dll + 0002:00000124 __imp__PGPOUIWindowTitle 46603124 pgpsdkui:PGPsdkUI.dll + 0002:00000128 __imp__PGPsdkUILibInit 46603128 pgpsdkui:PGPsdkUI.dll + 0002:0000012c \177PGPsdkUI_NULL_THUNK_DATA_DLA 4660312c pgpsdkui:PGPsdkUI.dll + 0002:00000130 ?g_hInst@@3PAUHINSTANCE__@@A 46603130 commonheaders.obj + 0002:00000158 ?pgpVer@@3IA 46603158 main.obj + 0002:0000015c ?pgpContext@@3PAUPGPContext@@A 4660315c main.obj + 0002:00000160 ?pgpKeyDB@@3PAUPGPKeySet@@A 46603160 main.obj + 0002:00000164 ?pszPassphrase@@3PADA 46603164 main.obj + 0002:00000168 ?pgpErrMsg@@3PADA 46603168 main.obj + 0002:0000016c __hmod__PGP_SDK 4660316c pgp_sdk:PGP_SDK.dll + 0002:00000170 __hmod__PGPSDKUI 46603170 pgpsdkui:PGPsdkUI.dll + 0002:00000174 ___puiHead 46603174 delayimp:delayhlp.obj + 0002:00000178 ___pfnDliFailureHook 46603178 delayimp:delayhk1.obj + 0002:0000017c ___pfnDliNotifyHook 4660317c delayimp:delayhk2.obj + + entry point at 0000:00000000 + + Static symbols + + 0001:00000ddf ?OverlayIAT@@YGXPAU_IMAGE_THUNK_DATA32@@PBU1@@Z 46601ddf f delayimp:delayhlp.obj diff --git a/CryptoPP/PGPw/Release8/PGPsdkW8.dll b/CryptoPP/PGPw/Release8/PGPsdkW8.dll new file mode 100644 index 0000000..f026dde Binary files /dev/null and b/CryptoPP/PGPw/Release8/PGPsdkW8.dll differ diff --git a/CryptoPP/PGPw/Release8/PGPsdkW8.map b/CryptoPP/PGPw/Release8/PGPsdkW8.map new file mode 100644 index 0000000..e6ccff0 --- /dev/null +++ b/CryptoPP/PGPw/Release8/PGPsdkW8.map @@ -0,0 +1,216 @@ + PGPsdkW8 + + Timestamp is 45ddf360 (Thu Feb 22 22:47:44 2007) + + Preferred load address is 46800000 + + Start Length Name Class + 0001:00000000 00000044H .idata$5 CODE + 0001:00000050 0000003eH .rdata CODE + 0001:00000090 00000dd1H .text CODE + 0001:00000e64 00000040H .didat$2 CODE + 0001:00000ea4 00000020H .didat$3 CODE + 0001:00000ec4 00000098H .didat$4 CODE + 0001:00000f5c 000002d0H .didat$6 CODE + 0001:0000122c 00000098H .didat$7 CODE + 0001:000012c4 00000050H .idata$2 CODE + 0001:00001314 00000014H .idata$3 CODE + 0001:00001328 00000044H .idata$4 CODE + 0001:0000136c 00000102H .idata$6 CODE + 0001:00001470 00000172H .edata CODE + 0002:00000000 00000130H .data DATA + 0002:00000130 00000098H .didat$5 DATA + 0002:000001c8 00000050H .bss DATA + + Address Publics by Value Rva+Base Lib:Object + + 0001:00000000 __imp__LocalAlloc@8 46801000 kernel32:KERNEL32.dll + 0001:00000004 __imp__LocalFree@4 46801004 kernel32:KERNEL32.dll + 0001:00000008 __imp__lstrlenA@4 46801008 kernel32:KERNEL32.dll + 0001:0000000c __imp__GetLastError@0 4680100c kernel32:KERNEL32.dll + 0001:00000010 __imp__RaiseException@16 46801010 kernel32:KERNEL32.dll + 0001:00000014 __imp__InterlockedExchange@8 46801014 kernel32:KERNEL32.dll + 0001:00000018 __imp__FreeLibrary@4 46801018 kernel32:KERNEL32.dll + 0001:0000001c __imp__LoadLibraryA@4 4680101c kernel32:KERNEL32.dll + 0001:00000020 __imp__GetProcAddress@8 46801020 kernel32:KERNEL32.dll + 0001:00000024 \177KERNEL32_NULL_THUNK_DATA 46801024 kernel32:KERNEL32.dll + 0001:00000028 __imp__memmove 46801028 msvcrt:MSVCRT.dll + 0001:0000002c __imp___except_handler3 4680102c msvcrt:MSVCRT.dll + 0001:00000030 \177MSVCRT_NULL_THUNK_DATA 46801030 msvcrt:MSVCRT.dll + 0001:00000034 __imp__MessageBoxA@16 46801034 user32:USER32.dll + 0001:00000038 \177USER32_NULL_THUNK_DATA 46801038 user32:USER32.dll + 0001:0000003c __imp__GetOpenFileNameA@4 4680103c comdlg32:comdlg32.dll + 0001:00000040 \177comdlg32_NULL_THUNK_DATA 46801040 comdlg32:comdlg32.dll + 0001:00000070 __sz_PGPsdk 46801070 pgpsdk:PGPsdk.dll + 0001:00000080 __sz_PGPsdkUI 46801080 pgpsdkui:PGPsdkUI.dll + 0001:00000090 ?ClearPGPError@@YAXXZ 46801090 f main.obj + 0001:00000099 ?CheckPGPError@@YA_NH@Z 46801099 f main.obj + 0001:000000c5 __pgp_init 468010c5 f main.obj + 0001:00000173 __pgp_done 46801173 f main.obj + 0001:00000226 __pgp_open_keyrings 46801226 f main.obj + 0001:000002ac __pgp_close_keyrings 468012ac f main.obj + 0001:000002c7 __pgp_get_version 468012c7 f main.obj + 0001:000002cd __pgp_get_error 468012cd f main.obj + 0001:000002d3 __pgp_encrypt_keydb 468012d3 f main.obj + 0001:000003c8 __pgp_decrypt_keydb 468013c8 f main.obj + 0001:00000514 ?_pgp_import_key@@YAHPAPAUPGPKeyDB@@PBD@Z 46801514 f main.obj + 0001:00000552 __pgp_encrypt_key 46801552 f main.obj + 0001:0000069b __pgp_decrypt_key 4680169b f main.obj + 0001:00000823 __pgp_size_keyid 46801823 f main.obj + 0001:00000827 __pgp_select_keyid 46801827 f main.obj + 0001:0000090a ?ShowSelectKeyringsDlg@@YAHPAUHWND__@@PAD1@Z 4680190a f main.obj + 0001:0000097f ?dllmain@@YGHPAUHINSTANCE__@@KPAX@Z 4680197f f main.obj + 0001:0000098e __imp_load__PGPGetErrorString 4680198e pgpsdk:PGPsdk.dll + 0001:0000099a __tailMerge_PGPsdk 4680199a pgpsdk:PGPsdk.dll + 0001:000009a8 _PGPGetErrorString 468019a8 pgpsdk:PGPsdk.dll + 0001:000009ae __imp_load__PGPGetPGPsdkVersion 468019ae pgpsdk:PGPsdk.dll + 0001:000009ba _PGPGetPGPsdkVersion 468019ba pgpsdk:PGPsdk.dll + 0001:000009c0 __imp_load__PGPNewContext 468019c0 pgpsdk:PGPsdk.dll + 0001:000009cc _PGPNewContext 468019cc pgpsdk:PGPsdk.dll + 0001:000009d2 __imp_load__PGPsdkInit 468019d2 pgpsdk:PGPsdk.dll + 0001:000009de _PGPsdkInit 468019de pgpsdk:PGPsdk.dll + 0001:000009e4 __imp_load__PGPsdkCleanup 468019e4 pgpsdk:PGPsdk.dll + 0001:000009f0 _PGPsdkCleanup 468019f0 pgpsdk:PGPsdk.dll + 0001:000009f6 __imp_load__PGPFreeContext 468019f6 pgpsdk:PGPsdk.dll + 0001:00000a02 _PGPFreeContext 46801a02 pgpsdk:PGPsdk.dll + 0001:00000a08 __imp_load__PGPFreeKeyDB 46801a08 pgpsdk:PGPsdk.dll + 0001:00000a14 _PGPFreeKeyDB 46801a14 pgpsdk:PGPsdk.dll + 0001:00000a1a __imp_load__PGPFreeData 46801a1a pgpsdk:PGPsdk.dll + 0001:00000a26 _PGPFreeData 46801a26 pgpsdk:PGPsdk.dll + 0001:00000a2c __imp_load__PGPFreeFileSpec 46801a2c pgpsdk:PGPsdk.dll + 0001:00000a38 _PGPFreeFileSpec 46801a38 pgpsdk:PGPsdk.dll + 0001:00000a3e __imp_load__PGPOpenKeyDBFile 46801a3e pgpsdk:PGPsdk.dll + 0001:00000a4a _PGPOpenKeyDBFile 46801a4a pgpsdk:PGPsdk.dll + 0001:00000a50 __imp_load__PGPNewFileSpecFromFullPath 46801a50 pgpsdk:PGPsdk.dll + 0001:00000a5c _PGPNewFileSpecFromFullPath 46801a5c pgpsdk:PGPsdk.dll + 0001:00000a62 __imp_load__PGPEncode 46801a62 pgpsdk:PGPsdk.dll + 0001:00000a6e _PGPEncode 46801a6e pgpsdk:PGPsdk.dll + 0001:00000a74 __imp_load__PGPOInputBuffer 46801a74 pgpsdk:PGPsdk.dll + 0001:00000a80 _PGPOInputBuffer 46801a80 pgpsdk:PGPsdk.dll + 0001:00000a86 __imp_load__PGPOArmorOutput 46801a86 pgpsdk:PGPsdk.dll + 0001:00000a92 _PGPOArmorOutput 46801a92 pgpsdk:PGPsdk.dll + 0001:00000a98 __imp_load__PGPOAllocatedOutputBuffer 46801a98 pgpsdk:PGPsdk.dll + 0001:00000aa4 _PGPOAllocatedOutputBuffer 46801aa4 pgpsdk:PGPsdk.dll + 0001:00000aaa __imp_load__PGPOEncryptToKeyDBObj 46801aaa pgpsdk:PGPsdk.dll + 0001:00000ab6 _PGPOEncryptToKeyDBObj 46801ab6 pgpsdk:PGPsdk.dll + 0001:00000abc __imp_load__PGPOVersionString 46801abc pgpsdk:PGPsdk.dll + 0001:00000ac8 _PGPOVersionString 46801ac8 pgpsdk:PGPsdk.dll + 0001:00000ace __imp_load__PGPOLastOption 46801ace pgpsdk:PGPsdk.dll + 0001:00000ada _PGPOLastOption 46801ada pgpsdk:PGPsdk.dll + 0001:00000ae0 __imp_load__PGPFindKeyByKeyID 46801ae0 pgpsdk:PGPsdk.dll + 0001:00000aec _PGPFindKeyByKeyID 46801aec pgpsdk:PGPsdk.dll + 0001:00000af2 __imp_load__PGPDecode 46801af2 pgpsdk:PGPsdk.dll + 0001:00000afe _PGPDecode 46801afe pgpsdk:PGPsdk.dll + 0001:00000b04 __imp_load__PGPOKeyDBRef 46801b04 pgpsdk:PGPsdk.dll + 0001:00000b10 _PGPOKeyDBRef 46801b10 pgpsdk:PGPsdk.dll + 0001:00000b16 __imp_load__PGPOPassphrase 46801b16 pgpsdk:PGPsdk.dll + 0001:00000b22 _PGPOPassphrase 46801b22 pgpsdk:PGPsdk.dll + 0001:00000b28 __imp_load__PGPImport 46801b28 pgpsdk:PGPsdk.dll + 0001:00000b34 _PGPImport 46801b34 pgpsdk:PGPsdk.dll + 0001:00000b3a __imp_load__PGPFreeKeyIter 46801b3a pgpsdk:PGPsdk.dll + 0001:00000b46 _PGPFreeKeyIter 46801b46 pgpsdk:PGPsdk.dll + 0001:00000b4c __imp_load__PGPCountKeysInKeyDB 46801b4c pgpsdk:PGPsdk.dll + 0001:00000b58 _PGPCountKeysInKeyDB 46801b58 pgpsdk:PGPsdk.dll + 0001:00000b5e __imp_load__PGPKeyIterNextKeyDBObj 46801b5e pgpsdk:PGPsdk.dll + 0001:00000b6a _PGPKeyIterNextKeyDBObj 46801b6a pgpsdk:PGPsdk.dll + 0001:00000b70 __imp_load__PGPNewKeyIterFromKeyDB 46801b70 pgpsdk:PGPsdk.dll + 0001:00000b7c _PGPNewKeyIterFromKeyDB 46801b7c pgpsdk:PGPsdk.dll + 0001:00000b82 __imp_load__PGPGetKeyIDString 46801b82 pgpsdk:PGPsdk.dll + 0001:00000b8e _PGPGetKeyIDString 46801b8e pgpsdk:PGPsdk.dll + 0001:00000b94 __imp_load__PGPGetKeyDBObjDataProperty 46801b94 pgpsdk:PGPsdk.dll + 0001:00000ba0 _PGPGetKeyDBObjDataProperty 46801ba0 pgpsdk:PGPsdk.dll + 0001:00000ba6 __imp_load__PGPsdkUILibInit 46801ba6 pgpsdkui:PGPsdkUI.dll + 0001:00000bb2 __tailMerge_PGPsdkUI 46801bb2 pgpsdkui:PGPsdkUI.dll + 0001:00000bc0 _PGPsdkUILibInit 46801bc0 pgpsdkui:PGPsdkUI.dll + 0001:00000bc6 __imp_load__PGPsdkUILibCleanup 46801bc6 pgpsdkui:PGPsdkUI.dll + 0001:00000bd2 _PGPsdkUILibCleanup 46801bd2 pgpsdkui:PGPsdkUI.dll + 0001:00000bd8 __imp_load__PGPPassphraseDialog 46801bd8 pgpsdkui:PGPsdkUI.dll + 0001:00000be4 _PGPPassphraseDialog 46801be4 pgpsdkui:PGPsdkUI.dll + 0001:00000bea __imp_load__PGPOUIOutputPassphrase 46801bea pgpsdkui:PGPsdkUI.dll + 0001:00000bf6 _PGPOUIOutputPassphrase 46801bf6 pgpsdkui:PGPsdkUI.dll + 0001:00000bfc __imp_load__PGPRecipientDialog 46801bfc pgpsdkui:PGPsdkUI.dll + 0001:00000c08 _PGPRecipientDialog 46801c08 pgpsdkui:PGPsdkUI.dll + 0001:00000c0e __imp_load__PGPOUIParentWindowHandle 46801c0e pgpsdkui:PGPsdkUI.dll + 0001:00000c1a _PGPOUIParentWindowHandle 46801c1a pgpsdkui:PGPsdkUI.dll + 0001:00000c20 __imp_load__PGPOUIWindowTitle 46801c20 pgpsdkui:PGPsdkUI.dll + 0001:00000c2c _PGPOUIWindowTitle 46801c2c pgpsdkui:PGPsdkUI.dll + 0001:00000c32 _GetOpenFileNameA@4 46801c32 f comdlg32:comdlg32.dll + 0001:00000c40 __except_handler3 46801c40 f msvcrt:MSVCRT.dll + 0001:00000c46 ___delayLoadHelper@8 46801c46 f delayimp:delayhlp.obj + 0001:00000e64 __DELAY_IMPORT_DESCRIPTOR_PGPsdk 46801e64 pgpsdk:PGPsdk.dll + 0001:00000e84 __DELAY_IMPORT_DESCRIPTOR_PGPsdkUI 46801e84 pgpsdkui:PGPsdkUI.dll + 0001:00000ea4 __NULL_DELAY_IMPORT_DESCRIPTOR 46801ea4 pgpsdk:PGPsdk.dll + 0001:00000f38 \177PGPsdk_NULL_THUNK_DATA_DLN 46801f38 pgpsdk:PGPsdk.dll + 0001:00000f58 \177PGPsdkUI_NULL_THUNK_DATA_DLN 46801f58 pgpsdkui:PGPsdkUI.dll + 0001:00001230 \177PGPsdk_NULL_THUNK_DATA_DLB 46802230 pgpsdk:PGPsdk.dll + 0001:000012a8 \177PGPsdkUI_NULL_THUNK_DATA_DLB 468022a8 pgpsdkui:PGPsdkUI.dll + 0001:000012c4 __IMPORT_DESCRIPTOR_KERNEL32 468022c4 kernel32:KERNEL32.dll + 0001:000012d8 __IMPORT_DESCRIPTOR_USER32 468022d8 user32:USER32.dll + 0001:000012ec __IMPORT_DESCRIPTOR_comdlg32 468022ec comdlg32:comdlg32.dll + 0001:00001300 __IMPORT_DESCRIPTOR_MSVCRT 46802300 msvcrt:MSVCRT.dll + 0001:00001314 __NULL_IMPORT_DESCRIPTOR 46802314 kernel32:KERNEL32.dll + 0002:00000000 ?szModuleName@@3PBDB 46803000 commonheaders.obj + 0002:00000004 ?szVersionStr@@3PBDB 46803004 commonheaders.obj + 0002:00000008 ??_C@_0BG@HGBA@PGPsdk?5DLL?5?$CI1?40?41?411?$CJ?$AA@ 46803008 commonheaders.obj + 0002:00000020 ??_C@_06DDFD@PGPsdk?$AA@ 46803020 commonheaders.obj + 0002:00000028 ??_C@_0EB@DOFC@You?5selected?5more?5than?5one?5key?4?5@ 46803028 main.obj + 0002:0000006c ??_C@_0BF@LLHL@Select?5Contact?8s?5Key?$AA@ 4680306c main.obj + 0002:00000084 ??_C@_0BE@KDOJ@Open?5Secret?5Keyring?$AA@ 46803084 main.obj + 0002:00000098 ??_C@_0EA@KJFM@Secret?5key?5rings?5?$CIsecring?4skr?$CJ?$AAs@ 46803098 main.obj + 0002:000000d8 ??_C@_0BE@JBON@Open?5Public?5Keyring?$AA@ 468030d8 main.obj + 0002:000000f0 ??_C@_0EA@CLAC@Public?5key?5rings?5?$CIpubring?4pkr?$CJ?$AAp@ 468030f0 main.obj + 0002:00000130 __imp__PGPGetErrorString 46803130 pgpsdk:PGPsdk.dll + 0002:00000134 __imp__PGPGetPGPsdkVersion 46803134 pgpsdk:PGPsdk.dll + 0002:00000138 __imp__PGPNewContext 46803138 pgpsdk:PGPsdk.dll + 0002:0000013c __imp__PGPsdkInit 4680313c pgpsdk:PGPsdk.dll + 0002:00000140 __imp__PGPsdkCleanup 46803140 pgpsdk:PGPsdk.dll + 0002:00000144 __imp__PGPFreeContext 46803144 pgpsdk:PGPsdk.dll + 0002:00000148 __imp__PGPFreeKeyDB 46803148 pgpsdk:PGPsdk.dll + 0002:0000014c __imp__PGPFreeData 4680314c pgpsdk:PGPsdk.dll + 0002:00000150 __imp__PGPFreeFileSpec 46803150 pgpsdk:PGPsdk.dll + 0002:00000154 __imp__PGPOpenKeyDBFile 46803154 pgpsdk:PGPsdk.dll + 0002:00000158 __imp__PGPNewFileSpecFromFullPath 46803158 pgpsdk:PGPsdk.dll + 0002:0000015c __imp__PGPEncode 4680315c pgpsdk:PGPsdk.dll + 0002:00000160 __imp__PGPOInputBuffer 46803160 pgpsdk:PGPsdk.dll + 0002:00000164 __imp__PGPOArmorOutput 46803164 pgpsdk:PGPsdk.dll + 0002:00000168 __imp__PGPOAllocatedOutputBuffer 46803168 pgpsdk:PGPsdk.dll + 0002:0000016c __imp__PGPOEncryptToKeyDBObj 4680316c pgpsdk:PGPsdk.dll + 0002:00000170 __imp__PGPOVersionString 46803170 pgpsdk:PGPsdk.dll + 0002:00000174 __imp__PGPOLastOption 46803174 pgpsdk:PGPsdk.dll + 0002:00000178 __imp__PGPFindKeyByKeyID 46803178 pgpsdk:PGPsdk.dll + 0002:0000017c __imp__PGPDecode 4680317c pgpsdk:PGPsdk.dll + 0002:00000180 __imp__PGPOKeyDBRef 46803180 pgpsdk:PGPsdk.dll + 0002:00000184 __imp__PGPOPassphrase 46803184 pgpsdk:PGPsdk.dll + 0002:00000188 __imp__PGPImport 46803188 pgpsdk:PGPsdk.dll + 0002:0000018c __imp__PGPFreeKeyIter 4680318c pgpsdk:PGPsdk.dll + 0002:00000190 __imp__PGPCountKeysInKeyDB 46803190 pgpsdk:PGPsdk.dll + 0002:00000194 __imp__PGPKeyIterNextKeyDBObj 46803194 pgpsdk:PGPsdk.dll + 0002:00000198 __imp__PGPNewKeyIterFromKeyDB 46803198 pgpsdk:PGPsdk.dll + 0002:0000019c __imp__PGPGetKeyIDString 4680319c pgpsdk:PGPsdk.dll + 0002:000001a0 __imp__PGPGetKeyDBObjDataProperty 468031a0 pgpsdk:PGPsdk.dll + 0002:000001a4 \177PGPsdk_NULL_THUNK_DATA_DLA 468031a4 pgpsdk:PGPsdk.dll + 0002:000001a8 __imp__PGPsdkUILibCleanup 468031a8 pgpsdkui:PGPsdkUI.dll + 0002:000001ac __imp__PGPPassphraseDialog 468031ac pgpsdkui:PGPsdkUI.dll + 0002:000001b0 __imp__PGPOUIOutputPassphrase 468031b0 pgpsdkui:PGPsdkUI.dll + 0002:000001b4 __imp__PGPRecipientDialog 468031b4 pgpsdkui:PGPsdkUI.dll + 0002:000001b8 __imp__PGPOUIParentWindowHandle 468031b8 pgpsdkui:PGPsdkUI.dll + 0002:000001bc __imp__PGPOUIWindowTitle 468031bc pgpsdkui:PGPsdkUI.dll + 0002:000001c0 __imp__PGPsdkUILibInit 468031c0 pgpsdkui:PGPsdkUI.dll + 0002:000001c4 \177PGPsdkUI_NULL_THUNK_DATA_DLA 468031c4 pgpsdkui:PGPsdkUI.dll + 0002:000001c8 ?g_hInst@@3PAUHINSTANCE__@@A 468031c8 commonheaders.obj + 0002:000001f0 ?pgpVer@@3IA 468031f0 main.obj + 0002:000001f4 ?pgpContext@@3PAUPGPContext@@A 468031f4 main.obj + 0002:000001f8 ?pgpKeyDB@@3PAUPGPKeyDB@@A 468031f8 main.obj + 0002:000001fc ?pszPassphrase@@3PADA 468031fc main.obj + 0002:00000200 ?pgpErrMsg@@3PADA 46803200 main.obj + 0002:00000204 __hmod__PGPSDK 46803204 pgpsdk:PGPsdk.dll + 0002:00000208 __hmod__PGPSDKUI 46803208 pgpsdkui:PGPsdkUI.dll + 0002:0000020c ___puiHead 4680320c delayimp:delayhlp.obj + 0002:00000210 ___pfnDliFailureHook 46803210 delayimp:delayhk1.obj + 0002:00000214 ___pfnDliNotifyHook 46803214 delayimp:delayhk2.obj + + entry point at 0000:00000000 + + Static symbols + + 0001:00000e3f ?OverlayIAT@@YGXPAU_IMAGE_THUNK_DATA32@@PBU1@@Z 46801e3f f delayimp:delayhlp.obj diff --git a/CryptoPP/PGPw/commonheaders.cpp b/CryptoPP/PGPw/commonheaders.cpp new file mode 100644 index 0000000..763395f --- /dev/null +++ b/CryptoPP/PGPw/commonheaders.cpp @@ -0,0 +1,5 @@ +#include "commonheaders.h" + +LPCSTR szModuleName = MODULENAME; +LPCSTR szVersionStr = MODULENAME" DLL ("__VERSION_STRING")"; +HINSTANCE g_hInst; diff --git a/CryptoPP/PGPw/commonheaders.h b/CryptoPP/PGPw/commonheaders.h new file mode 100644 index 0000000..8c79d2e --- /dev/null +++ b/CryptoPP/PGPw/commonheaders.h @@ -0,0 +1,64 @@ +// Windows API + +#pragma once +//#define WIN32_LEAN_AND_MEAN +//#pragma warning(disable: 4078) + +#include +//#include +#include +#include "..\version.h" + +#pragma comment(linker,"/merge:.rdata=.text") +#pragma comment(linker,"/entry:dllmain") +#pragma comment(linker,"/nodefaultlib") +#pragma comment(linker,"/subsystem:windows") +#pragma optimize("gsy", on) + +// PGP API +#ifndef PGP_WIN32 +#error Define PGP_WIN32 to SDK version (e.g. 0x658) +#endif + +#include +#include +#include +#include +#include +#include +#include + + +#define MODULENAME "PGPsdk" +BOOL ShowSelectKeyringsDlg(HWND,LPSTR,LPSTR); + +extern LPCSTR szModuleName; +extern LPCSTR szVersionStr; +extern HINSTANCE g_hInst; + + +#define DLLEXPORT __declspec(dllexport) + +extern "C" DLLEXPORT int __cdecl _pgp_init(void); +extern "C" DLLEXPORT int __cdecl _pgp_done(void); +extern "C" DLLEXPORT int __cdecl _pgp_open_keyrings(LPSTR,LPSTR); +extern "C" DLLEXPORT int __cdecl _pgp_close_keyrings(void); +extern "C" DLLEXPORT int __cdecl _pgp_get_version(void); +extern "C" DLLEXPORT LPSTR __cdecl _pgp_get_error(void); +extern "C" DLLEXPORT int __cdecl _pgp_size_keyid(void); +extern "C" DLLEXPORT PVOID __cdecl _pgp_select_keyid(HWND,LPSTR); +extern "C" DLLEXPORT LPSTR __cdecl _pgp_encrypt_keydb(LPCSTR,PVOID); +extern "C" DLLEXPORT LPSTR __cdecl _pgp_decrypt_keydb(LPCSTR); +//extern "C" DLLEXPORT int __cdecl _pgp_check_key(LPCSTR); +extern "C" DLLEXPORT LPSTR __cdecl _pgp_encrypt_key(LPCSTR,LPCSTR); +extern "C" DLLEXPORT LPSTR __cdecl _pgp_decrypt_key(LPCSTR,LPCSTR); + +/* +#undef RtlMoveMemory +#undef RtlFillMemory +#undef RtlZeroMemory + +NTSYSAPI VOID NTAPI RtlMoveMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, SIZE_T Length); +NTSYSAPI VOID NTAPI RtlFillMemory(VOID UNALIGNED *Destination, SIZE_T Length, BYTE Fill); +NTSYSAPI VOID NTAPI RtlZeroMemory(VOID UNALIGNED *Destination, SIZE_T Length); +*/ diff --git a/CryptoPP/PGPw/main.cpp b/CryptoPP/PGPw/main.cpp new file mode 100644 index 0000000..116615b --- /dev/null +++ b/CryptoPP/PGPw/main.cpp @@ -0,0 +1,584 @@ +#include "commonheaders.h" + +// pgpsdk.lib pgpsdknl.lib pgpsdkui.lib libcmt.lib +// /delayload:pgpsdk.dll,pgpsdknl.dll,pgpsdkui.dll + +PGPContextRef pgpContext; +#if (PGP_WIN32 < 0x700) +PGPKeySetRef pgpKeyDB = 0; +#else +PGPKeyDBRef pgpKeyDB = 0; +#endif +LPSTR pszPassphrase = 0; +LPSTR pgpErrMsg = 0; +#define pgpErrMsgLen 512 +UINT pgpVer; + + +void ClearPGPError() +{ + *pgpErrMsg = '\0'; +} + + +bool CheckPGPError(PGPError err) +{ + if (IsPGPError(err)) { + PGPSize ErrMsgLen = pgpErrMsgLen; + PGPGetErrorString(err, ErrMsgLen, pgpErrMsg); + return 1; + } + else { + *pgpErrMsg = '\0'; + return 0; + } +} + +#define _pgp_memcpy memmove +/* +void _pgp_memcpy(LPSTR dst, LPSTR src, UINT size) +{ + for(UINT i=0;i> 12; + switch(PGPMajorVersion(pgpVer)) { + case 2: + pgpVer = 1<<24 | ((minor+1)<<16) | (PGPRevVersion(pgpVer)<<8); + break; + case 3: + pgpVer = 1<<24 | ((minor+5)<<16) | (PGPRevVersion(pgpVer)<<8); + break; + default: + pgpVer = 1<<24 | (minor<<16) | (PGPRevVersion(pgpVer)<<8); + break; + } +#else + pgpVer = PGPGetPGPsdkVersion(); +#endif + + return 1; +} + + +int __cdecl _pgp_done() +{ + pgpVer = 0; + __try { + if(pgpErrMsg) LocalFree(pgpErrMsg); + if (pszPassphrase) PGPFreeData(pszPassphrase); +#if (PGP_WIN32 < 0x700) + if (pgpKeyDB) PGPFreeKeySet(pgpKeyDB); +#else + if (pgpKeyDB) PGPFreeKeyDB(pgpKeyDB); +#endif + PGPFreeContext(pgpContext); + PGPsdkUILibCleanup(); + PGPsdkCleanup(); + pszPassphrase = pgpErrMsg = 0; + pgpKeyDB = 0; + pgpContext = 0; + } + __except ( EXCEPTION_EXECUTE_HANDLER ) { + return 0; + } + return 1; +} + + +int __cdecl _pgp_open_keyrings(LPSTR PubRingPath, LPSTR SecRingPath) +{ + _pgp_close_keyrings(); + +#if (PGP_WIN32 < 0x700) + PGPError err = PGPOpenDefaultKeyRings(pgpContext, kPGPKeyRingOpenFlags_None, &pgpKeyDB); +#else + if ((!PubRingPath || !*PubRingPath) && !ShowSelectKeyringsDlg(0,PubRingPath,SecRingPath)) { + return 0; + } + + PGPFileSpecRef PubKeyRing, SecKeyRing; + PGPNewFileSpecFromFullPath(pgpContext, PubRingPath, &PubKeyRing); + PGPNewFileSpecFromFullPath(pgpContext, SecRingPath, &SecKeyRing); + + PGPError err = PGPOpenKeyDBFile(pgpContext, kPGPOpenKeyDBFileOptions_None, PubKeyRing, SecKeyRing, &pgpKeyDB); + PGPFreeFileSpec(SecKeyRing); + PGPFreeFileSpec(PubKeyRing); +#endif + if (CheckPGPError(err)) { + return 0; + } + return 1; +} + + +int __cdecl _pgp_close_keyrings() +{ +#if (PGP_WIN32 < 0x700) + if (pgpKeyDB) { + PGPFreeKeySet(pgpKeyDB); + pgpKeyDB = 0; + } +#else + if (pgpKeyDB) { + PGPFreeKeyDB(pgpKeyDB); + pgpKeyDB = 0; + } +#endif + return 1; +} + + +int __cdecl _pgp_get_version() +{ + return pgpVer; +} + + +LPSTR __cdecl _pgp_get_error() +{ + return pgpErrMsg; +} + + +LPSTR __cdecl _pgp_encrypt_keydb(LPCSTR szPlainMsg, PVOID pgpKeyID) +{ + PGPKeyID *RemoteKeyID = (PGPKeyID *) pgpKeyID; + LPSTR szEncMsg = 0; + DWORD dwEncMsgLen; + + ClearPGPError(); + if(!pgpKeyDB) + return 0; + +#if (PGP_WIN32 < 0x700) + PGPFilterRef IDFilter; + PGPNewKeyIDFilter(pgpContext, RemoteKeyID, &IDFilter); + + PGPKeySetRef PublicKey; + PGPFilterKeySet(pgpKeyDB, IDFilter, &PublicKey); +#else + PGPKeyDBObjRef PublicKey; + PGPFindKeyByKeyID(pgpKeyDB, RemoteKeyID, &PublicKey); +#endif + + PGPError err = PGPEncode(pgpContext, + PGPOInputBuffer(pgpContext, szPlainMsg, lstrlen(szPlainMsg)), + PGPOArmorOutput(pgpContext, TRUE), + PGPOAllocatedOutputBuffer(pgpContext, (LPVOID *)&szEncMsg, 16384, (PGPUInt32 *)&dwEncMsgLen), +#if (PGP_WIN32 < 0x700) + PGPOEncryptToKeySet(pgpContext, PublicKey), +#else + PGPOEncryptToKeyDBObj(pgpContext, PublicKey), +#endif + PGPOVersionString(pgpContext, szVersionStr), + PGPOLastOption(pgpContext)); + +#if (PGP_WIN32 < 0x700) + PGPFreeKeySet(PublicKey); + PGPFreeFilter(IDFilter); +#endif + + if (CheckPGPError(err)) + return 0; + + LPSTR szMsg = (LPSTR) LocalAlloc(LPTR,dwEncMsgLen+1); + _pgp_memcpy(szMsg, szEncMsg, dwEncMsgLen); + szMsg[dwEncMsgLen] = 0; + PGPFreeData((LPVOID)szEncMsg); + + return szMsg; +} + + +LPSTR __cdecl _pgp_decrypt_keydb(LPCSTR szEncMsg) +{ + LPSTR szPlainMsg = 0; + DWORD dwPlainMsgLen; + + ClearPGPError(); + if(!pgpKeyDB) + return 0; + + int iTry = 0; + + do { + if (!pszPassphrase && + PGPPassphraseDialog(pgpContext, + PGPOUIOutputPassphrase(pgpContext, &pszPassphrase), + PGPOLastOption(pgpContext)) == kPGPError_UserAbort) { + iTry = 3; + break; + } + + PGPError err = PGPDecode(pgpContext, + PGPOInputBuffer(pgpContext, szEncMsg, lstrlen(szEncMsg)), + PGPOAllocatedOutputBuffer(pgpContext, (LPVOID *)&szPlainMsg, 16384, (PGPUInt32 *)&dwPlainMsgLen), +#if (PGP_WIN32 < 0x700) + PGPOKeySetRef(pgpContext, pgpKeyDB), +#else + PGPOKeyDBRef(pgpContext, pgpKeyDB), +#endif + PGPOPassphrase(pgpContext, pszPassphrase), + PGPOLastOption(pgpContext)); + + if (CheckPGPError(err)) + iTry = 3; + else + if (!dwPlainMsgLen) { + PGPFreeData(pszPassphrase); + pszPassphrase = 0; + iTry++; + } + + } while(!dwPlainMsgLen && iTry<3); + + if(iTry == 3) return 0; + + LPSTR szMsg = (LPSTR) LocalAlloc(LPTR,dwPlainMsgLen+1); + _pgp_memcpy(szMsg, szPlainMsg, dwPlainMsgLen); + szMsg[dwPlainMsgLen] = 0; + PGPFreeData((LPVOID)szPlainMsg); + + return szMsg; +} + + +#if (PGP_WIN32 < 0x700) +PGPError _pgp_import_key(PGPKeySetRef *keySet, LPCSTR pgpKey) +{ + return PGPImportKeySet( pgpContext, + keySet, + PGPOInputBuffer( pgpContext, + pgpKey, + lstrlen(pgpKey) ), + PGPOLastOption( pgpContext ) ); +} +#else +PGPError _pgp_import_key(PGPKeyDBRef *keyDB, LPCSTR pgpKey) +{ + return PGPImport( pgpContext, + keyDB, + PGPOInputBuffer( pgpContext, + pgpKey, + lstrlen(pgpKey) ), + PGPOLastOption( pgpContext ) ); +} +#endif + +/* +int __cdecl _pgp_check_key(LPCSTR pgpKey) +{ +#if (PGP_WIN32 < 0x700) + PGPKeySetRef PrivateKey; + if (CheckPGPError(_pgp_import_key(&PrivateKey,pgpKey))) + return 0; + PGPFreeKeySet(PrivateKey); +#else + PGPKeyDBRef PrivateKey; + if (CheckPGPError(_pgp_import_key(&PrivateKey,pgpKey))) + return 0; + PGPFreeKeyDB(PrivateKey); +#endif + return 1; +} +*/ + +LPSTR __cdecl _pgp_encrypt_key(LPCSTR szPlainMsg, LPCSTR pgpKey) +{ + LPSTR szEncMsg = 0; + DWORD dwEncMsgLen; + + PGPUInt32 dwKeys; +#if (PGP_WIN32 < 0x700) + PGPKeySetRef PublicKey; + if (CheckPGPError(_pgp_import_key(&PublicKey,pgpKey))) + return 0; + PGPCountKeys(PublicKey, &dwKeys); +#else + PGPKeyDBRef PublicKeyDB; + if (CheckPGPError(_pgp_import_key(&PublicKeyDB,pgpKey))) + return 0; + + PGPKeyIterRef KeyIterRef; + PGPNewKeyIterFromKeyDB(PublicKeyDB, &KeyIterRef); + + PGPKeyDBObjRef PublicKey; + PGPKeyIterNextKeyDBObj(KeyIterRef, kPGPKeyDBObjType_Key, &PublicKey); + + PGPCountKeysInKeyDB(PublicKeyDB, &dwKeys); +#endif + if(dwKeys==0) { +#if (PGP_WIN32 < 0x700) + PGPFreeKeySet(PublicKey); +#else + PGPFreeKeyIter(KeyIterRef); + PGPFreeKeyDB(PublicKeyDB); +#endif + return 0; + } + + PGPError err = PGPEncode(pgpContext, + PGPOInputBuffer(pgpContext, szPlainMsg, lstrlen(szPlainMsg)), + PGPOArmorOutput(pgpContext, TRUE), + PGPOAllocatedOutputBuffer(pgpContext, (LPVOID *)&szEncMsg, 16384, (PGPUInt32 *)&dwEncMsgLen), +#if (PGP_WIN32 < 0x700) + PGPOEncryptToKeySet(pgpContext, PublicKey), +#else + PGPOEncryptToKeyDBObj(pgpContext, PublicKey), +#endif + PGPOVersionString(pgpContext, szVersionStr), + PGPOLastOption(pgpContext)); + +#if (PGP_WIN32 < 0x700) + PGPFreeKeySet(PublicKey); +#else + PGPFreeKeyIter(KeyIterRef); + PGPFreeKeyDB(PublicKeyDB); +#endif + + if (CheckPGPError(err)) + return 0; + + LPSTR szMsg = (LPSTR) LocalAlloc(LPTR,dwEncMsgLen+1); + _pgp_memcpy(szMsg, szEncMsg, dwEncMsgLen); + szMsg[dwEncMsgLen] = 0; + PGPFreeData((LPVOID)szEncMsg); + + return szMsg; +} + + +LPSTR __cdecl _pgp_decrypt_key(LPCSTR szEncMsg, LPCSTR pgpKey) +{ + LPSTR szPlainMsg = 0; + DWORD dwPlainMsgLen; + + PGPUInt32 dwKeys; +#if (PGP_WIN32 < 0x700) + PGPKeySetRef PrivateKeyDB; + if (CheckPGPError(_pgp_import_key(&PrivateKeyDB,pgpKey))) + return 0; + PGPCountKeys(PrivateKeyDB, &dwKeys); +#else + PGPKeyDBRef PrivateKeyDB; + if (CheckPGPError(_pgp_import_key(&PrivateKeyDB,pgpKey))) + return 0; + PGPCountKeysInKeyDB(PrivateKeyDB, &dwKeys); +#endif + if(dwKeys==0) { +#if (PGP_WIN32 < 0x700) + PGPFreeKeySet(PrivateKeyDB); +#else + PGPFreeKeyDB(PrivateKeyDB); +#endif + return 0; + } + + int iTry = 0; + + do { + if (!pszPassphrase && + PGPPassphraseDialog(pgpContext, + PGPOUIOutputPassphrase(pgpContext, &pszPassphrase), + PGPOLastOption(pgpContext)) == kPGPError_UserAbort) { + iTry = 3; + break; + } + +/* +#if (PGP_WIN32 < 0x700) + PGPKeyListRef PrivateKeyList; + PGPOrderKeySet(PrivateKeyDB, kPGPKeyIDOrdering, &PrivateKeyList); + + PGPKeyIterRef KeyIterRef; + PGPNewKeyIter(PrivateKeyList, &KeyIterRef); + + PGPKeyRef PrivateKey; + for(int i=0;i 1) + MessageBox(hDlg, "You selected more than one key. Only the first key will be used.", szModuleName, MB_ICONINFORMATION); + + static PGPKeyID KeyID; + +#if (PGP_WIN32 < 0x700) + PGPKeyListRef ContactKeyList; + PGPOrderKeySet(ContactKeyDB, kPGPKeyIDOrdering, &ContactKeyList); + + PGPKeyIterRef KeyIterRef; + PGPNewKeyIter(ContactKeyList, &KeyIterRef); + + PGPKeyRef ContactKey; + PGPKeyIterNext(KeyIterRef, &ContactKey); + + PGPGetKeyIDFromKey(ContactKey, &KeyID); + PGPGetKeyIDString(&KeyID, kPGPKeyIDString_Abbreviated, szKeyID); + + PGPFreeKeyList(ContactKeyList); + PGPFreeKeyIter(KeyIterRef); + PGPFreeKeySet(ContactKeyDB); +#else + PGPKeyIterRef KeyIterRef; + PGPNewKeyIterFromKeyDB(ContactKeyDB, &KeyIterRef); + + PGPKeyDBObjRef KeyDBObjRef; + PGPKeyIterNextKeyDBObj(KeyIterRef, kPGPKeyDBObjType_Key, &KeyDBObjRef); + + PGPSize dwFilled; + PGPGetKeyDBObjDataProperty(KeyDBObjRef, kPGPKeyProperty_KeyID, &KeyID, sizeof(PGPKeyID), &dwFilled); + PGPGetKeyIDString(&KeyID, kPGPKeyIDString_Abbreviated, szKeyID); + + PGPFreeKeyIter(KeyIterRef); + PGPFreeKeyDB(ContactKeyDB); +#endif + + return (PVOID)&KeyID; +} + + +#if (PGP_WIN32 >= 0x700) +BOOL ShowSelectKeyringsDlg(HWND hParent, LPSTR PubRingPath, LPSTR SecRingPath) +{ + // set keyring paths + OPENFILENAME ofn={0}; + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = hParent; + ofn.nMaxFile = MAX_PATH; + ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_NONETWORKBUTTON; + + ofn.lpstrFile = PubRingPath; + ofn.lpstrFilter = "Public key rings (pubring.pkr)\0pubring.pkr\0All files (*.*)\0*.*\0"; + ofn.lpstrTitle = "Open Public Keyring"; + if (!GetOpenFileName(&ofn)) return FALSE; + + ofn.lpstrFile = SecRingPath; + ofn.lpstrFilter = "Secret key rings (secring.skr)\0secring.skr\0All files (*.*)\0*.*\0"; + ofn.lpstrTitle = "Open Secret Keyring"; + if (!GetOpenFileName(&ofn)) return FALSE; + + return TRUE; +} +#endif + + +// dllmain +BOOL WINAPI dllmain(HINSTANCE hInst, DWORD dwReason, LPVOID) { + g_hInst = hInst; + return TRUE; +} + diff --git a/CryptoPP/PGPw/sdk6/include/pgpBase.h b/CryptoPP/PGPw/sdk6/include/pgpBase.h new file mode 100644 index 0000000..7e460c8 --- /dev/null +++ b/CryptoPP/PGPw/sdk6/include/pgpBase.h @@ -0,0 +1,270 @@ +/*____________________________________________________________________________ + pgpBase.h + + Copyright (C) 1997 Network Associates Inc. and affiliated companies. + All rights reserved. + + This file deals with system dependencies to derive our very basic data + types. It should not contain any higher level types. + + $Id: pgpBase.h,v 1.27.16.1 1999/08/04 18:35:43 sluu Exp $ +____________________________________________________________________________*/ +#ifndef Included_pgpBase_h /* [ */ +#define Included_pgpBase_h + +#include "pgpPFLConfig.h" + + +#include + + + +#if !( defined(PGP_MACINTOSH) || defined(PGP_UNIX) || defined(PGP_WIN32) ) +#error one of {PGP_MACINTOSH, PGP_UNIX, PGP_WIN32} must be defined +#endif + +#if PGP_MACINTOSH +#include +#if __MWERKS__ && ! defined( __dest_os ) + #include + #define __dest_os __mac_os +#endif +#else + /* aCC bars on if this file is not included first */ + #if PGP_COMPILER_HPUX + #include + #endif /* PGP_COMPILER_HPUX */ + #include +#endif + +#if PGP_WIN32 +#include /* For size_t */ +#endif + +#if ! NO_LIMITS_H +#include +#endif + + +/*____________________________________________________________________________ + PGP basic types +____________________________________________________________________________*/ + +typedef unsigned char PGPBoolean; /* can be TRUE or FALSE */ +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + + +/* PGPUInt8, PGPInt8 */ +#if UCHAR_MAX == 0xff + +typedef unsigned char PGPUInt8; +typedef signed char PGPInt8; +#define MAX_PGPUInt8 UCHAR_MAX +#define MAX_PGPInt8 SCHAR_MAX + +#else +#error This machine has no 8-bit type +#endif + + +/* PGPUInt16, PGPInt16 */ +#if UINT_MAX == 0xffff + +typedef unsigned int PGPUInt16; +typedef int PGPInt16; +#define MAX_PGPUInt16 UINT_MAX +#define MAX_PGPInt16 INT_MAX + +#elif USHRT_MAX == 0xffff + +typedef unsigned short PGPUInt16; +typedef short PGPInt16; +#define MAX_PGPUInt16 USHRT_MAX +#define MAX_PGPInt16 SHRT_MAX + +#else +#error This machine has no 16-bit type +#endif + + +/* PGPUInt32, PGPInt32 */ +#if UINT_MAX == 0xfffffffful + +typedef unsigned int PGPUInt32; +typedef int PGPInt32; +#define MAX_PGPUInt32 UINT_MAX +#define MAX_PGPInt32 INT_MAX + +#elif ULONG_MAX == 0xfffffffful + +typedef unsigned long PGPUInt32; +typedef long PGPInt32; +#define MAX_PGPUInt32 ULONG_MAX +#define MAX_PGPInt32 LONG_MAX + +#elif USHRT_MAX == 0xfffffffful + +typedef unsigned short PGPUInt32; +typedef short PGPInt32; +#define MAX_PGPUInt32 USHRT_MAX +#define MAX_PGPInt32 SHRT_MAX + +#else +#error This machine has no 32-bit type +#endif + + +/*____________________________________________________________________________ + PGPUInt64, PGPInt64 + + Find a 64-bit data type, if possible. + The conditions here are more complicated to avoid using numbers that + will choke lesser preprocessors (like 0xffffffffffffffff) unless + we're reasonably certain that they'll be acceptable. + + Some *preprocessors* choke on constants that long even if the + compiler can accept them, so it doesn't work reliably to test values. + So cross our fingers and hope that it's a 64-bit type. + + GCC uses ULONG_LONG_MAX. Solaris uses ULLONG_MAX. + IRIX uses ULONGLONG_MAX. Are there any other names for this? +____________________________________________________________________________*/ +#if ULONG_MAX > 0xfffffffful +#if ULONG_MAX == 0xfffffffffffffffful + +typedef ulong PGPUInt64; +typedef long PGPInt64; +#define PGP_HAVE64 1 + +#endif +#endif + + +#ifndef PGP_HAVE64 + +#if defined(ULONG_LONG_MAX) || defined (ULLONG_MAX) || defined(ULONGLONG_MAX) +typedef unsigned long long PGPUInt64; +typedef long long PGPInt64; +#define PGP_HAVE64 1 + +#endif +#endif + + +#ifndef PGP_HAVE64 +#if defined(__MWERKS__) +#if __option( longlong ) + +typedef unsigned long long PGPUInt64; +typedef long long PGPInt64; +#define PGP_HAVE64 1 + +#endif +#endif +#endif + +#if PGP_HAVE64 +/* too painful to test all the variants above, so just do it this way */ +#define MAX_PGPUInt64 ((PGPUInt64)0xfffffffffffffffful) +#define MAX_PGPInt64 ((PGPInt64)0x7fffffffffffffff) +#endif + + +#if INT_MAX == 0x7FFFFFFFL +#define PGPENUM_TYPEDEF( enumName, typeName ) typedef enum enumName typeName +#else +#define PGPENUM_TYPEDEF( enumName, typeName ) typedef PGPInt32 typeName +#endif +#define kPGPEnumMaxValue INT_MAX + +#define PGP_ENUM_FORCE( enumName ) \ + k ## enumName ## force = kPGPEnumMaxValue + + +typedef PGPUInt8 PGPByte; + +typedef PGPInt32 PGPError; + +/* a simple value sufficient to hold any numeric or pointer type */ +typedef void * PGPUserValue; + +/* A PGPSize refers to in memory sizes. Use PGPFileOffset for file offsets */ +#if PGP_UNIX_HPUX +/* HPUX has conflicting types for size_t. This forces a PGPSize to + * always be the same type. */ +typedef unsigned long PGPSize; +#else +typedef size_t PGPSize; +#endif + +#define MAX_PGPSize ( ~(PGPSize)0 ) + +/* An offset or size of a file */ +#if PGP_UNIX +typedef off_t PGPFileOffset; +#else +#if PGP_HAVE64 +typedef PGPInt64 PGPFileOffset; +#else +typedef PGPInt32 PGPFileOffset; +#endif +#endif + +typedef PGPUInt32 PGPFlags; +typedef PGPUInt32 PGPTime; +typedef PGPUInt32 PGPTimeInterval; /* In milliseconds */ + +typedef struct PGPVersion +{ + PGPUInt16 majorVersion; + PGPUInt16 minorVersion; + +} PGPVersion; + +/*____________________________________________________________________________ + These macros should surround all C declarations in public + header files which define function or data symbols. +____________________________________________________________________________*/ + +#ifdef __cplusplus /* [ */ + +#define PGP_BEGIN_C_DECLARATIONS extern "C" { +#define PGP_END_C_DECLARATIONS } + +#else /* ] __cplusplus [ */ + +#define PGP_BEGIN_C_DECLARATIONS +#define PGP_END_C_DECLARATIONS + +#endif /* ] __cplusplus */ + + + + +#ifndef pgpMin +#define pgpMin(x,y) (((x)<(y)) ? (x) : (y)) +#endif + +#ifndef pgpMax +#define pgpMax(x,y) (((x)>(y)) ? (x) : (y)) +#endif + +#ifndef PGP_DEPRECATED +#define PGP_DEPRECATED 1 +#endif + +#endif /* ] Included_pgpBase_h */ + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk6/include/pgpBigNum.h b/CryptoPP/PGPw/sdk6/include/pgpBigNum.h new file mode 100644 index 0000000..81c6b17 --- /dev/null +++ b/CryptoPP/PGPw/sdk6/include/pgpBigNum.h @@ -0,0 +1,208 @@ +/*____________________________________________________________________________ + Copyright (C) 1997 Network Associates Inc. and affiliated companies. + All rights reserved. + + $Id: pgpBigNum.h,v 1.9 1999/03/10 02:47:07 heller Exp $ +____________________________________________________________________________*/ + + +#ifndef Included_pgpBigNum_h +#define Included_pgpBigNum_h + +#include "pgpBase.h" + +#include "pgpUtilities.h" + +#include "pgpMemoryMgr.h" + +PGP_BEGIN_C_DECLARATIONS + +#if PRAGMA_IMPORT_SUPPORTED +#pragma import on +#endif + + +typedef struct PGPBigNum * PGPBigNumRef; +#define kPGPInvalidBigNumRef ( (PGPBigNumRef)NULL ) + + +/* Creates a new bignum, secure, or plain s*/ +PGPError PGPNewBigNum( PGPMemoryMgrRef mgr, + PGPBoolean secure, PGPBigNumRef *newBN ); + +/* destoys the bignum and all memory it uses */ +PGPError PGPFreeBigNum( PGPBigNumRef bn ); + + +/* Create a new big num with same value as src */ +PGPError PGPCopyBigNum( PGPBigNumRef src, PGPBigNumRef * dest ); + +/* Make existing bignum dest have same value as source */ +PGPError PGPAssignBigNum( PGPBigNumRef src, PGPBigNumRef dest ); + + +/* Swap two BigNums. Very fast. */ +PGPError PGPSwapBigNum( PGPBigNumRef a, PGPBigNumRef b); + + +/* + * Move bytes between the given buffer and the given BigNum encoded in + * base 256. I.e. after either of these, the buffer will be equal to + * (bn / 256^lsbyte) % 256^len. The difference is which is altered to + * match the other! + */ +PGPError PGPBigNumExtractBigEndianBytes( PGPBigNumRef bn, + PGPByte *dest, PGPUInt32 lsbyte, PGPUInt32 len ); + +PGPError PGPBigNumInsertBigEndianBytes(PGPBigNumRef bn, + PGPByte const *src, PGPUInt32 lsbyte, PGPUInt32 len ); + +/* The same, but the buffer is little-endian. */ +PGPError PGPBigNumExtractLittleEndianBytes( PGPBigNumRef bn, + PGPByte *dest, PGPUInt32 lsbyte, PGPUInt32 len ); + +PGPError PGPBigNumInsertLittleEndianBytes(PGPBigNumRef bn, + PGPByte const *src, PGPUInt32 lsbyte, PGPUInt32 len ); + +/* Return the least-significant bits (at least 16) of the BigNum */ +PGPUInt16 PGPBigNumGetLSWord( PGPBigNumRef bn ); + +/* + * Return the number of significant bits in the BigNum. + * 0 or 1+floor(log2(src)) + */ +PGPUInt32 PGPBigNumGetSignificantBits( PGPBigNumRef bn ); + +/* + * Adds two bignums into dest. Faster if dest is same as lhs or rhs. + */ +PGPError PGPBigNumAdd( PGPBigNumRef lhs, + PGPBigNumRef rhs, PGPBigNumRef dest ); + +/* + * lhs-rhs. dest and src may be the same, but bnSetQ(dest, 0) is faster. + * if dest < src, returns error and dest is undefined. + */ +PGPError PGPBigNumSubtract( PGPBigNumRef lhs, + PGPBigNumRef rhs, PGPBigNumRef dest, + PGPBoolean *underflow ); + + +/* Return sign (-1, 0, +1) of a-b. a <=> b --> bnCmpQ(a, b) <=> 0 */ +PGPInt32 PGPBigNumCompareQ( PGPBigNumRef bn, PGPUInt16 sm ); + +/* dest = src, where 0 <= src < 2^16. */ +PGPError PGPBigNumSetQ( PGPBigNumRef dest, PGPUInt16 sm ); + +/* dest = bn + sm, where 0 <= sm < 2^16 */ +PGPError PGPBigNumAddQ( PGPBigNumRef bn, PGPUInt16 sm, + PGPBigNumRef dest); + +/* dest = bn + sm, where 0 <= sm < 2^16 */ +PGPError PGPBigNumSubtractQ( PGPBigNumRef bn, PGPUInt16 sm, + PGPBigNumRef dest, PGPBoolean *underflow); + +/* Return sign (-1, 0, +1) of a-b. a <=> b --> bnCmp(a, b) <=> 0 */ +PGPInt32 PGPBigNumCompare( PGPBigNumRef lhs, PGPBigNumRef rhs); + +/* dest = src * src. dest may be the same as src, but it costs time. */ +PGPError PGPBigNumSquare( PGPBigNumRef src, PGPBigNumRef dest); + +/* dest = a * b. dest may be the same as a or b, but it costs time. */ +PGPError PGPBigNumMultiply( PGPBigNumRef lhs, PGPBigNumRef rhs, + PGPBigNumRef dest); + +/* dest = a * b, where 0 <= b < 2^16. dest and a may be the same. */ +PGPError PGPBigNumMultiplyQ( PGPBigNumRef lhs, PGPUInt16 sm, + PGPBigNumRef dest); + +/* + * q = n/d, r = n%d. r may be the same as n, but not d, + * and q may not be the same as n or d. + * re-entrancy issue: this temporarily modifies d, but restores + * it for return. + */ +PGPError PGPBigNumDivide( PGPBigNumRef numerator, + PGPBigNumRef denominator, + PGPBigNumRef quotient, + PGPBigNumRef remainder); +/* + * dest = n % d. dest and src may be the same, but not dest and d. + * re-entrancy issue: this temporarily modifies d, but restores + * it for return. + */ +PGPError PGPBigNumMod( PGPBigNumRef numerator, + PGPBigNumRef denominator, + PGPBigNumRef dest ); + +/* return src % d, where 0 <= d < 2^16. */ +PGPUInt16 PGPBigNumModQ( PGPBigNumRef numerator, + PGPUInt16 denominator ); + +/* n = n^exp, modulo "mod" "mod" *must* be odd */ +PGPError PGPBigNumExpMod( + PGPBigNumRef n, + PGPBigNumRef exponent, + PGPBigNumRef mod, + PGPBigNumRef dest ); + +/* + * dest = n1^e1 * n2^e2, modulo "mod". "mod" *must* be odd. + * dest may be the same as n1 or n2. + */ +PGPError PGPBigNumDoubleExpMod( + PGPBigNumRef n1, + PGPBigNumRef exponent1, + PGPBigNumRef n2, + PGPBigNumRef exponent2, + PGPBigNumRef mod, + PGPBigNumRef dest ); + +/* dest = 2^exp, modulo "mod" "mod" *must* be odd */ +PGPError PGPBigNumTwoExpMod( + PGPBigNumRef exponent, + PGPBigNumRef mod, + PGPBigNumRef dest ); + +/* dest = gcd(a, b). The inputs may overlap arbitrarily. */ +PGPError PGPBigNumGCD( PGPBigNumRef a, PGPBigNumRef b, + PGPBigNumRef dest ); + +/* dest = src^-1, modulo "mod". dest may be the same as src. */ +PGPError PGPBigNumInv( PGPBigNumRef src, + PGPBigNumRef mod, + PGPBigNumRef dest ); + + +/* Shift dest left "amt" places */ +PGPError PGPBigNumLeftShift( PGPBigNumRef dest, PGPUInt32 amt ); + +/* Shift dest right "amt" places, discarding low-order bits */ +PGPError PGPBigNumRightShift( PGPBigNumRef dest, PGPUInt32 amt ); + +/* right shift all low order 0-bits, return number of bits shifted */ +PGPUInt16 PGPBigNumMakeOdd( PGPBigNumRef dest ); + + +#if PRAGMA_IMPORT_SUPPORTED +#pragma import reset +#endif + +PGP_END_C_DECLARATIONS + +#endif /* Included_pgpBigNum_h */ + + + + + + + + + + + + + + + diff --git a/CryptoPP/PGPw/sdk6/include/pgpCBC.h b/CryptoPP/PGPw/sdk6/include/pgpCBC.h new file mode 100644 index 0000000..9e3ea03 --- /dev/null +++ b/CryptoPP/PGPw/sdk6/include/pgpCBC.h @@ -0,0 +1,93 @@ +/*____________________________________________________________________________ + pgpCBC.h + + Copyright (C) 1997 Network Associates Inc. and affiliated companies. + All rights reserved. + + $Id: pgpCBC.h,v 1.5 1999/03/10 02:47:09 heller Exp $ +____________________________________________________________________________*/ +#ifndef Included_pgpCBC_h /* [ */ +#define Included_pgpCBC_h + +#include "pgpSymmetricCipher.h" + + +PGP_BEGIN_C_DECLARATIONS +#if PRAGMA_IMPORT_SUPPORTED +#pragma import on +#endif + +/*____________________________________________________________________________ + A CBC context requires use of a symmetric cipher which has been created + and whose key has been set. An error will be returned if this is not + the case. + + After the call, the CBCContextRef "owns" the + symmetric ref and will dispose of it properly (even if an error + occurs). The caller should no longer reference it. +____________________________________________________________________________*/ +PGPError PGPNewCBCContext( PGPSymmetricCipherContextRef ref, + PGPCBCContextRef *outRef ); + + +/*____________________________________________________________________________ + Disposal clears all data in memory before releasing it. +____________________________________________________________________________*/ +PGPError PGPFreeCBCContext( PGPCBCContextRef ref ); + + +/*____________________________________________________________________________ + Make an exact copy, including current state. Original is not changed. +____________________________________________________________________________*/ +PGPError PGPCopyCBCContext( PGPCBCContextRef ref, PGPCBCContextRef *outRef ); + + + +/*____________________________________________________________________________ + IV size is implicit (same size as the symmetric cipher block size). + IV is *copied*. + Caller may want to destroy the original after passing it in. +____________________________________________________________________________*/ +PGPError PGPInitCBC( PGPCBCContextRef ref, + const void *key, + const void *initializationVector ); + + +/*____________________________________________________________________________ + Call repeatedly to process arbitrary amounts of data. Each call must + have bytesIn be a multiple of the cipher block size. +____________________________________________________________________________*/ +PGPError PGPCBCEncrypt( PGPCBCContextRef ref, + const void *in, PGPSize bytesIn, void *out ); + +PGPError PGPCBCDecrypt( PGPCBCContextRef ref, + const void *in, PGPSize bytesIn, void *out ); + + + +/*____________________________________________________________________________ + Get the symmetric cipher being used for this CBC context. + You can use this to determine useful things about the underlying cipher + such as its block size. +____________________________________________________________________________*/ +PGPError PGPCBCGetSymmetricCipher( PGPCBCContextRef ref, + PGPSymmetricCipherContextRef *outRef ); + + + +#if PRAGMA_IMPORT_SUPPORTED +#pragma import reset +#endif +PGP_END_C_DECLARATIONS + +#endif /* ] Included_pgpCBC_h */ + + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk6/include/pgpCFB.h b/CryptoPP/PGPw/sdk6/include/pgpCFB.h new file mode 100644 index 0000000..54ae8d7 --- /dev/null +++ b/CryptoPP/PGPw/sdk6/include/pgpCFB.h @@ -0,0 +1,127 @@ +/*____________________________________________________________________________ + Copyright (C) 1997 Network Associates Inc. and affiliated companies. + All rights reserved. + + $Id: pgpCFB.h,v 1.6 1999/03/10 02:47:11 heller Exp $ +____________________________________________________________________________*/ +#ifndef Included_pgpCFB_h /* [ */ +#define Included_pgpCFB_h + +#include "pgpSymmetricCipher.h" + + +PGP_BEGIN_C_DECLARATIONS +#if PRAGMA_IMPORT_SUPPORTED +#pragma import on +#endif + +/*____________________________________________________________________________ + A CFB context requires use of a symmetric cipher which has been created + and whose key has been set. An error will be returned if this is not + the case. + + After the call, the CFBRef "owns" the symmetric ref and will + dispose of it properly (even if an error occurs). + The caller should no longer reference it. +____________________________________________________________________________*/ +PGPError PGPNewCFBContext( PGPSymmetricCipherContextRef ref, + PGPUInt16 interleaveFactor, + PGPCFBContextRef *outRef ); + + +/*____________________________________________________________________________ + Disposal clears all data in memory before releasing it. +____________________________________________________________________________*/ +PGPError PGPFreeCFBContext( PGPCFBContextRef ref ); + + +/*____________________________________________________________________________ + Make an exact copy, including current state. Original is not changed. +____________________________________________________________________________*/ +PGPError PGPCopyCFBContext( PGPCFBContextRef ref, + PGPCFBContextRef *outRef ); + + + +/*____________________________________________________________________________ + IV size is implicit (same size as the symmetric cipher block size). + IV is *copied*. + Caller may want to destroy the original after passing it in. + Calling this implicitly calls PGPResetCFB(). +____________________________________________________________________________*/ +PGPError PGPInitCFB( PGPCFBContextRef ref, + const void *key, + const void *initializationVector ); + + +/*____________________________________________________________________________ + Call repeatedly to process arbitrary amounts of data. +____________________________________________________________________________*/ +PGPError PGPCFBEncrypt( PGPCFBContextRef ref, + const void *in, PGPSize bytesIn, void *out ); + +PGPError PGPCFBDecrypt( PGPCFBContextRef ref, + const void *in, PGPSize bytesIn, void *out ); + + + +/*____________________________________________________________________________ + Get the symmetric cipher being used for this CFB context. + You can use this to determine useful things about the underlying cipher + such as its block size. +____________________________________________________________________________*/ +PGPError PGPCFBGetSymmetricCipher( + PGPCFBContextRef ref, + PGPSymmetricCipherContextRef *outRef ); + + + +/*____________________________________________________________________________ + Reset the feedback mechanism to use whatever we have so far, plus previous + bytes for a total of the cipher block size bytes. This effectively + changes the cipher block boundary. +____________________________________________________________________________*/ +PGPError PGPCFBSync( PGPCFBContextRef ref ); + + + +/*____________________________________________________________________________ + Fetch random bytes from the cipher. Returns the actual number of + random bytes obtained. +____________________________________________________________________________*/ +PGPError PGPCFBGetRandom( PGPCFBContextRef ref, + PGPSize requestCount, void *out, PGPSize *outCount); + + +/*____________________________________________________________________________ + Make more random bytes available using the supplied salt, which must + be the same as the symmetric cipher block size. +____________________________________________________________________________*/ +PGPError PGPCFBRandomCycle( PGPCFBContextRef ref, + const void *salt); + + +/*____________________________________________________________________________ + Make more random bytes available using the supplied salt, which must + be the same as the symmetric cipher block size. +____________________________________________________________________________*/ +PGPError PGPCFBRandomWash( PGPCFBContextRef ref, + const void *in, PGPSize bytesIn ); + + +#if PRAGMA_IMPORT_SUPPORTED +#pragma import reset +#endif +PGP_END_C_DECLARATIONS + +#endif /* ] Included_pgpCFB_h */ + + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk6/include/pgpConfig.h b/CryptoPP/PGPw/sdk6/include/pgpConfig.h new file mode 100644 index 0000000..f72f0d4 --- /dev/null +++ b/CryptoPP/PGPw/sdk6/include/pgpConfig.h @@ -0,0 +1,96 @@ +/* + * pgpConfig.h -- Configuration for the PGPsdk. This file contains + * the configuration information for the PGPsdk, and it should be + * included in all PGPsdk source files. + * + * $Id: pgpConfig.h,v 1.13 1997/09/30 21:03:13 lloyd Exp $ + */ + +/* Define to empty if the compiler does not support 'const' variables. */ +/* #undef const */ + +/* Define to `long' if doesn't define. */ +/* #undef off_t */ + +/* Define to `unsigned' if doesn't define. */ +/* #undef size_t */ + + +#ifndef Included_pgpConfig_h /* [ */ +#define Included_pgpConfig_h + +#include "pgpPFLConfig.h" + + + + + +#ifndef Included_pgpPFLConfig_h /* [ */ + +#define HAVE_STDARG_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_UNISTD_H 0 +#define HAVE_USHORT 0 +#define HAVE_UINT 0 +#define HAVE_ULONG 0 +#define NO_LIMITS_H 0 +#define NO_POPEN 1 + +#if defined( _MSC_VER ) +#define PGP_HAVE64 1 +typedef __int64 PGPInt64; +typedef unsigned __int64 PGPUInt64; + +#elif defined( __MWERKS__ ) + +#define PGP_HAVE64 0 + +#endif + + + +#endif /*Included_pgpPFLConfig_h*/ /* ] */ + + +/* Checks for various types */ +#define HAVE_UCHAR 0 + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Checks for various specific header files */ +#define HAVE_FCNTL_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_SYS_IOCTL_H 0 +#define HAVE_SYS_TIME_H 0 +#define HAVE_SYS_TIMEB_H 1 +#define HAVE_SYS_PARAM_H 0 + +/* Check if is broken and #includes wrong */ +#define TIME_WITH_SYS_TIME 0 + +/* Checks for various functions */ +#define HAVE_GETHRTIME 0 +#define HAVE_CLOCK_GETTIME 0 +#define HAVE_CLOCK_GETRES 0 +#define HAVE_GETTIMEOFDAY 0 +#define HAVE_GETITIMER 0 +#define HAVE_SETITIMER 0 +#define HAVE_FTIME 1 +#define HAVE_MKSTEMP 0 + + +#if defined( __MWERKS__ ) + +#define PGPTTYE /* nothing */ + +#elif defined( _MSC_VER ) + +/* Tags for exported functions, needed for dynamic linking on some platforms */ +#define PGPTTYE /* nothing */ + +#endif + + + +#endif /* ] Included_pgpConfig_h */ diff --git a/CryptoPP/PGPw/sdk6/include/pgpEncode.h b/CryptoPP/PGPw/sdk6/include/pgpEncode.h new file mode 100644 index 0000000..8b87c1c --- /dev/null +++ b/CryptoPP/PGPw/sdk6/include/pgpEncode.h @@ -0,0 +1,301 @@ +/*____________________________________________________________________________ + pgpEncode.h + + Copyright (C) 1997 Network Associates Inc. and affiliated companies. + All rights reserved. + + This file contains the prototypes for functions which encode/decode files + and buffers. + + $Id: pgpEncode.h,v 1.104 1999/05/07 23:47:46 hal Exp $ +____________________________________________________________________________*/ + +#ifndef Included_pgpEncode_h /* [ */ +#define Included_pgpEncode_h + +#include "pgpPubTypes.h" +#include "pgpTLS.h" + +#if PRAGMA_ALIGN_SUPPORTED +#pragma options align=mac68k +#endif + +/* + * The PGPEvent structure is used to notify clients of the encode API of + * various events. + */ + +/* PGP Event types */ + +enum PGPEventType_ +{ + kPGPEvent_NullEvent = 0, /* Nothing happened */ + kPGPEvent_InitialEvent = 1, /* Final event */ + kPGPEvent_FinalEvent = 2, /* Final event */ + kPGPEvent_ErrorEvent = 3, /* An error occurred */ + kPGPEvent_WarningEvent = 4, /* Warning event */ + kPGPEvent_EntropyEvent = 5, /* More entropy is needed */ + kPGPEvent_PassphraseEvent = 6, /* A passphrase is needed */ + kPGPEvent_InsertKeyEvent = 7, /* Smart card must be inserted */ + kPGPEvent_AnalyzeEvent = 8, /* Initial analysis event, + before any output */ + kPGPEvent_RecipientsEvent = 9, /* Recipient list report, + before any output */ + kPGPEvent_KeyFoundEvent = 10, /* Key packet found */ + kPGPEvent_OutputEvent = 11, /* Output specification needed */ + kPGPEvent_SignatureEvent = 12, /* Signature status report */ + kPGPEvent_BeginLexEvent = 13, /* Initial event per lexical unit*/ + kPGPEvent_EndLexEvent = 14, /* Final event per lexical unit */ + kPGPEvent_RecursionEvent = 15, /* Notification of recursive + job creation */ + kPGPEvent_DetachedSignatureEvent = 16, /* Need input for verification of + detached signature */ + kPGPEvent_KeyGenEvent = 17, /* Key generation progress */ + + kPGPEvent_KeyServerEvent = 18, /* Key Server progress */ + kPGPEvent_KeyServerSignEvent= 19, /* Key Server passphrase */ + kPGPEvent_KeyServerTLSEvent = 20, /* Key Server TLS event */ + kPGPEvent_KeyServerIdleEvent= 21, /* Idle during keyserver call */ + + kPGPEvent_SocketsIdleEvent = 22, /* Idle during sockets */ + kPGPEvent_DecryptionEvent = 23, /* Decryption data report */ + kPGPEvent_EncryptionEvent = 24, /* Encryption data report */ + PGP_ENUM_FORCE( PGPEventType_ ) +}; +PGPENUM_TYPEDEF( PGPEventType_, PGPEventType ); + + +/* PGP Analyze event callback codes */ + +enum PGPAnalyzeType_ +{ + kPGPAnalyze_Encrypted = 0, /* Encrypted message */ + kPGPAnalyze_Signed = 1, /* Signed message */ + kPGPAnalyze_DetachedSignature = 2, /* Detached signature */ + kPGPAnalyze_Key = 3, /* Key data */ + kPGPAnalyze_Unknown = 4, /* Non-pgp message */ + kPGPAnalyze_X509Certificate = 5, /* X.509 certificate */ + + PGP_ENUM_FORCE( PGPAnalyzeType_ ) +}; +PGPENUM_TYPEDEF( PGPAnalyzeType_, PGPAnalyzeType ); + + + + +/* Individual event information structs, combined as a union in PGPEvent */ + +typedef struct PGPEventNullData_ +{ + PGPFileOffset bytesWritten; + PGPFileOffset bytesTotal; +} PGPEventNullData; + +typedef struct PGPEventErrorData_ +{ + PGPError error; + void *errorArg; +} PGPEventErrorData; + +typedef struct PGPEventWarningData_ +{ + PGPError warning; + void *warningArg; +} PGPEventWarningData; + +typedef struct PGPEventEntropyData_ +{ + PGPUInt32 entropyBitsNeeded; +} PGPEventEntropyData; + +typedef struct PGPEventPassphraseData_ +{ + PGPBoolean fConventional; + PGPKeySetRef keyset; +} PGPEventPassphraseData; + +typedef struct PGPEventRecipientsData_ +{ + PGPKeySetRef recipientSet; + PGPUInt32 conventionalPassphraseCount; + PGPUInt32 keyCount; + PGPKeyID const * keyIDArray; +} PGPEventRecipientsData; + +typedef struct PGPEventKeyFoundData_ +{ + PGPKeySetRef keySet; +} PGPEventKeyFoundData; + +typedef struct PGPEventSignatureData_ +{ + PGPKeyID signingKeyID; + PGPKeyRef signingKey; + PGPBoolean checked; + PGPBoolean verified; + PGPBoolean keyRevoked; + PGPBoolean keyDisabled; + PGPBoolean keyExpired; + PGPBoolean keyMeetsValidityThreshold; + PGPValidity keyValidity; + PGPTime creationTime; +} PGPEventSignatureData; + +typedef struct PGPEventDecryptionData_ +{ + PGPCipherAlgorithm cipherAlgorithm; + PGPByte *sessionKey; + PGPSize sessionKeyLength; +} PGPEventDecryptionData; + +typedef struct PGPEventEncryptionData_ +{ + PGPCipherAlgorithm cipherAlgorithm; + PGPByte *sessionKey; + PGPSize sessionKeyLength; +} PGPEventEncryptionData; + +typedef struct PGPEventAnalyzeData_ +{ + PGPAnalyzeType sectionType; +} PGPEventAnalyzeData; + +typedef struct PGPEventOutputData_ +{ + PGPUInt32 messageType; + char *suggestedName; + PGPBoolean forYourEyesOnly; +} PGPEventOutputData; + +typedef struct PGPEventBeginLexData_ +{ + PGPUInt32 sectionNumber; + PGPSize sectionOffset; +} PGPEventBeginLexData; + +typedef struct PGPEventEndLexData_ +{ + PGPUInt32 sectionNumber; +} PGPEventEndLexData; + +typedef struct PGPEventKeyGenData_ +{ + PGPUInt32 state; +} PGPEventKeyGenData; + +typedef struct PGPEventKeyServerData_ +{ + PGPKeyServerRef keyServerRef; + PGPUInt32 state; /* PGPKeyServerState */ +} PGPEventKeyServerData; + +typedef struct PGPEventKeyServerSignData_ +{ + PGPKeyServerRef keyServerRef; +} PGPEventKeyServerSignData; + +typedef struct PGPEventKeyServerTLSData_ +{ + PGPKeyServerRef keyServerRef; + PGPUInt32 state; /* PGPKeyServerState */ + PGPtlsSessionRef tlsSession; +} PGPEventKeyServerTLSData; + +typedef struct PGPEventKeyServerIdleData_ +{ + PGPKeyServerRef keyServerRef; +} PGPEventKeyServerIdleData; + + +/* + * The following events have no event-specific data defined for them: + * kPGPEvent_InsertKeyEvent + * kPGPEvent_RecursionEvent + * kPGPEvent_DetachedSignatureEvent + * kPGPEvent_InitialEvent + * kPGPEvent_FinalEvent + * kPGPEvent_SocketsIdleEvent + */ + +/* Union of all event data structures above */ +typedef union PGPEventData_ +{ + PGPEventNullData nullData; + PGPEventErrorData errorData; + PGPEventWarningData warningData; + PGPEventEntropyData entropyData; + PGPEventPassphraseData passphraseData; + PGPEventRecipientsData recipientsData; + PGPEventKeyFoundData keyFoundData; + PGPEventSignatureData signatureData; + PGPEventDecryptionData decryptionData; + PGPEventEncryptionData encryptionData; + PGPEventAnalyzeData analyzeData; + PGPEventOutputData outputData; + PGPEventBeginLexData beginLexData; + PGPEventEndLexData endLexData; + PGPEventKeyGenData keyGenData; + PGPEventKeyServerData keyServerData; + PGPEventKeyServerSignData keyServerSignData; + PGPEventKeyServerTLSData keyServerTLSData; + PGPEventKeyServerIdleData keyServerIdleData; +} PGPEventData; + +/* Refs to internal "job" structure */ +typedef struct PGPJob * PGPJobRef; + +#define kInvalidPGPJobRef ((PGPJobRef) NULL) +#define PGPJobRefIsValid( ref ) ( (ref) != kInvalidPGPJobRef ) + +/* PGPEvent structure */ + +struct PGPEvent +{ + PGPVersion version; /* Version of event structure */ + struct PGPEvent_ *nextEvent; /* Allow lists of events */ + PGPJobRef job; /* Associated with what job */ + PGPEventType type; /* Type of event */ + PGPEventData data; /* Event specific data */ +}; +typedef struct PGPEvent PGPEvent; + + +#if PRAGMA_ALIGN_SUPPORTED +#pragma options align=reset +#endif + +PGP_BEGIN_C_DECLARATIONS + +#if PRAGMA_IMPORT_SUPPORTED +#pragma import on +#endif + +/* +** Functions to encode and decode. The variable parameters are one or more +** PGPOptionListRef's which describe the inputs, outputs, and options. +*/ + +PGPError PGPEncode(PGPContextRef context, + PGPOptionListRef firstOption, ...); +PGPError PGPDecode(PGPContextRef context, + PGPOptionListRef firstOption, ...); + +PGPError PGPAddJobOptions(PGPJobRef job, + PGPOptionListRef firstOption, ...); + +#if PRAGMA_IMPORT_SUPPORTED +#pragma import reset +#endif +PGP_END_C_DECLARATIONS + +#endif /* ] Included_pgpEncode_h */ + + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk6/include/pgpErrors.h b/CryptoPP/PGPw/sdk6/include/pgpErrors.h new file mode 100644 index 0000000..52ffcfe --- /dev/null +++ b/CryptoPP/PGPw/sdk6/include/pgpErrors.h @@ -0,0 +1,305 @@ +/*____________________________________________________________________________ + pgpErrors.h + + Copyright (C) 1997 Network Associates Inc. and affiliated companies. + All rights reserved. + + Error codes for all PGP errors can be found in this file. + + $Id: pgpErrors.h,v 1.96 1999/05/11 19:01:17 heller Exp $ +____________________________________________________________________________*/ +#ifndef Included_pgpErrors_h /* [ */ +#define Included_pgpErrors_h + +#include "pgpPubTypes.h" + + +#include "pgpPFLErrors.h" + +#define kPGPErrorRange 1000 + +enum PGPError_ +{ + /* + NOTE: error code values must not be changed; + compiled client code depends on them. + */ + kPGPError_FirstError = -11500, + kPGPError_Last = -10500, + + kPGPError_BadPassphrase = -11500, + kPGPError_OptionNotFound = -11499, + +/* Errors from pgpEncode */ + kPGPError_RedundantOptions = -11498, + kPGPError_KeyRevoked = -11497, + kPGPError_KeyExpired = -11496, + kPGPError_KeyDisabled = -11495, + kPGPError_KeyInvalid = -11494, + kPGPError_KeyUnusableForEncryption = -11493, + kPGPError_KeyUnusableForSignature = -11492, + kPGPError_OutputBufferTooSmall = -11491, + kPGPError_InconsistentEncryptionAlgorithms = -11490, + kPGPError_MissingPassphrase = -11489, + kPGPError_CombinedConventionalAndPublicEncryption= -11488, + kPGPError_DetachedSignatureWithoutSigningKey= -11487, + kPGPError_DetachedSignatureWithEncryption = -11486, + kPGPError_NoInputOptions = -11485, + kPGPError_MultipleInputOptions = -11484, + kPGPError_InputFile = -11483, + kPGPError_NoOutputOptions = -11482, + kPGPError_MultipleOutputOptions = -11481, + kPGPError_MissingEventHandler = -11480, + kPGPError_MissingKeySet = -11479, + kPGPError_DetachedSignatureFound = -11478, + kPGPError_NoDecryptionKeyFound = -11477, + kPGPError_CorruptSessionKey = -11476, + kPGPError_SkipSection = -11475, + kPGPError_Interrupted = -11474, + kPGPError_TooManyARRKs = -11473, + kPGPError_KeyUnusableForDecryption = -11472, + + kPGPError_IncompatibleAPI = -11460, + +/* misc errors */ + kPGPError_NotMacBinary = -11450, + kPGPError_NoMacBinaryTranslationAvailable = -11449, + kPGPError_BadSignature = -11448, + kPGPError_CAPIUnsupportedKey = -11447, + kPGPError_SelfTestFailed = -11446, + kPGPError_SelfTestsNotExecuted = -11445, + kPGPError_BadIntegrity = -11444, + kPGPError_DeCompressionFailed = -11443, + +/* filter errors */ + + kPGPError_InconsistentFilterClasses = -11440, + kPGPError_UnsupportedLDAPFilter = -11439, + kPGPError_UnsupportedHKPFilter = -11438, + kPGPError_UnknownFilterType = -11437, + kPGPError_InvalidFilterParameter = -11436, + kPGPError_UnsupportedNetToolsCAFilter = -11435, + +/* old errors: */ + + kPGPError_OutOfRings = -11420, + kPGPError_BadHashNumber = -11419, + kPGPError_BadCipherNumber = -11418, + kPGPError_BadKeyLength = -11417, + kPGPError_SizeAdviseFailure = -11416, + kPGPError_ConfigParseFailure = -11415, + kPGPError_ConfigParseFailureBadFunction = -11414, + kPGPError_ConfigParseFailureBadOptions = -11413, + kPGPError_KeyIsLocked = -11412, + kPGPError_CantDecrypt = -11411, + kPGPError_UnknownString2Key = -11410, + kPGPError_BadSessionKeySize = -11409, + kPGPError_UnknownVersion = -11408, + kPGPError_BadSessionKeyAlgorithm = -11407, + kPGPError_UnknownSignatureType = -11406, + kPGPError_BadSignatureSize = -11405, + kPGPError_SignatureBitsWrong = -11404, + kPGPError_ExtraDateOnSignature = -11403, + kPGPError_SecretKeyNotFound = -11402, + kPGPError_AdditionalRecipientRequestKeyNotFound = -11401, + kPGPError_InvalidCommit = -11400, + kPGPError_CantHash = -11399, + kPGPError_UnbalancedScope = -11398, + kPGPError_WrongScope = -11397, + kPGPError_FIFOReadError = -11396, + kPGPError_RandomSeedTooSmall = -11395, + kPGPError_EnvPriorityTooLow = -11394, + kPGPError_UnknownCharMap = -11393, + kPGPError_AsciiParseIncomplete = -11392, + kPGPError_BadPacket = -11391, + + kPGPError_TroubleKeySubKey = -11390, + kPGPError_TroubleSigSubKey = -11389, + kPGPError_TroubleBadTrust = -11388, + kPGPError_TroubleUnknownPacketByte = -11387, + kPGPError_TroubleUnexpectedSubKey = -11386, + kPGPError_TroubleUnexpectedName = -11385, + kPGPError_TroubleUnexpectedSignature = -11384, + kPGPError_TroubleUnexpectedUnknown = -11383, + kPGPError_TroubleUnexpectedTrust = -11382, + kPGPError_TroubleKeyTooBig = -11381, + kPGPError_TroubleSecretKeyTooBig = -11380, + kPGPError_TroubleNameTooBig = -11379, + kPGPError_TroubleSignatureTooBig = -11378, + kPGPError_TroubleUnknownTooBig = -11377, + kPGPError_TroubleDuplicateKeyID = -11376, + kPGPError_TroubleDuplicateKey = -11375, + kPGPError_TroubleDuplicateSecretKey = -11374, + kPGPError_TroubleDuplicateName = -11373, + kPGPError_TroubleDuplicateSignature = -11372, + kPGPError_TroubleDuplicateUnknown = -11371, + kPGPError_TroubleBareKey = -11370, + kPGPError_TroubleVersionBugPrev = -11369, + kPGPError_TroubleVersionBugCur = -11368, + kPGPError_TroubleOldSecretKey = -11367, + kPGPError_TroubleNewSecretKey = -11366, + kPGPError_TroubleImportingNonexportableSignature= -11365, + kPGPError_TroubleDuplicateCRL = -11364, + kPGPError_TroubleCRLTooBig = -11363, + + /* + * The set of errors in this range are the ones which will NOT abort + * a keyring check operation. These errors just make us skip the key + * and go on to the next. + */ +kPGPError_KEY_MIN = -11350, + kPGPError_KEY_LONG = kPGPError_KEY_MIN, + kPGPError_KeyPacketTruncated = -11349, + kPGPError_UnknownKeyVersion = -11348, + kPGPError_UnknownPublicKeyAlgorithm = -11347, + kPGPError_MalformedKeyModulus = -11346, + kPGPError_MalformedKeyExponent = -11345, + kPGPError_RSAPublicModulusIsEven = -11344, + kPGPError_RSAPublicExponentIsEven = -11343, + kPGPError_MalformedKeyComponent = -11342, + kPGPError_KeyTooLarge = -11341, + kPGPError_PublicKeyTooSmall = -11340, + kPGPError_PublicKeyTooLarge = -11339, + kPGPError_PublicKeyUnimplemented = -11338, + kPGPError_CRLPacketTruncated = -11337, +kPGPError_KEY_MAX = kPGPError_PublicKeyUnimplemented, + + +/* kPGPError_SIG_MAX */ + kPGPError_SIG_LONG = -11330, + kPGPError_TruncatedSignature = -11329, + kPGPError_MalformedSignatureInteger = -11328, + kPGPError_UnknownSignatureAlgorithm = -11327, + kPGPError_ExtraSignatureMaterial = -11326, + kPGPError_UnknownSignatureVersion = -11325, + kPGPError_RevocationKeyNotFound = -11324, +/* kPGPError_SIG_MIN */ + +/* kPGPError_KEYDB_MAX */ + kPGPError_OutOfEntropy = -11320, + kPGPError_ItemIsReadOnly = -11319, + kPGPError_InvalidProperty = -11318, + kPGPError_FileCorrupt = -11317, + kPGPError_DuplicateCert = -11316, + kPGPError_DuplicateUserID = -11315, + kPGPError_CertifyingKeyDead = -11314, + kPGPError_ItemWasDeleted = -11313, + kPGPError_KeyDBMismatch = -11312, +/* kPGPError_KEYDB_MIN = kPGPError_KeyDBMismatch */ + +/* kPGPError_SERVER_MAX */ + kPGPError_ServerInProgress = -11300, + kPGPError_ServerOperationNotSupported = -11299, + kPGPError_ServerInvalidProtocol = -11298, + kPGPError_ServerRequestFailed = -11297, + kPGPError_ServerOpen = -11296, + kPGPError_ServerNotOpen = -11295, + kPGPError_ServerKeyAlreadyExists = -11294, + kPGPError_ServerNotInitialized = -11293, + kPGPError_ServerPartialAddFailure = -11292, + kPGPError_ServerCorruptKeyBlock = -11291, + kPGPError_ServerUnknownResponse = -11290, + kPGPError_ServerTimedOut = -11289, + kPGPError_ServerOpenFailed = -11288, + kPGPError_ServerAuthorizationRequired = -11287, + kPGPError_ServerAuthorizationFailed = -11286, + kPGPError_ServerSearchFailed = -11285, + kPGPError_ServerPartialSearchResults = -11284, + kPGPError_ServerBadKeysInSearchResults = -11283, + kPGPError_ServerKeyFailedPolicy = -11282, + kPGPError_ServerOperationRequiresTLS = -11281, + kPGPError_ServerNoStaticStorage = -11280, + kPGPError_ServerCertNotFound = -11279, + +/* TLS errors */ + kPGPError_TLSUnexpectedClose = -11250, + kPGPError_TLSProtocolViolation = -11249, + kPGPError_TLSVersionUnsupported = -11248, + kPGPError_TLSWrongState = -11247, + kPGPError_TLSAlertReceived = -11246, + kPGPError_TLSKeyUnusable = -11245, + kPGPError_TLSNoCommonCipher = -11244, + kPGPError_TLSWouldBlock = -11243, + kPGPError_TLSRcvdHandshakeRequest = -11242, + +/* X509 certificate errors */ + kPGPError_X509NeededCertNotAvailable = -11240, + kPGPError_X509SelfSignedCert = -11239, + kPGPError_X509InvalidCertificateSignature = -11238, + kPGPError_X509InvalidCertificateFormat = -11237, + + kPGPError_BigNumNoInverse = -11150, + +/* PGPSockets errors */ + kPGPError_SocketsNetworkDown = -11100, + kPGPError_SocketsNotInitialized = -11099, + kPGPError_SocketsInProgress = -11098, + kPGPError_SocketsNotConnected = -11097, + kPGPError_SocketsNotBound = -11096, + kPGPError_SocketsOperationNotSupported = -11095, + kPGPError_SocketsProtocolNotSupported = -11094, + kPGPError_SocketsAddressFamilyNotSupported = -11093, + kPGPError_SocketsNotASocket = -11092, + kPGPError_SocketsAddressInUse = -11091, + kPGPError_SocketsBufferOverflow = -11090, + kPGPError_SocketsListenQueueFull = -11089, + kPGPError_SocketsAddressNotAvailable = -11088, + kPGPError_SocketsAlreadyConnected = -11087, + kPGPError_SocketsTimedOut = -11086, + kPGPError_SocketsNoStaticStorage = -11085, + + kPGPError_SocketsHostNotFound = -11050, + kPGPError_SocketsDomainServerError = -11049, + +/* Errors from X.509 layer */ + kPGPError_X509AttributeNotSupported = -10999, + kPGPError_InvalidPKCS7Encoding = -10998, + kPGPError_CMSInitialization = -10997, + kPGPError_InvalidDistinguishedName = -10996, + kPGPError_CertRequestCreationFailure = -10995, + kPGPError_MissingX509Certificate = -10994, + kPGPError_PKCS7SignFailure = -10993, + kPGPError_ASNPackFailure = -10992, + kPGPError_InvalidInputFormat = -10991, + kPGPError_InvalidOutputFormat = -10990, + kPGPError_InvalidCertificateExtension = -10989, + kPGPError_PublicKeyNotFound = -10988, + + kPGPError_CRSMissingRequiredAttribute = -10979, + kPGPError_CRSInvalidCharacter = -10978, + kPGPError_CRSInvalidAttributeType = -10977, + kPGPError_CRSInvalidCertType = -10976, + kPGPError_CRSInvalidAttributeValueLength = -10975, + kPGPError_CRSInvalidAuthenticateValue = -10974, + + + kPGPError_DummyEnumValue + /* kPGPError_Last */ +} ; + + +PGP_BEGIN_C_DECLARATIONS +#if PRAGMA_IMPORT_SUPPORTED +#pragma import on +#endif + +PGPError PGPGetErrorString( PGPError theError, + PGPSize bufferSize, char * theString ); + +#if PRAGMA_IMPORT_SUPPORTED +#pragma import reset +#endif +PGP_END_C_DECLARATIONS + + +#endif /* ] Included_pgpErrors_h */ + + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk6/include/pgpFeatures.h b/CryptoPP/PGPw/sdk6/include/pgpFeatures.h new file mode 100644 index 0000000..96016ad --- /dev/null +++ b/CryptoPP/PGPw/sdk6/include/pgpFeatures.h @@ -0,0 +1,176 @@ +/*____________________________________________________________________________ + Copyright (C) 1997 Network Associates Inc. and affiliated companies. + All rights reserved. + + Determine which features are present in the PGPsdk. This is the only + way to correctly determine which features are present. The version + number may be the same for different builds that lack some features. + + $Id: pgpFeatures.h,v 1.18.20.1 1999/08/17 20:04:30 cpeterson Exp $ +____________________________________________________________________________*/ +#ifndef Included_pgpFeatures_h /* [ */ +#define Included_pgpFeatures_h + + +#include "pgpPubTypes.h" + + + +#if PRAGMA_ALIGN_SUPPORTED +#pragma options align=mac68k /* [ */ +#endif + + +/*____________________________________________________________________________ + Each selector designates a PGPFlags word, which can be obtained via + PGPGetFeatureFlags(). The flags can be tested using the + supplied masks. We can add more selectors as needed. The masks + are not intended to be restricted to a single bit. + Flags should not be used for attributes that have unknown length. + + A kPGPError_ItemNotFound will be returned if the caller specifies + a selector which is not recognized by the PGPsdk. This could + occur if an app links to an older version of the SDK. +____________________________________________________________________________*/ + +/* selectors which are passed to PGPGetFeatureFlags */ +enum PGPFeatureSelector_ +{ + kPGPFeatures_GeneralSelector = 1, + kPGPFeatures_ImplementationSelector = 2, + PGP_ENUM_FORCE( PGPFeatureSelector_ ) +}; +PGPENUM_TYPEDEF( PGPFeatureSelector_, PGPFeatureSelector ); + + +/* flags for kPGPFeatures_GeneralSelector */ +enum +{ + kPGPFeatureMask_CanEncrypt = 0x1, + kPGPFeatureMask_CanDecrypt = 0x2, + kPGPFeatureMask_CanSign = 0x4, + kPGPFeatureMask_CanVerify = 0x8, + kPGPFeatureMask_CanGenerate = 0x10, + kPGPFeatureMask_RngHardware = 0x20 +}; + + +/* flags for kPGPFeatures_ImplementationSelector */ +enum +{ + kPGPFeatureMask_IsDebugBuild = 0x1, + kPGPFeatureMask_HasTimeout = 0x2 +}; + + + +typedef struct PGPAlgorithmInfo +{ + char shortName[ 32 ]; + char longName[ 96 ]; + char copyright[ 128 ]; + PGPFlags flags; /* reserved; 0 for now */ + PGPUInt32 reserved[ 16 ]; /* reserved; 0 for now */ +} PGPAlgorithmInfo; + + +typedef struct PGPPublicKeyAlgorithmInfo +{ + PGPAlgorithmInfo info; + + PGPPublicKeyAlgorithm algID; + + PGPBoolean canEncrypt; + PGPBoolean canDecrypt; + PGPBoolean canSign; + PGPBoolean canVerify; + PGPBoolean canGenerate; + PGPBoolean reserved1; + PGPBoolean reserved2; + PGPBoolean reserved3; + + PGPUInt32 reserved[ 8 ]; +} PGPPublicKeyAlgorithmInfo; + + +typedef struct PGPSymmetricCipherInfo +{ + PGPAlgorithmInfo info; + + PGPCipherAlgorithm algID; + + PGPUInt32 reserved[ 8 ]; +} PGPSymmetricCipherInfo; + + + +#if PRAGMA_ALIGN_SUPPORTED +#pragma options align=reset /* ] */ +#endif + + + + + +PGP_BEGIN_C_DECLARATIONS +#if PRAGMA_IMPORT_SUPPORTED +#pragma import on +#endif + + +/* see kPGPsdkAPIVersion in pgpUtilities.h for version format */ +PGPError PGPGetSDKVersion( PGPUInt32 *version ); + + +/*____________________________________________________________________________ + Return a C string of the form: + + "PGPsdk version 1.0 (C) Network Associates, Inc" +____________________________________________________________________________*/ +PGPError PGPGetSDKString( char theString[ 256 ] ); + + + +/* return a flags word for the feature selector */ +PGPError PGPGetFeatureFlags( PGPFeatureSelector selector, + PGPFlags *flags ); + +/* use this to test whether a feature exists after getting flags */ +#define PGPFeatureExists( flags, maskValue ) \ + ( ( (flags) & (maskValue) ) != 0 ) + + +/*____________________________________________________________________________ + Routines to determine which algorithms are present. + + To determine if a specific algorithm is available, you will need to + index through the available algorithms and check the algorithm ID. +____________________________________________________________________________*/ +PGPError PGPCountPublicKeyAlgorithms( PGPUInt32 *numPKAlgs ); +PGPError PGPGetIndexedPublicKeyAlgorithmInfo( PGPUInt32 theIndex, + PGPPublicKeyAlgorithmInfo *info); + +PGPError PGPCountSymmetricCiphers( PGPUInt32 *numPKAlgs ); +PGPError PGPGetIndexedSymmetricCipherInfo( PGPUInt32 theIndex, + PGPSymmetricCipherInfo *info); + + + +#if PRAGMA_IMPORT_SUPPORTED +#pragma import reset +#endif +PGP_END_C_DECLARATIONS + + + + +#endif /* ] Included_pgpFeatures_h */ + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk6/include/pgpGroups.h b/CryptoPP/PGPw/sdk6/include/pgpGroups.h new file mode 100644 index 0000000..65e4bc2 --- /dev/null +++ b/CryptoPP/PGPw/sdk6/include/pgpGroups.h @@ -0,0 +1,322 @@ +/*____________________________________________________________________________ + Copyright (C) 1997 Network Associates Inc. and affiliated companies. + All rights reserved. + + $Id: pgpGroups.h,v 1.6 1999/03/10 02:51:18 heller Exp $ +____________________________________________________________________________*/ + +#ifndef Included_pgpGroups_h /* [ */ +#define Included_pgpGroups_h + +#include "pgpPubTypes.h" +#include "pgpEncode.h" + +#if PRAGMA_ALIGN_SUPPORTED +#pragma options align=mac68k +#endif + +#define kPGPMaxGroupNameLength 63 +#define kPGPMaxGroupDescriptionLength 63 + +typedef char PGPGroupName[ kPGPMaxGroupNameLength + 1 ]; +typedef char PGPGroupDescription[ kPGPMaxGroupDescriptionLength + 1 ]; + + +typedef struct PGPGroupSet * PGPGroupSetRef; +typedef struct PGPGroupIter * PGPGroupItemIterRef; + +#define kInvalidPGPGroupSetRef ((PGPGroupSetRef) NULL) +#define kInvalidPGPGroupItemIterRef ((PGPGroupItemIterRef) NULL) + +#define PGPGroupSetRefIsValid(ref) ((ref) != kInvalidPGPGroupSetRef) +#define PGPGroupItemIterRefIsValid(ref) ((ref) != kInvalidPGPGroupItemIterRef) + +/* any type will do that is distinct */ +typedef PGPUInt32 PGPGroupID; +#define kPGPInvalidGroupID ( (PGPGroupID)0 ) + +enum PGPGroupItemType_ +{ + kPGPGroupItem_KeyID = 1, + kPGPGroupItem_Group, + + PGP_ENUM_FORCE( PGPGroupItemType_) +}; +PGPENUM_TYPEDEF( PGPGroupItemType_, PGPGroupItemType ); + +/*____________________________________________________________________________ + A run-time group item, used when iterating through a group. + For client use; not necessarily the internal storage format. + + 'userValue' is *not* saved to disk. +____________________________________________________________________________*/ + +typedef struct PGPGroupItem +{ + PGPGroupItemType type; + PGPUserValue userValue; + + union + { + /* type selects which substructure */ + struct /* if kGroupItem_Group */ + { + PGPGroupID id; + } group; + + struct /* if kGroupItem_KeyID */ + { + PGPPublicKeyAlgorithm algorithm; + PGPKeyID keyID; + } key; + } u; + + PGPUInt32 reserved[4]; + +} PGPGroupItem; + + +typedef PGPInt32 (*PGPGroupItemCompareProc)( PGPGroupItem *, + PGPGroupItem *, PGPUserValue userValue ); + +/*____________________________________________________________________________ + Info obtained via PGPGetGroupInfo. +____________________________________________________________________________*/ + +typedef struct PGPGroupInfo +{ + PGPGroupID id; + PGPGroupName name; + PGPGroupName description; + PGPUserValue userValue; + +} PGPGroupInfo; + + +typedef PGPFlags PGPGroupItemIterFlags; +/* flag (1UL << 0 ) is reserved */ +#define kPGPGroupIterFlags_Recursive (PGPFlags)(1UL << 1 ) +#define kPGPGroupIterFlags_Keys (PGPFlags)(1UL << 2 ) +#define kPGPGroupIterFlags_Groups (PGPFlags)(1UL << 3 ) + +#define kPGPGroupIterFlags_AllKeysRecursive \ + ( kPGPGroupIterFlags_Recursive | kPGPGroupIterFlags_Keys ) + +#define kPGPGroupIterFlags_AllGroupsRecursive \ + ( kPGPGroupIterFlags_Recursive | kPGPGroupIterFlags_Groups ) + +#define kPGPGroupIterFlags_AllItems \ + ( kPGPGroupIterFlags_Keys | kPGPGroupIterFlags_Groups ) + +#define kPGPGroupIterFlags_AllRecursive \ + ( kPGPGroupIterFlags_Recursive | kPGPGroupIterFlags_AllItems ) + + + +#if PRAGMA_ALIGN_SUPPORTED +#pragma options align=reset +#endif + +PGP_BEGIN_C_DECLARATIONS + +#if PRAGMA_IMPORT_SUPPORTED +#pragma import on +#endif + + +/*____________________________________________________________________________ + Manipulating pgp group sets (PGPGroupSetRef) +____________________________________________________________________________*/ +/* create a new, empty groups collection */ +PGPError PGPNewGroupSet( PGPContextRef context, PGPGroupSetRef *outRef ); + +/* file is *not* left open; all data is loaded into memory */ +PGPError PGPNewGroupSetFromFile( PGPContextRef context, + PGPFileSpecRef file, + PGPGroupSetRef *outRef ); + +#if PGP_MACINTOSH +PGPError PGPNewGroupSetFromFSSpec( PGPContextRef context, + const FSSpec *spec, PGPGroupSetRef *outRef ); +#endif + +/* overwrites existing. Don't bother unless PGPGroupSetNeedsCommit() */ +PGPError PGPSaveGroupSetToFile( PGPGroupSetRef set, PGPFileSpecRef file ); + +/* free all data structures; be sure to save first if you want */ +PGPError PGPFreeGroupSet( PGPGroupSetRef set ); + + +/* has the group changed? */ +PGPBoolean PGPGroupSetNeedsCommit( PGPGroupSetRef set ); + +PGPContextRef PGPGetGroupSetContext( PGPGroupSetRef set ); + +/* export the groupset to a buffer. Use PGPFreeData to free the buffer */ +PGPError PGPExportGroupSetToBuffer( PGPGroupSetRef set, void **buffer, + PGPSize *bufferSize ); + +/* import a groupset from a buffer */ +PGPError PGPImportGroupSetFromBuffer(PGPContextRef context, void *buffer, + PGPSize bufSize, PGPGroupSetRef *outSet ); + +/*____________________________________________________________________________ + Manipulating groups + + Groups are always referred to by IDs which remain valid until the set + is disposed. +____________________________________________________________________________*/ + +/* initial parent ID is kPGPInvalidGroupID */ +PGPError PGPNewGroup( PGPGroupSetRef set, + const char * name, const char *description, PGPGroupID *id ); + +PGPError PGPCountGroupsInSet( PGPGroupSetRef set, + PGPUInt32 *numGroups); +PGPError PGPGetIndGroupID( PGPGroupSetRef set, + PGPUInt32 groupIndex, PGPGroupID *id ); + +/* delete this group from the set */ +/* All references to it are removed in all sets */ +PGPError PGPDeleteGroup( PGPGroupSetRef set, PGPGroupID id ); + +/* delete the indexed item from the group */ +/* the item may be a group or a key */ +PGPError PGPDeleteIndItemFromGroup( PGPGroupSetRef set, + PGPGroupID id, PGPUInt32 item ); + +/* same as PGPDeleteIndItemFromGroup, but accepts an item */ +PGPError PGPDeleteItemFromGroup( PGPGroupSetRef set, + PGPGroupID id, PGPGroupItem const *item ); + + +PGPError PGPGetGroupInfo( PGPGroupSetRef set, + PGPGroupID id, PGPGroupInfo *info ); + +PGPError PGPSetGroupName( PGPGroupSetRef set, + PGPGroupID id, const char * name ); +PGPError PGPSetGroupUserValue( PGPGroupSetRef set, + PGPGroupID id, PGPUserValue userValue ); +PGPError PGPSetGroupDescription( PGPGroupSetRef set, + PGPGroupID id, const char * name ); + +/* 'item' specifies a group or a key id */ +/* you must fill the item in completely */ +PGPError PGPAddItemToGroup( PGPGroupSetRef set, + PGPGroupItem const *item, PGPGroupID group ); + + +PGPError PGPMergeGroupIntoDifferentSet( PGPGroupSetRef fromSet, + PGPGroupID fromID, PGPGroupSetRef toSet ); + +PGPError PGPMergeGroupSets( PGPGroupSetRef fromSet, + PGPGroupSetRef intoSet ); + +PGPError PGPCopyGroupSet(PGPGroupSetRef sourceSet, + PGPGroupSetRef *destSet); + +/*____________________________________________________________________________ + Manipulating group items +____________________________________________________________________________*/ + +/* count how many items there are in a group */ +/* totalItems includes keys and groups */ +PGPError PGPCountGroupItems( PGPGroupSetRef set, + PGPGroupID id, PGPBoolean recursive, + PGPUInt32 * numKeys, + PGPUInt32 * totalItems ); + +/* non-recursive call; index only applies to group itself */ +PGPError PGPGetIndGroupItem( PGPGroupSetRef set, + PGPGroupID id, PGPUInt32 groupIndex, PGPGroupItem * item ); + +/* use PGPGetIndGroupItem() if you want to get the user value */ +PGPError PGPSetIndGroupItemUserValue( PGPGroupSetRef set, + PGPGroupID id, PGPUInt32 groupIndex, PGPUserValue userValue ); + +PGPError PGPSortGroupItems( PGPGroupSetRef set, PGPGroupID id, + PGPGroupItemCompareProc, PGPUserValue userValue ); + +PGPError PGPSortGroupSet( PGPGroupSetRef set, + PGPGroupItemCompareProc, PGPUserValue userValue ); + +/*____________________________________________________________________________ + PGPGroupItemIterRef--iterator through group items. + + Special note: this is not a full-fledged iterator. You may *not* add + or delete items while iterating and you may only move forward. However, + you may change the values of items. +____________________________________________________________________________*/ + +PGPError PGPNewGroupItemIter( PGPGroupSetRef set, PGPGroupID id, + PGPGroupItemIterFlags flags, PGPGroupItemIterRef *iter ); + +PGPError PGPFreeGroupItemIter( PGPGroupItemIterRef iter ); + +/* returns kPGPError_EndOfIteration when done */ +PGPError PGPGroupItemIterNext( PGPGroupItemIterRef iter, + PGPGroupItem * item ); + +/*____________________________________________________________________________ + Group utilities +____________________________________________________________________________*/ + +/*____________________________________________________________________________ + Return the lowest validity of any item in the group + keyset should contain all keys available + It is not an error if keys can't be found; you may want to check + the not found count. + + The lowest validity is kPGPValidity_Invalid and kPGPValidity_Unknown + is never returned. +____________________________________________________________________________*/ +PGPError PGPGetGroupLowestValidity( PGPGroupSetRef set, PGPGroupID id, + PGPKeySetRef keySet, PGPValidity * lowestValidity, + PGPUInt32 * numKeysNotFound); + +/*____________________________________________________________________________ + All all the keys in the group (and its subgroups) to the keyset +____________________________________________________________________________*/ +PGPError PGPNewKeySetFromGroup( PGPGroupSetRef set, PGPGroupID id, + PGPKeySetRef masterSet, PGPKeySetRef * resultSet, + PGPUInt32 * numKeysNotFound); + +/*____________________________________________________________________________ + Create a simple, flattened group of unique key IDs from the source group. + Note that sourceSet and destSet must be different. +____________________________________________________________________________*/ +PGPError PGPNewFlattenedGroupFromGroup(PGPGroupSetRef sourceSet, + PGPGroupID sourceID, PGPGroupSetRef destSet, + PGPGroupID *destID); + +/*____________________________________________________________________________ + Perform a "standard" sort on a group +____________________________________________________________________________*/ +PGPError PGPSortGroupSetStd( PGPGroupSetRef set, PGPKeySetRef keys ); + + +#if PRAGMA_IMPORT_SUPPORTED +#pragma import reset +#endif + +PGP_END_C_DECLARATIONS + +#endif /* ] Included_pgpGroups_h */ + + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ + + + + + + + + diff --git a/CryptoPP/PGPw/sdk6/include/pgpHMAC.h b/CryptoPP/PGPw/sdk6/include/pgpHMAC.h new file mode 100644 index 0000000..a04dc95 --- /dev/null +++ b/CryptoPP/PGPw/sdk6/include/pgpHMAC.h @@ -0,0 +1,75 @@ +/*____________________________________________________________________________ + pgpHMAC.h + + Copyright (C) 1997 Network Associates Inc. and affiliated companies. + All rights reserved. + + $Id: pgpHMAC.h,v 1.3 1999/03/10 02:51:38 heller Exp $ +____________________________________________________________________________*/ +#ifndef Included_pgpHMAC_h /* [ */ +#define Included_pgpHMAC_h + +#include "pgpPubTypes.h" +#include "pgpMemoryMgr.h" + + +PGP_BEGIN_C_DECLARATIONS +#if PRAGMA_IMPORT_SUPPORTED +#pragma import on +#endif + +/*____________________________________________________________________________ + Create a new HMAC of the specified algorithm. + + If the algorithm is not available then kPGPError_AlgorithmNotAvailable is + returned. +____________________________________________________________________________*/ +PGPError PGPNewHMACContext( PGPMemoryMgrRef memoryMgr, + PGPHashAlgorithm algorithm, + PGPByte * secret, + PGPSize secretLen, + PGPHMACContextRef * outRef ); + +/*____________________________________________________________________________ + Any existing intermediate HMAC is lost. +____________________________________________________________________________*/ +PGPError PGPFreeHMACContext( PGPHMACContextRef ref ); + +/*____________________________________________________________________________ + Reset an HMAC as if it had been created anew. Any existing intermediate + hash is lost. +____________________________________________________________________________*/ +PGPError PGPResetHMAC( PGPHMACContextRef ref ); + +/*____________________________________________________________________________ + Continue the HMAC, accumulating an intermediate result +____________________________________________________________________________*/ +PGPError PGPContinueHMAC( PGPHMACContextRef ref, + const void *in, PGPSize numBytes ); + + +/*____________________________________________________________________________ + Finalize the HMAC, depositing the result into 'hmacOut'. + + This size of the output will be the same size as the hash + algorithm output. +____________________________________________________________________________*/ +PGPError PGPFinalizeHMAC( PGPHMACContextRef ref, void *hmacOut ); + + +#if PRAGMA_IMPORT_SUPPORTED +#pragma import reset +#endif +PGP_END_C_DECLARATIONS + +#endif /* ] Included_pgpHMAC_h */ + + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk6/include/pgpHash.h b/CryptoPP/PGPw/sdk6/include/pgpHash.h new file mode 100644 index 0000000..101120d --- /dev/null +++ b/CryptoPP/PGPw/sdk6/include/pgpHash.h @@ -0,0 +1,95 @@ +/*____________________________________________________________________________ + pgpHash.h + + Copyright (C) 1997 Network Associates Inc. and affiliated companies. + All rights reserved. + + $Id: pgpHash.h,v 1.15 1999/03/10 02:51:20 heller Exp $ +____________________________________________________________________________*/ +#ifndef Included_pgpHashing_h /* [ */ +#define Included_pgpHashing_h + +#include "pgpPubTypes.h" +#include "pgpMemoryMgr.h" + + +PGP_BEGIN_C_DECLARATIONS +#if PRAGMA_IMPORT_SUPPORTED +#pragma import on +#endif + +/*____________________________________________________________________________ + Create a new hash of the specified algorithm. + + If the algorithm is not available then kPGPError_AlgorithmNotAvailable is + returned. +____________________________________________________________________________*/ +PGPError PGPNewHashContext( PGPMemoryMgrRef memoryMgr, + PGPHashAlgorithm algorithm, + PGPHashContextRef * outRef ); + + +/*____________________________________________________________________________ + Any existing intermediate hash is lost. +____________________________________________________________________________*/ +PGPError PGPFreeHashContext( PGPHashContextRef ref ); + + +/*____________________________________________________________________________ + An exact duplicate of the hash is made. +____________________________________________________________________________*/ +PGPError PGPCopyHashContext( PGPHashContextRef ref, + PGPHashContextRef * outRef); + + + +/*____________________________________________________________________________ + Reset a hash as if it had been created anew. Any existing intermediate + hash is lost. +____________________________________________________________________________*/ +PGPError PGPResetHash( PGPHashContextRef ref ); + + +/*____________________________________________________________________________ + Continue the hash, accumulating an intermediate result +____________________________________________________________________________*/ +PGPError PGPContinueHash( PGPHashContextRef ref, + const void *in, PGPSize numBytes ); + + +/*____________________________________________________________________________ + Finalize the hash, depositing the result into 'hashOut'. + + After calling this routine, the hash is reset via PGPResetHash(). + If you want an intermediate result, use PGPCopyHash() and finalize the + copy. +____________________________________________________________________________*/ +PGPError PGPFinalizeHash( PGPHashContextRef ref, void *hashOut ); + + +/*____________________________________________________________________________ + Determine size of resulting hash in bytes e.g. a 160 bit hash yields 20. + Used for generic code which may not know how big a hash is being produced. + + Question: can we reasonably assume 8 bits per byte? If not, how does + PGPFinalizeHash return its result? +____________________________________________________________________________*/ +PGPError PGPGetHashSize( PGPHashContextRef ref, PGPSize *hashSize ); + + +#if PRAGMA_IMPORT_SUPPORTED +#pragma import reset +#endif +PGP_END_C_DECLARATIONS + +#endif /* ] Included_pgpHashing_h */ + + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk6/include/pgpKeyServer.h b/CryptoPP/PGPw/sdk6/include/pgpKeyServer.h new file mode 100644 index 0000000..25579aa --- /dev/null +++ b/CryptoPP/PGPw/sdk6/include/pgpKeyServer.h @@ -0,0 +1,360 @@ +/*____________________________________________________________________________ + Copyright (C) 1997 Network Associates Inc. and affiliated companies. + All rights reserved. + + + + $Id: pgpKeyServer.h,v 1.43 1999/04/12 18:59:57 jason Exp $ +____________________________________________________________________________*/ + +#ifndef Included_pgpKeyServer_h +#define Included_pgpKeyServer_h + +#include "pgpOptionList.h" +#include "pgpErrors.h" +#include "pgpGroups.h" +#include "pgpTLS.h" + + +enum PGPKeyServerState_ +{ + kPGPKeyServerState_Invalid = 0, + kPGPKeyServerState_Opening = 1, + kPGPKeyServerState_Querying = 2, + kPGPKeyServerState_ReceivingResults = 3, + kPGPKeyServerState_ProcessingResults = 4, + kPGPKeyServerState_Uploading = 5, + kPGPKeyServerState_Deleting = 6, + kPGPKeyServerState_Disabling = 7, + kPGPKeyServerState_Closing = 8, + + kPGPKeyServerState_TLSUnableToSecureConnection = 9, + kPGPKeyServerState_TLSConnectionSecured = 10, + + PGP_ENUM_FORCE(PGPKeyServerState_) +}; + +PGPENUM_TYPEDEF(PGPKeyServerState_, PGPKeyServerState); + +enum PGPKeyServerProtocol_ +{ + kPGPKeyServerProtocol_Invalid = 0, + kPGPKeyServerProtocol_LDAP = 1, + kPGPKeyServerProtocol_HTTP = 2, + kPGPKeyServerProtocol_LDAPS = 3, + kPGPKeyServerProtocol_HTTPS = 4, + + PGP_ENUM_FORCE( PGPKeyServerProtocol_ ) +}; + +PGPENUM_TYPEDEF( PGPKeyServerProtocol_, PGPKeyServerProtocol ); + +enum PGPKeyServerClass_ +{ + kPGPKeyServerClass_Invalid = 0, + kPGPKeyServerClass_PGP = 1, + kPGPKeyServerClass_NetToolsCA = 2, + kPGPKeyServerClass_Verisign = 3, + kPGPKeyServerClass_Entrust = 4, + + PGP_ENUM_FORCE( PGPKeyServerClass_ ) +}; + +PGPENUM_TYPEDEF( PGPKeyServerClass_, PGPKeyServerClass ); + +enum PGPKeyServerKeySpace_ /* These are only valid for LDAP keyservers */ +{ + kPGPKeyServerKeySpace_Invalid = 0, + kPGPKeyServerKeySpace_Default = 1, + kPGPKeyServerKeySpace_Normal = 2, + kPGPKeyServerKeySpace_Pending = 3, + + PGP_ENUM_FORCE( PGPKeyServerKeySpace_ ) +}; + +PGPENUM_TYPEDEF( PGPKeyServerKeySpace_, PGPKeyServerKeySpace ); + +enum PGPKeyServerAccessType_ /* These are only valid for LDAP keyservers */ +{ + kPGPKeyServerAccessType_Invalid = 0, + kPGPKeyServerAccessType_Default = 1, + kPGPKeyServerAccessType_Normal = 2, + kPGPKeyServerAccessType_Administrator = 3, + + PGP_ENUM_FORCE( PGPKeyServerAccessType_ ) +}; + +PGPENUM_TYPEDEF( PGPKeyServerAccessType_, PGPKeyServerAccessType ); + +/* PGPKeyServerMonitorValues are null terminated linked lists. + The values member is a null terminated array of char*s. +*/ + +typedef struct PGPKeyServerMonitorValues +{ + char * name; + char ** values; + struct PGPKeyServerMonitorValues * next; +} PGPKeyServerMonitorValues; + +typedef struct PGPKeyServerMonitor +{ + PGPKeyServerRef keyServerRef; + PGPKeyServerMonitorValues * valuesHead; +} PGPKeyServerMonitor; + + +typedef struct PGPKeyServerThreadStorage * PGPKeyServerThreadStorageRef; +# define kInvalidPGPKeyServerThreadStorageRef \ + ((PGPKeyServerThreadStorageRef) NULL) +#define PGPKeyServerThreadStorageRefIsValid(ref) \ + ((ref) != kInvalidPGPKeyServerThreadStorageRef) + +#if PGP_DEPRECATED /* [ */ + +#define kPGPKeyServerType_Invalid kPGPKeyServerProtocol_Invalid +#define kPGPKeyServerType_LDAP kPGPKeyServerProtocol_LDAP +#define kPGPKeyServerType_HTTP kPGPKeyServerProtocol_HTTP +#define kPGPKeyServerType_LDAPS kPGPKeyServerProtocol_LDAPS +#define kPGPKeyServerType_HTTPS kPGPKeyServerProtocol_HTTPS + +typedef PGPKeyServerProtocol PGPKeyServerType; + +#endif /* ] PGP_DEPRECATED */ + +PGP_BEGIN_C_DECLARATIONS +#if PRAGMA_IMPORT_SUPPORTED +#pragma import on +#endif + + +/* Use the idle event handler to receive periodic idle events during + network calls. Usually this is used only in non-preemptive multi-tasking + OSes to allow yielding in threads. Pre-emptive multi-tasking systems + should probably not use the call as it interrupts the efficient wait state + of threads waiting on network calls. + + Idle event handlers need to be added on a per thread basis. + + Returning an error from the idle event handler will cause the keyserver + to quit processing and to return a kPGPError_UserAbort. */ +PGPError PGPSetKeyServerIdleEventHandler( + PGPEventHandlerProcPtr inCallback, + PGPUserValue inUserData); + +PGPError PGPGetKeyServerIdleEventHandler( + PGPEventHandlerProcPtr * outCallback, + PGPUserValue * outUserData); + +/* Network library options */ + +PGPOptionListRef PGPONetURL(PGPContextRef context, const char *url); + +PGPOptionListRef PGPONetHostName(PGPContextRef context, + const char *hostName, PGPUInt16 port); + +PGPOptionListRef PGPONetHostAddress(PGPContextRef context, + PGPUInt32 hostAddress, PGPUInt16 port); + +PGPOptionListRef PGPOKeyServerProtocol(PGPContextRef context, + PGPKeyServerProtocol serverProtocol); + +PGPOptionListRef PGPOKeyServerKeySpace(PGPContextRef context, + PGPKeyServerKeySpace serverSpace); + +PGPOptionListRef PGPOKeyServerAccessType(PGPContextRef context, + PGPKeyServerAccessType accessType); + +PGPOptionListRef PGPOKeyServerCAKey(PGPContextRef context, + PGPKeyRef caKey); + +PGPOptionListRef PGPOKeyServerRequestKey(PGPContextRef context, + PGPKeyRef requestKey); + +PGPOptionListRef PGPOKeyServerSearchKey(PGPContextRef context, + PGPKeyRef searchKey); + +PGPOptionListRef PGPOKeyServerSearchFilter(PGPContextRef context, + PGPFilterRef searchFilter); + +/* Static storage creation */ +PGPError PGPKeyServerCreateThreadStorage( + PGPKeyServerThreadStorageRef * outPreviousStorage); +PGPError PGPKeyServerDisposeThreadStorage( + PGPKeyServerThreadStorageRef inPreviousStorage); + +/* Initialize and close the keyserver library */ +PGPError PGPKeyServerInit(void); + +PGPError PGPKeyServerCleanup(void); + + +/* Creating and freeing a keyserver ref. */ +PGPError PGPNewKeyServer( + PGPContextRef inContext, + PGPKeyServerClass inClass, + PGPKeyServerRef *outKeyServerRef, + PGPOptionListRef firstOption, + ... ); + +PGPError PGPFreeKeyServer(PGPKeyServerRef inKeyServerRef); +PGPError PGPIncKeyServerRefCount(PGPKeyServerRef inKeyServerRef); + + +/* Set and get the keyserver's event handler. Note that returning an error + for a keyserver event will abort the current call. */ +PGPError PGPSetKeyServerEventHandler( + PGPKeyServerRef inKeyServerRef, + PGPEventHandlerProcPtr inCallback, + PGPUserValue inUserData); + +PGPError PGPGetKeyServerEventHandler( + PGPKeyServerRef inKeyServerRef, + PGPEventHandlerProcPtr * outCallback, + PGPUserValue * outUserData); + + +/* Canceling a call to a keyserver. This is the only call that can be made + to a keyserver that is currently in another call. Also, once you have + returned from a canceled call, you may only close the keyserver. */ +PGPError PGPCancelKeyServerCall(PGPKeyServerRef inKeyServerRef); + + +/* Opening and closing the keyserver. A keyserver ref can be opened and + closed multiple times as necessary. */ +PGPError PGPKeyServerOpen(PGPKeyServerRef inKeyServerRef, + PGPtlsSessionRef inTLSSessionRef); + +PGPError PGPKeyServerClose(PGPKeyServerRef inKeyServerRef); + + +/* Get keyserver info. */ +PGPError PGPGetKeyServerTLSSession(PGPKeyServerRef inKeyServerRef, + PGPtlsSessionRef * outTLSSessionRef); + +PGPError PGPGetKeyServerProtocol(PGPKeyServerRef inKeyServerRef, + PGPKeyServerProtocol * outType); + +PGPError PGPGetKeyServerAccessType(PGPKeyServerRef inKeyServerRef, + PGPKeyServerAccessType * outAccessType); + +PGPError PGPGetKeyServerKeySpace(PGPKeyServerRef inKeyServerRef, + PGPKeyServerKeySpace * outKeySpace); + +PGPError PGPGetKeyServerPort(PGPKeyServerRef inKeyServerRef, + PGPUInt16 * outPort); + +PGPError PGPGetKeyServerHostName(PGPKeyServerRef inKeyServerRef, + char ** outHostName); /* Use PGPFreeData to free */ + +PGPError PGPGetKeyServerAddress(PGPKeyServerRef inKeyServerRef, + PGPUInt32 * outAddress); + +PGPError PGPGetKeyServerPath(PGPKeyServerRef inKeyServerRef, + char ** outPath); /* Use PGPFreeData to free */ + +PGPContextRef PGPGetKeyServerContext(PGPKeyServerRef inKeyServerRef); + +/* If there was an error string returned from the server, you can get it with + this function. Note that if there is no string, the function will return + kPGPError_NoErr and *outErrorString will be NULL */ +PGPError PGPGetLastKeyServerErrorString( + PGPKeyServerRef inKeyServerRef, + char ** outErrorString); /* Use PGPFreeData to free */ + + +/* These functions may be used with both HTTP and LDAP keyservers */ +PGPError PGPQueryKeyServer(PGPKeyServerRef inKeyServerRef, + PGPFilterRef inFilterRef, + PGPKeySetRef * outFoundKeys); + +PGPError PGPUploadToKeyServer(PGPKeyServerRef inKeyServerRef, + PGPKeySetRef inKeysToUpload, + PGPKeySetRef * outKeysThatFailed); + + +/* These functions may only be used with LDAP keyservers */ +PGPError PGPDeleteFromKeyServer(PGPKeyServerRef inKeyServerRef, + PGPKeySetRef inKeysToDelete, + PGPKeySetRef * outKeysThatFailed); + +PGPError PGPDisableFromKeyServer(PGPKeyServerRef inKeyServerRef, + PGPKeySetRef inKeysToDisable, + PGPKeySetRef * outKeysThatFailed); + +PGPError PGPSendGroupsToServer(PGPKeyServerRef inKeyServerRef, + PGPGroupSetRef inGroupSetRef); + +PGPError PGPRetrieveGroupsFromServer( + PGPKeyServerRef inKeyServerRef, + PGPGroupSetRef * outGroupSetRef); + +PGPError PGPNewServerMonitor(PGPKeyServerRef inKeyServerRef, + PGPKeyServerMonitor ** outMonitor); + +PGPError PGPFreeServerMonitor(PGPKeyServerMonitor * inMonitor); + +/* X.509 Certificate Request functions */ + +PGPError PGPSendCertificateRequest( + PGPKeyServerRef inKeyServerRef, + PGPOptionListRef firstOption, + ... ); + +PGPError PGPRetrieveCertificate( + PGPKeyServerRef inKeyServerRef, + PGPOptionListRef firstOption, + ... ); + +PGPError PGPRetrieveCertificateRevocationList( + PGPKeyServerRef inKeyServerRef, + PGPOptionListRef firstOption, + ... ); + +/*************************************************************************** +**************************************************************************** + NOTE: These functions are deprecated and should not be used + + PGPGetKeyServerType -> PGPGetKeyServerProtocol + PGPNewKeyServerFromURL -> PGPNewKeyServer + PGPNewKeyServerFromHostName -> PGPNewKeyServer + PGPNewKeyServerFromHostAddress -> PGPNewKeyServer + +**************************************************************************** +***************************************************************************/ + +#if PGP_DEPRECATED /* [ */ + +PGPError PGPNewKeyServerFromURL(PGPContextRef inContext, + const char * inURL, + PGPKeyServerAccessType inAccessType, + PGPKeyServerKeySpace inKeySpace, + PGPKeyServerRef * outKeyServerRef); + +PGPError PGPNewKeyServerFromHostName(PGPContextRef inContext, + const char * inHostName, + PGPUInt16 inPort, /* default for protocol if 0 */ + PGPKeyServerProtocol inType, + PGPKeyServerAccessType inAccessType, + PGPKeyServerKeySpace inKeySpace, + PGPKeyServerRef * outKeyServerRef); + +PGPError PGPNewKeyServerFromHostAddress(PGPContextRef inContext, + PGPUInt32 inAddress, + PGPUInt16 inPort, /* default for protocol if 0 */ + PGPKeyServerProtocol inType, + PGPKeyServerAccessType inAccessType, + PGPKeyServerKeySpace inKeySpace, + PGPKeyServerRef * outKeyServerRef); + +PGPError PGPGetKeyServerType(PGPKeyServerRef inKeyServerRef, + PGPKeyServerType * outType); + +#endif /* ] PGP_DEPRECATED */ + +#if PRAGMA_IMPORT_SUPPORTED +#pragma import reset +#endif +PGP_END_C_DECLARATIONS + +#endif diff --git a/CryptoPP/PGPw/sdk6/include/pgpKeys.h b/CryptoPP/PGPw/sdk6/include/pgpKeys.h new file mode 100644 index 0000000..8bfdc34 --- /dev/null +++ b/CryptoPP/PGPw/sdk6/include/pgpKeys.h @@ -0,0 +1,879 @@ +/*____________________________________________________________________________ + pgpKeys.h + + Copyright(C) 1996,1997 Network Associates Inc. and affiliated companies. + All rights reserved. + + Public definitions for PGP KeyDB Library + + $Id: pgpKeys.h,v 1.132 1999/05/18 19:38:45 heller Exp $ +____________________________________________________________________________*/ +#ifndef Included_pgpKeys_h /* [ */ +#define Included_pgpKeys_h + + + +#include "pgpPubTypes.h" +#include "pgpHash.h" +#include "pgpOptionList.h" + + + +/* Key ordering */ +enum PGPKeyOrdering_ +{ + kPGPInvalidOrdering = 0, + kPGPAnyOrdering = 1, + kPGPUserIDOrdering = 2, + kPGPReverseUserIDOrdering = 3, + kPGPKeyIDOrdering = 4, + kPGPReverseKeyIDOrdering = 5, + kPGPValidityOrdering = 6, + kPGPReverseValidityOrdering = 7, + kPGPTrustOrdering = 8, + kPGPReverseTrustOrdering = 9, + kPGPEncryptKeySizeOrdering = 10, + kPGPReverseEncryptKeySizeOrdering = 11, + kPGPSigKeySizeOrdering = 12, + kPGPReverseSigKeySizeOrdering = 13, + kPGPCreationOrdering = 14, + kPGPReverseCreationOrdering = 15, + kPGPExpirationOrdering = 16, + kPGPReverseExpirationOrdering = 17, + + PGP_ENUM_FORCE( PGPKeyOrdering_ ) +} ; +PGPENUM_TYPEDEF( PGPKeyOrdering_, PGPKeyOrdering ); + + + +/* Key properties */ + +enum PGPKeyPropName_ +{ +/* String properties */ + kPGPKeyPropFingerprint = 1, + kPGPKeyPropPreferredAlgorithms = 2, + kPGPKeyPropThirdPartyRevocationKeyID= 3, + kPGPKeyPropKeyData = 4, + kPGPKeyPropX509MD5Hash = 5, + + /* Number properties */ + kPGPKeyPropAlgID = 20, + kPGPKeyPropBits = 21, + kPGPKeyPropTrust = 22, /* old trust model only */ + kPGPKeyPropValidity = 23, /* both trust models */ + kPGPKeyPropLockingAlgID = 24, + kPGPKeyPropLockingBits = 25, + kPGPKeyPropFlags = 26, + + /* Time properties */ + kPGPKeyPropCreation = 40, + kPGPKeyPropExpiration = 41, + kPGPKeyPropCRLThisUpdate = 42, + kPGPKeyPropCRLNextUpdate = 43, + + /* PGPBoolean properties */ + kPGPKeyPropIsSecret = 60, + kPGPKeyPropIsAxiomatic = 61, + kPGPKeyPropIsRevoked = 62, + kPGPKeyPropIsDisabled = 63, + kPGPKeyPropIsNotCorrupt = 64, + kPGPKeyPropIsExpired = 65, + kPGPKeyPropNeedsPassphrase = 66, + kPGPKeyPropHasUnverifiedRevocation = 67, + kPGPKeyPropCanEncrypt = 68, + kPGPKeyPropCanDecrypt = 69, + kPGPKeyPropCanSign = 70, + kPGPKeyPropCanVerify = 71, + kPGPKeyPropIsEncryptionKey = 72, + kPGPKeyPropIsSigningKey = 73, + kPGPKeyPropIsSecretShared = 74, + kPGPKeyPropIsRevocable = 75, + kPGPKeyPropHasThirdPartyRevocation = 76, + kPGPKeyPropHasCRL = 77, + + PGP_ENUM_FORCE( PGPKeyPropName_ ) +} ; +PGPENUM_TYPEDEF( PGPKeyPropName_, PGPKeyPropName ); + + +/* kPGPKeyPropFlags bits */ +enum /* PGPKeyPropFlags */ +{ + kPGPKeyPropFlags_UsageSignUserIDs = (1UL << 0 ), + kPGPKeyPropFlags_UsageSignMessages = (1UL << 1 ), + kPGPKeyPropFlags_UsageEncryptCommunications = (1UL << 2 ), + kPGPKeyPropFlags_UsageEncryptStorage = (1UL << 3 ), + + kPGPKeyPropFlags_PrivateSplit = (1UL << 4 ), + kPGPKeyPropFlags_PrivateShared = (1UL << 7 ) +} ; +typedef PGPFlags PGPKeyPropFlags; + + + +/* User ID properties */ + +enum PGPUserIDPropName_ +{ + /* String properties */ + kPGPUserIDPropName = 80, + kPGPUserIDPropAttributeData = 81, + kPGPUserIDPropCommonName = 82, + kPGPUserIDPropEmailAddress = 83, + + /* Number properties */ + kPGPUserIDPropValidity = 100, /* both trust models */ + kPGPUserIDPropConfidence = 101, /* new trust model only */ + kPGPUserIDPropAttributeType = 102, + + /* Time properties */ + + /* PGPBoolean properties */ + kPGPUserIDPropIsAttribute = 110, + + PGP_ENUM_FORCE( PGPUserIDPropName_ ) +} ; +PGPENUM_TYPEDEF( PGPUserIDPropName_, PGPUserIDPropName ); + +/* Signature properties */ + +enum PGPSigPropName_ +{ + /* String properties */ + kPGPSigPropKeyID = 120, + kPGPSigPropX509Certificate = 121, + kPGPSigPropX509IASN = 122, + kPGPSigPropX509LongName = 123, + kPGPSigPropX509IssuerLongName = 124, + kPGPSigPropX509DNSName = 125, + kPGPSigPropX509IPAddress = 126, + kPGPSigPropX509DERDName = 127, + + /* Number properties */ + kPGPSigPropAlgID = 140, + kPGPSigPropTrustLevel = 141, + kPGPSigPropTrustValue = 142, + + /* Time properties */ + kPGPSigPropCreation = 160, + kPGPSigPropExpiration = 161, + + /* PGPBoolean properties */ + kPGPSigPropIsRevoked = 180, + kPGPSigPropIsNotCorrupt = 181, + kPGPSigPropIsTried = 182, + kPGPSigPropIsVerified = 183, + kPGPSigPropIsMySig = 184, + kPGPSigPropIsExportable = 185, + kPGPSigPropHasUnverifiedRevocation = 186, + kPGPSigPropIsExpired = 187, + kPGPSigPropIsX509 = 188, + + PGP_ENUM_FORCE( PGPSigPropName_ ) +} ; +PGPENUM_TYPEDEF( PGPSigPropName_, PGPSigPropName ); +/* + * Note on kPGPSigPropIsMySig. This is a convenience property for + * determining whether the certification was made by one of the + * caller's own private keys. This can only return true if the + * signing key is in the same base keyset as the certification. If the + * signing key is( suspected to be) in a different base keyset, call + * PGPGetSigCertifierKey( certset, signerset, &key) followed by + * PGPGetKeyBoolean( key, kPGPKeyPropIsSecret, &secret). + */ + + +/* Attribute types, for use with kPGPUserIDPropAttributeType */ +enum PGPAttributeType_ +{ + kPGPAttribute_Image = 1, + kPGPAttribute_IPAddress = 10, + kPGPAttribute_DNSName = 11, + kPGPAttribute_Notation = 20, + + PGP_ENUM_FORCE( PGPAttributeType_ ) +} ; +PGPENUM_TYPEDEF( PGPAttributeType_, PGPAttributeType ); + + +enum /* PGPKeyRingOpenFlags */ +{ + kPGPKeyRingOpenFlags_None = 0, + kPGPKeyRingOpenFlags_Reserved = (1UL << 0 ), + kPGPKeyRingOpenFlags_Mutable = (1UL << 1 ), + kPGPKeyRingOpenFlags_Create = (1UL << 2 ), + + /* The following flags are only used by PGPOpenKeyRing */ + kPGPKeyRingOpenFlags_Private = (1UL << 8 ), + kPGPKeyRingOpenFlags_Trusted = (1UL << 9 ) +} ; +typedef PGPFlags PGPKeyRingOpenFlags; + +/* + * Used by filtering functions to specify type of match. + */ + +enum PGPMatchCriterion_ +{ + kPGPMatchDefault = 1, + kPGPMatchEqual = 1, /* searched val == supplied val */ + kPGPMatchGreaterOrEqual = 2, /* searched val >= supplied val */ + kPGPMatchLessOrEqual = 3, /* searched val <= supplied val */ + kPGPMatchSubString = 4, /* searched val is contained in supplied val */ + + PGP_ENUM_FORCE( PGPMatchCriterion_ ) +} ; +PGPENUM_TYPEDEF( PGPMatchCriterion_, PGPMatchCriterion ); + + +/* This is the value of the expiration time which means "never expires" */ +#define kPGPExpirationTime_Never ( (PGPTime)0 ) + +/* Secret sharing header size */ +#define kPGPShareHeaderSize 4 + +/* Public entry points */ + +PGP_BEGIN_C_DECLARATIONS +#if PRAGMA_IMPORT_SUPPORTED +#pragma import on +#endif + + +/* Functions for setting up key filters. */ + +PGPError PGPIncFilterRefCount ( PGPFilterRef filter ); + +PGPError PGPFreeFilter ( PGPFilterRef filter ); + +PGPError PGPNewKeyIDFilter( PGPContextRef context, + PGPKeyID const * keyID, PGPFilterRef *outFilter); + +PGPError PGPNewSubKeyIDFilter( PGPContextRef context, + PGPKeyID const * subKeyID, + PGPFilterRef * outFilter); + +PGPError PGPNewKeyEncryptAlgorithmFilter( PGPContextRef context, + PGPPublicKeyAlgorithm encryptAlgorithm, + PGPFilterRef *outFilter ); + +PGPError PGPNewKeyFingerPrintFilter( PGPContextRef context, + void const *fingerPrint, + PGPSize fingerPrintLength, PGPFilterRef *outFilter ); + +PGPError PGPNewKeyCreationTimeFilter( PGPContextRef context, + PGPTime creationTime, PGPMatchCriterion match, + PGPFilterRef *outFilter ); + +PGPError PGPNewKeyExpirationTimeFilter( PGPContextRef context, + PGPTime expirationTime, + PGPMatchCriterion match, PGPFilterRef *outFilter ); + +PGPError PGPNewKeyRevokedFilter( PGPContextRef context, + PGPBoolean revoked, PGPFilterRef *outFilter ); + +PGPError PGPNewKeyDisabledFilter( PGPContextRef context, + PGPBoolean disabled, + PGPFilterRef * outFilter); + +PGPError PGPNewKeySigAlgorithmFilter( PGPContextRef context, + PGPPublicKeyAlgorithm sigAlgorithm, + PGPFilterRef *outFilter ); + +PGPError PGPNewKeyEncryptKeySizeFilter( PGPContextRef context, + PGPUInt32 keySize, PGPMatchCriterion match, + PGPFilterRef *outFilter ); + +PGPError PGPNewKeySigKeySizeFilter( PGPContextRef context, + PGPUInt32 keySize, PGPMatchCriterion match, + PGPFilterRef *outFilter ); + +PGPError PGPNewUserIDStringFilter( PGPContextRef context, + char const * userIDString, + PGPMatchCriterion match, + PGPFilterRef * outFilter); + +PGPError PGPNewUserIDEmailFilter( PGPContextRef context, + char const * emailString, + PGPMatchCriterion match, + PGPFilterRef * outFilter); + +PGPError PGPNewUserIDNameFilter( PGPContextRef context, + char const * nameString, + PGPMatchCriterion match, + PGPFilterRef * outFilter); + +PGPError PGPNewSigKeyIDFilter( PGPContextRef context, + PGPKeyID const * keyID, + PGPFilterRef *outFilter ); + +PGPError PGPNewKeyBooleanFilter( PGPContextRef context, + PGPKeyPropName property, PGPBoolean match, + PGPFilterRef *outFilter ); + +PGPError PGPNewKeyNumberFilter( PGPContextRef context, + PGPKeyPropName property, PGPUInt32 value, + PGPMatchCriterion match, PGPFilterRef *outFilter ); + +PGPError PGPNewKeyTimeFilter( PGPContextRef context, + PGPKeyPropName property, PGPTime value, + PGPMatchCriterion match, PGPFilterRef *outFilter ); + +PGPError PGPNewKeyPropertyBufferFilter( PGPContextRef context, + PGPKeyPropName property, void *buffer, PGPSize length, + PGPMatchCriterion match, PGPFilterRef *outFilter ); + +PGPError PGPNewSubKeyBooleanFilter( PGPContextRef context, + PGPKeyPropName property, PGPBoolean match, + PGPFilterRef *outFilter ); + +PGPError PGPNewSubKeyNumberFilter( PGPContextRef context, + PGPKeyPropName property, PGPUInt32 value, + PGPMatchCriterion match, PGPFilterRef *outFilter ); + +PGPError PGPNewSubKeyTimeFilter( PGPContextRef context, + PGPKeyPropName property, PGPTime value, + PGPMatchCriterion match, PGPFilterRef *outFilter ); + +PGPError PGPNewSubKeyPropertyBufferFilter( PGPContextRef context, + PGPKeyPropName property, void *buffer, PGPSize length, + PGPMatchCriterion match, PGPFilterRef *outFilter ); + +PGPError PGPNewUserIDBooleanFilter( PGPContextRef context, + PGPUserIDPropName property, PGPBoolean match, + PGPFilterRef *outFilter ); + +PGPError PGPNewUserIDNumberFilter( PGPContextRef context, + PGPUserIDPropName property, PGPUInt32 value, + PGPMatchCriterion match, PGPFilterRef *outFilter ); + +PGPError PGPNewUserIDStringBufferFilter( PGPContextRef context, + PGPUserIDPropName property, + void *buffer, PGPSize length, + PGPMatchCriterion match, PGPFilterRef *outFilter ); + +PGPError PGPNewSigBooleanFilter( PGPContextRef context, + PGPSigPropName property, PGPBoolean match, + PGPFilterRef *outFilter ); + +PGPError PGPNewSigNumberFilter( PGPContextRef context, + PGPSigPropName property, PGPUInt32 value, + PGPMatchCriterion match, PGPFilterRef *outFilter ); + +PGPError PGPNewSigTimeFilter( PGPContextRef context, + PGPSigPropName property, PGPTime value, + PGPMatchCriterion match, PGPFilterRef *outFilter ); + +PGPError PGPNewSigPropertyBufferFilter( PGPContextRef context, + PGPSigPropName property, void *buffer, PGPSize length, + PGPMatchCriterion match, PGPFilterRef *outFilter ); + +/* freeing outfilter will call PGPFreeFilter on filter */ +PGPError PGPNegateFilter( PGPFilterRef filter, + PGPFilterRef *outFilter); + +/* freeing outfilter will call PGPFreeFilter on filter1, filter2 */ +PGPError PGPIntersectFilters( PGPFilterRef filter1, + PGPFilterRef filter2, PGPFilterRef *outFilter); + +/* freeing outfilter will call PGPFreeFilter on filter1, filter2 */ +PGPError PGPUnionFilters( PGPFilterRef filter1, + PGPFilterRef filter2, PGPFilterRef *outFilter); + + +PGPError PGPFilterKeySet( PGPKeySetRef origSet, + PGPFilterRef filter, PGPKeySetRef *resultSet); + + +/* Keyserver filter functions */ + +PGPError PGPLDAPQueryFromFilter( PGPFilterRef filter, + char **queryOut ); + +PGPError PGPHKSQueryFromFilter( PGPFilterRef filter, + char **queryOut ); + +PGPError PGPNetToolsCAHTTPQueryFromFilter( PGPFilterRef filter, + char **queryOut ); + +/* KeySet manipulations */ + + +/* Creates a new memory-based KeyDB and returns its root set */ +PGPError PGPNewKeySet(PGPContextRef context, PGPKeySetRef *keySet); + + +/* Used for building arbitrary subsets of an existing KeyDB */ +PGPError PGPNewEmptyKeySet(PGPKeySetRef origSet, PGPKeySetRef *newSet); +PGPError PGPNewSingletonKeySet(PGPKeyRef key, PGPKeySetRef *keySet); +PGPError PGPUnionKeySets(PGPKeySetRef set1, PGPKeySetRef set2, + PGPKeySetRef *newSet); + +PGPError PGPOpenDefaultKeyRings( PGPContextRef context, + PGPKeyRingOpenFlags openFlags, PGPKeySetRef *keySet); + +PGPError PGPOpenKeyRingPair( PGPContextRef context, + PGPKeyRingOpenFlags openFlags, + PGPFileSpecRef pubFileRef, PGPFileSpecRef secFileRef, + PGPKeySetRef *keySet); + +PGPError PGPOpenKeyRing (PGPContextRef context, + PGPKeyRingOpenFlags openFlags, PGPFileSpecRef fileRef, + PGPKeySetRef *keySet); + +PGPError PGPCommitKeyRingChanges (PGPKeySetRef keys); + +PGPError PGPPropagateTrust (PGPKeySetRef keys); + +PGPError PGPRevertKeyRingChanges (PGPKeySetRef keys); + +PGPError PGPCheckKeyRingSigs (PGPKeySetRef keysToCheck, + PGPKeySetRef keysSigning, PGPBoolean checkAll, + PGPEventHandlerProcPtr eventHandler, + PGPUserValue eventHandlerData); + +PGPError PGPReloadKeyRings (PGPKeySetRef keys); + +PGPError PGPGetKeyByKeyID (PGPKeySetRef keys, + PGPKeyID const * keyID, + PGPPublicKeyAlgorithm pubKeyAlgorithm, + PGPKeyRef *outRef); + +PGPBoolean PGPKeySetIsMember(PGPKeyRef key, PGPKeySetRef set); + +PGPError PGPCountKeys( PGPKeySetRef keys, PGPUInt32 *numKeys); + +PGPError PGPIncKeySetRefCount( PGPKeySetRef keys); + +PGPError PGPFreeKeySet( PGPKeySetRef keys); + +PGPBoolean PGPKeySetIsMutable( PGPKeySetRef keys); + +PGPBoolean PGPKeySetNeedsCommit( PGPKeySetRef keys); + + +PGPError PGPAddKeys( PGPKeySetRef keysToAdd, PGPKeySetRef set ); + +PGPError PGPRemoveKeys( PGPKeySetRef keysToRemove, PGPKeySetRef set ); + + + +/* Key manipulation functions */ + +PGPError PGPDisableKey( PGPKeyRef key); + +PGPError PGPEnableKey( PGPKeyRef key); + +PGPError PGPRemoveSubKey( PGPSubKeyRef subkey); + +PGPError PGPRemoveUserID( PGPUserIDRef userID); + +PGPError PGPSetPrimaryUserID( PGPUserIDRef userid); + +PGPError PGPCertifyPrimaryUserID( PGPUserIDRef userid, + PGPOptionListRef firstOption, ...); + +PGPError PGPGetSigCertifierKey( PGPSigRef cert, PGPKeySetRef allkeys, + PGPKeyRef *certkey); + +PGPError PGPGetSigX509CertifierSig( PGPSigRef cert, + PGPKeySetRef allkeys, PGPSigRef *certsig); + +PGPError PGPRemoveSig( PGPSigRef cert); + +PGPError PGPCountAdditionalRecipientRequests( PGPKeyRef basekey, + PGPUInt32 * numARKeys); + +PGPError PGPGetIndexedAdditionalRecipientRequestKey( + PGPKeyRef basekey, PGPKeySetRef allkeys, PGPUInt32 nth, + PGPKeyRef *arkey, PGPKeyID *arkeyid, + PGPByte *arclass ); + +PGPError PGPCountRevocationKeys( PGPKeyRef basekey, + PGPUInt32 * numRevKeys); + +PGPError PGPGetIndexedRevocationKey( + PGPKeyRef basekey, PGPKeySetRef allkeys, PGPUInt32 nth, + PGPKeyRef *revkey, PGPKeyID *revkeyid ); +PGPError PGPGetCRLDistributionPoints( + PGPKeyRef cakey, PGPKeySetRef keyset, + PGPUInt32 *pnDistPoints, PGPByte **pDpoints, + PGPSize **pdpointLengths ); + + +/* Wrapper functions */ +PGPError PGPGenerateKey( PGPContextRef context, PGPKeyRef *key, + PGPOptionListRef firstOption, ...); +PGPError PGPGenerateSubKey( PGPContextRef context, + PGPSubKeyRef *subkey, + PGPOptionListRef firstOption, ...); +PGPUInt32 PGPGetKeyEntropyNeeded( PGPContextRef context, + PGPOptionListRef firstOption, ...); +PGPError PGPExportKeySet( PGPKeySetRef keys, + PGPOptionListRef firstOption, ...); +PGPError PGPExport( PGPContextRef context, + PGPOptionListRef firstOption, ...); +PGPError PGPImportKeySet( PGPContextRef context, + PGPKeySetRef *keys, + PGPOptionListRef firstOption, ...); +PGPError PGPSignUserID( PGPUserIDRef userID, + PGPKeyRef certifyingKey, + PGPOptionListRef firstOption, ...); +PGPError PGPAddUserID( PGPKeyRef key, char const *userID, + PGPOptionListRef firstOption, ...); +PGPError PGPAddAttributeUserID( PGPKeyRef key, + PGPAttributeType attributeType, + PGPByte *attributeData, PGPSize attributeLength, + PGPOptionListRef firstOption, ...); +PGPError PGPRevokeSig( PGPSigRef cert, PGPKeySetRef allkeys, + PGPOptionListRef firstOption, ...); +PGPError PGPRevokeKey( PGPKeyRef key, + PGPOptionListRef firstOption, ...); +PGPError PGPRevokeSubKey( PGPSubKeyRef subkey, + PGPOptionListRef firstOption, ...); +PGPError PGPChangePassphrase( PGPKeyRef key, + PGPOptionListRef firstOption, ...); +PGPError PGPChangeSubKeyPassphrase( PGPSubKeyRef subkey, + PGPOptionListRef firstOption, ...); +PGPBoolean PGPPassphraseIsValid( PGPKeyRef key, + PGPOptionListRef firstOption, ...); +PGPError PGPSetKeyAxiomatic( PGPKeyRef key, + PGPOptionListRef firstOption, ...); + + + +/* + * Trust values for PGPSetKeyTrust and kPGPKeyPropTrust property: + * + * kPGPKeyTrust_Undefined (do not pass to PGPSetKeyTrust) + * kPGPKeyTrust_Unknown (unknown) + * kPGPKeyTrust_Never (never) + * kPGPKeyTrust_Marginal (sometimes) + * kPGPKeyTrust_Complete (always) + * kPGPKeyTrust_Ultimate (do not pass to PGPSetKeyTrust) + */ + + /* old trust model */ +PGPError PGPSetKeyTrust( PGPKeyRef key, PGPUInt32 trust); + +PGPError PGPUnsetKeyAxiomatic( PGPKeyRef key); + +/* Get property functions */ + +PGPError PGPGetKeyBoolean( PGPKeyRef key, PGPKeyPropName propname, + PGPBoolean *prop); + +PGPError PGPGetKeyNumber( PGPKeyRef key, PGPKeyPropName propname, + PGPInt32 *prop); + +/* 'buffer' is NOT null-terminated */ +/* returns kPGPError_BufferTooSmall if buffer is too small, but +fill buffer to capacity */ +PGPError PGPGetKeyPropertyBuffer( PGPKeyRef key, + PGPKeyPropName propname, + PGPSize bufferSize, void *data, PGPSize *fullSize); + +PGPError PGPGetKeyTime( PGPKeyRef key, PGPKeyPropName propname, + PGPTime *prop); + +PGPError PGPGetSubKeyBoolean( PGPSubKeyRef subkey, + PGPKeyPropName propname, PGPBoolean *prop); + +PGPError PGPGetSubKeyNumber( PGPSubKeyRef subkey, + PGPKeyPropName propname, PGPInt32 *prop); + +/* returns kPGPError_BufferTooSmall if buffer is too small, but +fill buffer to capacity */ +PGPError PGPGetSubKeyPropertyBuffer( PGPSubKeyRef subkey, + PGPKeyPropName propname, + PGPSize bufferSize, void *prop, PGPSize *fullSize); + +PGPError PGPGetSubKeyTime( PGPSubKeyRef subkey, + PGPKeyPropName propname, PGPTime *prop); + +PGPError PGPGetUserIDNumber( PGPUserIDRef userID, + PGPUserIDPropName propname, PGPInt32 *prop); + +PGPError PGPGetUserIDBoolean( PGPUserIDRef userID, + PGPUserIDPropName propname, PGPBoolean *prop); + +/* 'string' is always NULL-terminated */ +/* returns kPGPError_BufferTooSmall if buffer is too small, but +fill buffer to capacity */ +PGPError PGPGetUserIDStringBuffer( PGPUserIDRef userID, + PGPUserIDPropName propname, + PGPSize bufferSize, + char * string, + PGPSize * fullSize); + +/* 'buffer' is NOT null-terminated */ +/* returns kPGPError_BufferTooSmall if buffer is too small, but +fill buffer to capacity */ +PGPError PGPGetSigPropertyBuffer( PGPSigRef cert, + PGPSigPropName propname, + PGPSize bufferSize, void *data, PGPSize *fullSize); + +PGPError PGPGetSigBoolean( PGPSigRef cert, + PGPSigPropName propname, PGPBoolean *prop); + +PGPError PGPGetSigNumber( PGPSigRef cert, PGPSigPropName propname, + PGPInt32 *prop); + +PGPError PGPGetKeyIDOfCertifier( PGPSigRef sig, PGPKeyID *outID ); + +PGPError PGPGetSigTime( PGPSigRef cert, PGPSigPropName propname, + PGPTime *prop); + +PGPError PGPGetHashAlgUsed( PGPKeyRef key, PGPHashAlgorithm *hashAlg); + +/* Convenience property functions */ + +PGPError PGPGetPrimaryUserID( PGPKeyRef key, PGPUserIDRef *outRef ); +PGPError PGPGetPrimaryAttributeUserID (PGPKeyRef key, + PGPAttributeType attributeType, PGPUserIDRef *outRef); + +/* 'string' is always a C string and + *fullSize includes the '\0' terminator */ +/* returns kPGPError_BufferTooSmall if buffer is too small, but +fill buffer to capacity */ +PGPError PGPGetPrimaryUserIDNameBuffer( PGPKeyRef key, + PGPSize bufferSize, + char * string, PGPSize *fullSize ); + +PGPError PGPGetPrimaryUserIDValidity(PGPKeyRef key, + PGPValidity *validity); + + +PGPInt32 PGPCompareKeys(PGPKeyRef a, PGPKeyRef b, + PGPKeyOrdering order); + +PGPInt32 PGPCompareUserIDStrings(char const *a, char const *b); + +PGPError PGPOrderKeySet( PGPKeySetRef src, + PGPKeyOrdering order, PGPKeyListRef *outRef ); + +PGPError PGPIncKeyListRefCount( PGPKeyListRef keys); + +PGPError PGPFreeKeyList( PGPKeyListRef keys); + + +/* Key iteration functions */ + + + +PGPError PGPNewKeyIter (PGPKeyListRef keys, PGPKeyIterRef *outRef); + +PGPError PGPCopyKeyIter (PGPKeyIterRef orig, PGPKeyIterRef *outRef); + +PGPError PGPFreeKeyIter (PGPKeyIterRef iter); + +PGPInt32 PGPKeyIterIndex (PGPKeyIterRef iter); + +PGPError PGPKeyIterRewind (PGPKeyIterRef iter); + +PGPInt32 PGPKeyIterSeek (PGPKeyIterRef iter, PGPKeyRef key); + +PGPError PGPKeyIterMove (PGPKeyIterRef iter, PGPInt32 relOffset, + PGPKeyRef *outRef); + +PGPError PGPKeyIterNext (PGPKeyIterRef iter, PGPKeyRef *outRef); + +PGPError PGPKeyIterPrev (PGPKeyIterRef iter, PGPKeyRef *outRef); + +PGPError PGPKeyIterKey (PGPKeyIterRef iter, PGPKeyRef *outRef); + +PGPError PGPKeyIterSubKey (PGPKeyIterRef iter, + PGPSubKeyRef *outRef ); + +PGPError PGPKeyIterUserID (PGPKeyIterRef iter, + PGPUserIDRef *outRef ); +PGPError PGPKeyIterSig (PGPKeyIterRef iter, + PGPSigRef *outRef ); + +PGPError PGPKeyIterNextSubKey (PGPKeyIterRef iter, + PGPSubKeyRef *outRef ); + +PGPError PGPKeyIterPrevSubKey (PGPKeyIterRef iter, + PGPSubKeyRef *outRef); + +PGPError PGPKeyIterRewindSubKey (PGPKeyIterRef iter); + +PGPError PGPKeyIterNextUserID (PGPKeyIterRef iter, + PGPUserIDRef *outRef); + +PGPError PGPKeyIterPrevUserID (PGPKeyIterRef iter, + PGPUserIDRef *outRef); + +PGPError PGPKeyIterRewindUserID (PGPKeyIterRef iter); + +PGPError PGPKeyIterNextUIDSig (PGPKeyIterRef iter, + PGPSigRef *outRef); + +PGPError PGPKeyIterPrevUIDSig (PGPKeyIterRef iter, + PGPSigRef *outRef); + +PGPError PGPKeyIterRewindUIDSig (PGPKeyIterRef iter); + + +/* Get/set default private key */ + +PGPError PGPGetDefaultPrivateKey( PGPKeySetRef keyset, + PGPKeyRef *outRef ); + +PGPError PGPSetDefaultPrivateKey( PGPKeyRef key); + + + +/* Get/set user value */ + +PGPError PGPSetKeyUserVal( PGPKeyRef key, PGPUserValue userValue); + +PGPError PGPSetUserIDUserVal( PGPUserIDRef userid, + PGPUserValue userValue); + +PGPError PGPSetSubKeyUserVal( PGPSubKeyRef subkey, + PGPUserValue userValue); + +PGPError PGPSetSigUserVal( PGPSigRef cert, + PGPUserValue userValue); + +PGPError PGPGetKeyUserVal( PGPKeyRef key, + PGPUserValue *userValue); + +PGPError PGPGetUserIDUserVal( PGPUserIDRef userid, + PGPUserValue *userValue); + +PGPError PGPGetSubKeyUserVal( PGPSubKeyRef subkey, + PGPUserValue *userValue); + +PGPError PGPGetSigUserVal( PGPSigRef cert, + PGPUserValue *userValue); + +/* Passphrase conversion to passkeybuffer */ +/* The size of the output buffer is from the kPGPKeyPropLockingBits property */ + +PGPError PGPGetKeyPasskeyBuffer ( PGPKeyRef key, + void *passkeyBuffer, PGPOptionListRef firstOption,...); + +PGPError PGPGetSubKeyPasskeyBuffer ( PGPSubKeyRef subkey, + void *passkeyBuffer, PGPOptionListRef firstOption,...); + + +/* Change key options which are stored in self signatures internally */ + +PGPError PGPAddKeyOptions( PGPKeyRef key, + PGPOptionListRef firstOption, ...); + +PGPError PGPRemoveKeyOptions( PGPKeyRef key, + PGPOptionListRef firstOption, ...); + +PGPError PGPUpdateKeyOptions( PGPKeyRef key, + PGPOptionListRef firstOption, ...); + + + +/*____________________________________________________________________________ + Key IDs +____________________________________________________________________________*/ +PGPError PGPGetKeyIDFromString( + const char *string, PGPKeyID *id ); + +PGPError PGPGetKeyIDFromKey( PGPKeyRef key, PGPKeyID *id ); + +PGPError PGPGetKeyIDFromSubKey( PGPSubKeyRef key, PGPKeyID * id ); + +enum PGPKeyIDStringType_ +{ + kPGPKeyIDString_Abbreviated = 2, + kPGPKeyIDString_Full = 3, + PGP_ENUM_FORCE( PGPKeyIDStringType_ ) +}; +PGPENUM_TYPEDEF( PGPKeyIDStringType_, PGPKeyIDStringType ); + + +#define kPGPMaxKeyIDStringSize ( 127 + 1 ) +PGPError PGPGetKeyIDString( PGPKeyID const * ref, + PGPKeyIDStringType type, + char outString[ kPGPMaxKeyIDStringSize ] ); + + +/* outputs opaque string of bytes for storage of maximum size as keyID*/ +/* do NOT attempt to parse the output; it is opaque to you */ +#define kPGPMaxExportedKeyIDSize ( sizeof( PGPKeyID ) ) +PGPError PGPExportKeyID( PGPKeyID const * keyID, + PGPByte exportedData[ kPGPMaxExportedKeyIDSize ], + PGPSize *exportedLength ); + +/* must be in format output by PGPExportKeyID */ +PGPError PGPImportKeyID( void const * data, PGPKeyID * id ); + +/* returns 0 if equal, -1 if key1 < key2, 1 if key1 > key2 */ +PGPInt32 PGPCompareKeyIDs( PGPKeyID const * key, PGPKeyID const * key2); + + + + +/*____________________________________________________________________________ + Getting contexts back from key related items. If the key is invalid, + you get kPGPInvalidRef back. +____________________________________________________________________________*/ + +PGPContextRef PGPGetKeyListContext( PGPKeyListRef ref ); +PGPContextRef PGPGetKeySetContext( PGPKeySetRef ref ); +PGPContextRef PGPGetKeyIterContext( PGPKeyIterRef ref ); +PGPContextRef PGPGetKeyContext( PGPKeyRef ref ); +PGPContextRef PGPGetSubKeyContext( PGPSubKeyRef ref ); +PGPContextRef PGPGetUserIDContext( PGPUserIDRef ref ); + +/*____________________________________________________________________________ + Getting parent objects from key related items. If the input is invalid, + you get kPGPInvalidRef back. +____________________________________________________________________________*/ +PGPKeyRef PGPGetUserIDKey( PGPUserIDRef ref ); +PGPUserIDRef PGPGetSigUserID( PGPSigRef ref ); +PGPKeyRef PGPGetSigKey( PGPSigRef ref ); + + +/*____________________________________________________________________________ + Secret sharing functionality +____________________________________________________________________________*/ + +PGPError PGPSecretShareData(PGPContextRef context, + void const * input, PGPSize inputBytes, + PGPUInt32 threshold, PGPUInt32 nShares, void * output); + +PGPError PGPSecretReconstructData(PGPContextRef context, + void * input, PGPSize outputBytes, + PGPUInt32 nShares, void * output); + + +/*____________________________________________________________________________ + X509 certificate specific +____________________________________________________________________________*/ + +PGPError PGPVerifyX509CertificateChain (PGPContextRef context, + PGPByte *certchain, PGPByte *rootcerts); + +PGPError PGPCreateDistinguishedName( PGPContextRef context, + char const *str, + PGPByte **pdname, PGPSize *pdnamelen ); + + +#if PRAGMA_IMPORT_SUPPORTED +#pragma import reset +#endif +PGP_END_C_DECLARATIONS + + +#endif /* ] Included_pgpKeys_h */ + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk6/include/pgpMemoryMgr.h b/CryptoPP/PGPw/sdk6/include/pgpMemoryMgr.h new file mode 100644 index 0000000..7480d52 --- /dev/null +++ b/CryptoPP/PGPw/sdk6/include/pgpMemoryMgr.h @@ -0,0 +1,235 @@ +/*____________________________________________________________________________ + Copyright (C) 1997 Network Associates Inc. and affiliated companies. + All rights reserved. + + Contains the definition of the PGPMemoryMgr object. + + $Id: pgpMemoryMgr.h,v 1.21 1999/05/07 01:55:45 heller Exp $ +____________________________________________________________________________*/ + +#ifndef Included_pgpMemoryMgr_h /* [ */ +#define Included_pgpMemoryMgr_h + + +#include "pgpBase.h" + +/*____________________________________________________________________________ + Mini-tutorial: + + A PGPMemoryMgr is an object which implements memory management, including + allocation, reallocation, deallocation, and secure versions of the same. + + *** Using it *** + A typical sequence of calls is as follows: + PGPNewMemoryMgr + ... + PGPNewData or PGPNewSecureData + PGPFreeData + ... + PGPFreeMemoryMgr + + Typically, a program will create one PGPMemoryMgr per thread at + thread creation time and use that memory mgr until the thread dies. + Generally, an individual PGPMemoryMgr instance is not thread-safe; + you must either synchronize or use one PGPMemoryMgr per thread. + + + *** Custom Allocators *** + + Default allocators are supplied, but the client can create a custom + PGPMemoryMgr using PGPNewMemoryMgrCustom() which uses client-supplied + routines. + Custom routines need only concern themselves with the actual + allocation and deallocation. + The following should be kept in mind for user supplied routines: + - they can ignore the allocation flags passed + - leaks, memory clearing, etc is done by the PGPMemoryMgr + - secure allocator must set 'isNonPageable' to TRUE only if the + memory really can't be paged. + - the user value is not interpreted by the PGPMemoryMgr. Typically, + it would be a pointer to some data the allocation routines use + to store state. + + + *** Secure memory allocation *** + + Blocks can be allocated as "Secure" blocks. Secure blocks are guaranteed + to be wiped when they are deallocated. Additionally, if the operating + system and the current conditions allow, the block will be allocated + in non-pageable memory. You can determine the attributes of a block using + PGPGetMemoryMgrDataInfo(). + + + *** Leaks tracking *** + + Leaks tracking is implemented when debugging is on, + but currently reporting is limited to reporting the number of leaks + outstanding when the PGPMemoryMgr is disposed. + + + *** Debugging *** + + For debugging purposes, blocks may be larger in debug mode to accomodate + various schemes to detect stray pointers, etc. +____________________________________________________________________________*/ + + +#if PRAGMA_ALIGN_SUPPORTED +#pragma options align=mac68k +#endif + +enum +{ + kPGPMemoryMgrFlags_None = 0, + kPGPMemoryMgrFlags_Clear = 1 +}; + +typedef PGPFlags PGPMemoryMgrFlags; + +typedef struct PGPMemoryMgr PGPMemoryMgr; +typedef PGPMemoryMgr * PGPMemoryMgrRef; + +#define kInvalidPGPMemoryMgrRef ((PGPMemoryMgrRef) NULL) +#define PGPMemoryMgrRefIsValid(ref) ((ref) != kInvalidPGPMemoryMgrRef) + +typedef void *(*PGPMemoryMgrAllocationProc)( PGPMemoryMgrRef mgr, + PGPUserValue userValue, + PGPSize requestSize, PGPMemoryMgrFlags flags ); + +/* realloc not be implemented using PGPNewData() */ +typedef PGPError (*PGPMemoryMgrReallocationProc)( PGPMemoryMgrRef mgr, + PGPUserValue userValue, + void **allocation, PGPSize newAllocationSize, + PGPMemoryMgrFlags flags, PGPSize existingSize ); + +typedef PGPError (*PGPMemoryMgrDeallocationProc)( PGPMemoryMgrRef mgr, + PGPUserValue userValue, + void *allocation, PGPSize allocationSize ); + + + +typedef void *(*PGPMemoryMgrSecureAllocationProc)( PGPMemoryMgrRef mgr, + PGPUserValue userValue, + PGPSize requestSize, PGPMemoryMgrFlags flags, + PGPBoolean *isNonPageable ); + + +/* deallocation proc need not clear the memory upon deallocation since + PGPFreeData() does it automatically */ +typedef PGPError (*PGPMemoryMgrSecureDeallocationProc)( PGPMemoryMgrRef mgr, + PGPUserValue userValue, + void *allocation, PGPSize allocationSize, + PGPBoolean wasLocked ); + + +typedef struct PGPNewMemoryMgrStruct +{ + /* sizeofStruct must be inited to sizeof( PGPNewMemoryMgrStruct ) */ + PGPUInt32 sizeofStruct; + PGPFlags reservedFlags; + + PGPMemoryMgrAllocationProc allocProc; + PGPMemoryMgrReallocationProc reallocProc; + PGPMemoryMgrDeallocationProc deallocProc; + + PGPMemoryMgrSecureAllocationProc secureAllocProc; + void * reserved; /* MUST be zeroed */ + PGPMemoryMgrSecureDeallocationProc secureDeallocProc; + + PGPUserValue customValue; + void * pad[ 8 ]; /* MUST be zeroed */ +} PGPNewMemoryMgrStruct; + +PGP_BEGIN_C_DECLARATIONS +#if PRAGMA_IMPORT_SUPPORTED +#pragma import on +#endif + + +/*____________________________________________________________________________ + Memory Mgr routines +____________________________________________________________________________*/ +PGPBoolean PGPMemoryMgrIsValid( PGPMemoryMgrRef mgr ); +#define PGPValidateMemoryMgr( mgr ) \ + PGPValidateParam( PGPMemoryMgrIsValid( mgr ) ) + +PGPError PGPNewMemoryMgr( PGPFlags reserved, + PGPMemoryMgrRef *newMemoryMgr ); + +PGPError PGPNewMemoryMgrCustom( PGPNewMemoryMgrStruct const * custom, + PGPMemoryMgrRef *newMemoryMgr ); + +PGPError PGPFreeMemoryMgr( PGPMemoryMgrRef mgr ); + +PGPError PGPGetMemoryMgrCustomValue( PGPMemoryMgrRef mgr, + PGPUserValue *customValue ); +PGPError PGPSetMemoryMgrCustomValue( PGPMemoryMgrRef mgr, + PGPUserValue customValue ); + +/* allocate a block of the specified size */ +void * PGPNewData( PGPMemoryMgrRef mgr, + PGPSize requestSize, PGPMemoryMgrFlags flags ); + +/* allocate a block of the specified size in non-pageable memory */ +/* *isSecure is TRUE if the block definitely can't be paged */ +void * PGPNewSecureData( PGPMemoryMgrRef mgr, + PGPSize requestSize, PGPMemoryMgrFlags flags ); + +/* properly reallocs secure or non-secure blocks */ +/* WARNING: the block may move, even if its size is being reduced */ +PGPError PGPReallocData( PGPMemoryMgrRef mgr, + void **allocation, PGPSize newAllocationSize, + PGPMemoryMgrFlags flags ); + +/* properly frees secure or non-secure blocks */ +PGPError PGPFreeData( void *allocation ); + + +/*____________________________________________________________________________ + Block Info: + kPGPMemoryMgrBlockInfo_Valid it's a valid block + kPGPMemoryMgrBlockInfo_Secure block is a secure allocation + kPGPMemoryMgrBlockInfo_NonPageable block cannot be paged by VM + + Secure blocks are always wiped before being disposed, + but may or may not be pageable, depending on the OS facilities. Some + OSs may not provide the ability to make blocks non-pageable. + + You should check these flags if the information matters to you. +____________________________________________________________________________*/ +#define kPGPMemoryMgrBlockInfo_Valid ( ((PGPFlags)1) << 0 ) +#define kPGPMemoryMgrBlockInfo_Secure ( ((PGPFlags)1) << 1 ) +#define kPGPMemoryMgrBlockInfo_NonPageable ( ((PGPFlags)1) << 2 ) +PGPFlags PGPGetMemoryMgrDataInfo( void *allocation ); + + +/*____________________________________________________________________________ + Default memory manager routines: +____________________________________________________________________________*/ + +PGPMemoryMgrRef PGPGetDefaultMemoryMgr(void); +PGPError PGPSetDefaultMemoryMgr(PGPMemoryMgrRef memoryMgr); + + +#if PRAGMA_IMPORT_SUPPORTED +#pragma import reset +#endif +PGP_END_C_DECLARATIONS + + + +#if PRAGMA_ALIGN_SUPPORTED +#pragma options align=reset +#endif + + +#endif /* ] Included_pgpMemoryMgr_h */ + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk6/include/pgpOptionList.h b/CryptoPP/PGPw/sdk6/include/pgpOptionList.h new file mode 100644 index 0000000..7ccbc8e --- /dev/null +++ b/CryptoPP/PGPw/sdk6/include/pgpOptionList.h @@ -0,0 +1,452 @@ +/*____________________________________________________________________________ + pgpOptionList.h + + Copyright (C) 1997 Network Associates Inc. and affiliated companies. + All rights reserved. + + This file contains the types and prototypes for functions which manipulate + PGPOptionList data structures. + + $Id: pgpOptionList.h,v 1.35 1999/05/07 23:47:46 hal Exp $ +____________________________________________________________________________*/ + +#ifndef Included_pgpOptionList_h /* [ */ +#define Included_pgpOptionList_h + +#include + +#include "pgpPubTypes.h" + +#if PGP_MACINTOSH +#include +#endif + +/* Standard event callback declaration */ +struct PGPEvent; +typedef PGPError (*PGPEventHandlerProcPtr)(PGPContextRef context, + struct PGPEvent *event, PGPUserValue userValue); + +/* Export formats for exporting functions */ +enum PGPExportFormat_ +{ + kPGPExportFormat_Basic = 1, + kPGPExportFormat_Complete = 255, + + kPGPExportFormat_X509Cert = 10000, + + kPGPExportFormat_X509CertReq = 11000, + kPGPExportFormat_NetToolsCAV1_CertReq, + kPGPExportFormat_VerisignV1_CertReq, + kPGPExportFormat_EntrustV1_CertReq, + + /* Deprecated aliases for three above */ +/* kPGPExportFormat_NetToolsCAV1 = 11001, + kPGPExportFormat_VerisignV1, + kPGPExportFormat_EntrustV1, +*/ + kPGPExportFormat_X509GetCertInitial = 11010, + kPGPExportFormat_NetToolsCAV1_GetCertInitial, + kPGPExportFormat_VerisignV1_GetCertInitial, + kPGPExportFormat_EntrustV1_GetCertInitial, + + kPGPExportFormat_X509GetCRL = 11020, + kPGPExportFormat_NetToolsCAV1_GetCRL, + kPGPExportFormat_VerisignV1_GetCRL, + kPGPExportFormat_EntrustV1_GetCRL, + + PGP_ENUM_FORCE( PGPExportFormat_ ) +} ; +PGPENUM_TYPEDEF( PGPExportFormat_, PGPExportFormat ); + +/* Input formats for PGPOInputFormat */ +enum PGPInputFormat_ +{ + kPGPInputFormat_Unknown = 0, + kPGPInputFormat_PGP = 1, + + kPGPInputFormat_X509DataInPKCS7 = 10000, + kPGPInputFormat_NetToolsCAV1_DataInPKCS7, + kPGPInputFormat_VerisignV1_DataInPKCS7, + kPGPInputFormat_EntrustV1_DataInPKCS7, + + /* Deprecated aliases for three above */ +/* kPGPInputFormat_NetToolsCAV1 = 10001, + kPGPInputFormat_VerisignV1, + kPGPInputFormat_EntrustV1, +*/ + kPGPInputFormat_PEMEncodedX509Cert, + kPGPInputFormat_NetToolsCAV1_PEMEncoded, + kPGPInputFormat_VerisignV1_PEMEncoded, + kPGPInputFormat_EntrustV1_PEMEncoded, + + /* Input formats for X.509 private keys */ + kPGPInputFormat_PrivateKeyInfo, + kPGPInputFormat_PKCS12, + + PGP_ENUM_FORCE( PGPInputFormat_ ) +} ; +PGPENUM_TYPEDEF( PGPInputFormat_, PGPInputFormat ); + +/* Output formats for PGPOOutputFormat */ +enum PGPOutputFormat_ +{ + kPGPOutputFormat_Unknown = 0, + kPGPOutputFormat_PGP = 1, + + kPGPOutputFormat_X509CertReqInPKCS7 = 10000, + kPGPOutputFormat_NetToolsCAV1_CertReqInPKCS7, + kPGPOutputFormat_VerisignV1_CertReqInPKCS7, + kPGPOutputFormat_EntrustV1_CertReqInPKCS7, + + /* Deprecated aliases for above three */ +/* kPGPOutputFormat_NetToolsCAV1 = 10001, + kPGPOutputFormat_VerisignV1, + kPGPOutputFormat_EntrustV1, +*/ + kPGPOutputFormat_X509GetCertInitialInPKCS7 = 10010, + kPGPOutputFormat_NetToolsCAV1_GetCertInitialInPKCS7, + kPGPOutputFormat_VerisignV1_GetCertInitialInPKCS7, + kPGPOutputFormat_EntrustV1_GetCertInitialInPKCS7, + + kPGPOutputFormat_X509GetCRLInPKCS7 = 10020, + kPGPOutputFormat_NetToolsCAV1_GetCRLInPKCS7, + kPGPOutputFormat_VerisignV1_GetCRLInPKCS7, + kPGPOutputFormat_EntrustV1_GetCRLInPKCS7, + + PGP_ENUM_FORCE( PGPOutputFormat_ ) +} ; +PGPENUM_TYPEDEF( PGPOutputFormat_, PGPOutputFormat ); + +/* Attribute-Value structure for PGPOAttributeValue */ +enum PGPAVAttribute_ +{ + /* Pointer properties */ + kPGPAVAttributeFirstPointer = 0, + kPGPAVAttribute_CommonName = kPGPAVAttributeFirstPointer, + kPGPAVAttribute_Email, + kPGPAVAttribute_OrganizationName, + kPGPAVAttribute_OrganizationalUnitName, + kPGPAVAttribute_SurName, + kPGPAVAttribute_SerialNumber, + kPGPAVAttribute_Country, + kPGPAVAttribute_Locality, + kPGPAVAttribute_State, + kPGPAVAttribute_StreetAddress, + kPGPAVAttribute_Title, + kPGPAVAttribute_Description, + kPGPAVAttribute_PostalCode, + kPGPAVAttribute_POBOX, + kPGPAVAttribute_PhysicalDeliveryOfficeName, + kPGPAVAttribute_TelephoneNumber, + kPGPAVAttribute_X121Address, + kPGPAVAttribute_ISDN, + kPGPAVAttribute_DestinationIndicator, + kPGPAVAttribute_Name, + kPGPAVAttribute_GivenName, + kPGPAVAttribute_Initials, + kPGPAVAttribute_HouseIdentifier, + kPGPAVAttribute_DirectoryManagementDomain, + kPGPAVAttribute_DomainComponent, + kPGPAVAttribute_UnstructuredName, + kPGPAVAttribute_UnstructuredAddress, + kPGPAVAttribute_RFC822Name, + kPGPAVAttribute_DNSName, + kPGPAVAttribute_AnotherName, + kPGPAVAttribute_IPAddress, + kPGPAVAttribute_CertificateExtension, + + /* Verisign specific */ + kPGPAVAttribute_Challenge, + kPGPAVAttribute_CertType, + kPGPAVAttribute_MailFirstName, + kPGPAVAttribute_MailMiddleName, + kPGPAVAttribute_MailLastName, + kPGPAVAttribute_EmployeeID, + kPGPAVAttribute_MailStop, + kPGPAVAttribute_AdditionalField4, + kPGPAVAttribute_AdditionalField5, + kPGPAVAttribute_AdditionalField6, + kPGPAVAttribute_Authenticate, + + + /* Boolean properties */ + kPGPAVAttributeFirstBoolean = 1000, + + /* Verisign specific */ + kPGPAVAttribute_EmbedEmail, + + + /* Numeric (PGPUInt32) properties */ + kPGPAVAttributeFirstNumber = 2000, + + PGP_ENUM_FORCE( PGPAVAttribute_ ) +} ; +PGPENUM_TYPEDEF( PGPAVAttribute_, PGPAVAttribute ); + +typedef struct PGPAttributeValue { + PGPAVAttribute attribute; + PGPSize size; + union { + PGPBoolean booleanvalue; + PGPUInt32 longvalue; + void *pointervalue; + } value; + PGPUInt32 unused; +} PGPAttributeValue ; + + + +PGP_BEGIN_C_DECLARATIONS + +#if PRAGMA_IMPORT_SUPPORTED +#pragma import on +#endif + +PGPError PGPNewOptionList(PGPContextRef context, + PGPOptionListRef *outList); +PGPError PGPAppendOptionList(PGPOptionListRef optionList, + PGPOptionListRef firstOption, ...); +PGPError PGPBuildOptionList( PGPContextRef context, + PGPOptionListRef *outList, + PGPOptionListRef firstOption, ...); +PGPError PGPCopyOptionList(PGPOptionListRef optionList, + PGPOptionListRef *outList ); +PGPError PGPFreeOptionList(PGPOptionListRef optionList); + +/* +** The following functions are used to create PGPOptionListRef's for +** specifying the various options to several SDK functions. The +** functions can be used as inline parameters in a temporary manner or +** used with PGPBuildOptionList() to create persistent lists. +*/ + +/* +** Special PGPOptionListRef to mark last option passed to those functions +** which take variable lists of PGPOptionListRef's: +*/ + +PGPOptionListRef PGPOLastOption( PGPContextRef context ); + +/* +** Special PGPOptionListRef which is always ignored: +*/ + +PGPOptionListRef PGPONullOption( PGPContextRef context); + +/* Data input (required): */ + +PGPOptionListRef PGPOInputFile( PGPContextRef context, + PGPFileSpecRef fileRef); +PGPOptionListRef PGPOInputBuffer( PGPContextRef context, + void const *buffer, PGPSize bufferSize); +#if PGP_MACINTOSH +PGPOptionListRef PGPOInputFileFSSpec( PGPContextRef context, + const FSSpec *fileSpec); +#endif + +/* Data output (optional, generates event if missing): */ + +PGPOptionListRef PGPOOutputFile( PGPContextRef context, + PGPFileSpecRef fileRef); +PGPOptionListRef PGPOOutputBuffer( PGPContextRef context, + void *buffer, PGPSize bufferSize, + PGPSize *outputDataLength); +#if PGP_MACINTOSH +PGPOptionListRef PGPOOutputFileFSSpec( PGPContextRef context, + const FSSpec *fileSpec); +#endif + +/* '*buffer' must be disposed of via PGPFreeData() */ +/* maximum memory usage will be no more than maximumBufferSize */ +PGPOptionListRef PGPOAllocatedOutputBuffer(PGPContextRef context, + void **buffer, + PGPSize maximumBufferSize, + PGPSize *actualBufferSize); +PGPOptionListRef PGPOAppendOutput( PGPContextRef context, + PGPBoolean appendOutput ); +PGPOptionListRef PGPODiscardOutput( PGPContextRef context, + PGPBoolean discardOutput ); + +/* Encrypting and signing */ + +PGPOptionListRef PGPOEncryptToKey( PGPContextRef context, + PGPKeyRef keyRef); +PGPOptionListRef PGPOEncryptToKeySet( PGPContextRef context, + PGPKeySetRef keySetRef); +PGPOptionListRef PGPOEncryptToUserID( PGPContextRef context, + PGPUserIDRef userIDRef); +PGPOptionListRef PGPOSignWithKey( PGPContextRef context, + PGPKeyRef keyRef, + PGPOptionListRef firstOption, ...); +PGPOptionListRef PGPOConventionalEncrypt( PGPContextRef context, + PGPOptionListRef firstOption, + ...); + +PGPOptionListRef PGPOPassphraseBuffer( PGPContextRef context, + const void *passphrase, PGPSize passphraseLength); +PGPOptionListRef PGPOPassphrase( PGPContextRef context, + const char *passphrase); +PGPOptionListRef PGPOPasskeyBuffer( PGPContextRef context, + const void *passkey, PGPSize passkeyLength); +PGPOptionListRef PGPOSessionKey( PGPContextRef context, + const void *sessionKey, PGPSize sessionKeyLength); +PGPOptionListRef PGPOAskUserForEntropy( PGPContextRef context, + PGPBoolean askUserForEntropy ); +PGPOptionListRef PGPORawPGPInput( PGPContextRef context, + PGPBoolean rawPGPInput ); +PGPOptionListRef PGPOCompression( PGPContextRef context, + PGPBoolean compression ); + +PGPOptionListRef PGPOLocalEncoding( PGPContextRef context, + PGPLocalEncodingFlags localEncode); +PGPOptionListRef PGPOOutputLineEndType(PGPContextRef context, + PGPLineEndType lineEnd); +PGPOptionListRef PGPOPGPMIMEEncoding(PGPContextRef context, + PGPBoolean mimeEncoding, PGPSize *mimeBodyOffset, + char mimeSeparator[ kPGPMimeSeparatorSize ]); +PGPOptionListRef PGPOOmitMIMEVersion( PGPContextRef context, + PGPBoolean omitVersion); +PGPOptionListRef PGPOX509Encoding( PGPContextRef context, + PGPBoolean x509Encoding); + +PGPOptionListRef PGPODetachedSig( PGPContextRef context, + PGPOptionListRef firstOption, + ...); + +PGPOptionListRef PGPOCipherAlgorithm( PGPContextRef context, + PGPCipherAlgorithm algorithm); +PGPOptionListRef PGPOHashAlgorithm( PGPContextRef context, + PGPHashAlgorithm algorithm); + +PGPOptionListRef PGPOFailBelowValidity( PGPContextRef context, + PGPValidity minValidity); +PGPOptionListRef PGPOWarnBelowValidity( PGPContextRef context, + PGPValidity minValidity); + + +PGPOptionListRef PGPOEventHandler( PGPContextRef context, + PGPEventHandlerProcPtr eventHandler, + PGPUserValue eventHandlerData); +PGPOptionListRef PGPOSendNullEvents( PGPContextRef context, + PGPTimeInterval approxInterval); + +PGPOptionListRef PGPOArmorOutput( PGPContextRef context, + PGPBoolean armorOutput ); +PGPOptionListRef PGPODataIsASCII( PGPContextRef context, + PGPBoolean dataIsASCII ); +PGPOptionListRef PGPOClearSign( PGPContextRef context, + PGPBoolean clearSign ); +PGPOptionListRef PGPOForYourEyesOnly( PGPContextRef context, + PGPBoolean forYourEyesOnly ); +PGPOptionListRef PGPOKeySetRef( PGPContextRef context, + PGPKeySetRef keysetRef); + +PGPOptionListRef PGPOExportKeySet( PGPContextRef context, + PGPKeySetRef keysetRef); +PGPOptionListRef PGPOExportKey( PGPContextRef context, + PGPKeyRef keyRef); +PGPOptionListRef PGPOExportUserID( PGPContextRef context, + PGPUserIDRef useridRef); +PGPOptionListRef PGPOExportSig( PGPContextRef context, + PGPSigRef sigRef); + +PGPOptionListRef PGPOImportKeysTo( PGPContextRef context, + PGPKeySetRef keysetRef); +PGPOptionListRef PGPOSendEventIfKeyFound( PGPContextRef context, + PGPBoolean sendEventIfKeyFound ); +PGPOptionListRef PGPOPassThroughIfUnrecognized( PGPContextRef context, + PGPBoolean passThroughIfUnrecognized ); +PGPOptionListRef PGPOPassThroughClearSigned( PGPContextRef context, + PGPBoolean passThroughClearSigned ); +PGPOptionListRef PGPOPassThroughKeys( PGPContextRef context, + PGPBoolean passThroughKeys ); +PGPOptionListRef PGPORecursivelyDecode( PGPContextRef context, + PGPBoolean recurse ); + +PGPOptionListRef PGPOKeyGenParams( PGPContextRef context, + PGPPublicKeyAlgorithm pubKeyAlg, + PGPUInt32 bits); + +PGPOptionListRef PGPOKeyGenName( PGPContextRef context, + const void *name, PGPSize nameLength); + +PGPOptionListRef PGPOCreationDate( PGPContextRef context, + PGPTime creationDate); +PGPOptionListRef PGPOExpiration( PGPContextRef context, + PGPUInt32 expirationDays); + +PGPOptionListRef PGPOAdditionalRecipientRequestKeySet( + PGPContextRef context, + PGPKeySetRef arKeySetRef, PGPByte arkClass); + +PGPOptionListRef PGPORevocationKeySet(PGPContextRef context, + PGPKeySetRef raKeySetRef); + +PGPOptionListRef PGPOKeyGenMasterKey( PGPContextRef context, + PGPKeyRef masterKeyRef); + +PGPOptionListRef PGPOPreferredAlgorithms( + PGPContextRef context, + PGPCipherAlgorithm const *prefAlg, + PGPUInt32 numAlgs); + +PGPOptionListRef PGPOKeyGenFast( PGPContextRef context, + PGPBoolean fastGen); + +PGPOptionListRef PGPOKeyGenUseExistingEntropy( PGPContextRef context, + PGPBoolean useExistingEntropy); + +PGPOptionListRef PGPOCommentString( PGPContextRef context, + char const *comment); + +PGPOptionListRef PGPOVersionString( PGPContextRef context, + char const *version); + +PGPOptionListRef PGPOFileNameString( PGPContextRef context, + char const *fileName); + +PGPOptionListRef PGPOSigRegularExpression(PGPContextRef context, + char const *regularExpression); + +PGPOptionListRef PGPOExportPrivateKeys( PGPContextRef context, + PGPBoolean exportKeys); + +PGPOptionListRef PGPOExportPrivateSubkeys( PGPContextRef context, + PGPBoolean exportSubkeys); + +PGPOptionListRef PGPOExportFormat(PGPContextRef context, + PGPExportFormat exportFormat); + +PGPOptionListRef PGPOExportable( PGPContextRef context, + PGPBoolean exportable); + +PGPOptionListRef PGPOSigTrust( PGPContextRef context, + PGPUInt32 trustLevel, + PGPUInt32 trustValue); + +PGPOptionListRef PGPOInputFormat( PGPContextRef context, + PGPInputFormat inputFormat ); + +PGPOptionListRef PGPOOutputFormat( PGPContextRef context, + PGPOutputFormat outputFormat ); + +PGPOptionListRef PGPOAttributeValue( PGPContextRef context, + PGPAttributeValue *attributeValue, + PGPUInt32 attributeValueCount); + +#if PRAGMA_IMPORT_SUPPORTED +#pragma import reset +#endif + +PGP_END_C_DECLARATIONS + +#endif /* ] Included_pgpOptionList_h */ + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk6/include/pgpPFLConfig.h b/CryptoPP/PGPw/sdk6/include/pgpPFLConfig.h new file mode 100644 index 0000000..a5d7e67 --- /dev/null +++ b/CryptoPP/PGPw/sdk6/include/pgpPFLConfig.h @@ -0,0 +1,51 @@ +/*____________________________________________________________________________ + pgpPFLConfig.h (Win32 version) + + Copyright (C) 1997 Network Associates Inc. and affiliated companies. + All rights reserved. + + This file contains the Win32 version of the configuration file + normally generated by the automatic configure script on Unix. + + $Id: pgpPFLConfig.h,v 1.8 1999/03/10 02:53:58 heller Exp $ +____________________________________________________________________________*/ +#ifndef Included_pgpPFLConfig_h /* [ */ +#define Included_pgpPFLConfig_h + +#define HAVE_STDARG_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_SYS_STAT_H 1 +#define HAVE_UNISTD_H 0 +#define HAVE_USHORT 0 +#define HAVE_UINT 0 +#define HAVE_ULONG 0 +#define NO_LIMITS_H 0 +#define NO_POPEN 1 + +#if defined( __MWERKS__ ) + + #define PGP_HAVE64 0 + + +#elif defined( _MSC_VER ) + #define PGP_HAVE64 1 + typedef __int64 PGPInt64; + typedef unsigned __int64 PGPUInt64; + + + +#endif + + + + +#endif /* ] Included_pgpPFLConfig_h */ + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk6/include/pgpPFLErrors.h b/CryptoPP/PGPw/sdk6/include/pgpPFLErrors.h new file mode 100644 index 0000000..ca35c79 --- /dev/null +++ b/CryptoPP/PGPw/sdk6/include/pgpPFLErrors.h @@ -0,0 +1,97 @@ +/*____________________________________________________________________________ + Copyright (C) 1997 Network Associates Inc. and affiliated companies. + All rights reserved. + + Error codes. + + $Id: pgpPFLErrors.h,v 1.24.6.1 1999/06/13 20:27:13 heller Exp $ +____________________________________________________________________________*/ +#ifndef Included_pgpPFLErrors_h /* [ */ +#define Included_pgpPFLErrors_h + +#include "pgpBase.h" + +#define kPGPPFLErrorBase -12000 +#define kPGPPFLErrorRange 500 + +enum +{ + /* + NOTE: error numbers must not be changed as compile clients depend on them. + */ + + kPGPError_NoErr = 0, + + kPGPError_BadParams = -12000, + kPGPError_OutOfMemory = -11999, + kPGPError_BufferTooSmall = -11998, + + kPGPError_FileNotFound = -11997, + kPGPError_CantOpenFile = -11996, + kPGPError_FilePermissions = -11995, + kPGPError_FileLocked = -11994, + /* Was kPGPError_DiskFull = -11993, */ + kPGPError_IllegalFileOp = -11992, + kPGPError_FileOpFailed = -11991, + kPGPError_ReadFailed = -11990, + kPGPError_WriteFailed = -11989, + kPGPError_EOF = -11988, + + kPGPError_UserAbort = -11987, + kPGPError_UnknownRequest = -11986, + kPGPError_LazyProgrammer = -11985, + kPGPError_ItemNotFound = -11984, + kPGPError_ItemAlreadyExists = -11983, + kPGPError_AssertFailed = -11982, + kPGPError_BadMemAddress = -11981, + kPGPError_UnknownError = -11980, + + kPGPError_PrefNotFound = -11979, + kPGPError_EndOfIteration = -11978, + kPGPError_ImproperInitialization = -11977, + kPGPError_CorruptData = -11976, + kPGPError_FeatureNotAvailable = -11975, + + kPGPError_DiskFull = -11960, + kPGPError_DiskLocked = -11959, + + + kPGPError_LastPFLError = kPGPPFLErrorBase + kPGPPFLErrorRange - 1 +}; + +#define IsPGPError( err ) ( (err) != kPGPError_NoErr ) +#define IsntPGPError( err ) ( (err) == kPGPError_NoErr ) + + + +#define PGPValidateParam( expr ) \ + if ( ! (expr ) ) \ + {\ + return( kPGPError_BadParams );\ + } + +#define PGPValidatePtr( ptr ) \ + PGPValidateParam( (ptr) != NULL ) + + +PGP_BEGIN_C_DECLARATIONS + + +PGPError PGPGetPFLErrorString( PGPError theError, + PGPSize bufferSize, char * theString ); + + +PGP_END_C_DECLARATIONS + + +#endif /* ] Included_pgpPFLErrors_h */ + + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk6/include/pgpPubTypes.h b/CryptoPP/PGPw/sdk6/include/pgpPubTypes.h new file mode 100644 index 0000000..a420bfb --- /dev/null +++ b/CryptoPP/PGPw/sdk6/include/pgpPubTypes.h @@ -0,0 +1,276 @@ +/*____________________________________________________________________________ + pgpPubTypes.h + + Copyright (C) 1997 Network Associates Inc. and affiliated companies. + All rights reserved. + + Opaque types for various modules go in this file. + + $Id: pgpPubTypes.h,v 1.49.6.1 1999/06/11 06:14:33 heller Exp $ +____________________________________________________________________________*/ +#ifndef Included_pgpPubTypes_h /* [ */ +#define Included_pgpPubTypes_h + + +#include "pgpConfig.h" +#include "pgpBase.h" + + +/*____________________________________________________________________________ + General data types used by PGPsdk +____________________________________________________________________________*/ +typedef struct PGPContext * PGPContextRef; +typedef struct PGPFileSpec * PGPFileSpecRef; +typedef struct PGPOptionList * PGPOptionListRef; + +/*____________________________________________________________________________ + Data types used by the key manipulation functions +____________________________________________________________________________*/ + +typedef struct PGPKeyDB * PGPKeyDBRef; +typedef struct PGPKey * PGPKeyRef; +typedef struct PGPSubKey * PGPSubKeyRef; +typedef struct PGPUserID * PGPUserIDRef; +typedef struct PGPSig * PGPSigRef; +typedef struct PGPKeySet * PGPKeySetRef; +typedef struct PGPKeyList * PGPKeyListRef; +typedef struct PGPKeyIter * PGPKeyIterRef; +typedef struct PGPFilter * PGPFilterRef; + +typedef struct PGPKeyID +{ + /* do not attempt to interpret these bytes; they *will* change */ + PGPByte opaqueBytes[ 34 ]; +} PGPKeyID; + + +/*____________________________________________________________________________ + Data types used by symmetric ciphers, cipher modes, hashing +____________________________________________________________________________*/ +typedef struct PGPHashContext * PGPHashContextRef; +typedef struct PGPHMACContext * PGPHMACContextRef; +typedef struct PGPPublicKeyContext * PGPPublicKeyContextRef; +typedef struct PGPPrivateKeyContext * PGPPrivateKeyContextRef; +typedef struct PGPCBCContext * PGPCBCContextRef; +typedef struct PGPCFBContext * PGPCFBContextRef; +typedef struct PGPSymmetricCipherContext * PGPSymmetricCipherContextRef; + +/*____________________________________________________________________________ + Data types used by keyserver code +____________________________________________________________________________*/ + +typedef struct PGPKeyServer * PGPKeyServerRef; + +/*____________________________________________________________________________ + Invalid values for each of the "ref" data types. Use these for assignment + and initialization only. Use the PGPXXXRefIsValid macros (below) to test + for valid/invalid values. +____________________________________________________________________________*/ + +#define kInvalidPGPContextRef ((PGPContextRef) NULL) +#define kInvalidPGPFileSpecRef ((PGPFileSpecRef) NULL) +#define kInvalidPGPOptionListRef ((PGPOptionListRef) NULL) + +#define kInvalidPGPKeyDBRef ((PGPKeyDBRef) NULL) +#define kInvalidPGPKeyRef ((PGPKeyRef) NULL) +#define kInvalidPGPSubKeyRef ((PGPSubKeyRef) NULL) +#define kInvalidPGPUserIDRef ((PGPUserIDRef) NULL) +#define kInvalidPGPSigRef ((PGPSigRef) NULL) +#define kInvalidPGPKeySetRef ((PGPKeySetRef) NULL) +#define kInvalidPGPKeyListRef ((PGPKeyListRef) NULL) +#define kInvalidPGPKeyIterRef ((PGPKeyIterRef) NULL) +#define kInvalidPGPFilterRef ((PGPFilterRef) NULL) +#define kInvalidPGPKeyServerRef ((PGPKeyServerRef) NULL) + + +#define kInvalidPGPHashContextRef \ + ((PGPHashContextRef) NULL) +#define kInvalidPGPHMACContextRef \ + ((PGPHMACContextRef) NULL) +#define kInvalidPGPCFBContextRef \ + ((PGPCFBContextRef) NULL) +#define kInvalidPGPCBCContextRef \ + ((PGPCBCContextRef) NULL) +#define kInvalidPGPSymmetricCipherContextRef \ + ((PGPSymmetricCipherContextRef) NULL) +#define kInvalidPGPPublicKeyContextRef \ + ((PGPPublicKeyContextRef) NULL) +#define kInvalidPGPPrivateKeyContextRef \ + ((PGPPrivateKeyContextRef) NULL) + +/* kPGPInvalidRef is deprecated. Please use a type-specific version */ +#define kPGPInvalidRef NULL + +/*____________________________________________________________________________ + Macros to test for ref validity. Use these in preference to comparing + directly with the kInvalidXXXRef values. +____________________________________________________________________________*/ + +#define PGPContextRefIsValid( ref ) ( (ref) != kInvalidPGPContextRef ) +#define PGPFileSpecRefIsValid( ref ) ( (ref) != kInvalidPGPFileSpecRef ) +#define PGPOptionListRefIsValid( ref ) ( (ref) != kInvalidPGPOptionListRef ) + +#define PGPKeyDBRefIsValid( ref ) ( (ref) != kInvalidPGPKeyDBRef ) +#define PGPKeyRefIsValid( ref ) ( (ref) != kInvalidPGPKeyRef ) +#define PGPSubKeyRefIsValid( ref ) ( (ref) != kInvalidPGPSubKeyRef ) +#define PGPUserIDRefIsValid( ref ) ( (ref) != kInvalidPGPUserIDRef ) +#define PGPSigRefIsValid( ref ) ( (ref) != kInvalidPGPSigRef ) +#define PGPKeySetRefIsValid( ref ) ( (ref) != kInvalidPGPKeySetRef ) +#define PGPKeyListRefIsValid( ref ) ( (ref) != kInvalidPGPKeyListRef ) +#define PGPKeyIterRefIsValid( ref ) ( (ref) != kInvalidPGPKeyIterRef ) +#define PGPFilterRefIsValid( ref ) ( (ref) != kInvalidPGPFilterRef ) +#define PGPKeyServerRefIsValid( ref ) ( (ref) != kInvalidPGPKeyServerRef ) + +#define PGPHashContextRefIsValid( ref ) \ + ( (ref) != kInvalidPGPHashContextRef ) +#define PGPHMACContextRefIsValid( ref ) \ + ( (ref) != kInvalidPGPHMACContextRef ) +#define PGPCFBContextRefIsValid( ref ) \ + ( (ref) != kInvalidPGPCFBContextRef ) +#define PGPCBCContextRefIsValid( ref ) \ + ( (ref) != kInvalidPGPCBCContextRef ) +#define PGPSymmetricCipherContextRefIsValid( ref ) \ + ( (ref) != kInvalidPGPSymmetricCipherContextRef ) +#define PGPPublicKeyContextRefIsValid( ref ) \ + ( (ref) != kInvalidPGPPublicKeyContextRef ) +#define PGPPrivateKeyContextRefIsValid( ref ) \ + ( (ref) != kInvalidPGPPrivateKeyContextRef ) + +/* PGPRefIsValid() is deprecated. Please use a type-specific version */ +#define PGPRefIsValid( ref ) ( (ref) != kPGPInvalidRef ) + +/*____________________________________________________________________________ + Symmetric Ciphers +____________________________________________________________________________*/ + +enum PGPCipherAlgorithm_ +{ + /* do NOT change these values */ + kPGPCipherAlgorithm_None = 0, + kPGPCipherAlgorithm_IDEA = 1, + kPGPCipherAlgorithm_3DES = 2, + kPGPCipherAlgorithm_CAST5 = 3, + + kPGPCipherAlgorithm_First = kPGPCipherAlgorithm_IDEA, + kPGPCipherAlgorithm_Last = kPGPCipherAlgorithm_CAST5, + + PGP_ENUM_FORCE( PGPCipherAlgorithm_ ) +}; +PGPENUM_TYPEDEF( PGPCipherAlgorithm_, PGPCipherAlgorithm ); + +/*____________________________________________________________________________ + Hash algorithms +____________________________________________________________________________*/ + +enum PGPHashAlgorithm_ +{ + /* do NOT change these values */ + kPGPHashAlgorithm_Invalid = 0, + kPGPHashAlgorithm_MD5 = 1, + kPGPHashAlgorithm_SHA = 2, + kPGPHashAlgorithm_RIPEMD160 = 3, + + kPGPHashAlgorithm_First = kPGPHashAlgorithm_MD5, + kPGPHashAlgorithm_Last = kPGPHashAlgorithm_RIPEMD160, + + PGP_ENUM_FORCE( PGPHashAlgorithm_ ) +}; +PGPENUM_TYPEDEF( PGPHashAlgorithm_, PGPHashAlgorithm ); + +/*____________________________________________________________________________ + Public/Private key algorithms +____________________________________________________________________________*/ +enum PGPPublicKeyAlgorithm_ +{ + /* note: do NOT change these values */ + kPGPPublicKeyAlgorithm_Invalid = 0xFFFFFFFF, + kPGPPublicKeyAlgorithm_RSA = 1, + kPGPPublicKeyAlgorithm_RSAEncryptOnly = 2, + kPGPPublicKeyAlgorithm_RSASignOnly = 3, + kPGPPublicKeyAlgorithm_ElGamal = 0x10, /* A.K.A.Diffie-Hellman */ + kPGPPublicKeyAlgorithm_DSA = 0x11, + + kPGPPublicKeyAlgorithm_First = kPGPPublicKeyAlgorithm_RSA, + kPGPPublicKeyAlgorithm_Last = kPGPPublicKeyAlgorithm_DSA, + + PGP_ENUM_FORCE( PGPPublicKeyAlgorithm_ ) +}; +PGPENUM_TYPEDEF( PGPPublicKeyAlgorithm_, PGPPublicKeyAlgorithm ); + +/*____________________________________________________________________________ + Trust values, used to set validity values +____________________________________________________________________________*/ + +#define kPGPKeyTrust_Mask 0x7u +#define kPGPKeyTrust_Undefined 0x0u +#define kPGPKeyTrust_Unknown 0x1u +#define kPGPKeyTrust_Never 0x2u +#define kPGPKeyTrust_Marginal 0x5u +#define kPGPKeyTrust_Complete 0x6u +#define kPGPKeyTrust_Ultimate 0x7u + +#define kPGPNameTrust_Mask 0x3u +#define kPGPNameTrust_Unknown 0x0u +#define kPGPNameTrust_Untrusted 0x1u +#define kPGPNameTrust_Marginal 0x2u +#define kPGPNameTrust_Complete 0x3u + +/*____________________________________________________________________________ + Validity levels, used for thresholds in options +____________________________________________________________________________*/ + +enum PGPValidity_ +{ + kPGPValidity_Unknown = kPGPNameTrust_Unknown, + kPGPValidity_Invalid = kPGPNameTrust_Untrusted, + kPGPValidity_Marginal = kPGPNameTrust_Marginal, + kPGPValidity_Complete = kPGPNameTrust_Complete, + + PGP_ENUM_FORCE( PGPValidity_ ) +} ; +PGPENUM_TYPEDEF( PGPValidity_, PGPValidity ); + +/*____________________________________________________________________________ + Line endings types +____________________________________________________________________________*/ + +enum PGPLineEndType_ +{ + kPGPLineEnd_Default = 0, + kPGPLineEnd_LF = 1, + kPGPLineEnd_CR = 2, + kPGPLineEnd_CRLF = (kPGPLineEnd_LF | kPGPLineEnd_CR), + PGP_ENUM_FORCE( PGPLineEndType_ ) +}; +PGPENUM_TYPEDEF( PGPLineEndType_, PGPLineEndType ); + +/*____________________________________________________________________________ + Local encoding types + + Only one of Force or Auto should be used. The other values are modifiers +____________________________________________________________________________*/ + +#define kPGPLocalEncoding_None 0x0 /* nothing on */ +#define kPGPLocalEncoding_Force 0x01 +#define kPGPLocalEncoding_Auto 0x02 +#define kPGPLocalEncoding_NoMacBinCRCOkay 0x04 + +typedef PGPFlags PGPLocalEncodingFlags; + + +/* max length is 255; the +1 is for the trailing \0 */ +#define kPGPMaxUserIDSize ( (PGPSize)255 + 1 ) + +/* Size of buffer for PGP-MIME separator (null terminated) */ +#define kPGPMimeSeparatorSize 81 + +#endif /* ] Included_pgpPubTypes_h */ + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk6/include/pgpPublicKey.h b/CryptoPP/PGPw/sdk6/include/pgpPublicKey.h new file mode 100644 index 0000000..d780876 --- /dev/null +++ b/CryptoPP/PGPw/sdk6/include/pgpPublicKey.h @@ -0,0 +1,213 @@ +/*____________________________________________________________________________ + pgpPublicKey.h + + Copyright (C) 1997 Network Associates Inc. and affiliated companies. + All rights reserved. + + $Id: pgpPublicKey.h,v 1.10 1999/03/10 02:54:43 heller Exp $ +____________________________________________________________________________*/ +#ifndef Included_pgpPublicKey_h /* [ */ +#define Included_pgpPublicKey_h + +#include "pgpPubTypes.h" +#include "pgpOptionList.h" + + + +/*____________________________________________________________________________ + Encryption/Signature Message Formats +____________________________________________________________________________*/ + +enum PGPPublicKeyMessageFormat_ +{ + kPGPPublicKeyMessageFormat_PGP = 1, + kPGPPublicKeyMessageFormat_PKCS1 = 2, + kPGPPublicKeyMessageFormat_X509 = 3, + kPGPPublicKeyMessageFormat_IKE = 4, + + PGP_ENUM_FORCE( PGPPublicKeyMessageFormat_ ) +}; +PGPENUM_TYPEDEF( PGPPublicKeyMessageFormat_, PGPPublicKeyMessageFormat ); + + + +PGP_BEGIN_C_DECLARATIONS +#if PRAGMA_IMPORT_SUPPORTED +#pragma import on +#endif + + + +/*____________________________________________________________________________ + Public-key operations +____________________________________________________________________________*/ + + + +/*____________________________________________________________________________ + Return a context for public-key operations based on the specified key. + The specified message format is used for all operations with this + context. +____________________________________________________________________________*/ +PGPError PGPNewPublicKeyContext( PGPKeyRef publicKeyRef, + PGPPublicKeyMessageFormat messageFormat, + PGPPublicKeyContextRef *outRef ); + + +/*____________________________________________________________________________ + Dispose of a public-key context. +____________________________________________________________________________*/ +PGPError PGPFreePublicKeyContext( PGPPublicKeyContextRef ref ); + + +/*____________________________________________________________________________ + Determine maximum sizes for inputs and outputs. +____________________________________________________________________________*/ +PGPError PGPGetPublicKeyOperationSizes( PGPPublicKeyContextRef ref, + PGPSize *maxDecryptedBufferSize, + PGPSize *maxEncryptedBufferSize, + PGPSize *maxSignatureSize ); + + +/*____________________________________________________________________________ + Encrypt one block of data, using PKCS-1 padding. Output buffer must + be of size maxEncryptedBufferSize from PGPGetPublicKeyEncryptionSize. + outSize is a return parameter. For some formatting modes the actual + output size may be less than the maximum possible. +____________________________________________________________________________*/ +PGPError PGPPublicKeyEncrypt( PGPPublicKeyContextRef ref, + void const *in, PGPSize inSize, void *out, + PGPSize *outSize ); + + +/*____________________________________________________________________________ + Verify a signature on a message hash. Returns kPGPError_NoErr on + correct verification, else an error code. The message hash is + finalized and freed by this call (and should not have been finalized + prior to the call). +____________________________________________________________________________*/ + +PGPError PGPPublicKeyVerifySignature( PGPPublicKeyContextRef ref, + PGPHashContextRef hashContext, + void const *signature, PGPSize signatureSize ); + + +/*____________________________________________________________________________ + Verify a signature on a low-level buffer. Returns kPGPError_NOErr + correct verification, else an error code. Not valid with + kPGPPublicKeyMessageFormat_PGP contexts. +____________________________________________________________________________*/ + +PGPError PGPPublicKeyVerifyRaw( PGPPublicKeyContextRef ref, + void const *signedData, PGPSize signedDataSize, + void const *signature, PGPSize signatureSize ); + + +/*____________________________________________________________________________ + Private-key operations +____________________________________________________________________________*/ + + + +/*____________________________________________________________________________ + Return a context for private-key operations based on the specified + key (which must have a private part). The specified message + format is used for all operations with this context. Unlocks key + data using passphrase. +____________________________________________________________________________*/ + + +PGPError PGPNewPrivateKeyContext( PGPKeyRef privateKeyRef, + PGPPublicKeyMessageFormat messageFormat, + PGPPrivateKeyContextRef *outRef, + PGPOptionListRef firstOption, ...); + +/*____________________________________________________________________________ + Dispose of a private-key context. All sensitive data is wiped before + being deleted. +____________________________________________________________________________*/ +PGPError PGPFreePrivateKeyContext( PGPPrivateKeyContextRef ref ); + + +/*____________________________________________________________________________ + Determine maximum sizes for inputs and outputs. +____________________________________________________________________________*/ +PGPError PGPGetPrivateKeyOperationSizes( PGPPrivateKeyContextRef ref, + PGPSize *maxDecryptedBufferSize, + PGPSize *maxEncryptedBufferSize, + PGPSize *maxSignatureSize); + + +/*____________________________________________________________________________ + Decrypt one block of data. Output buffer must be of size at least + maxDecryptedBufferSize from PGPGetPrivateKeyDecryptionSize. + outSize is a return parameter. For some formatting modes the actual + output size may be less than the maximum possible. +____________________________________________________________________________*/ +PGPError PGPPrivateKeyDecrypt( PGPPrivateKeyContextRef ref, + void const *in, PGPSize inSize, void *out, + PGPSize *outSize ); + + +/*____________________________________________________________________________ + Sign a message hash. Output signature buffer must be of size at + least maxSignatureSize from PGPGetPrivateKeyDecryptionSize. + signatureSize is a return parameter. For some formatting modes + the actual signature size may be less than the maximum possible. + The message hash is finalized and freed by this call (and should + not have been finalized prior to the call). +____________________________________________________________________________*/ + + +PGPError PGPPrivateKeySign( PGPPrivateKeyContextRef ref, + PGPHashContextRef hashContext, + void *signature, PGPSize *signatureSize ); + +/*____________________________________________________________________________ + Sign a low level signedData buffer. Output signature buffer must be + of size at least maxSignatureSize from PGPGetPrivateKeyDecryptionSize. + signatureSize is a return parameter. Not valid with + kPGPPublicKeyMessageFormat_PGP contexts. +____________________________________________________________________________*/ + +PGPError PGPPrivateKeySignRaw( PGPPrivateKeyContextRef ref, + void const *signedData, PGPSize signedDataSize, + void const *signature, PGPSize *signatureSize ); + + +/*____________________________________________________________________________ + Miscellaneous operations +____________________________________________________________________________*/ + + + +/*____________________________________________________________________________ +Given the size of a prime modulus in bits, this returns an appropriate +size for an exponent in bits, such that the work factor to find a +discrete log modulo the modulus is approximately equal to half the +length of the exponent. This makes the exponent an appropriate size +for a subgroup in a discrete log signature scheme. For encryption +schemes, where decryption attacks can be stealthy and undetected, we +use 3/2 times the returned exponent size. +____________________________________________________________________________*/ + +PGPError PGPDiscreteLogExponentBits( PGPUInt32 modulusBits, + PGPUInt32 *exponentBits ); + + +#if PRAGMA_IMPORT_SUPPORTED +#pragma import reset +#endif +PGP_END_C_DECLARATIONS + +#endif /* ] Included_pgpPublicKey_h */ + + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk6/include/pgpRandomPool.h b/CryptoPP/PGPw/sdk6/include/pgpRandomPool.h new file mode 100644 index 0000000..5a7fabe --- /dev/null +++ b/CryptoPP/PGPw/sdk6/include/pgpRandomPool.h @@ -0,0 +1,49 @@ +/*____________________________________________________________________________ + pgpRandomPool.h + + Copyright (C) 1997 Network Associates Inc. and affiliated companies. + All rights reserved. + + $Id: pgpRandomPool.h,v 1.13 1999/04/13 17:43:18 cpeterson Exp $ +____________________________________________________________________________*/ +#ifndef Included_pgpRandomPool_h /* [ */ +#define Included_pgpRandomPool_h + +#include "pgpBase.h" + +PGP_BEGIN_C_DECLARATIONS +#if PRAGMA_IMPORT_SUPPORTED +#pragma import on +#endif + +PGPUInt32 PGPGlobalRandomPoolAddKeystroke( PGPInt32 event); +PGPUInt32 PGPGlobalRandomPoolMouseMoved(void); +PGPError PGPGlobalRandomPoolAddSystemState(void); + +/* Extra functions for entropy estimation */ +PGPUInt32 PGPGlobalRandomPoolGetEntropy( void ); +PGPUInt32 PGPGlobalRandomPoolGetSize( void ); +PGPUInt32 PGPGlobalRandomPoolGetMinimumEntropy( void ); +PGPBoolean PGPGlobalRandomPoolHasMinimumEntropy( void ); + + +#if PGP_DEPRECATED +PGPUInt32 PGPGlobalRandomPoolAddMouse( PGPUInt32 x, PGPUInt32 y); +#endif + +#if PRAGMA_IMPORT_SUPPORTED +#pragma import reset +#endif +PGP_END_C_DECLARATIONS + +#endif /* ] Included_pgpRandomPool_h */ + + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk6/include/pgpSDKPrefs.h b/CryptoPP/PGPw/sdk6/include/pgpSDKPrefs.h new file mode 100644 index 0000000..2662786 --- /dev/null +++ b/CryptoPP/PGPw/sdk6/include/pgpSDKPrefs.h @@ -0,0 +1,74 @@ +/*____________________________________________________________________________ + Copyright (C) 1997 Network Associates Inc. and affiliated companies. + All rights reserved. + + $Id: pgpSDKPrefs.h,v 1.7 1999/05/17 07:53:20 heller Exp $ +____________________________________________________________________________*/ +#ifndef Included_pgpCDKPrefs_h /* [ */ +#define Included_pgpCDKPrefs_h + +#include "pgpConfig.h" +#include "pgpPubTypes.h" + + +enum PGPsdkPrefSelector_ +{ + kPGPsdkPref_DefaultKeyID = 3, + kPGPsdkPref_PublicKeyring = 5, + kPGPsdkPref_PrivateKeyring = 6, + kPGPsdkPref_RandomSeedFile = 7, + kPGPsdkPref_GroupsFile = 8, + + PGP_ENUM_FORCE( PGPsdkPrefSelector_ ) +}; +PGPENUM_TYPEDEF( PGPsdkPrefSelector_, PGPsdkPrefSelector ); + + + +PGP_BEGIN_C_DECLARATIONS +#if PRAGMA_IMPORT_SUPPORTED +#pragma import on +#endif + +/* call this if you want the CDK to use prefs stored in the prefs file */ +PGPError PGPsdkLoadPrefs( PGPContextRef context, + PGPFileSpecRef prefSpec ); +PGPError PGPsdkLoadDefaultPrefs( PGPContextRef context ); + +/* save any changed preferences to disk */ +PGPError PGPsdkSavePrefs( PGPContextRef context ); + + +PGPError PGPsdkPrefSetFileSpec( PGPContextRef context, + PGPsdkPrefSelector selector, PGPFileSpecRef ref ); + +/* caller must deallocate *outRef with PGPFreeFileSpec */ +PGPError PGPsdkPrefGetFileSpec( PGPContextRef context, + PGPsdkPrefSelector selector, PGPFileSpecRef * outRef ); + + +PGPError PGPsdkPrefSetData( PGPContextRef context, + PGPsdkPrefSelector selector, + void const *data, PGPSize size ); + +/* caller must deallocate *dataOut with PGPFreeData */ +PGPError PGPsdkPrefGetData( PGPContextRef context, + PGPsdkPrefSelector selector, + void **dataOut, PGPSize *sizeOut ); + +#if PRAGMA_IMPORT_SUPPORTED +#pragma import reset +#endif +PGP_END_C_DECLARATIONS + +#endif /* ] Included_pgpCDKPrefs_h */ + + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk6/include/pgpSockets.h b/CryptoPP/PGPw/sdk6/include/pgpSockets.h new file mode 100644 index 0000000..c884cc5 --- /dev/null +++ b/CryptoPP/PGPw/sdk6/include/pgpSockets.h @@ -0,0 +1,476 @@ +/*____________________________________________________________________________ + Copyright (C) 1997 Network Associates Inc. and affiliated companies. + All rights reserved. + + + + $Id: pgpSockets.h,v 1.27.6.1.6.1 1999/08/04 18:36:04 sluu Exp $ +____________________________________________________________________________*/ + + +#ifndef Included_pgpSockets_h /* [ */ +#define Included_pgpSockets_h + +#include + +#include "pgpOptionList.h" +#include "pgpTLS.h" +#include "pgpErrors.h" + +#if PGP_UNIX +# include +# include +#if PGP_UNIX_LINUX +# include /* Needed for unknown reason */ +# include /* Need FIONREAD */ +#elif PGP_UNIX_SOLARIS +# include +#elif PGP_UNIX_AIX +# include +# include +#endif /* ! PGP_UNIX_LINUX */ +# include +# include +#endif + +#if PGP_WIN32 +# include +#endif + +PGP_BEGIN_C_DECLARATIONS + +#if PRAGMA_IMPORT_SUPPORTED +# pragma import on +#endif + +typedef struct PGPSocket * PGPSocketRef; + +/* + * Unix and Windows share the same Berkley socket interface. This isn't + * the most efficient Windows implmentation of TCP/IP, but it is + * compatable with UNIX berkley sockets, making cross-platform possible. + * + * Trying to write cross-platform win32 TCP/IP code using all the fancy + * dancy Win32 network functions would be nearly impossible IMHO + * + * The Mac doesn't have the berkley stuff, so we roll our own for all + * of the structures. + * + * Start with Unix and Win32 + */ +#if PGP_UNIX || PGP_WIN32 + +# define kInvalidPGPSocketRef ((PGPSocketRef) (~0)) + + typedef struct hostent PGPHostEntry; + typedef struct protoent PGPProtocolEntry; + typedef struct servent PGPServiceEntry; + typedef struct sockaddr_in PGPSocketAddressInternet; + typedef struct sockaddr PGPSocketAddress; + typedef struct in_addr PGPInternetAddress; + typedef fd_set PGPSocketSet; + typedef struct timeval PGPSocketsTimeValue; + +# define PGPSOCKETSET_CLEAR(socketRef, set) FD_CLR((int) (socketRef), (set)) +# define PGPSOCKETSET_SET(socketRef, set) FD_SET((int) (socketRef), (set)) +# define PGPSOCKETSET_ZERO(set) FD_ZERO((set)) +# define PGPSOCKETSET_ISSET(socketRef, set) FD_ISSET((int) (socketRef), (set)) + + /* Address families */ + enum { + kPGPAddressFamilyUnspecified = AF_UNSPEC, + kPGPAddressFamilyInternet = AF_INET + }; + + /* Protocol families */ + enum { + kPGPProtocolFamilyInternet = PF_INET + }; + + /* Types */ + enum { + kPGPSocketTypeStream = SOCK_STREAM, + kPGPSocketTypeDatagram = SOCK_DGRAM + }; + + /* Commands for PGPIOControlSocket */ + enum { + kPGPSocketCommandGetUnreadData = FIONREAD + }; + + /* Levels for PGPGetSocketOptions and PGPSetSocketOptions */ + enum { + kPGPSocketOptionLevelSocket = SOL_SOCKET + }; + + /* Options for PGPGetSocketOptions and PGPSetSocketOptions */ +/* On Linux (2.0.24), include has SOL_SOCKET and SO_TYPE, */ +/* but unclear as to what would correspond to SO_ACCEPTCONN, if any. */ +#if PGP_UNIX_LINUX +/* #ifndef SO_ACCEPTCONN */ +#define SO_ACCEPTCONN 0 +/* #endif */ /* SO_ACCEPTCONN */ +#endif /* PGP_UNIX_LINUX */ + enum { + kPGPSocketOptionAcceptingConnections = SO_ACCEPTCONN, + kPGPSocketOptionType = SO_TYPE + }; + + /* Protocols */ + enum { + kPGPTCPProtocol = IPPROTO_TCP, + kPGPUDPProtocol = IPPROTO_UDP + }; + + /* Send flags */ + enum { + kPGPSendFlagNone = 0 + }; + + /* Receive flags */ + enum { + kPGPReceiveFlagNone = 0 + }; + + /* Internet Addresses */ + enum { + kPGPInternetAddressAny = INADDR_ANY + }; + +#endif /* PGP_UNIX || PGP_WIN32 */ + +/* + * Onto the Mac, where we need to create our own versions of the various + * structures. + */ +#if PGP_MACINTOSH + +# define kInvalidPGPSocketRef ((PGPSocketRef) NULL) + + typedef struct PGPInternetAddress { + union { + struct { + PGPByte s_b1; + PGPByte s_b2; + PGPByte s_b3; + PGPByte s_b4; + } S_un_b; + struct { + PGPUInt16 s_w1; + PGPUInt16 s_w2; + } S_un_w; + PGPUInt32 S_addr; + } S_un; +# define s_addr S_un.S_addr + } PGPInternetAddress; + + typedef struct PGPSocketAddressInternet { + PGPInt16 sin_family; + PGPUInt16 sin_port; + PGPInternetAddress sin_addr; + PGPByte sin_zero[8]; + } PGPSocketAddressInternet; + + typedef struct PGPSocketAddress { + PGPUInt16 sa_family; + PGPByte sa_data[14]; + } PGPSocketAddress; + + typedef struct PGPHostEntry { + char * h_name; + char ** unused; + PGPInt16 h_addrtype; + PGPInt16 h_length; + char ** h_addr_list; +# define h_addr h_addr_list[0] + } PGPHostEntry; + + typedef struct PGPProtocolEntry { + char * p_name; + char ** p_aliases; + PGPInt16 p_proto; + } PGPProtocolEntry; + + typedef struct PGPServiceEntry { + char * s_name; + char ** s_aliases; + PGPUInt16 s_port; + char * s_proto; + } PGPServiceEntry; + + /* Select types and defines */ +# ifndef PGPSOCKETSET_SETSIZE +# define PGPSOCKETSET_SETSIZE 64 +# endif + + typedef struct PGPSocketSet { + PGPUInt16 fd_count; + PGPSocketRef fd_array[PGPSOCKETSET_SETSIZE]; + } PGPSocketSet; + +# define PGPSOCKETSET_CLEAR(socketRef, set) do { \ + PGPUInt16 __i; \ + for (__i = 0; __i < ((PGPSocketSet * (set))->fd_count; __i++) { \ + if (((PGPSocketSet *) (set))->fd_array[__i] == socketRef) { \ + while (__i < (((PGPSocketSet *) (set))->fd_count - 1)) { \ + ((PGPSocketSet *) (set))->fd_array[__i] = \ + ((PGPSocketSet *) (set))->fd_array[__i + 1]; \ + __i++; \ + } \ + ((PGPSocketSet *) (set))->fd_count--; \ + break; \ + } \ + } \ + } while (0) + +# define PGPSOCKETSET_SET(socketRef, set) do { \ + if (((PGPSocketSet *) (set))->fd_count < PGPSOCKETSET_SETSIZE) { \ + ((PGPSocketSet *) (set))->fd_array[((PGPSocketSet *) \ + (set))->fd_count++] = (socketRef); \ + } \ + } while (0) + +# define PGPSOCKETSET_ZERO(set) (((PGPSocketSet *) (set))->fd_count = 0) + + PGPInt32 __PGPSocketsIsSet(PGPSocketRef, PGPSocketSet *); + +# define PGPSOCKETSET_ISSET(socketRef, set) __PGPSocketsIsSet( \ + (socketRef),(set)) + + typedef struct PGPSocketsTimeValue { + PGPInt32 tv_sec; /* seconds */ + PGPInt32 tv_usec; /* and microseconds */ + } PGPSocketsTimeValue; + + /* Address families */ + enum { + kPGPAddressFamilyUnspecified = 0, + kPGPAddressFamilyInternet = 2 + }; + + /* Protocol families */ + enum { + kPGPProtocolFamilyInternet = kPGPAddressFamilyInternet + }; + + /* Types */ + enum { + kPGPSocketTypeStream = 1, + kPGPSocketTypeDatagram = 2 + }; + + /* Commands for PGPIOControlSocket */ + enum { + kPGPSocketCommandGetUnreadData = (0x40000000 + | (((long) sizeof(PGPUInt32) & 0x7F) << 16) | ('f' << 8) | 127) + }; + + /* Levels for PGPGetSocketOptions and PGPSetSocketOptions */ + enum { + kPGPSocketOptionLevelSocket = 0xFFFFFFFF + }; + + /* Options for PGPGetSocketOptions and PGPSetSocketOptions */ + enum { + kPGPSocketOptionAcceptingConnections = 0x00000002, + kPGPSocketOptionType = 0x00001008 + }; + + /* Protocols */ + enum { + kPGPTCPProtocol = 6, + kPGPUDPProtocol = 17 + }; + + /* Send flags */ + enum { + kPGPSendFlagNone = 0 + }; + + /* Receive flags */ + enum { + kPGPReceiveFlagNone = 0 + }; + + /* Internet Addresses */ + enum { + kPGPInternetAddressAny = 0x00000000 + }; + +#endif /* PGP_MACINTOSH */ + +/* + * Some global things for all platforms + */ + +#define PGPSocketRefIsValid(ref) ((ref) != kInvalidPGPSocketRef) + +typedef struct PGPSocketsThreadStorage * PGPSocketsThreadStorageRef; +# define kInvalidPGPSocketsThreadStorageRef \ + ((PGPSocketsThreadStorageRef) NULL) +#define PGPSocketsThreadStorageRefIsValid(ref) \ + ((ref) != kInvalidPGPSocketsThreadStorageRef) + +/* Errors */ +#define kPGPSockets_Error -1 + +/* Net byte ordering macros (PGP_WORDSBIGENDIAN defined by configure) */ +#if PGP_WORDSBIGENDIAN +# define PGPHostToNetLong(x) (x) +# define PGPHostToNetShort(x) (x) +# define PGPNetToHostLong(x) (x) +# define PGPNetToHostShort(x) (x) +#else + PGPInt32 PGPHostToNetLong(PGPInt32 x); + PGPInt16 PGPHostToNetShort(PGPInt16 x); + PGPInt32 PGPNetToHostLong(PGPInt32 x); + PGPInt16 PGPNetToHostShort(PGPInt16 x); +#endif /* PGP_WORDSBIGENDIAN */ + +/* + * Shared function interface (except for idle handler code) + */ + +/* + * Use the idle event handler to receive periodic idle events during + * network calls. Usually this is used only in non-preemptive multi-tasking + * OSes to allow yielding in threads. Pre-emptive multi-tasking systems + * should probably not use the call as it interrupts the efficient wait state + * of threads waiting on network calls. + * + * Idle event handlers need to be added on a per thread basis. + * + * Returning an error from the idle event handler will cause the socket + * that is blocking to close. + * + */ +PGPError PGPSetSocketsIdleEventHandler( + PGPEventHandlerProcPtr inCallback, + PGPUserValue inUserData); + +PGPError PGPGetSocketsIdleEventHandler( + PGPEventHandlerProcPtr * outCallback, + PGPUserValue * outUserData); + +/* Static storage creation */ +PGPError PGPSocketsCreateThreadStorage( + PGPSocketsThreadStorageRef * outPreviousStorage); +PGPError PGPSocketsDisposeThreadStorage( + PGPSocketsThreadStorageRef inPreviousStorage); + +/* Stack based class for saving and restoring thread storage */ +#ifdef __cplusplus /* [ */ +class StPGPPreserveSocketsStorage { +public: + StPGPPreserveSocketsStorage() : mStorage(NULL) + { PGPSocketsCreateThreadStorage(&mStorage); } + ~StPGPPreserveSocketsStorage() + { PGPSocketsDisposeThreadStorage(mStorage); } + +protected: + PGPSocketsThreadStorageRef mStorage; +}; +#endif /* ] __cplusplus */ + + +/* Initialization and termination */ +PGPError PGPSocketsInit(void); +void PGPSocketsCleanup(void); + +/* Socket creation and destruction */ +PGPSocketRef PGPOpenSocket(PGPInt32 inAddressFamily, PGPInt32 inSocketType, + PGPInt32 inSocketProtocol); +PGPInt32 PGPCloseSocket(PGPSocketRef inSocketRef); + +/* Endpoint binding */ +PGPInt32 PGPBindSocket(PGPSocketRef inSocketRef, + const PGPSocketAddress * inAddress, + PGPInt32 inAddressLength); +PGPInt32 PGPConnect(PGPSocketRef inSocketRef, + const PGPSocketAddress * inServerAddress, + PGPInt32 inAddressLength); + +/* Send functions */ +PGPInt32 PGPSend(PGPSocketRef inSocketRef, const void * inBuffer, + PGPInt32 inBufferLength, PGPInt32 inFlags); +PGPInt32 PGPWrite(PGPSocketRef inSocketRef, const void * inBuffer, + PGPInt32 inBufferLength); +PGPInt32 PGPSendTo(PGPSocketRef inSocketRef, const void * inBuffer, + PGPInt32 inBufferLength, PGPInt32 inFlags, + PGPSocketAddress * inAddress, + PGPInt32 inAddressLength); + +/* Receive functions */ +PGPInt32 PGPReceive(PGPSocketRef inSocketRef, void * outBuffer, + PGPInt32 inBufferSize, PGPInt32 inFlags); +PGPInt32 PGPRead(PGPSocketRef inSocketRef, void * outBuffer, + PGPInt32 inBufferSize); +PGPInt32 PGPReceiveFrom(PGPSocketRef inSocketRef, void * outBuffer, + PGPInt32 inBufferSize, PGPInt32 inFlags, + PGPSocketAddress * outAddress, + PGPInt32 * ioAddressLength); + +/* Server functions */ +PGPInt32 PGPListen(PGPSocketRef inSocketRef, PGPInt32 inMaxBacklog); +PGPSocketRef PGPAccept(PGPSocketRef inSocketRef, + PGPSocketAddress * outAddress, + PGPInt32 * ioAddressLength); + +/* Select */ +/* Note that inNumSetCount is not used under Mac and Windows */ +PGPInt32 PGPSelect(PGPInt32 inNumSetCount, + PGPSocketSet * ioReadSet, + PGPSocketSet * ioWriteSet, + PGPSocketSet * ioErrorSet, + const PGPSocketsTimeValue * inTimeout); + +/* DNS and protocol services */ +PGPHostEntry * PGPGetHostByName(const char * inName); +PGPHostEntry * PGPGetHostByAddress(const char* inAddress, + PGPInt32 inLength, + PGPInt32 inType); +PGPInt32 PGPGetHostName(char * outName, PGPInt32 inNameLength); +PGPProtocolEntry * PGPGetProtocolByName(const char * inName); +PGPProtocolEntry * PGPGetProtocolByNumber(PGPInt32 inNumber); +PGPServiceEntry * PGPGetServiceByName(const char * inName, + const char * inProtocol); +PGPServiceEntry * PGPGetServiceByPort(PGPInt32 inPort, + const char * inProtocol); + +/* Error reporting */ +PGPError PGPGetLastSocketsError(void); + +/* Utilities */ +PGPInt32 PGPGetSocketName(PGPSocketRef inSocketRef, + PGPSocketAddress * outName, + PGPInt32 * ioNameLength); +PGPInt32 PGPGetPeerName(PGPSocketRef inSocketRef, + PGPSocketAddress * outName, + PGPInt32 * ioNameLength); +PGPUInt32 PGPDottedToInternetAddress(const char * inAddress); +char * PGPInternetAddressToDottedString(PGPInternetAddress inAddress); + +/* Control and options */ +PGPInt32 PGPIOControlSocket(PGPSocketRef inSocketRef, + PGPInt32 inCommand, PGPUInt32 * ioParam); +PGPInt32 PGPGetSocketOptions(PGPSocketRef inSocketRef, PGPInt32 inLevel, + PGPInt32 inOptionName, + char * outOptionValue, + PGPInt32 * ioOptionLength); +PGPInt32 PGPSetSocketOptions(PGPSocketRef inSocketRef, PGPInt32 inLevel, + PGPInt32 inOptionName, + const char * inOptionValue, + PGPInt32 inOptionLength); + +/* TLS */ +PGPError PGPSocketsEstablishTLSSession(PGPSocketRef inSocketRef, + PGPtlsSessionRef inTLSSession); + + +#if PRAGMA_IMPORT_SUPPORTED +#pragma import reset +#endif + +PGP_END_C_DECLARATIONS + +#endif /* Included_pgpSockets_h */ diff --git a/CryptoPP/PGPw/sdk6/include/pgpSymmetricCipher.h b/CryptoPP/PGPw/sdk6/include/pgpSymmetricCipher.h new file mode 100644 index 0000000..b1dec16 --- /dev/null +++ b/CryptoPP/PGPw/sdk6/include/pgpSymmetricCipher.h @@ -0,0 +1,122 @@ +/*____________________________________________________________________________ + pgpSymmetricCipher.h + + Copyright (C) 1997 Network Associates Inc. and affiliated companies. + All rights reserved. + + public header file for symmetric ciphers + + $Id: pgpSymmetricCipher.h,v 1.22 1999/03/10 02:58:47 heller Exp $ +____________________________________________________________________________*/ +#ifndef Included_pgpSymmetricCipher_h /* [ */ +#define Included_pgpSymmetricCipher_h + +#include "pgpPubTypes.h" +#include "pgpMemoryMgr.h" + +PGP_BEGIN_C_DECLARATIONS +#if PRAGMA_IMPORT_SUPPORTED +#pragma import on +#endif + + + +/*____________________________________________________________________________ + Create a new cipher of the specified algorithm. Cannot be used until + PGPSetSymmetricCipherKey() has been called. + + If the algorithm is not available then kPGPError_AlgorithmNotAvailable is + returned. + + Existing algorithms have only one key size. Values: + kPGPCipherAlgorithm_CAST5 128 / 8 = 16 + kPGPCipherAlgorithm_3DES 192 / 8 = 24 + kPGPCipherAlgorithm_IDEA 128 / 8 = 16 + In the future symmetric ciphers could be added that have different key + sizes for the same algorithm. +____________________________________________________________________________*/ +PGPError PGPNewSymmetricCipherContext( PGPMemoryMgrRef memoryMgr, + PGPCipherAlgorithm algorithm, PGPSize keySizeInBytes, + PGPSymmetricCipherContextRef *outRef ); + + +/*____________________________________________________________________________ + Disposal clears all data in memory before releasing it. +____________________________________________________________________________*/ +PGPError PGPFreeSymmetricCipherContext( PGPSymmetricCipherContextRef ref ); + + +/*____________________________________________________________________________ + Make an exact copy of the cipher, including the key. +____________________________________________________________________________*/ +PGPError PGPCopySymmetricCipherContext( PGPSymmetricCipherContextRef ref, + PGPSymmetricCipherContextRef *outRef ); + + +/*____________________________________________________________________________ + The key must be set before using; a cipher can be repeatedly reset and + reused with different keys to avoid having to create and destroy new + contexts each time (and it's also cryptographically better not to reuse + a key). + + kKey size is implicit based on algorithm. 'key' is *copied*. Caller + may want to destroy the original after passing it in. +____________________________________________________________________________*/ +PGPError PGPInitSymmetricCipher( PGPSymmetricCipherContextRef ref, + const void *key ); + +/*____________________________________________________________________________ + Wipe any sensitive data in the cipher. Cipher remains alive, but + key must be set before any data is encrypted. +____________________________________________________________________________*/ +PGPError PGPWipeSymmetricCipher( PGPSymmetricCipherContextRef ref ); + + +/*____________________________________________________________________________ + "Wash" the symmetric cipher +____________________________________________________________________________*/ +PGPError PGPWashSymmetricCipher( PGPSymmetricCipherContextRef ref, + void const *buf, PGPSize len); + + +/*____________________________________________________________________________ + Encrypt or decrypt one "block" of data. The block size is determined + by the cipher (see PGPGetSymmetricCipherBlockSize()). +____________________________________________________________________________*/ +PGPError PGPSymmetricCipherEncrypt( PGPSymmetricCipherContextRef ref, + const void *in, void *out ); + +PGPError PGPSymmetricCipherDecrypt( PGPSymmetricCipherContextRef ref, + const void *in, void *out ); + + + + +/*____________________________________________________________________________ + Determine key and block size for specified algorithm. Stateless routine + does not need a context. +____________________________________________________________________________*/ +PGPError PGPGetSymmetricCipherSizes( + PGPSymmetricCipherContextRef ref, + PGPSize *keySize , PGPSize *blockSize ); + + + +#if PRAGMA_IMPORT_SUPPORTED +#pragma import reset +#endif +PGP_END_C_DECLARATIONS + + + +#endif /* ] Included_pgpSymmetricCipher_h */ + + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk6/include/pgpTLS.h b/CryptoPP/PGPw/sdk6/include/pgpTLS.h new file mode 100644 index 0000000..ec2903a --- /dev/null +++ b/CryptoPP/PGPw/sdk6/include/pgpTLS.h @@ -0,0 +1,316 @@ +/*____________________________________________________________________________ + Copyright (C) 1997-1999 Network Associates, Inc. + All rights reserved. + + $Id: pgpTLS.h,v 1.32 1999/01/25 11:31:49 wprice Exp $ +____________________________________________________________________________*/ +#ifndef Included_PGPtls_h /* [ */ +#define Included_PGPtls_h + +#include "pgpPubTypes.h" + +PGP_BEGIN_C_DECLARATIONS +#if PRAGMA_IMPORT_SUPPORTED +#pragma import on +#endif + + +typedef struct PGPtlsContext * PGPtlsContextRef; +typedef const struct PGPtlsContext * PGPtlsConstContextRef; + +#define kInvalidPGPtlsContextRef ((PGPtlsContextRef) NULL) +#define PGPtlsContextRefIsValid( ref ) ( (ref) != kInvalidPGPtlsContextRef ) + +typedef struct PGPtlsSession * PGPtlsSessionRef; +typedef const struct PGPtlsSession * PGPtlsConstSessionRef; + +#define kInvalidPGPtlsSessionRef ((PGPtlsSessionRef) NULL) +#define PGPtlsSessionRefIsValid( ref ) ( (ref) != kInvalidPGPtlsSessionRef ) + + +typedef PGPFlags PGPtlsFlags; +#define kPGPtlsFlags_ServerSide 0x01 +#define kPGPtlsFlags_ClientSide 0x02 +#define kPGPtlsFlags_RequestClientCert 0x04 +#define kPGPtlsFlags_NonBlockingIO 0x08 + +enum PGPtlsCipherSuiteNum_ +{ + kPGPtls_TLS_NULL_WITH_NULL_NULL = 0, + kPGPtls_TLS_PGP_DHE_DSS_WITH_CAST_CBC_SHA = 1, + kPGPtls_TLS_PGP_DHE_RSA_WITH_CAST_CBC_SHA = 2, + kPGPtls_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA = 3, + kPGPtls_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = 4, + kPGPtls_TLS_RSA_WITH_3DES_EDE_CBC_SHA = 5, + kPGPtls_TLS_RSA_WITH_IDEA_CBC_SHA = 6, + kPGPtls_TLS_PGP_RSA_WITH_CAST_CBC_SHA = 7, + kPGPtls_TLS_PGP_DHE_DSS_WITH_NULL_SHA = 8, + kPGPtls_TLS_DHE_DSS_WITH_NULL_SHA = 9, + + PGP_ENUM_FORCE( PGPtlsCipherSuiteNum_ ) +}; +PGPENUM_TYPEDEF( PGPtlsCipherSuiteNum_, PGPtlsCipherSuiteNum ); + +enum PGPtlsProtocolState_ +{ + kPGPtls_IdleState = 0, + kPGPtls_FatalErrorState = 1, + kPGPtls_ClosedState = 2, + kPGPtls_HandshakeState = 3, + kPGPtls_ReadyState = 4, + + PGP_ENUM_FORCE( PGPtlsProtocolState_ ) +}; +PGPENUM_TYPEDEF( PGPtlsProtocolState_, PGPtlsProtocolState ); + +enum PGPtlsPrime_ +{ + kPGPtls_DHPrime1024 = 0, + kPGPtls_DHPrime1536 = 1, + kPGPtls_DHPrime2048 = 2, + kPGPtls_DHPrime3072 = 3, + kPGPtls_DHPrime4096 = 4, + + PGP_ENUM_FORCE( PGPtlsPrime_ ) +}; +PGPENUM_TYPEDEF( PGPtlsPrime_, PGPtlsPrime ); + +enum PGPtlsAlert_ +{ + kPGPtls_AT_CloseNotify = 0, + kPGPtls_AT_UnexpectedMessage = 10, /* FATAL */ + kPGPtls_AT_BadRecordMAC = 20, /* FATAL */ + kPGPtls_AT_DecryptionFailed = 21, /* FATAL */ + kPGPtls_AT_RecordOverflow = 22, /* FATAL */ + kPGPtls_AT_DecompressionFailure = 30, /* FATAL */ + kPGPtls_AT_HandshakeFailure = 40, /* FATAL */ + kPGPtls_AT_NoCertificate = 41, /* SSL3 */ + kPGPtls_AT_BadCertificate = 42, + kPGPtls_AT_UnsupportedCert = 43, + kPGPtls_AT_CertRevoked = 44, + kPGPtls_AT_CertExpired = 45, + kPGPtls_AT_CertUnknown = 46, + kPGPtls_AT_IllegalParameter = 47, /* FATAL */ + kPGPtls_AT_UnknownCA = 48, /* FATAL */ + kPGPtls_AT_AccessDenied = 49, /* FATAL */ + kPGPtls_AT_DecodeError = 50, /* FATAL */ + kPGPtls_AT_DecryptError = 51, + kPGPtls_AT_ExportRestriction = 60, /* FATAL */ + kPGPtls_AT_ProtocolVersion = 70, /* FATAL */ + kPGPtls_AT_InsufficientSecurity = 71, /* FATAL */ + kPGPtls_AT_InternalError = 80, /* FATAL */ + kPGPtls_AT_UserCancelled = 90, + kPGPtls_AT_NoRenegotiation = 100, + + kPGPtls_AT_None = 255, + + PGP_ENUM_FORCE( PGPtlsAlert_ ) +}; +PGPENUM_TYPEDEF( PGPtlsAlert_, PGPtlsAlert ); + +/* The Send and Receive function pointers should return + kPGPError_TLSWouldBlock when the socket is non-blocking and the + call would block. The Send and Receive functions passed in will + need to translate the platform-specific socket error in appropriate + cases by using calls such as WSAGetLastError() on Win32. Remember + to call PGPtlsSendQueueIdle for non-blocking sockets also if + kPGPError_TLSWouldBlock is returned from a send on a non-blocking + socket. */ + +typedef PGPInt32 (* PGPtlsReceiveProcPtr)(void *inData, void *outBuffer, + PGPInt32 inBufferSize); +typedef PGPInt32 (* PGPtlsSendProcPtr)(void *inData, const void *inBuffer, + PGPInt32 inBufferLength); + + +PGPError PGPNewTLSContext( PGPContextRef context, + PGPtlsContextRef *outRef ); + +PGPError PGPFreeTLSContext( PGPtlsContextRef ref ); + +/*____________________________________________________________________________ + The following function activates or deactivates the session key cache + for TLS sessions. This defaults to on but can be deactivated with this + function to force all connections to proceed through the entire + handshake. +____________________________________________________________________________*/ +PGPError PGPtlsSetCache( PGPtlsContextRef ref, PGPBoolean useCache ); + +PGPError PGPtlsClearCache( PGPtlsContextRef ref ); + +PGPError PGPNewTLSSession( PGPtlsContextRef ref, + PGPtlsSessionRef *outRef ); + +PGPError PGPFreeTLSSession( PGPtlsSessionRef ref ); + +PGPError PGPCopyTLSSession( PGPtlsSessionRef ref, PGPtlsSessionRef *outRef ); + +/* Default options are client side and no client cert request */ +PGPError PGPtlsSetProtocolOptions( PGPtlsSessionRef ref, + PGPtlsFlags options ); + + +/*____________________________________________________________________________ + The following function must be called to cleanly close a TLS + connection. If it is not called, the session will not be able + to be resumed from the session cache. + + In the event the application determines any problem with the + connection such as the remote key not being valid, call this + function with dontCache set to true in order to not cache the + session keys. +____________________________________________________________________________*/ +PGPError PGPtlsClose( PGPtlsSessionRef ref, + PGPBoolean dontCache ); + +/*____________________________________________________________________________ + The following function must be called to initiate the PGPtls session. + Once a TLS session has been assigned to a socket, no data can be sent + over that socket by the application until the handshake is completed. + Handshake completion is indicated by completion of this call without + error or by checking the state of the PGPtlsSession. It will be + kPGPtls_ReadyState when the application layer may send and receive + data securely. + + This function performs all negotiation of the TLS connection. +____________________________________________________________________________*/ +PGPError PGPtlsHandshake( PGPtlsSessionRef ref ); + +/*____________________________________________________________________________ + The following function should be called before PGPtlsHandshake. + In the general case, the remoteID will be an IP address. This + is provided to PGPtls in order to allow it to cache the current + session and be able to look it up later. If the remoteID passed + into a future session is the same as a previously cached session, + PGPtls will attempt to resume the session. +____________________________________________________________________________*/ +PGPError PGPtlsSetRemoteUniqueID( PGPtlsSessionRef ref, + PGPUInt32 remoteID ); + +/*____________________________________________________________________________ + The following function sets the local private authenticating key. + + The passphrase and key are retained in memory. By default, no + key is specified and a client side session will return no key in the + client key exchange message to the server. + It is an error not to specify a key on a server side TLS session. + This function must be passed either PGPOPassphrase or PGPOPasskeyBuffer. + You may pass in just a PGP key, PGP w/ X.509 cert, or both -- and they + must be the same -- the cert must be from the key. For an X.509 cert, + the inCertChain keyset must contain the keys of all keys in the + certificate chain for that certificate up to the root. To disable X.509 + certs, simply pass nothing (ie. kPGPInvalidSigRef). The inCertChain + keyset must remain valid for the lifetime of the TLS connection. +____________________________________________________________________________*/ +PGPError PGPtlsSetLocalPrivateKey( PGPtlsSessionRef ref, + PGPKeyRef inKey, + PGPSigRef inX509Cert, + PGPKeySetRef inCertChain, + PGPOptionListRef firstOption, ... ); + +/*____________________________________________________________________________ + The following function sets the preferred cipher suite. + + There is no guarantee that cipher will actually be negotiated, + but it will be attempted in preference to others. +____________________________________________________________________________*/ +PGPError PGPtlsSetPreferredCipherSuite( PGPtlsSessionRef ref, + PGPtlsCipherSuiteNum cipher ); + +/*____________________________________________________________________________ + The following function sets the desired DH prime. + + The requested primes are drawn from a set of primes hard-coded + into PGPtls. New primes can be added in a fully compatible + fashion since the server sends the prime to the client, but this + version of the API does not support passing in a desired prime. The + default prime if this function is not called is kPGPtls_DHPrime2048. +____________________________________________________________________________*/ +PGPError PGPtlsSetDHPrime( PGPtlsSessionRef ref, + PGPtlsPrime prime ); + +/*____________________________________________________________________________ + The following function gets the authenticated remote key after a + successful handshake. You must call this function after a successful + handshake to verify that the remote key is authorized to make the + connection. +____________________________________________________________________________*/ +PGPError PGPtlsGetRemoteAuthenticatedKey( PGPtlsSessionRef ref, + PGPKeyRef * outKey, + PGPKeySetRef * outKeySet ); + +/*____________________________________________________________________________ + The following function returns the negotiated symmetric cipher. + + This function will return an error if called before a successful + handshake. +____________________________________________________________________________*/ +PGPError PGPtlsGetNegotiatedCipherSuite( PGPtlsSessionRef ref, + PGPtlsCipherSuiteNum *outCipher ); + +PGPError PGPtlsGetState( PGPtlsSessionRef ref, + PGPtlsProtocolState *outState ); + +/*____________________________________________________________________________ + The following two functions process data through TLS. + + It is an error to call these functions without having set a + Read function pointer or Write function pointer. Most applications + will never need to use these functions as the function pointers + are automatically configured by PGPsockets, and these functions + are automatically called by the PGPsockets implementations of + PGPWrite and PGPRead whenever a PGPtlsSessionRef has been set for + a given socket. +____________________________________________________________________________*/ +PGPError PGPtlsReceive( PGPtlsSessionRef ref, + void * outBuffer, + PGPSize * bufferSize ); + +PGPError PGPtlsSend( PGPtlsSessionRef ref, + const void * inBuffer, + PGPSize inBufferLength ); + +PGPError PGPtlsSetReceiveCallback( PGPtlsSessionRef ref, + PGPtlsReceiveProcPtr tlsReceiveProc, + void * inData ); + +PGPError PGPtlsSetSendCallback( PGPtlsSessionRef ref, + PGPtlsSendProcPtr tlsSendProc, + void * inData ); + + +/*____________________________________________________________________________ + The following function is necessary *only* on a non-blocking socket. + If a call to PGPtlsSend returns kPGPError_TLSWouldBlock, call + the following function repeatedly until that error is no longer + returned in order to make sure data is sent. Another call to + PGPtlsSend will also call this function automatically and queue + any new data if necessary. +____________________________________________________________________________*/ +PGPError PGPtlsSendQueueIdle( PGPtlsSessionRef ref ); + +PGPSize PGPtlsReceiveBufferSize( PGPtlsSessionRef ref ); + +/*____________________________________________________________________________ + The following function gets the ID of the fatal alert which caused + the TLS session to abort and go into the kPGPtls_FatalErrorState. +____________________________________________________________________________*/ +PGPError PGPtlsGetAlert( PGPtlsSessionRef ref, PGPtlsAlert *outAlert ); + + +#if PRAGMA_IMPORT_SUPPORTED +#pragma import reset +#endif +PGP_END_C_DECLARATIONS + +#endif /* ] Included_PGPtls_h */ + + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk6/include/pgpUserInterface.h b/CryptoPP/PGPw/sdk6/include/pgpUserInterface.h new file mode 100644 index 0000000..8d2e05d --- /dev/null +++ b/CryptoPP/PGPw/sdk6/include/pgpUserInterface.h @@ -0,0 +1,290 @@ +/*____________________________________________________________________________ + Copyright (C) 1997 Network Associates Inc. and affiliated companies. + All rights reserved. + + This file contains the prototypes for functions which use UI to interact + with the user. + + $Id: pgpUserInterface.h,v 1.40 1999/03/10 02:59:37 heller Exp $ +____________________________________________________________________________*/ + +#ifndef Included_pgpUserInterface_h /* [ */ +#define Included_pgpUserInterface_h + +#include "pgpPubTypes.h" +#include "pgpGroups.h" + +#if PGP_WIN32 +#include "windows.h" +#endif + +PGP_BEGIN_C_DECLARATIONS + +#if PRAGMA_IMPORT_SUPPORTED +#pragma import on +#endif + +#if PRAGMA_ALIGN_SUPPORTED +#pragma options align=mac68k +#endif + +enum PGPAdditionalRecipientRequestEnforcement_ +{ + kPGPARREnforcement_Invalid = 0, + kPGPARREnforcement_None = 1, + kPGPARREnforcement_Warn = 2, + kPGPARREnforcement_Strict = 3, + + PGP_ENUM_FORCE( PGPAdditionalRecipientRequestEnforcement_ ) +}; +PGPENUM_TYPEDEF( PGPAdditionalRecipientRequestEnforcement_, + PGPAdditionalRecipientRequestEnforcement ); + +enum PGPRecipientSpecType_ +{ + kPGPRecipientSpecType_Invalid = 0, + kPGPRecipientSpecType_Key = 1, + kPGPRecipientSpecType_UserID = 2, + kPGPRecipientSpecType_KeyID = 3, + + PGP_ENUM_FORCE( PGPRecipientSpecType_ ) +}; +PGPENUM_TYPEDEF( PGPRecipientSpecType_, PGPRecipientSpecType ); + +typedef struct PGPRecipientSpec +{ + PGPRecipientSpecType type; + PGPBoolean locked; + PGPBoolean reserved8[3]; /* Must be zero */ + PGPUInt32 reserved32[3]; /* Must be zero */ + + union + { + PGPKeyRef key; + char userIDStr[256]; /* Null terminated string */ + + struct + { + PGPKeyID keyID; + PGPPublicKeyAlgorithm algorithm; + } id; + + } u; + +} PGPRecipientSpec; + +typedef struct PGPKeyServerSpec +{ + PGPKeyServerRef server; + const char *serverName; /* Optional */ + PGPUInt32 reserved[5]; /* Must be zero */ + +} PGPKeyServerSpec; + +#if PRAGMA_ALIGN_SUPPORTED +#pragma options align=reset +#endif + +PGPError PGPRecipientDialog( + PGPContextRef context, + PGPKeySetRef allKeys, + PGPBoolean alwaysDisplayDialog, + PGPKeySetRef *recipientKeys, + PGPOptionListRef firstOption, ... ); + +PGPError PGPPassphraseDialog( + PGPContextRef context, + PGPOptionListRef firstOption, ... ); + +PGPError PGPConfirmationPassphraseDialog( + PGPContextRef context, + PGPOptionListRef firstOption, ... ); + +PGPError PGPKeyPassphraseDialog( + PGPContextRef context, + PGPKeyRef theKey, + PGPOptionListRef firstOption, ... ); + +PGPError PGPSigningPassphraseDialog( + PGPContextRef context, + PGPKeySetRef allKeys, + PGPKeyRef *signingKey, + PGPOptionListRef firstOption, ... ); + +PGPError PGPDecryptionPassphraseDialog( + PGPContextRef context, + PGPKeySetRef recipientKeys, + PGPUInt32 keyIDCount, + const PGPKeyID keyIDList[], + PGPKeyRef *decryptionKey, + PGPOptionListRef firstOption, ... ); + +PGPError PGPConventionalEncryptionPassphraseDialog( + PGPContextRef context, + PGPOptionListRef firstOption, ... ); + +PGPError PGPConventionalDecryptionPassphraseDialog( + PGPContextRef context, + PGPOptionListRef firstOption, ... ); + +PGPError PGPOptionsDialog( + PGPContextRef context, + PGPOptionListRef firstOption, ... ); + +PGPError PGPCollectRandomDataDialog( + PGPContextRef context, + PGPUInt32 neededEntropyBits, + PGPOptionListRef firstOption, ... ); + +PGPError PGPSearchKeyServerDialog( + PGPContextRef context, + PGPUInt32 serverCount, + const PGPKeyServerSpec serverList[], + PGPtlsContextRef tlsContext, + PGPBoolean searchAllServers, + PGPKeySetRef *foundKeys, + PGPOptionListRef firstOption, ... ); + +PGPError PGPSendToKeyServerDialog( + PGPContextRef context, + const PGPKeyServerSpec *server, + PGPtlsContextRef tlsContext, + PGPKeySetRef keysToSend, + PGPKeySetRef *failedKeys, + PGPOptionListRef firstOption, ... ); + +/* +** Returns a value in the range 0-100 which crudely estimates +** the "quality" of a passphrase. +*/ + +PGPUInt32 PGPEstimatePassphraseQuality(const char *passphrase); + +/* General dialog options */ + +PGPOptionListRef PGPOUIDialogPrompt(PGPContextRef context, + const char *prompt); + +PGPOptionListRef PGPOUIWindowTitle(PGPContextRef context, + const char *title); + +PGPOptionListRef PGPOUIDialogOptions(PGPContextRef context, + PGPOptionListRef firstOption, ...); + +#if PGP_WIN32 +PGPOptionListRef PGPOUIParentWindowHandle(PGPContextRef context, + HWND hwndParent); +#endif + +/* All passphrase dialogs */ + +/* Caller should free passphrase with PGPFreeData() */ +PGPOptionListRef PGPOUIOutputPassphrase(PGPContextRef context, + char **passphrase); + +PGPOptionListRef PGPOUIMinimumPassphraseQuality(PGPContextRef context, + PGPUInt32 minimumPassphraseQuality); + +PGPOptionListRef PGPOUIMinimumPassphraseLength(PGPContextRef context, + PGPUInt32 minimumPassphraseLength); + +/* PGPConfirmationPassphraseDialog() options */ + +PGPOptionListRef PGPOUIShowPassphraseQuality(PGPContextRef context, + PGPBoolean showPassphraseQuality); + +/* PGPSigningPassphraseDialog() and PGPDecryptionPassphraseDialog() options */ + +PGPOptionListRef PGPOUIDefaultKey(PGPContextRef context, + PGPKeyRef defaultKey); + +PGPOptionListRef PGPOUIVerifyPassphrase(PGPContextRef context, + PGPBoolean verifyPassphrase); + +PGPOptionListRef PGPOUIFindMatchingKey(PGPContextRef context, + PGPBoolean findMatchingKey); + +PGPOptionListRef PGPOUITextUI(PGPContextRef context, PGPBoolean textUI); + +/* PGPRecipientDialog() options: */ + +PGPOptionListRef PGPOUIRecipientList(PGPContextRef context, + PGPUInt32 *recipientCount, + PGPRecipientSpec **recipientList); + +PGPOptionListRef PGPOUIDefaultRecipients(PGPContextRef context, + PGPUInt32 recipientCount, + const PGPRecipientSpec recipientList[]); + +PGPOptionListRef PGPOUIDisplayMarginalValidity(PGPContextRef context, + PGPBoolean displayMarginalValidity); + +PGPOptionListRef PGPOUIIgnoreMarginalValidity(PGPContextRef context, + PGPBoolean ignoreMarginalValidity); + +PGPOptionListRef PGPOUIRecipientGroups(PGPContextRef context, + PGPGroupSetRef groupSet); + +PGPOptionListRef PGPOUIEnforceAdditionalRecipientRequests( + PGPContextRef context, + PGPAdditionalRecipientRequestEnforcement enforcement, + PGPBoolean alwaysDisplayDialogWithARRs); + +/* PGPDecryptionPassphraseDialog() and PGPRecipientDialog() only: */ + +PGPOptionListRef PGPOUIKeyServerUpdateParams(PGPContextRef context, + PGPUInt32 serverCount, + const PGPKeyServerSpec serverList[], + PGPtlsContextRef tlsContext, + PGPBoolean searchBeforeDisplay, + PGPKeySetRef *foundKeys, + PGPOptionListRef firstOption, ...); + +/* Key server search dialog options */ + +PGPOptionListRef PGPOUIKeyServerSearchFilter(PGPContextRef context, + PGPFilterRef filter); + +PGPOptionListRef PGPOUIKeyServerSearchKey(PGPContextRef context, + PGPKeyRef key); + +PGPOptionListRef PGPOUIKeyServerSearchKeySet(PGPContextRef context, + PGPKeySetRef keySet); + +PGPOptionListRef PGPOUIKeyServerSearchKeyIDList(PGPContextRef context, + PGPUInt32 keyIDCount, const PGPKeyID keyIDList[] ); + +/* +** These options are used to build the options dialog and are only +** applicable for the PGPOptionsDialog() and PGPOUIDialogOptions() calls. +** The "description" parameters are optional. +*/ + +PGPOptionListRef PGPOUICheckbox(PGPContextRef context, PGPUInt32 itemID, + const char *title, const char *description, + PGPUInt32 initialValue, PGPUInt32 *resultPtr, + PGPOptionListRef firstOption, ...); + +PGPOptionListRef PGPOUIPopupList(PGPContextRef context, PGPUInt32 itemID, + const char *title, const char *description, + PGPUInt32 listItemCount, const char *listItems[], + PGPUInt32 initialValue, PGPUInt32 *resultPtr, + PGPOptionListRef firstOption, ...); + +#if PRAGMA_IMPORT_SUPPORTED +#pragma import reset +#endif + +PGP_END_C_DECLARATIONS + +#endif /* ] Included_pgpUserInterface_h */ + + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk6/include/pgpUtilities.h b/CryptoPP/PGPw/sdk6/include/pgpUtilities.h new file mode 100644 index 0000000..d92c999 --- /dev/null +++ b/CryptoPP/PGPw/sdk6/include/pgpUtilities.h @@ -0,0 +1,231 @@ +/*____________________________________________________________________________ + pgpUtilities.h + + Copyright (C) 1997 Network Associates Inc. and affiliated companies. + All rights reserved. + + This file contains miscellaneous utility functions needed for the PGPsdk. + + $Id: pgpUtilities.h,v 1.68 1999/03/25 01:46:38 heller Exp $ +____________________________________________________________________________*/ + +#ifndef Included_pgpUtilities_h /* [ */ +#define Included_pgpUtilities_h + +#if PGP_MACINTOSH /* [ */ +#include +#endif /* ] PGP_MACINTOSH */ + +#include "pgpPubTypes.h" +#include "pgpMemoryMgr.h" + +#include + + +#if PRAGMA_ALIGN_SUPPORTED +#pragma options align=mac68k /* [ */ +#endif + + +#if PGP_MACINTOSH /* [ */ + +#define kPGPMacFileCreator_Keys 'pgpK' +#define kPGPMacFileCreator_DecryptedBinary '????' +#define kPGPMacFileCreator_DecryptedText 'ttxt' +#define kPGPMacFileCreator_Tools 'pgpM' + +#define kPGPMacFileType_ArmorFile 'TEXT' +#define kPGPMacFileType_EncryptedData 'pgEF' +#define kPGPMacFileType_SignedData 'pgSF' +#define kPGPMacFileType_DetachedSig 'pgDS' +#define kPGPMacFileType_RandomSeed 'pgRS' +#define kPGPMacFileType_PrivRing 'pgRR' +#define kPGPMacFileType_PubRing 'pgPR' +#define kPGPMacFileType_Groups 'pgGR' +#define kPGPMacFileType_Preferences 'pref' +#define kPGPMacFileType_DecryptedText 'TEXT' +#define kPGPMacFileType_DecryptedBinary 'BINA' +#define kPGPMacFileType_KeyShares 'pgSK' +#define kPGPMacFileType_Exported509Keys 'pgX5' + +#endif /* ] PGP_MACINTOSH */ + +PGP_BEGIN_C_DECLARATIONS +#if PRAGMA_IMPORT_SUPPORTED +#pragma import on +#endif + +/*____________________________________________________________________________ + Context routines +____________________________________________________________________________*/ + +/*____________________________________________________________________________ + API version: + Top byte is major, next 3 nibbles minor, next 2 bug fix, + last nibble reserved: 0xMMmmmrrR + + example: 1.0.0 = 0x01000000 + + 0x01000000 SDK 1.0.0 + 0x02000000 SDK 1.1.0 + 0x02000010 SDK 1.1.1 + 0x03000000 SDK 1.5 + 0x03000010 SDK 1.5.1 + 0x03000020 SDK 1.5.2 + 0x03001000 SDK 1.6 + 0x03002000 SDK 1.7 + 0x03002010 SDK 1.7.1 +_____________________________________________________________________________*/ +#define kPGPsdkAPIVersion ( (PGPUInt32)0x03002010 ) +#define PGPMajorVersion( v ) ( ( ((PGPUInt32)(v)) & 0xFF000000 ) >> 24 ) +#define PGPMinorVersion( v ) ( ( ((PGPUInt32)(v)) & 0x00FFF000 ) >> 16 ) +#define PGPRevVersion( v ) ( ( ((PGPUInt32)(v)) & 0x00000FF0 ) >> 4 ) + +typedef struct PGPNewContextStruct +{ + /* sizeofStruct must be inited to sizeof( PGPNewContextStruct ) */ + PGPUInt32 sizeofStruct; + PGPMemoryMgrRef memoryMgr; +} PGPNewContextStruct; + + + +/* always pass kPGPsdkVersion */ +PGPError PGPNewContext( PGPUInt32 clientAPIVersion, + PGPContextRef *newContext ); +PGPError PGPNewContextCustom( PGPUInt32 clientAPIVersion, + PGPNewContextStruct const *custom, + PGPContextRef *newContext ); + +PGPError PGPFreeContext( PGPContextRef context ); + +PGPError PGPGetContextUserValue( PGPContextRef context, + PGPUserValue *userValue ); +PGPError PGPSetContextUserValue( PGPContextRef context, + PGPUserValue userValue ); + +PGPError PGPContextGetRandomBytes(PGPContextRef context, + void *buf, PGPSize len ); + + +PGPMemoryMgrRef PGPGetContextMemoryMgr( PGPContextRef context ); + + + +/*____________________________________________________________________________ + FileRefs +____________________________________________________________________________*/ + +PGPError PGPCopyFileSpec(PGPFileSpecRef fileRef, + PGPFileSpecRef *ref); +PGPError PGPFreeFileSpec(PGPFileSpecRef fileRef); + +#if PGP_MACINTOSH /* [ */ + +PGPError PGPNewFileSpecFromFSSpec(PGPContextRef context, + const FSSpec *spec, PGPFileSpecRef *ref); +PGPError PGPGetFSSpecFromFileSpec(PGPFileSpecRef fileRef, + FSSpec *spec); +#else + +PGPError PGPNewFileSpecFromFullPath( PGPContextRef context, + char const *path, PGPFileSpecRef *ref); + +/* *fullPathPtr ***must*** be freed with PGPFreeData */ +PGPError PGPGetFullPathFromFileSpec( PGPFileSpecRef fileRef, + char ** fullPathPtr); + +#endif /* ] PGP_MACINTOSH */ + + + +/*____________________________________________________________________________ + Time +____________________________________________________________________________*/ +PGPTime PGPGetTime(void); + +/* these use time_t type as returned by time() in Std C libraries */ +time_t PGPGetStdTimeFromPGPTime(PGPTime theTime); +PGPTime PGPGetPGPTimeFromStdTime(time_t theTime); + + +/* year, month, day may be NULL if desired */ +void PGPGetYMDFromPGPTime( PGPTime theTime, + PGPUInt16 *year, PGPUInt16 *month, PGPUInt16 *day ); + + +#if PGP_MACINTOSH /* [ */ +PGPUInt32 PGPTimeToMacTime(PGPTime theTime); +PGPTime PGPTimeFromMacTime(PGPUInt32 theTime); +#endif /* ] PGP_MACINTOSH */ + + + +/*____________________________________________________________________________ + MacBinary support +____________________________________________________________________________*/ + + +/*____________________________________________________________________________ + Examine the input file to see if it's a MacBinary file. If it is + not a MacBinary file, then the original file is unaltered. + Otherwise, the file is converted and the original file is deleted. + + The resulting file is designated by 'outPGPSpec' and may have a different + name than the original. + + If the file is a TEXT file, appropriate line-end conversion is done. + + creator and type code pointers may be + null but otherwise contain the mac creator and type. + + This routine can be called on a Mac, but generally doesn't need to be. +____________________________________________________________________________*/ +PGPError PGPMacBinaryToLocal( PGPFileSpecRef inSpec, + PGPFileSpecRef * outSpec, + PGPUInt32 * macCreator, PGPUInt32 * macTypeCode ); + + + + +/*____________________________________________________________________________ + Library initialization + + Call PGPsdkXXXInit() before using that particular library. + Call PGPsdkXXXCleanup() when you are done (but after disposing of any + PGPContexts). + + You may call PGPsdkXXXInit multiple times (with no effect), but be sure + to call the matching PGPsdkXXXCleanup() for each call to PGPsdkXXXInit(). +____________________________________________________________________________*/ + +PGPError PGPsdkInit( void ); +PGPError PGPsdkCleanup( void ); + +PGPError PGPsdkNetworkLibInit( void ); +PGPError PGPsdkNetworkLibCleanup( void ); + +PGPError PGPsdkUILibInit( void ); +PGPError PGPsdkUILibCleanup( void ); + +#if PRAGMA_IMPORT_SUPPORTED +#pragma import reset +#endif +PGP_END_C_DECLARATIONS + + + +#if PRAGMA_ALIGN_SUPPORTED +#pragma options align=reset /* ] */ +#endif + +#endif /* ] Included_pgpUtilities_h */ + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk6/lib/PGP_SDK.lib b/CryptoPP/PGPw/sdk6/lib/PGP_SDK.lib new file mode 100644 index 0000000..9332eae Binary files /dev/null and b/CryptoPP/PGPw/sdk6/lib/PGP_SDK.lib differ diff --git a/CryptoPP/PGPw/sdk6/lib/PGPsdkNL.lib b/CryptoPP/PGPw/sdk6/lib/PGPsdkNL.lib new file mode 100644 index 0000000..30c5390 Binary files /dev/null and b/CryptoPP/PGPw/sdk6/lib/PGPsdkNL.lib differ diff --git a/CryptoPP/PGPw/sdk6/lib/PGPsdkUI.lib b/CryptoPP/PGPw/sdk6/lib/PGPsdkUI.lib new file mode 100644 index 0000000..65f6c55 Binary files /dev/null and b/CryptoPP/PGPw/sdk6/lib/PGPsdkUI.lib differ diff --git a/CryptoPP/PGPw/sdk8/include/pflTypes.h b/CryptoPP/PGPw/sdk8/include/pflTypes.h new file mode 100644 index 0000000..00f3242 --- /dev/null +++ b/CryptoPP/PGPw/sdk8/include/pflTypes.h @@ -0,0 +1,52 @@ +/*____________________________________________________________________________ + Copyright (C) 2002 PGP Corporation + All rights reserved. + + $Id: pflTypes.h,v 1.5 2003/11/20 21:15:48 vinnie Exp $ +____________________________________________________________________________*/ +#ifndef Included_pflTypes_h /* [ */ +#define Included_pflTypes_h + +#include "pgpBase.h" + +/* opaque declarations */ +typedef struct PFLFileSpec * PFLFileSpecRef; +typedef struct PFLFileSpec const * PFLConstFileSpecRef; + +typedef struct PFLDirectoryIter * PFLDirectoryIterRef; +typedef struct PFLDirectoryIter const * PFLConstDirectoryIterRef; + +/* Validity checks */ +#define kInvalidPFLFileSpecRef ((PFLFileSpecRef) NULL) +#define kInvalidPFLDirectoryIterRef ((PFLDirectoryIterRef) NULL) + +#define PFLFileSpecRefIsValid( ref ) ( (ref) != kInvalidPFLFileSpecRef ) +#define PFLDirectoryIterRefIsValid( ref ) \ + ( (ref) != kInvalidPFLDirectoryIterRef ) + +/* Languages supported by pgpLocStrings */ +enum PFLLanguage_ +{ + kPFLLanguage_Default = 0, + kPFLLanguage_English = 1, + kPFLLanguage_Japanese = 2, + kPFLLanguage_German = 3, + kPFLLanguage_Spanish = 4, + + PGP_ENUM_FORCE( PFLLanguage_ ) +}; + +PGPENUM_TYPEDEF( PFLLanguage_, PFLLanguage ); + + +#endif /* ] Included_pflTypes_h */ + + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk8/include/pgpAPIAdapter.h b/CryptoPP/PGPw/sdk8/include/pgpAPIAdapter.h new file mode 100644 index 0000000..e473df4 --- /dev/null +++ b/CryptoPP/PGPw/sdk8/include/pgpAPIAdapter.h @@ -0,0 +1,186 @@ +/*____________________________________________________________________________ + * Copyright (C) 2003 PGP Corporation + * All rights reserved. + * + * Size of UTF-16 string is always given in 16 bit characters. This includes + * PGPGetKeyDBObjDataPropertyU16 and PGPGetKeyDBObjAllocatedDataPropertyU16 + * for which void* is assumed to be PGPChar16* where applicable. + * So you can write like this: + * + * wchar_t s[80]; + * PGPSize size; + * PGPGetPrimaryUserIDNameU16( key, s, sizeof(s)/sizeof(s[0]), &size ); + * + * $Id: pgpAPIAdapter.h,v 1.12 2004/05/07 08:29:12 bgaiser Exp $ + *____________________________________________________________________________*/ +#ifndef Included_pgpAPIAdapter_h /* [ */ +#define Included_pgpAPIAdapter_h + +#include "pgpKeys.h" +#include "pgpKeyServer.h" + +#include "pgpMemoryMgr.h" +#include "pgpUtilities.h" +#include "pgpPFLErrors.h" +#include "pgpFileSpec.h" +#include "pgpHashWords.h" +#include "pgpShareFile.h" + +PGP_BEGIN_C_DECLARATIONS + +PGPError PGPGetErrorStringU8( PGPError theError, PGPSize bufferSize, PGPChar8 * theString ); +PGPError PGPGetErrorStringU16( PGPError theError, PGPSize bufferSize, PGPChar16 * theString ); + +PGPError PGPGetPGPsdkVersionStringU8( PGPChar8 versionString[ 256 ] ); +PGPError PGPGetPGPsdkVersionStringU16( PGPChar16 versionString[ 256 ] ); + +PGPError PGPNewFileSpecFromFullPathU8( PGPContextRef context, const PGPChar8 *path, PGPFileSpecRef *ref ); +PGPError PGPNewFileSpecFromFullPathU16( PGPContextRef context, const PGPChar16 *path, PGPFileSpecRef *ref ); + +PGPError PGPGetFullPathFromFileSpecU8( PGPFileSpecRef fileRef, PGPChar8 **fullPathPtr); +PGPError PGPGetFullPathFromFileSpecU16( PGPFileSpecRef fileRef, PGPChar16 **fullPathPtr); + +PGPError PGPRenameFileU8( PGPFileSpecRef fileRef, const PGPChar8 *newName ); +PGPError PGPRenameFileU16( PGPFileSpecRef fileRef, const PGPChar16 *newName ); + +PGPOptionListRef PGPOPassphraseBufferU8( PGPContextRef context, const PGPChar8 *passphrase, PGPSize passphraseLength); +PGPOptionListRef PGPOPassphraseBufferU16( PGPContextRef context, const PGPChar16 *passphrase, PGPSize passphraseLength); + +PGPOptionListRef PGPOPassphraseU8( PGPContextRef context, const PGPChar8 *passphrase); +PGPOptionListRef PGPOPassphraseU16( PGPContextRef context, const PGPChar16 *passphrase); + +PGPOptionListRef PGPOPGPMIMEEncodingU8(PGPContextRef context, PGPBoolean mimeEncoding, PGPSize *mimeBodyOffset, PGPChar8 mimeSeparator[ kPGPMimeSeparatorSize ]); +PGPOptionListRef PGPOPGPMIMEEncodingU16(PGPContextRef context, PGPBoolean mimeEncoding, PGPSize *mimeBodyOffset, PGPChar16 mimeSeparator[ kPGPMimeSeparatorSize ]); + +PGPOptionListRef PGPOKeyGenNameU8( PGPContextRef context, const void *name, PGPSize nameLength ); +PGPOptionListRef PGPOKeyGenNameU16( PGPContextRef context, const void *name, PGPSize nameLength ); + +PGPOptionListRef PGPOPreferredKeyServerU8( PGPContextRef context, PGPChar8 const * server ); +PGPOptionListRef PGPOPreferredKeyServerU16( PGPContextRef context, PGPChar16 const * server ); + +PGPOptionListRef PGPOCommentStringU8( PGPContextRef context,PGPChar8 const *comment); +PGPOptionListRef PGPOCommentStringU16( PGPContextRef context,PGPChar16 const *comment); + +PGPOptionListRef PGPOVersionStringU8( PGPContextRef context, PGPChar8 const *version); +PGPOptionListRef PGPOVersionStringU16( PGPContextRef context, PGPChar16 const *version); + +PGPOptionListRef PGPOFileNameStringU8( PGPContextRef context, PGPChar8 const *fileName); +PGPOptionListRef PGPOFileNameStringU16( PGPContextRef context, PGPChar16 const *fileName); + +PGPOptionListRef PGPOSigRegularExpressionU8(PGPContextRef context, PGPChar8 const *regularExpression); +PGPOptionListRef PGPOSigRegularExpressionU16(PGPContextRef context, PGPChar16 const *regularExpression); + +PGPError PGPGetKeyDBObjDataPropertyU8( PGPKeyDBObjRef key, PGPKeyDBObjProperty whichProperty, void *buffer, PGPSize bufferSize, PGPSize *dataSize); +PGPError PGPGetKeyDBObjDataPropertyU16( PGPKeyDBObjRef key, PGPKeyDBObjProperty whichProperty, void *buffer, PGPSize bufferSize, PGPSize *dataSize); + +PGPError PGPGetKeyDBObjAllocatedDataPropertyU8( PGPKeyDBObjRef obj, PGPKeyDBObjProperty prop, void **buffer, PGPSize *dataSize ); +PGPError PGPGetKeyDBObjAllocatedDataPropertyU16( PGPKeyDBObjRef obj, PGPKeyDBObjProperty prop, void **buffer, PGPSize *dataSize ); + +PGPError PGPNewKeyDBObjDataFilterU8( PGPContextRef context, PGPKeyDBObjProperty prop, const void *val, PGPSize len, PGPMatchCriterion match, PGPFilterRef *outFilter ); +PGPError PGPNewKeyDBObjDataFilterU16( PGPContextRef context, PGPKeyDBObjProperty prop, const void *val, PGPSize len, PGPMatchCriterion match, PGPFilterRef *outFilter ); + +PGPError PGPLDAPQueryFromFilterU8( PGPFilterRef filter, PGPChar8 **queryOut ); +PGPError PGPLDAPQueryFromFilterU16( PGPFilterRef filter, PGPChar16 **queryOut ); + +PGPError PGPLDAPX509QueryFromFilterU8( PGPFilterRef filter,PGPChar8 **queryOut ); +PGPError PGPLDAPX509QueryFromFilterU16( PGPFilterRef filter,PGPChar16 **queryOut ); + +PGPError PGPHKSQueryFromFilterU8( PGPFilterRef filter, PGPChar8 **queryOut ); +PGPError PGPHKSQueryFromFilterU16( PGPFilterRef filter, PGPChar16 **queryOut ); + +PGPError PGPNetToolsCAHTTPQueryFromFilterU8( PGPFilterRef filter, PGPChar8 **queryOut ); +PGPError PGPNetToolsCAHTTPQueryFromFilterU16( PGPFilterRef filter, PGPChar16 **queryOut ); + +PGPError PGPAddUserIDU8( PGPKeyDBObjRef key, PGPChar8 const *userID, PGPOptionListRef firstOption, ...); +PGPError PGPAddUserIDU16( PGPKeyDBObjRef key, PGPChar16 const *userID, PGPOptionListRef firstOption, ...); + +PGPInt32 PGPCompareUserIDStringsU8(PGPChar8 const *a, PGPChar8 const *b); +PGPInt32 PGPCompareUserIDStringsU16(PGPChar16 const *a, PGPChar16 const *b); + +PGPError PGPGetKeyIDStringU8( PGPKeyID const * ref, PGPKeyIDStringType type, PGPChar8 outString[ kPGPMaxKeyIDStringSize ] ); +PGPError PGPGetKeyIDStringU16( PGPKeyID const * ref, PGPKeyIDStringType type, PGPChar16 outString[ kPGPMaxKeyIDStringSize ] ); + +PGPError PGPNewKeyIDFromStringU8( const PGPChar8 *string, PGPPublicKeyAlgorithm pkalg, PGPKeyID * outID ); +PGPError PGPNewKeyIDFromStringU16( const PGPChar16 *string, PGPPublicKeyAlgorithm pkalg, PGPKeyID * outID ); + +PGPError PGPSetPKCS11DrvFileU8( PGPChar8 *module ); +PGPError PGPSetPKCS11DrvFileU16( PGPChar16 *module ); + +PGPError PGPGetTokenInfoDataPropertyU8( PGPContextRef context, PGPUInt32 tokenNumber, PGPTokenProperty prop, PGPByte *value, PGPSize size, PGPSize *sizeout ); +PGPError PGPGetTokenInfoDataPropertyU16( PGPContextRef context, PGPUInt32 tokenNumber, PGPTokenProperty prop, void *value, PGPSize size, PGPSize *sizeout ); + +PGPError PGPCreateDistinguishedNameU8( PGPContextRef context, PGPChar8 const *str, PGPByte **pdname, PGPSize *pdnamelen ); +PGPError PGPCreateDistinguishedNameU16( PGPContextRef context, PGPChar16 const *str, PGPByte **pdname, PGPSize *pdnamelen ); + +PGPError PGPGetPrimaryUserIDNameU8(PGPKeyDBObjRef key, PGPChar8 *buffer, PGPSize bufferSize, PGPSize *dataSize); +PGPError PGPGetPrimaryUserIDNameU16(PGPKeyDBObjRef key, PGPChar16 *buffer, PGPSize bufferSize, PGPSize *dataSize); + +PGPError PGPGetHashWordStringU8( PGPUInt32 index, PGPHashWordList list, PGPChar8 hashWordString[ 12 ] ); +PGPError PGPGetHashWordStringU16( PGPUInt32 index, PGPHashWordList list, PGPChar16 hashWordString[ 12 ] ); + +PGPError PGPSetShareFileUserIDU8( PGPShareFileRef shareFileRef, const PGPUTF8 *userID ); +PGPError PGPSetShareFileUserIDU16( PGPShareFileRef shareFileRef, const PGPChar16 *userID ); + +PGPError PGPGetShareFileUserIDU8( PGPShareFileRef shareFileRef, PGPSize bufferSize, PGPUTF8 *userID, PGPSize *fullSize ); +PGPError PGPGetShareFileUserIDU16( PGPShareFileRef shareFileRef, PGPSize bufferSize, PGPChar16 *userID, PGPSize *fullSize ); + +PGPError PGPGetTARCacheObjDataPropertyU8( PGPTARCacheObjRef obj, PGPTARCacheObjProperty prop, void *buffer, PGPSize bufSize, PGPSize *dataSize ); +PGPError PGPGetTARCacheObjDataPropertyU16( PGPTARCacheObjRef obj, PGPTARCacheObjProperty prop, void *buffer, PGPSize bufSize, PGPSize *dataSize ); + + +/* ----- SDK UI ----- */ +PGPUInt32 PGPEstimatePassphraseQualityU8( const PGPChar8 *passphrase ); +PGPUInt32 PGPEstimatePassphraseQualityU16( const PGPChar16 *passphrase ); + +PGPOptionListRef PGPOUIDialogPromptU8( PGPContextRef context, const PGPChar8 *prompt ); +PGPOptionListRef PGPOUIDialogPromptU16( PGPContextRef context, const PGPChar16 *prompt ); + +PGPOptionListRef PGPOUIWindowTitleU8( PGPContextRef context, const PGPChar8 *title ); +PGPOptionListRef PGPOUIWindowTitleU16( PGPContextRef context, const PGPChar16 *title ); + +PGPOptionListRef PGPOUIOutputPassphraseU8( PGPContextRef context, PGPChar8 **passphrase ); +PGPOptionListRef PGPOUIOutputPassphraseU16( PGPContextRef context, PGPChar16 **passphrase ); + +PGPOptionListRef PGPOUICheckboxU8(PGPContextRef context, PGPUInt32 itemID, const PGPChar8 *title, const PGPChar8 *description, PGPUInt32 initialValue, PGPUInt32 *resultPtr, PGPOptionListRef firstOption, ...); +PGPOptionListRef PGPOUICheckboxU16(PGPContextRef context, PGPUInt32 itemID, const PGPChar16 *title, const PGPChar16 *description, PGPUInt32 initialValue, PGPUInt32 *resultPtr, PGPOptionListRef firstOption, ...); + +PGPOptionListRef PGPOUIPopupListU8(PGPContextRef context, PGPUInt32 itemID, const PGPChar8 *title, const PGPChar8 *description,PGPUInt32 listItemCount, const PGPChar16 *listItems[], PGPUInt32 initialValue, PGPUInt32 *resultPtr, PGPOptionListRef firstOption, ...); +PGPOptionListRef PGPOUIPopupListU16(PGPContextRef context, PGPUInt32 itemID, const PGPChar16 *title, const PGPChar16 *description,PGPUInt32 listItemCount, const PGPChar16 *listItems[], PGPUInt32 initialValue, PGPUInt32 *resultPtr, PGPOptionListRef firstOption, ...); + + +/* ----- SDK Network ----- */ +PGPOptionListRef PGPONetURLU8(PGPContextRef context, const PGPChar8 *url); +PGPOptionListRef PGPONetURLU16(PGPContextRef context, const PGPChar16 *url); + +PGPOptionListRef PGPONetHostNameU8(PGPContextRef context, const PGPChar8 *hostName, PGPUInt16 port); +PGPOptionListRef PGPONetHostNameU16(PGPContextRef context, const PGPChar16 *hostName, PGPUInt16 port); + +PGPOptionListRef PGPOKeyServerKeyStoreDNU8(PGPContextRef context, const PGPChar8 *szKeyStoreDn); +PGPOptionListRef PGPOKeyServerKeyStoreDNU16(PGPContextRef context, const PGPChar16 *szKeyStoreDn); + +PGPError PGPGetKeyServerHostNameU8(PGPKeyServerRef inKeyServerRef, PGPChar8 ** outHostName); /* Use PGPFreeData to free */ +PGPError PGPGetKeyServerHostNameU16(PGPKeyServerRef inKeyServerRef, PGPChar16 ** outHostName); /* Use PGPFreeData to free */ + +PGPError PGPGetKeyServerPathU8(PGPKeyServerRef inKeyServerRef, PGPChar8 ** outPath); /* Use PGPFreeData to free */ +PGPError PGPGetKeyServerPathU16(PGPKeyServerRef inKeyServerRef, PGPChar16 ** outPath); /* Use PGPFreeData to free */ + +PGPError PGPGetLastKeyServerErrorStringU8(PGPKeyServerRef inKeyServerRef,PGPChar8 ** outErrorString); +PGPError PGPGetLastKeyServerErrorStringU16(PGPKeyServerRef inKeyServerRef,PGPChar16 ** outErrorString); + +PGPError PGPGetProxyServerU8(PGPContextRef context, PGPProxyServerType type, PGPChar8 **proxyAddress, PGPUInt16 *proxyPort ); +PGPError PGPGetProxyServerU16(PGPContextRef context, PGPProxyServerType type, PGPChar16 **proxyAddress, PGPUInt16 *proxyPort ); + +PGP_END_C_DECLARATIONS + +#endif /* ] Included_pgpAPIAdapter_h */ + + +/*__Editor_settings____ + * + * Local Variables: + * tab-width: 4 + * End: + * vi: ts=4 sw=4 + * vim: si + *_____________________*/ + diff --git a/CryptoPP/PGPw/sdk8/include/pgpBER.h b/CryptoPP/PGPw/sdk8/include/pgpBER.h new file mode 100644 index 0000000..ad20d03 --- /dev/null +++ b/CryptoPP/PGPw/sdk8/include/pgpBER.h @@ -0,0 +1,175 @@ +/*____________________________________________________________________________ + Copyright (C) 2002 PGP Corporation + All rights reserved. + + $Id: pgpBER.h,v 1.15 2003/08/08 04:40:39 ajivsov Exp $ +____________________________________________________________________________*/ + +/* + * For extremely detailed explanation of all the BER types and + * encoding, see X.208 (Specification of Abstract Syntax Notation One (ASN.1)) + * and X.209 (Specification of Basic Encoding Rules for Abstract Syntax + * Notation One (ASN.1)). + * + * These two sources will tell you everything you would ever need (and want) + * to know about BER and ASN.1. + */ + +#ifndef Included_pgpBER_h /* [ */ +#define Included_pgpBER_h + +#include "pgpPubTypes.h" +#include "pgpMemoryMgr.h" +#include "pgpSockets.h" + +/* BER types */ +/* The X.209 BER specification actually defines a lot more + * types than is listed here, but these are the only ones + * the current PGPldap implementation uses. */ +enum PGPberType_ +{ + kPGPberType_Boolean = 0x01, /* tag = 0x01 */ + kPGPberType_Int = 0x02, /* tag = 0x02 */ + kPGPberType_Bitstring = 0x03, /* tag = 0x03 */ + kPGPberType_Octetstring = 0x04, /* tag = 0x04 */ + kPGPberType_NULL = 0x05, /* tag = 0x05 */ + kPGPberType_ObjectID = 0x06, /* tag = 0x06 */ + kPGPberType_Enumeration = 0x0A, /* tag = 0x0A */ + kPGPberType_PrintableString = 0x0D, /* tag = 0x0D */ + kPGPberType_Sequence = 0x30, /* constructed, tag = 0x10 */ + kPGPberType_Set = 0x31, /* constructed, tag = 0x11 */ + + kPGPberType_None = 0xFFFFFFFF +}; +PGPENUM_TYPEDEF (PGPberType_, PGPberType); + +enum PGPberFormatSpecifier_ +{ + kPGPberFormatSpecifier_Boolean = 'b', + kPGPberFormatSpecifier_Int = 'i', + kPGPberFormatSpecifier_Octetstring = 'o', + kPGPberFormatSpecifier_String = 's', + kPGPberFormatSpecifier_StringVector = 'v', + kPGPberFormatSpecifier_BERVector = 'V', /* strings and lengths */ + kPGPberFormatSpecifier_NULL = 'n', + kPGPberFormatSpecifier_Enumeration = 'e', + kPGPberFormatSpecifier_Tag = 't', + kPGPberFormatSpecifier_BeginSequence= '{', + kPGPberFormatSpecifier_EndSequence = '}', + kPGPberFormatSpecifier_BeginSet = '[', + kPGPberFormatSpecifier_EndSet = ']', + + kPGPberFormatSpecifier_Force = '*' +}; +PGPENUM_TYPEDEF (PGPberFormatSpecifier_, PGPberFormatSpecifier); + + +typedef struct PGPberElement * PGPberElementRef; + +#define kInvalidPGPberElementRef ( (PGPberElementRef) NULL) +#define PGPberElementRefIsValid(ber) \ + ( (ber) != kInvalidPGPberElementRef ) +#define PGPValidateBERElementRef(ber) \ + PGPValidateParam( PGPberElementRefIsValid( ber ) ) + +typedef struct PGPberValue +{ + PGPSize length; + PGPByte *value; +} PGPberValue; + +/* Functions */ + + PGPError +PGPNewBERElement( + PGPContextRef context, + PGPberElementRef * ber ); + +/* ber_free */ + PGPError +PGPFreeBERElement( + PGPberElementRef ber ); + +/* BER encoding functions */ + PGPError +PGPberAppend( + PGPberElementRef ber, + const PGPChar8 * s, + ... ); + + PGPError +PGPberGetEncoding( + PGPberElementRef ber, + PGPByte ** encoding ); + +/* BER decoding functions */ + PGPError +PGPberRead( + PGPberElementRef ber, + const PGPChar8 * fmt, + ... ); + + PGPError +PGPberGetLength( + PGPberElementRef ber, + PGPSize * length ); + + PGPError +PGPberRewind( + PGPberElementRef ber ); + + PGPError +PGPberNextPrimitive( + PGPberElementRef ber ); + + PGPError +PGPberNextConstructed( + PGPberElementRef ber ); + + PGPError +PGPberNext( + PGPberElementRef ber ); + + PGPError +PGPberSkip( + PGPberElementRef ber ); + + PGPError +PGPberPeek( + PGPberElementRef ber, + PGPberType * tag, + PGPSize * len ); + + PGPError +PGPberGetIndex( + PGPberElementRef ber, + PGPUInt32 * index ); + + PGPError +PGPberSetIndex( + PGPberElementRef ber, + PGPUInt32 index ); + + PGPError +PGPberReadResponse( + PGPberElementRef ber, + PGPSocketRef sock ); + + PGPError +PGPberSetData( + PGPberElementRef ber, + PGPByte * data, + PGPSize len ); + + +#endif /* ] Included_pgpBER_h */ + + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk8/include/pgpBase.h b/CryptoPP/PGPw/sdk8/include/pgpBase.h new file mode 100644 index 0000000..53a1df4 --- /dev/null +++ b/CryptoPP/PGPw/sdk8/include/pgpBase.h @@ -0,0 +1,451 @@ +/*____________________________________________________________________________ + Copyright (C) 2002 PGP Corporation + All rights reserved. + + This file deals with system dependencies to derive our very basic data + types. It should not contain any higher level types. + + + $Id: pgpBase.h,v 1.30 2004/02/09 23:30:31 vinnie Exp $ +____________________________________________________________________________*/ + +#ifndef Included_pgpBase_h /* [ */ +#define Included_pgpBase_h + +#include "pgpPFLConfig.h" + +#if !( defined(PGP_MACINTOSH) || defined(PGP_UNIX) || defined(PGP_WIN32) ) +#error one of {PGP_MACINTOSH, PGP_UNIX, PGP_WIN32} must be defined +#endif + +#if PGP_MACINTOSH +#include +#if __MWERKS__ && ! defined( __dest_os ) + #include + #define __dest_os __mac_os +#endif +#else + /* aCC bars on if this file is not included first */ + #if PGP_COMPILER_HPUX + #include + #endif /* PGP_COMPILER_HPUX */ + #include +#endif + +#if PGP_WIN32 +#include /* For size_t */ +#endif + +#if ! NO_LIMITS_H +#include +#endif + +#ifndef PGP_UNICODE +#define PGP_UNICODE 0 +#endif + +#if PGP_WIN32 + /* check for inconsistent usage of UNICODE symbols */ + #if PGP_UNICODE + #if !defined(UNICODE) || !defined(_UNICODE) + #error UNICODE and _UNICODE must be defined + #endif + #else + #if defined(UNICODE) || defined(_UNICODE) + #error UNICODE and _UNICODE should not be defined + #endif + #endif +#endif + + +/*____________________________________________________________________________ + PGP basic types +____________________________________________________________________________*/ + +typedef unsigned char PGPBoolean; /* can be TRUE or FALSE */ + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +/* PGPUInt8, PGPInt8 */ +#if UCHAR_MAX == 0xff + +typedef unsigned char PGPUInt8; +typedef signed char PGPInt8; +#define MAX_PGPUInt8 UCHAR_MAX +#define MAX_PGPInt8 SCHAR_MAX + +#else +#error This machine has no 8-bit type +#endif + + +/* PGPUInt16, PGPInt16 */ +#if UINT_MAX == 0xffff + +typedef unsigned int PGPUInt16; +typedef int PGPInt16; +#define MAX_PGPUInt16 UINT_MAX +#define MAX_PGPInt16 INT_MAX + +#elif USHRT_MAX == 0xffff + +typedef unsigned short PGPUInt16; +typedef short PGPInt16; +#define MAX_PGPUInt16 USHRT_MAX +#define MAX_PGPInt16 SHRT_MAX + +#else +#error This machine has no 16-bit type +#endif + + +/* PGPUInt32, PGPInt32 */ +#if UINT_MAX == 0xfffffffful + +typedef unsigned int PGPUInt32; +typedef int PGPInt32; +#define MAX_PGPUInt32 UINT_MAX +#define MAX_PGPInt32 INT_MAX + +#elif ULONG_MAX == 0xfffffffful + +typedef unsigned long PGPUInt32; +typedef long PGPInt32; +#define MAX_PGPUInt32 ULONG_MAX +#define MAX_PGPInt32 LONG_MAX + +#elif USHRT_MAX == 0xfffffffful + +typedef unsigned short PGPUInt32; +typedef short PGPInt32; +#define MAX_PGPUInt32 USHRT_MAX +#define MAX_PGPInt32 SHRT_MAX + +#else +#error This machine has no 32-bit type +#endif + + +/*____________________________________________________________________________ + PGPUInt64, PGPInt64 + + Find a 64-bit data type, if possible. + The conditions here are more complicated to avoid using numbers that + will choke lesser preprocessors (like 0xffffffffffffffff) unless + we're reasonably certain that they'll be acceptable. + + Some *preprocessors* choke on constants that long even if the + compiler can accept them, so it doesn't work reliably to test values. + So cross our fingers and hope that it's a 64-bit type. + + GCC uses ULONG_LONG_MAX. Solaris uses ULLONG_MAX. + IRIX uses ULONGLONG_MAX. Are there any other names for this? +____________________________________________________________________________*/ + + +#if ULONG_MAX > 0xfffffffful +#if ULONG_MAX == 0xfffffffffffffffful + +typedef ulong PGPUInt64; +typedef long PGPInt64; +#define PGP_HAVE64 1 + +#endif +#endif + + +#ifndef PGP_HAVE64 + +#if defined(ULONG_LONG_MAX) || defined (ULLONG_MAX) || defined(ULONGLONG_MAX) || defined(__LONG_LONG_MAX__) +typedef unsigned long long PGPUInt64; +typedef long long PGPInt64; +#define PGP_HAVE64 1 + +#endif +#endif + +/*____________________________________________________________________________ + This was added because for some reason or another, __LONG_LONG_MAX__ is + not defined on Linux 6.1. Hopefully this doesn't break older versions of + Linux but you never know..... +____________________________________________________________________________*/ +#if defined(PGP_UNIX_LINUX) && !defined(PGP_HAVE64) +typedef long long PGPInt64; +typedef unsigned long long PGPUInt64; +#define PGP_HAVE64 1 +#endif + + +#ifndef PGP_HAVE64 +#if defined(__MWERKS__) +#if __option( longlong ) + +typedef unsigned long long PGPUInt64; +typedef long long PGPInt64; +#define PGP_HAVE64 1 + +#endif +#endif +#endif + +#if PGP_HAVE64 +/* too painful to test all the variants above, so just do it this way */ +#define MAX_PGPUInt64 ((PGPUInt64)0xfffffffffffffffful) +#define MAX_PGPInt64 ((PGPInt64)0x7fffffffffffffff) +#endif + + +/*____________________________________________________________________________ + PGPInt, PGPUInt, PGPLong, PGPULong + + Architecture-specific data types. + + PGPLong will be 64 bits on 64-bit architectures (Linux on AMD64 or WIN64). + PGPLong is hardware-supported integeral type such that + sizeof(PGPULong)==sizeof(void*) + + PGPInt is the most efficient harware-supported integeral type that is at + least 32 bit long. It should be the main type for internal counters, sizes, + offsets etc unless possibly the larger space of PGPSize is required. +____________________________________________________________________________*/ + +/* note that this should be changed for 16 bit platform */ +typedef int PGPInt; +typedef unsigned int PGPUInt; + +#if PGP_WIN32 + #if defined(_WIN64) + #if PGP_HAVE_64_HARDWARE==0 + #error "Configuration error: PGP_HAVE_64_HARDWARE must be 1 for WIN64" + #endif + typedef __int64 PGPLong; + typedef unsigned __int64 PGPULong; + #else + #ifndef _W64 + /* (this definition is only need for WINNT) */ + #define _W64 + #endif + typedef _W64 __int32 PGPLong; + typedef _W64 unsigned __int32 PGPULong; + #endif +#else + typedef unsigned long PGPULong; + typedef long PGPLong; +#endif + +#if INT_MAX == 0x7FFFFFFFL +#define PGPENUM_TYPEDEF( enumName, typeName ) typedef enum enumName typeName +#else +#define PGPENUM_TYPEDEF( enumName, typeName ) typedef PGPInt32 typeName +#endif +#define kPGPEnumMaxValue INT_MAX + +#define PGP_ENUM_FORCE( enumName ) \ + k ## enumName ## force = kPGPEnumMaxValue + + +typedef PGPUInt8 PGPByte; + +typedef PGPInt32 PGPError; + +/* a simple value sufficient to hold any numeric or pointer type */ +typedef void * PGPUserValue; + +/* A PGPSize refers to in memory sizes. Use PGPFileOffset for file offsets */ +typedef size_t PGPSize; +#define MAX_PGPSize ( ~(PGPSize)0 ) + +/* An offset or size of a file */ +#if PGP_UNIX +#ifdef HAVE_64BIT_FILES +typedef off64_t PGPFileOffset; +#else /* !HAVE_64BIT_FILES */ +typedef off_t PGPFileOffset; +#endif /* HAVE_64BIT_FILES */ +#else +#if PGP_HAVE64 +typedef PGPInt64 PGPFileOffset; +#else +typedef PGPInt32 PGPFileOffset; +#endif +#endif + +typedef PGPUInt32 PGPFlags; +typedef time_t PGPTime; +typedef PGPULong PGPTimeInterval; /* In milliseconds */ + +#define kPGPMaxTimeInterval (~(PGPTimeInterval)0) + +typedef struct PGPVersion +{ + PGPUInt16 majorVersion; + PGPUInt16 minorVersion; + +} PGPVersion; + +/* character types useful for Unicode issues */ +typedef char PGPChar8; +typedef PGPUInt16 PGPChar16; +typedef PGPUInt32 PGPChar32; +typedef unsigned char PGPUTF8; + +#if PGP_UNICODE +typedef PGPUInt16 PGPChar; +#else +typedef char PGPChar; +#endif + +typedef char PFLChar; +typedef char SDKUIChar; + + +/*____________________________________________________________________________ + These macros should surround all C declarations in public + header files which define function or data symbols. +____________________________________________________________________________*/ + +#ifdef __cplusplus /* [ */ + +#define PGP_BEGIN_C_DECLARATIONS extern "C" { +#define PGP_END_C_DECLARATIONS } + +#else /* ] __cplusplus [ */ + +#define PGP_BEGIN_C_DECLARATIONS +#define PGP_END_C_DECLARATIONS + +#endif /* ] __cplusplus */ + + +#ifndef pgpMin +#define pgpMin(x,y) (((x)<(y)) ? (x) : (y)) +#endif + +#ifndef pgpMax +#define pgpMax(x,y) (((x)>(y)) ? (x) : (y)) +#endif + +#ifndef PGP_DEPRECATED +#define PGP_DEPRECATED 1 +#endif + +#if PGP_WIN32 +# define BIG_ENDIAN 123 +# define LITTLE_ENDIAN 321 +# define BYTE_ORDER LITTLE_ENDIAN +#endif + +#if BYTE_ORDER == BIG_ENDIAN +# define PGP_WORDSBIGENDIAN 1 +# define PGP_WORDSLITTLEENDIAN 0 +#elif BYTE_ORDER == LITTLE_ENDIAN +# define PGP_WORDSBIGENDIAN 0 +# define PGP_WORDSLITTLEENDIAN 1 +#else +# error define your byte order +#endif + +/*____________________________________________________________________________ + * The PGP equivalent of the MS "TEXT" macro. PGPTEXT wraps a string literal + * and causes it to compile as 8 or 16 bit characters on the basis of the + * PGP_UNICODE symbol. + */ +#if PGP_UNICODE + #define PGPTEXT(literal) L##literal +#else + #define PGPTEXT(literal) literal +#endif + +/*____________________________________________________________________________ + * Macros for wrapping text literals. These macros serve two purposes: + * (a) to indicate to the reader of the source code the way in which the + * literal is used (and therefore why the string should not be externalized + * and localized), and (b) to indicate to the compiler whether the literal + * should be compiled as 8-bit or 16-bit characters. + * + * To the right of each macro is the abbreviation to use when naming + * string resources. + */ + +/* PGPTXT_USER should be used for strings which are to be displayed + * to the user, but which we have decided not to translate, for whatever + * reason. + */ +#define PGPTXT_USER(literal) PGPTEXT(literal) /* USR */ +#define PGPTXT_USER8(literal) literal +#define PGPTXT_USER16(literal) L##literal + +/* PGPTXT_ADMIN is for messages to be seen by an admin; we may choose to + * translate these in the future. + */ +#define PGPTXT_ADMIN(literal) PGPTEXT(literal) /* ADM */ + +/* PGPTXT_MACHINE strings are meant to be read by a machine. That is, + * the usual usage would be that this string is never seen by anyone, + * neither users, developers, admins nor qa; it is only seen by programs. + * This includes textual material in tables where that is meant to be + * compared against hardcoded strings looking for a match. Explicit + * 8- and 16-bit versions are provided. + */ +#define PGPTXT_MACHINE(literal) PGPTEXT(literal) /* MAC */ +#define PGPTXT_MACHINE8(literal) literal +#define PGPTXT_MACHINE16(literal) L##literal + +#define PFLTXT_MACHINE PGPTXT_MACHINE8 +#define SDKUITXT_MACHINE PGPTXT_DEBUG8 +#define SDKUITXT_USER PGPTXT_MACHINE8 + +/* String literals in obsolete sections of code may be left in for + * clarity or historical reasons. They should be marked with the + * PGPTXT_OBSOLETE macro. + */ +#define PGPTXT_OBSOLETE(literal) literal /* OBS */ + +/* PGPTXT_FIXBEFORESHIP is for strings for which the tagger is not sure + * what to do with them, but which will need to be decided eventually. + */ +#define PGPTXT_FIXBEFORESHIP(literal) literal /* FIX */ + +/* PGPTXT_DEBUG should be used for strings which are to be seen only by + * developers or testers. This would include compiled-out self-test + * code, debugging code, printf's, messageboxes, debug logs, and asserts. + */ +#define PGPTXT_DEBUG(literal) PGPTEXT(literal) /* DBG */ +#define PGPTXT_DEBUG8(literal) literal +#define PGPTXT_DEBUG16(literal) L##literal + +#define PFLTXT_DEBUG PGPTXT_DEBUG8 +#define SDKUITXT_DEBUG PGPTXT_DEBUG8 + +/* PGPTXT_DEFERRED is used to mark text for which externalization + * has been deferred because the text is not actually used in the + * current implementation but it may be someday. Externalizing + * such text would create unnecessary work for the localizers at + * this point in time. + */ +#define PGPTXT_DEFERRED(literal) PGPTEXT(literal) +#define PGPTXT_DEFERRED8(literal) literal +#define PGPTXT_DEFERRED16(literal) L##literal + +#if defined(__GNUC__) && (__GNUC__ >= 3) && (__GNUC_MINOR__ >= 1) && PGP_OSX +#define PGP_WEAK_IMPORT __attribute__((weak_import)) +#else +#define PGP_WEAK_IMPORT +#endif + +#endif /* ] Included_pgpBase_h */ + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk8/include/pgpBigNum.h b/CryptoPP/PGPw/sdk8/include/pgpBigNum.h new file mode 100644 index 0000000..fdc65e2 --- /dev/null +++ b/CryptoPP/PGPw/sdk8/include/pgpBigNum.h @@ -0,0 +1,177 @@ +/*____________________________________________________________________________ + Copyright (C) 2002 PGP Corporation + All rights reserved. + + $Id: pgpBigNum.h,v 1.7 2002/08/06 20:11:16 dallen Exp $ +____________________________________________________________________________*/ + +#ifndef Included_pgpBigNum_h +#define Included_pgpBigNum_h + +#include "pgpBase.h" +#include "pgpUtilities.h" + +PGP_BEGIN_C_DECLARATIONS + +typedef struct PGPBigNum * PGPBigNumRef; +#define kPGPInvalidBigNumRef ( (PGPBigNumRef)NULL ) + +/*____________________________________________________________________________ + Bignum basics +____________________________________________________________________________*/ +PGPError PGPNewBigNum( PGPContextRef context, PGPBoolean secure, + PGPBigNumRef *newBN ); + +PGPError PGPFreeBigNum( PGPBigNumRef bn ); + +PGPError PGPCopyBigNum( PGPBigNumRef src, PGPBigNumRef * dest ); +PGPError PGPAssignBigNum( PGPBigNumRef src, PGPBigNumRef dest ); +PGPError PGPSwapBigNum( PGPBigNumRef a, PGPBigNumRef b); + +/* +** Move bytes between the given buffer and the given BigNum encoded in +** base 256. I.e. after either of these, the buffer will be equal to +** (bn / 256^lsbyte) % 256^len. The difference is which is altered to +** match the other! +*/ +PGPError PGPBigNumExtractBigEndianBytes( PGPBigNumRef bn, + PGPByte *dest, PGPUInt32 lsbyte, PGPUInt32 len ); + +PGPError PGPBigNumInsertBigEndianBytes(PGPBigNumRef bn, + PGPByte const *src, PGPUInt32 lsbyte, PGPUInt32 len ); + +/* The same, but the buffer is little-endian. */ +PGPError PGPBigNumExtractLittleEndianBytes( PGPBigNumRef bn, + PGPByte *dest, PGPUInt32 lsbyte, PGPUInt32 len ); + +PGPError PGPBigNumInsertLittleEndianBytes(PGPBigNumRef bn, + PGPByte const *src, PGPUInt32 lsbyte, PGPUInt32 len ); + +/* Return the least-significant bits (at least 16) of the BigNum */ +PGPUInt16 PGPBigNumGetLSWord( PGPBigNumRef bn ); + +/* + * Return the number of significant bits in the BigNum. + * 0 or 1+floor(log2(src)) + */ +PGPUInt32 PGPBigNumGetSignificantBits( PGPBigNumRef bn ); + +/* + * Adds two bignums into dest. Faster if dest is same as lhs or rhs. + */ +PGPError PGPBigNumAdd( PGPBigNumRef lhs, PGPBigNumRef rhs, + PGPBigNumRef dest ); + +/* + * lhs-rhs. dest and src may be the same, but bnSetQ(dest, 0) is faster. + * if dest < src, returns error and dest is undefined. + */ +PGPError PGPBigNumSubtract( PGPBigNumRef lhs, PGPBigNumRef rhs, + PGPBigNumRef dest, PGPBoolean *underflow ); + +/* Return sign (-1, 0, +1) of a-b. a <=> b --> bnCmpQ(a, b) <=> 0 */ +PGPInt32 PGPBigNumCompareQ( PGPBigNumRef bn, PGPUInt16 sm ); + +/* dest = src, where 0 <= src < 2^16. */ +PGPError PGPBigNumSetQ( PGPBigNumRef dest, PGPUInt16 sm ); + +/* dest = bn + sm, where 0 <= sm < 2^16 */ +PGPError PGPBigNumAddQ( PGPBigNumRef bn, PGPUInt16 sm, + PGPBigNumRef dest); + +/* dest = bn + sm, where 0 <= sm < 2^16 */ +PGPError PGPBigNumSubtractQ( PGPBigNumRef bn, PGPUInt16 sm, + PGPBigNumRef dest, PGPBoolean *underflow); + +/* Return sign (-1, 0, +1) of a-b. a <=> b --> bnCmp(a, b) <=> 0 */ +PGPInt32 PGPBigNumCompare( PGPBigNumRef lhs, PGPBigNumRef rhs); + +/* dest = src * src. dest may be the same as src, but it costs time. */ +PGPError PGPBigNumSquare( PGPBigNumRef src, PGPBigNumRef dest); + +/* dest = a * b. dest may be the same as a or b, but it costs time. */ +PGPError PGPBigNumMultiply( PGPBigNumRef lhs, PGPBigNumRef rhs, + PGPBigNumRef dest); + +/* dest = a * b, where 0 <= b < 2^16. dest and a may be the same. */ +PGPError PGPBigNumMultiplyQ( PGPBigNumRef lhs, PGPUInt16 sm, + PGPBigNumRef dest); + +/* + * q = n/d, r = n%d. r may be the same as n, but not d, + * and q may not be the same as n or d. + * re-entrancy issue: this temporarily modifies d, but restores + * it for return. + */ +PGPError PGPBigNumDivide( PGPBigNumRef numerator, PGPBigNumRef denominator, + PGPBigNumRef quotient, PGPBigNumRef remainder); +/* + * dest = n % d. dest and src may be the same, but not dest and d. + * re-entrancy issue: this temporarily modifies d, but restores + * it for return. + */ +PGPError PGPBigNumMod( PGPBigNumRef numerator, PGPBigNumRef denominator, + PGPBigNumRef dest ); + +/* return src % d, where 0 <= d < 2^16. */ +PGPUInt16 PGPBigNumModQ( PGPBigNumRef numerator, PGPUInt16 denominator ); + +/* n = n^exp, modulo "mod" "mod" *must* be odd */ +PGPError PGPBigNumExpMod( PGPBigNumRef n, PGPBigNumRef exponent, + PGPBigNumRef mod, PGPBigNumRef dest ); + +/* + * dest = n1^e1 * n2^e2, modulo "mod". "mod" *must* be odd. + * dest may be the same as n1 or n2. + */ +PGPError PGPBigNumDoubleExpMod( PGPBigNumRef n1, PGPBigNumRef exponent1, + PGPBigNumRef n2, PGPBigNumRef exponent2, + PGPBigNumRef mod, PGPBigNumRef dest ); + +/* dest = 2^exp, modulo "mod" "mod" *must* be odd */ +PGPError PGPBigNumTwoExpMod( PGPBigNumRef exponent, PGPBigNumRef mod, + PGPBigNumRef dest ); + +/* dest = gcd(a, b). The inputs may overlap arbitrarily. */ +PGPError PGPBigNumGCD( PGPBigNumRef a, PGPBigNumRef b, PGPBigNumRef dest ); + +/* dest = src^-1, modulo "mod". dest may be the same as src. */ +PGPError PGPBigNumInv( PGPBigNumRef src, PGPBigNumRef mod, + PGPBigNumRef dest ); + + +/* Shift dest left "amt" places */ +PGPError PGPBigNumLeftShift( PGPBigNumRef dest, PGPUInt32 amt ); + +/* Shift dest right "amt" places, discarding low-order bits */ +PGPError PGPBigNumRightShift( PGPBigNumRef dest, PGPUInt32 amt ); + +/* right shift all low order 0-bits, return number of bits shifted */ +PGPUInt16 PGPBigNumMakeOdd( PGPBigNumRef dest ); + + +PGP_END_C_DECLARATIONS + +#endif /* Included_pgpBigNum_h */ + + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ + + + + + + + + + + + + diff --git a/CryptoPP/PGPw/sdk8/include/pgpCBC.h b/CryptoPP/PGPw/sdk8/include/pgpCBC.h new file mode 100644 index 0000000..26ae61d --- /dev/null +++ b/CryptoPP/PGPw/sdk8/include/pgpCBC.h @@ -0,0 +1,82 @@ +/*____________________________________________________________________________ + Copyright (C) 2002 PGP Corporation + All rights reserved. + + $Id: pgpCBC.h,v 1.6 2002/08/06 20:11:16 dallen Exp $ +____________________________________________________________________________*/ + +#ifndef Included_pgpCBC_h /* [ */ +#define Included_pgpCBC_h + +#include "pgpSymmetricCipher.h" + + +PGP_BEGIN_C_DECLARATIONS + +/*____________________________________________________________________________ + A CBC context requires use of a symmetric cipher which has been created + and whose key has been set. An error will be returned if this is not + the case. + + After the call, the CBCContextRef "owns" the + symmetric ref and will dispose of it properly (even if an error + occurs). The caller should no longer reference it. +____________________________________________________________________________*/ + +PGPError PGPNewCBCContext( PGPSymmetricCipherContextRef ref, + PGPCBCContextRef *outRef ); + +/*____________________________________________________________________________ + Disposal clears all data in memory before releasing it. +____________________________________________________________________________*/ + +PGPError PGPFreeCBCContext( PGPCBCContextRef ref ); + +/*____________________________________________________________________________ + Make an exact copy, including current state. Original is not changed. +____________________________________________________________________________*/ + +PGPError PGPCopyCBCContext( PGPCBCContextRef ref, PGPCBCContextRef *outRef ); + +/*____________________________________________________________________________ + IV size is implicit (same size as the symmetric cipher block size). + IV is *copied*. + Caller may want to destroy the original after passing it in. +____________________________________________________________________________*/ + +PGPError PGPInitCBC( PGPCBCContextRef ref, const void *key, + const void *initializationVector ); + +/*____________________________________________________________________________ + Call repeatedly to process arbitrary amounts of data. Each call must + have bytesIn be a multiple of the cipher block size. +____________________________________________________________________________*/ + +PGPError PGPCBCEncrypt( PGPCBCContextRef ref, const void *in, + PGPSize bytesIn, void *out ); + +PGPError PGPCBCDecrypt( PGPCBCContextRef ref, const void *in, + PGPSize bytesIn, void *out ); + +/*____________________________________________________________________________ + Get the symmetric cipher being used for this CBC context. + You can use this to determine useful things about the underlying cipher + such as its block size. +____________________________________________________________________________*/ + +PGPError PGPCBCGetSymmetricCipher( PGPCBCContextRef ref, + PGPSymmetricCipherContextRef *outRef ); + +PGP_END_C_DECLARATIONS + +#endif /* ] Included_pgpCBC_h */ + + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk8/include/pgpCFB.h b/CryptoPP/PGPw/sdk8/include/pgpCFB.h new file mode 100644 index 0000000..9745f96 --- /dev/null +++ b/CryptoPP/PGPw/sdk8/include/pgpCFB.h @@ -0,0 +1,115 @@ +/*____________________________________________________________________________ + Copyright (C) 2002 PGP Corporation + All rights reserved. + + $Id: pgpCFB.h,v 1.6 2002/08/06 20:11:16 dallen Exp $ +____________________________________________________________________________*/ + +#ifndef Included_pgpCFB_h /* [ */ +#define Included_pgpCFB_h + +#include "pgpSymmetricCipher.h" + +PGP_BEGIN_C_DECLARATIONS + +/*____________________________________________________________________________ + A CFB context requires use of a symmetric cipher which has been created + and whose key has been set. An error will be returned if this is not + the case. + + After the call, the CFBRef "owns" the symmetric ref and will + dispose of it properly (even if an error occurs). + The caller should no longer reference it. +____________________________________________________________________________*/ + +PGPError PGPNewCFBContext( PGPSymmetricCipherContextRef ref, + PGPUInt16 interleaveFactor, + PGPCFBContextRef *outRef ); + +/*____________________________________________________________________________ + Disposal clears all data in memory before releasing it. +____________________________________________________________________________*/ + +PGPError PGPFreeCFBContext( PGPCFBContextRef ref ); + +/*____________________________________________________________________________ + Make an exact copy, including current state. Original is not changed. +____________________________________________________________________________*/ + +PGPError PGPCopyCFBContext( PGPCFBContextRef ref, + PGPCFBContextRef *outRef ); + +/*____________________________________________________________________________ + IV size is implicit (same size as the symmetric cipher block size). + IV is *copied*. + Caller may want to destroy the original after passing it in. + Calling this implicitly calls PGPResetCFB(). +____________________________________________________________________________*/ + +PGPError PGPInitCFB( PGPCFBContextRef ref, const void *key, + const void *initializationVector ); + +/*____________________________________________________________________________ + Call repeatedly to process arbitrary amounts of data. +____________________________________________________________________________*/ + +PGPError PGPCFBEncrypt( PGPCFBContextRef ref, const void *in, + PGPSize bytesIn, void *out ); + +PGPError PGPCFBDecrypt( PGPCFBContextRef ref, const void *in, + PGPSize bytesIn, void *out ); + +/*____________________________________________________________________________ + Get the symmetric cipher being used for this CFB context. + You can use this to determine useful things about the underlying cipher + such as its block size. +____________________________________________________________________________*/ + +PGPError PGPCFBGetSymmetricCipher(PGPCFBContextRef ref, + PGPSymmetricCipherContextRef *outRef ); + +/*____________________________________________________________________________ + Reset the feedback mechanism to use whatever we have so far, plus previous + bytes for a total of the cipher block size bytes. This effectively + changes the cipher block boundary. +____________________________________________________________________________*/ + +PGPError PGPCFBSync( PGPCFBContextRef ref ); + +/*____________________________________________________________________________ + Fetch random bytes from the cipher. Returns the actual number of + random bytes obtained. +____________________________________________________________________________*/ + +PGPError PGPCFBGetRandom( PGPCFBContextRef ref, PGPSize requestCount, + void *out, PGPSize *outCount); + +/*____________________________________________________________________________ + Make more random bytes available using the supplied salt, which must + be the same as the symmetric cipher block size. +____________________________________________________________________________*/ + +PGPError PGPCFBRandomCycle( PGPCFBContextRef ref, const void *salt); + +/*____________________________________________________________________________ + Make more random bytes available using the supplied salt, which must + be the same as the symmetric cipher block size. +____________________________________________________________________________*/ + +PGPError PGPCFBRandomWash( PGPCFBContextRef ref, const void *in, + PGPSize bytesIn ); + + +PGP_END_C_DECLARATIONS + +#endif /* ] Included_pgpCFB_h */ + + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk8/include/pgpConfig.h b/CryptoPP/PGPw/sdk8/include/pgpConfig.h new file mode 100644 index 0000000..f2e9f88 --- /dev/null +++ b/CryptoPP/PGPw/sdk8/include/pgpConfig.h @@ -0,0 +1,96 @@ +/* + * pgpConfig.h -- Configuration for the PGPsdk. This file contains + * the configuration information for the PGPsdk, and it should be + * included in all PGPsdk source files. + * + * $Id: pgpConfig.h,v 1.1.1.1 1999/08/08 19:38:33 heller Exp $ + */ + +/* Define to empty if the compiler does not support 'const' variables. */ +/* #undef const */ + +/* Define to `long' if doesn't define. */ +/* #undef off_t */ + +/* Define to `unsigned' if doesn't define. */ +/* #undef size_t */ + + +#ifndef Included_pgpConfig_h /* [ */ +#define Included_pgpConfig_h + +#include "pgpPFLConfig.h" + + + + + +#ifndef Included_pgpPFLConfig_h /* [ */ + +#define HAVE_STDARG_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_UNISTD_H 0 +#define HAVE_USHORT 0 +#define HAVE_UINT 0 +#define HAVE_ULONG 0 +#define NO_LIMITS_H 0 +#define NO_POPEN 1 + +#if defined( _MSC_VER ) +#define PGP_HAVE64 1 +typedef __int64 PGPInt64; +typedef unsigned __int64 PGPUInt64; + +#elif defined( __MWERKS__ ) + +#define PGP_HAVE64 0 + +#endif + + + +#endif /*Included_pgpPFLConfig_h*/ /* ] */ + + +/* Checks for various types */ +#define HAVE_UCHAR 0 + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Checks for various specific header files */ +#define HAVE_FCNTL_H 1 +#define HAVE_LIMITS_H 1 +#define HAVE_SYS_IOCTL_H 0 +#define HAVE_SYS_TIME_H 0 +#define HAVE_SYS_TIMEB_H 1 +#define HAVE_SYS_PARAM_H 0 + +/* Check if is broken and #includes wrong */ +#define TIME_WITH_SYS_TIME 0 + +/* Checks for various functions */ +#define HAVE_GETHRTIME 0 +#define HAVE_CLOCK_GETTIME 0 +#define HAVE_CLOCK_GETRES 0 +#define HAVE_GETTIMEOFDAY 0 +#define HAVE_GETITIMER 0 +#define HAVE_SETITIMER 0 +#define HAVE_FTIME 1 +#define HAVE_MKSTEMP 0 + + +#if defined( __MWERKS__ ) + +#define PGPTTYE /* nothing */ + +#elif defined( _MSC_VER ) + +/* Tags for exported functions, needed for dynamic linking on some platforms */ +#define PGPTTYE /* nothing */ + +#endif + + + +#endif /* ] Included_pgpConfig_h */ diff --git a/CryptoPP/PGPw/sdk8/include/pgpEC.h b/CryptoPP/PGPw/sdk8/include/pgpEC.h new file mode 100644 index 0000000..c12ded4 --- /dev/null +++ b/CryptoPP/PGPw/sdk8/include/pgpEC.h @@ -0,0 +1,78 @@ +/*____________________________________________________________________________ + Copyright (C) 2002 PGP Corporation + All rights reserved. + + $Id: pgpEC.h,v 1.12 2003/12/13 01:20:39 dallen Exp $ +____________________________________________________________________________*/ + +#ifndef PGP_EC_PUB_H +#define PGP_EC_PUB_H + +PGP_BEGIN_C_DECLARATIONS + +/* Wrapper for the ec* routines and data types. + These are exported functions from PGPsdk + */ + +typedef signed char ** PGPECContextRef; +typedef signed short ** PGPECPointRef; +typedef signed int ** PGPECScalarRef; + +enum PGPECMemoryUsage_ +{ + kPGPECMemoryMedium = 0, + kPGPECMemoryHigh = 1, + + PGP_ENUM_FORCE( PGPECMemoryUsage_ ) +}; +PGPENUM_TYPEDEF( PGPECMemoryUsage_, PGPECMemoryUsage ); + +PGPError PGPECCreate2mContext( PGPMemoryMgrRef memoryMgr, + PGPSize bitsize, PGPECMemoryUsage memUsage, + PGPECContextRef *c ); + +PGPError PGPECFreeContext( PGPECContextRef p ); + +PGPError PGPECSetEC2mParamA( PGPECContextRef c, const unsigned *a ); +PGPError PGPECSetEC2mParamB( PGPECContextRef c, const unsigned *b ); +PGPError PGPECSetEC2mParamAInt( PGPECContextRef c, unsigned a ); +PGPError PGPECSetEC2mParamBInt( PGPECContextRef c, unsigned b ); + +PGPError PGPECGetBufferSize( PGPECContextRef c, + PGPSize *coordinateSize, PGPSize *scalarSize, + PGPSize *pointDecomprSize, PGPSize *pointComprSize ); + +PGPError PGPECScalarCreate( PGPECContextRef c, PGPECScalarRef *s, PGPBoolean isSecure ); +PGPError PGPECScalarFree( PGPECScalarRef s ); +PGPError PGPECScalarInsertBytes( PGPECScalarRef s, + const PGPByte *scalar /*network order*/, PGPECScalarRef G_ord ); + +PGPError PGPECPointCreate( PGPECContextRef c, PGPECPointRef *p ); +PGPError PGPECPointFree( PGPECPointRef p ); + +PGPError PGPECPointExtractBytes( PGPECPointRef p, PGPByte *out, unsigned flags ); +PGPError PGPECPointExtractXYBytes( PGPECPointRef p, PGPByte *out_x, PGPByte *out_y, unsigned flags ); +PGPError PGPECPointInsertBytes( PGPECPointRef p, const PGPByte *in, unsigned flags ); + +PGPError PGPECPointAssignContext( PGPECPointRef p, PGPECContextRef c ); + +PGPError PGPECPointPrefBasis( PGPECPointRef p ); + +PGPError PGPECPointMul( PGPECPointRef p, + PGPECScalarRef scalar, + PGPBoolean isPrecomputed, /* PGPECPointPrecomp already called */ + PGPECPointRef out ); + +PGPError PGPECPointAdd( PGPECPointRef p0, const PGPECPointRef p1, PGPECPointRef sum ); + +PGPError PGPECPointSetZero( PGPECPointRef p ); +PGPBoolean PGPECPointIsZero( PGPECPointRef p ); + +PGPBoolean PGPECPointIsConsistent( PGPECPointRef p ); + +PGPError PGPECPointCompress( PGPECPointRef p ); +PGPError PGPECPointDecompress( PGPECPointRef p ); + +PGP_END_C_DECLARATIONS + +#endif /* PGP_EC_PUB_H */ diff --git a/CryptoPP/PGPw/sdk8/include/pgpEncode.h b/CryptoPP/PGPw/sdk8/include/pgpEncode.h new file mode 100644 index 0000000..9f2830d --- /dev/null +++ b/CryptoPP/PGPw/sdk8/include/pgpEncode.h @@ -0,0 +1,306 @@ +/*____________________________________________________________________________ + Copyright (C) 2002 PGP Corporation + All rights reserved. + + This file contains the prototypes for functions which encode/decode files + and buffers. + + $Id: pgpEncode.h,v 1.20 2003/09/24 03:09:32 ajivsov Exp $ +____________________________________________________________________________*/ + +#ifndef Included_pgpEncode_h /* [ */ +#define Included_pgpEncode_h + +#include "pgpPubTypes.h" +#include "pgpTLS.h" + +#if PGP_MACINTOSH +#pragma options align=mac68k +#endif + +/*____________________________________________________________________________ + PGP Events + + The PGPEvent structure is used to notify clients of the encode API of + various events. Each event is denoted by an event type: +____________________________________________________________________________*/ + +enum PGPEventType_ +{ + kPGPEvent_NullEvent = 0, /* Nothing happened */ + kPGPEvent_InitialEvent = 1, /* Final event */ + kPGPEvent_FinalEvent = 2, /* Final event */ + kPGPEvent_ErrorEvent = 3, /* An error occurred */ + kPGPEvent_WarningEvent = 4, /* Warning event */ + kPGPEvent_EntropyEvent = 5, /* More entropy is needed */ + kPGPEvent_PassphraseEvent = 6, /* A passphrase is needed */ + kPGPEvent_InsertKeyEvent = 7, /* Smart card must be inserted */ + kPGPEvent_AnalyzeEvent = 8, /* Initial analysis event, + before any output */ + kPGPEvent_RecipientsEvent = 9, /* Recipient list report, + before any output */ + kPGPEvent_KeyFoundEvent = 10, /* Key packet found */ + kPGPEvent_OutputEvent = 11, /* Output specification needed */ + kPGPEvent_SignatureEvent = 12, /* Signature status report */ + kPGPEvent_BeginLexEvent = 13, /* Initial event per lexical unit*/ + kPGPEvent_EndLexEvent = 14, /* Final event per lexical unit */ + kPGPEvent_RecursionEvent = 15, /* Notification of recursive + job creation */ + kPGPEvent_DetachedSignatureEvent = 16, /* Need input for verification of + detached signature */ + kPGPEvent_KeyGenEvent = 17, /* Key generation progress */ + + kPGPEvent_KeyServerEvent = 18, /* Key Server progress */ + kPGPEvent_KeyServerSignEvent= 19, /* Key Server passphrase */ + kPGPEvent_KeyServerTLSEvent = 20, /* Key Server TLS event */ + kPGPEvent_KeyServerIdleEvent= 21, /* Idle during keyserver call */ + + kPGPEvent_SocketsIdleEvent = 22, /* Idle during sockets */ + kPGPEvent_DecryptionEvent = 23, /* Decryption data report */ + kPGPEvent_EncryptionEvent = 24, /* Encryption data report */ + + kPGPEvent_ToBeSignedEvent = 25, /* To-be-signed hash */ + + PGP_ENUM_FORCE( PGPEventType_ ) +}; +PGPENUM_TYPEDEF( PGPEventType_, PGPEventType ); + + +/* PGP Analyze event callback codes */ + +enum PGPAnalyzeType_ +{ + kPGPAnalyze_Encrypted = 0, /* Encrypted message */ + kPGPAnalyze_Signed = 1, /* Signed message */ + kPGPAnalyze_DetachedSignature = 2, /* Detached signature */ + kPGPAnalyze_Key = 3, /* Key data */ + kPGPAnalyze_Unknown = 4, /* Non-pgp message */ + kPGPAnalyze_X509Certificate = 5, /* X.509 certificate */ + kPGPAnalyze_SMIMEBody = 6, /* SMIME body */ + + PGP_ENUM_FORCE( PGPAnalyzeType_ ) +}; +PGPENUM_TYPEDEF( PGPAnalyzeType_, PGPAnalyzeType ); + +/* Individual event information structs, combined as a union in PGPEvent */ + +typedef struct PGPEventNullData_ +{ + PGPFileOffset bytesWritten; + PGPFileOffset bytesTotal; +} PGPEventNullData; + +typedef struct PGPEventErrorData_ +{ + PGPError error; + void *errorArg; +} PGPEventErrorData; + +typedef struct PGPEventWarningData_ +{ + PGPError warning; + void *warningArg; +} PGPEventWarningData; + +typedef struct PGPEventEntropyData_ +{ + PGPUInt32 entropyBitsNeeded; +} PGPEventEntropyData; + +typedef struct PGPEventPassphraseData_ +{ + PGPBoolean fConventional; + PGPKeySetRef keyset; + const PGPByte *ESKs; + PGPSize ESKsLength; +} PGPEventPassphraseData; + +typedef struct PGPEventRecipientsData_ +{ + PGPKeySetRef recipientSet; + PGPUInt32 conventionalPassphraseCount; + PGPUInt32 keyCount; + PGPKeyID const * keyIDArray; +} PGPEventRecipientsData; + +typedef struct PGPEventKeyFoundData_ +{ + PGPKeyDBRef keyDB; +} PGPEventKeyFoundData; + +typedef struct PGPEventSignatureData_ +{ + PGPKeyID signingKeyID; + PGPKeyDBObjRef signingKey; + PGPBoolean checked; + PGPBoolean verified; + PGPBoolean keyRevoked; + PGPBoolean keyDisabled; + PGPBoolean keyExpired; + PGPBoolean keyMeetsValidityThreshold; + PGPValidity keyValidity; + PGPTime creationTime; + PGPUInt32 expirationPeriod; +} PGPEventSignatureData; + +typedef struct PGPEventDecryptionData_ +{ + PGPCipherAlgorithm cipherAlgorithm; + PGPByte *sessionKey; + PGPSize sessionKeyLength; + PGPUInt32 keyCount; /* keyids of keys that can decrypt, */ + PGPKeyID const * keyIDArray; /* a subset of keys in PGPEventRecipientsData */ +} PGPEventDecryptionData; + +typedef struct PGPEventEncryptionData_ +{ + PGPCipherAlgorithm cipherAlgorithm; + PGPByte *sessionKey; + PGPSize sessionKeyLength; +} PGPEventEncryptionData; + +typedef struct PGPEventAnalyzeData_ +{ + PGPAnalyzeType sectionType; +} PGPEventAnalyzeData; + +typedef struct PGPEventOutputData_ +{ + PGPUInt32 messageType; + PGPChar8 *suggestedName; + PGPBoolean forYourEyesOnly; +} PGPEventOutputData; + +typedef struct PGPEventBeginLexData_ +{ + PGPUInt32 sectionNumber; + PGPSize sectionOffset; +} PGPEventBeginLexData; + +typedef struct PGPEventEndLexData_ +{ + PGPUInt32 sectionNumber; +} PGPEventEndLexData; + +typedef struct PGPEventKeyGenData_ +{ + PGPUInt32 state; +} PGPEventKeyGenData; + +typedef struct PGPEventKeyServerData_ +{ + PGPKeyServerRef keyServerRef; + PGPUInt32 state; /* PGPKeyServerState */ +} PGPEventKeyServerData; + +typedef struct PGPEventKeyServerSignData_ +{ + PGPKeyServerRef keyServerRef; +} PGPEventKeyServerSignData; + +typedef struct PGPEventKeyServerTLSData_ +{ + PGPKeyServerRef keyServerRef; + PGPUInt32 state; /* PGPKeyServerState */ + PGPtlsSessionRef tlsSession; +} PGPEventKeyServerTLSData; + +typedef struct PGPEventKeyServerIdleData_ +{ + PGPKeyServerRef keyServerRef; +} PGPEventKeyServerIdleData; + +typedef struct PGPEventToBeSignedData_ +{ + PGPKeyID keyID; + PGPHashAlgorithm hashAlg; + PGPByte hash[512/8]; + PGPSize hashSize; +} PGPEventToBeSignedData; + +/* + * The following events have no event-specific data defined for them: + * kPGPEvent_InsertKeyEvent + * kPGPEvent_RecursionEvent + * kPGPEvent_DetachedSignatureEvent + * kPGPEvent_InitialEvent + * kPGPEvent_FinalEvent + * kPGPEvent_SocketsIdleEvent + */ + +/* Union of all event data structures above */ +typedef union PGPEventData_ +{ + PGPEventNullData nullData; + PGPEventErrorData errorData; + PGPEventWarningData warningData; + PGPEventEntropyData entropyData; + PGPEventPassphraseData passphraseData; + PGPEventRecipientsData recipientsData; + PGPEventKeyFoundData keyFoundData; + PGPEventSignatureData signatureData; + PGPEventDecryptionData decryptionData; + PGPEventEncryptionData encryptionData; + PGPEventAnalyzeData analyzeData; + PGPEventOutputData outputData; + PGPEventBeginLexData beginLexData; + PGPEventEndLexData endLexData; + PGPEventKeyGenData keyGenData; + PGPEventKeyServerData keyServerData; + PGPEventKeyServerSignData keyServerSignData; + PGPEventKeyServerTLSData keyServerTLSData; + PGPEventKeyServerIdleData keyServerIdleData; + PGPEventToBeSignedData tbsData; +} PGPEventData; + +/* Refs to internal "job" structure */ +typedef struct PGPJob * PGPJobRef; + +#define kInvalidPGPJobRef ((PGPJobRef) NULL) +#define PGPJobRefIsValid( ref ) ( (ref) != kInvalidPGPJobRef ) + +/* PGPEvent structure */ + +struct PGPEvent +{ + PGPVersion version; /* Version of event structure */ + struct PGPEvent_ *nextEvent; /* Allow lists of events */ + PGPJobRef job; /* Associated with what job */ + PGPEventType type; /* Type of event */ + PGPEventData data; /* Event specific data */ +}; +typedef struct PGPEvent PGPEvent; + + +#if PGP_MACINTOSH +#pragma options align=reset +#endif + +PGP_BEGIN_C_DECLARATIONS + +/* +** Functions to encode and decode. The variable parameters are one or more +** PGPOptionListRef's which describe the inputs, outputs, and options. +*/ + +PGPError PGPEncode(PGPContextRef context, + PGPOptionListRef firstOption, ...); +PGPError PGPDecode(PGPContextRef context, + PGPOptionListRef firstOption, ...); + +PGPError PGPAddJobOptions(PGPJobRef job, + PGPOptionListRef firstOption, ...); + +PGP_END_C_DECLARATIONS + +#endif /* ] Included_pgpEncode_h */ + + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk8/include/pgpErrors.h b/CryptoPP/PGPw/sdk8/include/pgpErrors.h new file mode 100644 index 0000000..7174b0a --- /dev/null +++ b/CryptoPP/PGPw/sdk8/include/pgpErrors.h @@ -0,0 +1,393 @@ +/*____________________________________________________________________________ + Copyright (C) 2002 PGP Corporation + All rights reserved. + + Error codes for all PGPsdk errors can be found in this file. + + $Id: pgpErrors.h,v 1.28 2004/04/26 21:23:53 vinnie Exp $ +____________________________________________________________________________*/ + +#ifndef Included_pgpErrors_h /* [ */ +#define Included_pgpErrors_h + +#include "pgpPubTypes.h" + + +#include "pgpPFLErrors.h" + +#define kPGPErrorRange 1000 + +enum PGPError_ +{ + /* + NOTE: error code values must not be changed; + compiled client code depends on them. + */ + kPGPError_FirstError = -11500, + kPGPError_Last = -10500, + + kPGPError_BadPassphrase = -11500, + kPGPError_OptionNotFound = -11499, + +/* Errors from pgpEncode */ + kPGPError_RedundantOptions = -11498, + kPGPError_KeyRevoked = -11497, + kPGPError_KeyExpired = -11496, + kPGPError_KeyDisabled = -11495, + kPGPError_KeyInvalid = -11494, + kPGPError_KeyUnusableForEncryption = -11493, + kPGPError_KeyUnusableForSignature = -11492, + kPGPError_OutputBufferTooSmall = -11491, + kPGPError_InconsistentEncryptionAlgorithms = -11490, + kPGPError_MissingPassphrase = -11489, + kPGPError_CombinedConventionalAndPublicEncryption= -11488, + kPGPError_DetachedSignatureWithoutSigningKey= -11487, + kPGPError_DetachedSignatureWithEncryption = -11486, + kPGPError_NoInputOptions = -11485, + kPGPError_MultipleInputOptions = -11484, + kPGPError_InputFile = -11483, + kPGPError_NoOutputOptions = -11482, + kPGPError_MultipleOutputOptions = -11481, + kPGPError_MissingEventHandler = -11480, + kPGPError_MissingKeyDB = -11479, + kPGPError_DetachedSignatureFound = -11478, + kPGPError_NoDecryptionKeyFound = -11477, + kPGPError_CorruptSessionKey = -11476, + kPGPError_SkipSection = -11475, + kPGPError_Interrupted = -11474, + kPGPError_TooManyARRKs = -11473, + kPGPError_KeyUnusableForDecryption = -11472, + kPGPError_KeygenTimedOut = -11471, + + kPGPError_IncompatibleAPI = -11460, + +/* misc errors */ + kPGPError_CompressionFailed = -11453, + kPGPError_UnTARFailed = -11452, + kPGPError_MinorUnTARError = -11451, + kPGPError_NotMacBinary = -11450, + kPGPError_NoMacBinaryTranslationAvailable = -11449, + kPGPError_BadSignature = -11448, + kPGPError_CAPIUnsupportedKey = -11447, + kPGPError_SelfTestFailed = -11446, + kPGPError_SelfTestsNotExecuted = -11445, + kPGPError_BadIntegrity = -11444, + kPGPError_DeCompressionFailed = -11443, + kPGPError_DeletingSelfSig = -11442, + +/* filter errors */ + + kPGPError_InconsistentFilterClasses = -11440, + kPGPError_UnsupportedLDAPFilter = -11439, + kPGPError_UnsupportedHKPFilter = -11438, + kPGPError_UnknownFilterType = -11437, + kPGPError_InvalidFilterParameter = -11436, + kPGPError_UnsupportedNetToolsCAFilter = -11435, + +/* old errors: */ + + kPGPError_OutOfRings = -11420, + kPGPError_BadHashNumber = -11419, + kPGPError_BadCipherNumber = -11418, + kPGPError_BadKeyLength = -11417, + kPGPError_SizeAdviseFailure = -11416, + kPGPError_ConfigParseFailure = -11415, + kPGPError_ConfigParseFailureBadFunction = -11414, + kPGPError_ConfigParseFailureBadOptions = -11413, + kPGPError_KeyIsLocked = -11412, + kPGPError_CantDecrypt = -11411, + kPGPError_UnknownString2Key = -11410, + kPGPError_BadSessionKeySize = -11409, + kPGPError_UnknownVersion = -11408, + kPGPError_BadSessionKeyAlgorithm = -11407, + kPGPError_UnknownSignatureType = -11406, + kPGPError_BadSignatureSize = -11405, + kPGPError_SignatureBitsWrong = -11404, + kPGPError_ExtraDateOnSignature = -11403, + kPGPError_SecretKeyNotFound = -11402, + kPGPError_AdditionalRecipientRequestKeyNotFound = -11401, + kPGPError_InvalidCommit = -11400, + kPGPError_CantHash = -11399, + kPGPError_UnbalancedScope = -11398, + kPGPError_WrongScope = -11397, + kPGPError_FIFOReadError = -11396, + kPGPError_RandomSeedTooSmall = -11395, + kPGPError_EnvPriorityTooLow = -11394, + kPGPError_UnknownCharMap = -11393, + kPGPError_AsciiParseIncomplete = -11392, + kPGPError_BadPacket = -11391, + + kPGPError_TroubleKeySubKey = -11390, + kPGPError_TroubleSigSubKey = -11389, + kPGPError_TroubleBadTrust = -11388, + kPGPError_TroubleUnknownPacketByte = -11387, + kPGPError_TroubleUnexpectedSubKey = -11386, + kPGPError_TroubleUnexpectedName = -11385, + kPGPError_TroubleUnexpectedSignature = -11384, + kPGPError_TroubleUnexpectedUnknown = -11383, + kPGPError_TroubleUnexpectedTrust = -11382, + kPGPError_TroubleKeyTooBig = -11381, + kPGPError_TroubleSecretKeyTooBig = -11380, + kPGPError_TroubleNameTooBig = -11379, + kPGPError_TroubleSignatureTooBig = -11378, + kPGPError_TroubleUnknownTooBig = -11377, + kPGPError_TroubleDuplicateKeyID = -11376, + kPGPError_TroubleDuplicateKey = -11375, + kPGPError_TroubleDuplicateSecretKey = -11374, + kPGPError_TroubleDuplicateName = -11373, + kPGPError_TroubleDuplicateSignature = -11372, + kPGPError_TroubleDuplicateUnknown = -11371, + kPGPError_TroubleBareKey = -11370, + kPGPError_TroubleVersionBugPrev = -11369, + kPGPError_TroubleVersionBugCur = -11368, + kPGPError_TroubleOldSecretKey = -11367, + kPGPError_TroubleNewSecretKey = -11366, + kPGPError_TroubleImportingNonexportableSignature= -11365, + kPGPError_TroubleDuplicateCRL = -11364, + kPGPError_TroubleCRLTooBig = -11363, + + kPGPError_BadCompressionNumber = -11362, + + /* + * The set of errors in this range are the ones which will NOT abort + * a keyring check operation. These errors just make us skip the key + * and go on to the next. + */ +kPGPError_KEY_MIN = -11350, + kPGPError_KEY_LONG = kPGPError_KEY_MIN, + kPGPError_KeyPacketTruncated = -11349, + kPGPError_UnknownKeyVersion = -11348, + kPGPError_UnknownPublicKeyAlgorithm = -11347, + kPGPError_MalformedKeyModulus = -11346, + kPGPError_MalformedKeyExponent = -11345, + kPGPError_RSAPublicModulusIsEven = -11344, + kPGPError_RSAPublicExponentIsEven = -11343, + kPGPError_MalformedKeyComponent = -11342, + kPGPError_KeyTooLarge = -11341, + kPGPError_PublicKeyTooSmall = -11340, + kPGPError_PublicKeyTooLarge = -11339, + kPGPError_PublicKeyUnimplemented = -11338, + kPGPError_CRLPacketTruncated = -11337, + kPGPError_CorruptPrivateKey = -11336, + kPGPError_UnknownPaddingType = -11335, +kPGPError_KEY_MAX = kPGPError_CorruptPrivateKey, + + +/* kPGPError_SIG_MAX */ + kPGPError_SIG_LONG = -11330, + kPGPError_TruncatedSignature = -11329, + kPGPError_MalformedSignatureInteger = -11328, + kPGPError_UnknownSignatureAlgorithm = -11327, + kPGPError_ExtraSignatureMaterial = -11326, + kPGPError_UnknownSignatureVersion = -11325, + kPGPError_RevocationKeyNotFound = -11324, +/* kPGPError_SIG_MIN */ + +/* kPGPError_KEYDB_MAX */ + kPGPError_OutOfEntropy = -11320, + kPGPError_ItemIsReadOnly = -11319, + kPGPError_InvalidProperty = -11318, + kPGPError_FileCorrupt = -11317, + kPGPError_DuplicateCert = -11316, + kPGPError_DuplicateUserID = -11315, + kPGPError_CertifyingKeyDead = -11314, + kPGPError_ItemWasDeleted = -11313, + kPGPError_KeyDBMismatch = -11312, +/* kPGPError_KEYDB_MIN = kPGPError_KeyDBMismatch */ + +/* kPGPError_SERVER_MAX */ + kPGPError_ServerInProgress = -11300, + kPGPError_ServerOperationNotSupported = -11299, + kPGPError_ServerInvalidProtocol = -11298, + kPGPError_ServerRequestFailed = -11297, + kPGPError_ServerOpen = -11296, + kPGPError_ServerNotOpen = -11295, + kPGPError_ServerKeyAlreadyExists = -11294, + kPGPError_ServerNotInitialized = -11293, + kPGPError_ServerPartialAddFailure = -11292, + kPGPError_ServerCorruptKeyBlock = -11291, + kPGPError_ServerUnknownResponse = -11290, + kPGPError_ServerTimedOut = -11289, + kPGPError_ServerOpenFailed = -11288, + kPGPError_ServerAuthorizationRequired = -11287, + kPGPError_ServerAuthorizationFailed = -11286, + kPGPError_ServerSearchFailed = -11285, + kPGPError_ServerPartialSearchResults = -11284, + kPGPError_ServerBadKeysInSearchResults = -11283, + kPGPError_ServerKeyFailedPolicy = -11282, + kPGPError_ServerOperationRequiresTLS = -11281, + kPGPError_ServerNoStaticStorage = -11280, + kPGPError_ServerCertNotFound = -11279, + +/* TLS errors */ + kPGPError_TLSUnexpectedClose = -11250, + kPGPError_TLSProtocolViolation = -11249, + kPGPError_TLSVersionUnsupported = -11248, + kPGPError_TLSWrongState = -11247, + kPGPError_TLSAlertReceived = -11246, + kPGPError_TLSKeyUnusable = -11245, + kPGPError_TLSNoCommonCipher = -11244, + kPGPError_TLSWouldBlock = -11243, + kPGPError_TLSRcvdHandshakeRequest = -11242, + +/* X509 certificate errors */ + kPGPError_X509NeededCertNotAvailable = -11240, + kPGPError_X509SelfSignedCert = -11239, + kPGPError_X509InvalidCertificateSignature = -11238, + kPGPError_X509InvalidCertificateFormat = -11237, + kPGPError_X509InvalidCertificateTree = -11236, + +/* Key Splitting errors */ + kPGPError_SplitNotEnoughSharesInObject = -11230, + kPGPError_SplitDifferentSplitKeys = -11229, + kPGPError_SplitDifferentSharePool = -11228, + kPGPError_SplitIdenticalShares = -11227, + kPGPError_SKEPRejectedAuthentication = -11226, + kPGPError_SKEPIncorrectVersion = -11225, + +/* SECSH errors */ + kPGPError_SECSHUnexpectedClose = -11220, + kPGPError_SECSHProtocolViolation = -11219, + kPGPError_SECSHVersionUnsupported = -11218, + kPGPError_SECSHWrongState = -11217, + kPGPError_SECSHAlertReceived = -11216, + kPGPError_SECSHKeyUnusable = -11215, + kPGPError_SECSHNoCommonCipher = -11214, + kPGPError_SECSHWouldBlock = -11213, + kPGPError_SECSHRcvdHandshakeRequest = -11212, + + kPGPError_BigNumNoInverse = -11150, + +/* PGPSockets errors */ + kPGPError_SocketsNetworkDown = -11100, + kPGPError_SocketsNotInitialized = -11099, + kPGPError_SocketsInProgress = -11098, + kPGPError_SocketsNotConnected = -11097, + kPGPError_SocketsNotBound = -11096, + kPGPError_SocketsOperationNotSupported = -11095, + kPGPError_SocketsProtocolNotSupported = -11094, + kPGPError_SocketsAddressFamilyNotSupported = -11093, + kPGPError_SocketsNotASocket = -11092, + kPGPError_SocketsAddressInUse = -11091, + kPGPError_SocketsBufferOverflow = -11090, + kPGPError_SocketsListenQueueFull = -11089, + kPGPError_SocketsAddressNotAvailable = -11088, + kPGPError_SocketsAlreadyConnected = -11087, + kPGPError_SocketsTimedOut = -11086, + kPGPError_SocketsNoStaticStorage = -11085, + + kPGPError_SocketsHostNotFound = -11050, + kPGPError_SocketsDomainServerError = -11049, + +/* Errors from X.509 layer */ + kPGPError_X509AttributeNotSupported = -10999, + kPGPError_InvalidPKCS7Encoding = -10998, + kPGPError_CMSInitialization = -10997, + kPGPError_InvalidDistinguishedName = -10996, + kPGPError_CertRequestCreationFailure = -10995, + kPGPError_MissingX509Certificate = -10994, + kPGPError_PKCS7SignFailure = -10993, + kPGPError_ASNPackFailure = -10992, + kPGPError_InvalidInputFormat = -10991, + kPGPError_InvalidOutputFormat = -10990, + kPGPError_InvalidCertificateExtension = -10989, + kPGPError_PublicKeyNotFound = -10988, + + kPGPError_CRSMissingRequiredAttribute = -10979, + kPGPError_CRSInvalidCharacter = -10978, + kPGPError_CRSInvalidAttributeType = -10977, + kPGPError_CRSInvalidCertType = -10976, + kPGPError_CRSInvalidAttributeValueLength = -10975, + kPGPError_CRSInvalidAuthenticateValue = -10974, + + kPGPError_X509CertificateParseError = -10973, + kPGPError_PKCS7EncryptFailure = -10972, + kPGPError_PKCS7DecryptFailure = -10971, + + kPGPError_InvalidCertificateFormat = -11970, + +/* LDAP Errors */ +kPGPError_LDAPMIN = -10950, + kPGPError_LDAPOperationsError = kPGPError_LDAPMIN, + kPGPError_LDAPProtocolError = -10949, + kPGPError_LDAPTimelimitExceeded = -10948, + kPGPError_LDAPSizelimitExceeded = -10947, + kPGPError_LDAPStrongAuthNotSupported = -10946, + kPGPError_LDAPStrongAuthRequired = -10945, + kPGPError_LDAPPartialResults = -10944, + kPGPError_LDAPNoSuchAttribute = -10943, + kPGPError_LDAPUndefinedType = -10942, + kPGPError_LDAPInappropriateMatching = -10941, + kPGPError_LDAPConstraintViolation = -10940, + kPGPError_LDAPTypeOrValueExists = -10939, + kPGPError_LDAPInvalidSyntax = -10938, + kPGPError_LDAPNoSuchObject = -10937, + kPGPError_LDAPAliasProblem = -10936, + kPGPError_LDAPInvalidDNSyntax = -10935, + kPGPError_LDAPIsLeaf = -10934, + kPGPError_LDAPAliasDerefProblem = -10933, + kPGPError_LDAPInappropriateAuth = -10932, + kPGPError_LDAPInvalidCredentials = -10931, + kPGPError_LDAPInsufficientAccess = -10930, + kPGPError_LDAPBusy = -10929, + kPGPError_LDAPUnavailable = -10928, + kPGPError_LDAPUnwillingToPerform = -10927, + kPGPError_LDAPLoopDetect = -10926, + kPGPError_LDAPNamingViolation = -10925, + kPGPError_LDAPObjectClassViolation = -10924, + kPGPError_LDAPNotAllowedOnNonleaf = -10923, + kPGPError_LDAPNotAllowedOnRDN = -10922, + kPGPError_LDAPAlreadyExists = -10921, + kPGPError_LDAPNoObjectClassMods = -10920, + kPGPError_LDAPResultsTooLarge = -10919, + kPGPError_LDAPOther = -10918, + kPGPError_LDAPServerDown = -10917, + kPGPError_LDAPLocalError = -10916, + kPGPError_LDAPEncodingError = -10915, + kPGPError_LDAPDecodingError = -10914, + kPGPError_LDAPTimeout = -10913, + kPGPError_LDAPAuthUnknown = -10912, + kPGPError_LDAPFilterError = -10911, + kPGPError_LDAPUserCancelled = -10910, + kPGPError_LDAPParamError = -10909, + kPGPError_LDAPConnectError = -10908, + /* Reserve errors -10907 through -10881 for future LDAP versions */ + kPGPError_LDAPNotLDAPURL = -10880, + kPGPError_LDAPNoDN = -10879, + kPGPError_LDAPBadScope = -10878, +kPGPError_LDAPMAX = kPGPError_LDAPBadScope, + + /* Smart Card Errors */ + kPGPError_SmartCardError = -10850, + kPGPError_SmartCardOutOfMemory = -10849, + kPGPError_SmartCardKeyNotFound = -10848, + kPGPError_SmartCardX509Exists = -10847, + kPGPError_SmartCardKeyExists = -10846, + kPGPError_SmartCardPinLocked = -10845, + kPGPError_SmartCardNotFound = -10844, + + kPGPError_DummyEnumValue + /* kPGPError_Last */ +} ; + + +PGP_BEGIN_C_DECLARATIONS + +#undef PGPGetErrorString +PGPError PGPGetErrorString( PGPError theError, + PGPSize bufferSize, PGPChar8 * theString ); + +PGP_END_C_DECLARATIONS + + +#endif /* ] Included_pgpErrors_h */ + + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk8/include/pgpFeatures.h b/CryptoPP/PGPw/sdk8/include/pgpFeatures.h new file mode 100644 index 0000000..ad628a2 --- /dev/null +++ b/CryptoPP/PGPw/sdk8/include/pgpFeatures.h @@ -0,0 +1,143 @@ +/*____________________________________________________________________________ + Copyright (C) 2002 PGP Corporation + All rights reserved. + + Determine which features are present in the PGPsdk. This is the only + way to correctly determine which features are present. The version + number may be the same for different builds that lack some features. + + $Id: pgpFeatures.h,v 1.13 2004/03/15 19:18:55 vinnie Exp $ +____________________________________________________________________________*/ + +#ifndef Included_pgpFeatures_h /* [ */ +#define Included_pgpFeatures_h + +#include "pgpPubTypes.h" + +#if PGP_MACINTOSH +#pragma options align=mac68k /* [ */ +#endif + +/*____________________________________________________________________________ + Each selector designates a PGPFlags word, which can be obtained via + PGPGetFeatureFlags(). The flags can be tested using the + supplied masks. We can add more selectors as needed. The masks + are not intended to be restricted to a single bit. + Flags should not be used for attributes that have unknown length. + + A kPGPError_ItemNotFound will be returned if the caller specifies + a selector which is not recognized by the PGPsdk. This could + occur if an app links to an older version of the SDK. +____________________________________________________________________________*/ + +/* selectors which are passed to PGPGetFeatureFlags */ +enum PGPFeatureSelector_ +{ + kPGPFeatures_GeneralSelector = 1, + kPGPFeatures_ImplementationSelector = 2, + + PGP_ENUM_FORCE( PGPFeatureSelector_ ) +}; +PGPENUM_TYPEDEF( PGPFeatureSelector_, PGPFeatureSelector ); + + +/* flags for kPGPFeatures_GeneralSelector */ +enum +{ + kPGPFeatureMask_CanEncrypt = (1UL << 0), + kPGPFeatureMask_CanDecrypt = (1UL << 1), + kPGPFeatureMask_CanSign = (1UL << 2), + kPGPFeatureMask_CanVerify = (1UL << 3), + kPGPFeatureMask_CanGenerateKey = (1UL << 4), + kPGPFeatureMask_RngHardware = (1UL << 5), + kPGPFeatureMask_FIPSmode = (1UL << 6) +}; + +/* flags for kPGPFeatures_ImplementationSelector */ +enum +{ + kPGPFeatureMask_IsDebugBuild = (1UL << 0), + kPGPFeatureMask_HasTimeout = (1UL << 0) +}; + +#define kPGPAlgorithmInfoFlags_FIPS (PGPFlags)(1UL << 1 ) + +typedef struct PGPAlgorithmInfo +{ + PGPChar8 shortName[ 32 ]; + PGPChar8 longName[ 96 ]; + PGPChar8 copyright[ 128 ]; + PGPFlags flags; + PGPUInt32 reserved[ 16 ]; /* reserved; 0 for now */ + +} PGPAlgorithmInfo; + +typedef struct PGPPublicKeyAlgorithmInfo +{ + PGPAlgorithmInfo info; + + PGPPublicKeyAlgorithm algID; + + PGPBoolean canEncrypt; + PGPBoolean canDecrypt; + PGPBoolean canSign; + PGPBoolean canVerify; + PGPBoolean canGenerateKey; + PGPBoolean reserved1; + PGPBoolean reserved2; + PGPBoolean reserved3; + + PGPUInt32 reserved[ 8 ]; + +} PGPPublicKeyAlgorithmInfo; + +typedef struct PGPSymmetricCipherInfo +{ + PGPAlgorithmInfo info; + PGPCipherAlgorithm algID; + + PGPUInt32 reserved[ 8 ]; + +} PGPSymmetricCipherInfo; + +#if PGP_MACINTOSH +#pragma options align=reset /* ] */ +#endif + +PGP_BEGIN_C_DECLARATIONS + +/* return a flags word for the feature selector */ +PGPError PGPGetFeatureFlags( PGPFeatureSelector selector, + PGPFlags *flags ); + +/* use this to test whether a feature exists after getting flags */ +#define PGPFeatureExists( flags, maskValue ) ( ( (flags) & (maskValue) ) != 0 ) + + +/*____________________________________________________________________________ + Routines to determine which algorithms are present. + + To determine if a specific algorithm is available, you will need to + index through the available algorithms and check the algorithm ID. +____________________________________________________________________________*/ + +PGPError PGPCountPublicKeyAlgorithms( PGPUInt32 *numPKAlgs ); +PGPError PGPGetIndexedPublicKeyAlgorithmInfo( PGPUInt32 theIndex, + PGPPublicKeyAlgorithmInfo *info); + +PGPError PGPCountSymmetricCiphers( PGPUInt32 *numPKAlgs ); +PGPError PGPGetIndexedSymmetricCipherInfo( PGPUInt32 theIndex, + PGPSymmetricCipherInfo *info); + +PGP_END_C_DECLARATIONS + +#endif /* ] Included_pgpFeatures_h */ + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk8/include/pgpGroups.h b/CryptoPP/PGPw/sdk8/include/pgpGroups.h new file mode 100644 index 0000000..2f6ebd0 --- /dev/null +++ b/CryptoPP/PGPw/sdk8/include/pgpGroups.h @@ -0,0 +1,315 @@ +/*____________________________________________________________________________ + Copyright (C) 2002 PGP Corporation + All rights reserved. + + $Id: pgpGroups.h,v 1.12 2003/08/08 04:40:39 ajivsov Exp $ +____________________________________________________________________________*/ + +#ifndef Included_pgpGroups_h /* [ */ +#define Included_pgpGroups_h + +/*____________________________________________________________________________ + Note: All functions in this file have been deprecated and will be + replaced in the future with equivalent functionality. +____________________________________________________________________________*/ + +#include "pgpPubTypes.h" +#include "pgpEncode.h" + +#if PGP_DEPRECATED /* [ */ + +#if PGP_MACINTOSH +#include +#endif + +#if PGP_MACINTOSH +#pragma options align=mac68k +#endif + +#define kPGPMaxGroupNameLength 63 +#define kPGPMaxGroupDescriptionLength 63 + +typedef PGPChar8 PGPGroupName[ kPGPMaxGroupNameLength + 1 ]; +typedef PGPChar8 PGPGroupDescription[ kPGPMaxGroupDescriptionLength + 1 ]; + + +typedef struct PGPGroupSet * PGPGroupSetRef; +typedef struct PGPGroupIter * PGPGroupItemIterRef; + +#define kInvalidPGPGroupSetRef ((PGPGroupSetRef) NULL) +#define kInvalidPGPGroupItemIterRef ((PGPGroupItemIterRef) NULL) + +#define PGPGroupSetRefIsValid(ref) ((ref) != kInvalidPGPGroupSetRef) +#define PGPGroupItemIterRefIsValid(ref) ((ref) != kInvalidPGPGroupItemIterRef) + +/* any type will do that is distinct */ +typedef PGPUInt32 PGPGroupID; +#define kPGPInvalidGroupID ( (PGPGroupID)0 ) + +enum PGPGroupItemType_ +{ + kPGPGroupItem_KeyID = 1, + kPGPGroupItem_Group, + + PGP_ENUM_FORCE( PGPGroupItemType_) +}; +PGPENUM_TYPEDEF( PGPGroupItemType_, PGPGroupItemType ); + +/*____________________________________________________________________________ + A run-time group item, used when iterating through a group. + For client use; not necessarily the internal storage format. + + 'userValue' is *not* saved to disk. +____________________________________________________________________________*/ + +typedef struct PGPGroupItem +{ + PGPGroupItemType type; + PGPUserValue userValue; + + union + { + PGPGroupID groupID; + PGPKeyID keyID; + } u; +} PGPGroupItem; + + +typedef PGPInt32 (*PGPGroupItemCompareProc)( PGPGroupItem *, + PGPGroupItem *, PGPUserValue userValue ); + +/*____________________________________________________________________________ + Info obtained via PGPGetGroupInfo. +____________________________________________________________________________*/ + +typedef struct PGPGroupInfo +{ + PGPGroupID id; + PGPGroupName name; + PGPGroupName description; + PGPUserValue userValue; + +} PGPGroupInfo; + + +typedef PGPFlags PGPGroupItemIterFlags; +/* flag (1UL << 0 ) is reserved */ +#define kPGPGroupIterFlags_Recursive (PGPFlags)(1UL << 1 ) +#define kPGPGroupIterFlags_Keys (PGPFlags)(1UL << 2 ) +#define kPGPGroupIterFlags_Groups (PGPFlags)(1UL << 3 ) + +#define kPGPGroupIterFlags_AllKeysRecursive \ + ( kPGPGroupIterFlags_Recursive | kPGPGroupIterFlags_Keys ) + +#define kPGPGroupIterFlags_AllGroupsRecursive \ + ( kPGPGroupIterFlags_Recursive | kPGPGroupIterFlags_Groups ) + +#define kPGPGroupIterFlags_AllItems \ + ( kPGPGroupIterFlags_Keys | kPGPGroupIterFlags_Groups ) + +#define kPGPGroupIterFlags_AllRecursive \ + ( kPGPGroupIterFlags_Recursive | kPGPGroupIterFlags_AllItems ) + + + +#if PGP_MACINTOSH +#pragma options align=reset +#endif + +PGP_BEGIN_C_DECLARATIONS + +/*____________________________________________________________________________ + Manipulating pgp group sets (PGPGroupSetRef) +____________________________________________________________________________*/ +/* create a new, empty groups collection */ +PGPError PGPNewGroupSet( PGPContextRef context, PGPGroupSetRef *outRef ); + +/* file is *not* left open; all data is loaded into memory */ +PGPError PGPNewGroupSetFromFile( PGPContextRef context, + PGPFileSpecRef file, + PGPGroupSetRef *outRef ); + +#if PGP_MACINTOSH || PGP_OSX +PGPError PGPNewGroupSetFromFSSpec( PGPContextRef context, + const struct FSSpec *spec, PGPGroupSetRef *outRef ); +#endif + +/* overwrites existing. Don't bother unless PGPGroupSetNeedsCommit() */ +PGPError PGPSaveGroupSetToFile( PGPGroupSetRef set, PGPFileSpecRef file ); + +/* free all data structures; be sure to save first if you want */ +PGPError PGPFreeGroupSet( PGPGroupSetRef set ); + + +/* has the group changed? */ +PGPBoolean PGPGroupSetNeedsCommit( PGPGroupSetRef set ); + +PGPContextRef PGPGetGroupSetContext( PGPGroupSetRef set ); + +/* export the groupset to a buffer. Use PGPFreeData to free the buffer */ +PGPError PGPExportGroupSetToBuffer( PGPGroupSetRef set, void **buffer, + PGPSize *bufferSize ); + +/* import a groupset from a buffer */ +PGPError PGPImportGroupSetFromBuffer(PGPContextRef context, void *buffer, + PGPSize bufSize, PGPGroupSetRef *outSet ); + +/*____________________________________________________________________________ + Manipulating groups + + Groups are always referred to by IDs which remain valid until the set + is disposed. +____________________________________________________________________________*/ + +/* initial parent ID is kPGPInvalidGroupID */ +PGPError PGPNewGroup( PGPGroupSetRef set, + const PGPChar8 * name, const PGPChar8 *description, + PGPGroupID *id ); + +PGPError PGPCountGroupsInSet( PGPGroupSetRef set, + PGPUInt32 *numGroups); +PGPError PGPGetIndGroupID( PGPGroupSetRef set, + PGPUInt32 groupIndex, PGPGroupID *id ); + +/* delete this group from the set */ +/* All references to it are removed in all sets */ +PGPError PGPDeleteGroup( PGPGroupSetRef set, PGPGroupID id ); + +/* delete the indexed item from the group */ +/* the item may be a group or a key */ +PGPError PGPDeleteIndItemFromGroup( PGPGroupSetRef set, + PGPGroupID id, PGPUInt32 item ); + +/* same as PGPDeleteIndItemFromGroup, but accepts an item */ +PGPError PGPDeleteItemFromGroup( PGPGroupSetRef set, + PGPGroupID id, PGPGroupItem const *item ); + + +PGPError PGPGetGroupInfo( PGPGroupSetRef set, + PGPGroupID id, PGPGroupInfo *info ); + +PGPError PGPSetGroupName( PGPGroupSetRef set, + PGPGroupID id, const PGPChar8 * name ); +PGPError PGPSetGroupUserValue( PGPGroupSetRef set, + PGPGroupID id, PGPUserValue userValue ); +PGPError PGPSetGroupDescription( PGPGroupSetRef set, + PGPGroupID id, const PGPChar8 * name ); + +/* 'item' specifies a group or a key id */ +/* you must fill the item in completely */ +PGPError PGPAddItemToGroup( PGPGroupSetRef set, + PGPGroupItem const *item, PGPGroupID group ); + + +PGPError PGPMergeGroupIntoDifferentSet( PGPGroupSetRef fromSet, + PGPGroupID fromID, PGPGroupSetRef toSet ); + +PGPError PGPMergeGroupSets( PGPGroupSetRef fromSet, + PGPGroupSetRef intoSet ); + +PGPError PGPCopyGroupSet(PGPGroupSetRef sourceSet, + PGPGroupSetRef *destSet); + +/*____________________________________________________________________________ + Manipulating group items +____________________________________________________________________________*/ + +/* count how many items there are in a group */ +/* totalItems includes keys and groups */ +PGPError PGPCountGroupItems( PGPGroupSetRef set, + PGPGroupID id, PGPBoolean recursive, + PGPUInt32 * numKeys, + PGPUInt32 * totalItems ); + +/* non-recursive call; index only applies to group itself */ +PGPError PGPGetIndGroupItem( PGPGroupSetRef set, + PGPGroupID id, PGPUInt32 groupIndex, PGPGroupItem * item ); + +/* use PGPGetIndGroupItem() if you want to get the user value */ +PGPError PGPSetIndGroupItemUserValue( PGPGroupSetRef set, + PGPGroupID id, PGPUInt32 groupIndex, PGPUserValue userValue ); + +PGPError PGPSortGroupItems( PGPGroupSetRef set, PGPGroupID id, + PGPGroupItemCompareProc, PGPUserValue userValue ); + +PGPError PGPSortGroupSet( PGPGroupSetRef set, + PGPGroupItemCompareProc, PGPUserValue userValue ); + +/*____________________________________________________________________________ + PGPGroupItemIterRef--iterator through group items. + + Special note: this is not a full-fledged iterator. You may *not* add + or delete items while iterating and you may only move forward. However, + you may change the values of items. +____________________________________________________________________________*/ + +PGPError PGPNewGroupItemIter( PGPGroupSetRef set, PGPGroupID id, + PGPGroupItemIterFlags flags, PGPGroupItemIterRef *iter ); + +PGPError PGPFreeGroupItemIter( PGPGroupItemIterRef iter ); + +/* returns kPGPError_EndOfIteration when done */ +PGPError PGPGroupItemIterNext( PGPGroupItemIterRef iter, + PGPGroupItem * item ); + +/*____________________________________________________________________________ + Group utilities +____________________________________________________________________________*/ + +/*____________________________________________________________________________ + Return the lowest validity of any item in the group + keyset should contain all keys available + It is not an error if keys can't be found; you may want to check + the not found count. + + The lowest validity is kPGPValidity_Invalid and kPGPValidity_Unknown + is never returned. +____________________________________________________________________________*/ +PGPError PGPGetGroupLowestValidity( PGPGroupSetRef set, PGPGroupID id, + PGPKeyDBRef keyDB, PGPValidity * lowestValidity, + PGPUInt32 * numKeysNotFound); + +/*____________________________________________________________________________ + All all the keys in the group (and its subgroups) to the keyset +____________________________________________________________________________*/ +PGPError PGPNewKeySetFromGroup( PGPGroupSetRef set, PGPGroupID id, + PGPKeyDBRef keyDB, PGPKeySetRef * resultSet, + PGPUInt32 * numKeysNotFound); + +/*____________________________________________________________________________ + Create a simple, flattened group of unique key IDs from the source group. + Note that sourceSet and destSet must be different. +____________________________________________________________________________*/ +PGPError PGPNewFlattenedGroupFromGroup(PGPGroupSetRef sourceSet, + PGPGroupID sourceID, PGPGroupSetRef destSet, + PGPGroupID *destID); + +/*____________________________________________________________________________ + Perform a "standard" sort on a group +____________________________________________________________________________*/ +PGPError PGPSortGroupSetStd( PGPGroupSetRef set, PGPKeyDBRef keydb ); + + +PGP_END_C_DECLARATIONS + +#endif /* ] PGP_DEPRECATED */ + +#endif /* ] Included_pgpGroups_h */ + + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ + + + + + + + + diff --git a/CryptoPP/PGPw/sdk8/include/pgpHMAC.h b/CryptoPP/PGPw/sdk8/include/pgpHMAC.h new file mode 100644 index 0000000..3dc58a6 --- /dev/null +++ b/CryptoPP/PGPw/sdk8/include/pgpHMAC.h @@ -0,0 +1,67 @@ +/*____________________________________________________________________________ + Copyright (C) 2002 PGP Corporation + All rights reserved. + + $Id: pgpHMAC.h,v 1.6 2002/08/06 20:11:16 dallen Exp $ +____________________________________________________________________________*/ + +#ifndef Included_pgpHMAC_h /* [ */ +#define Included_pgpHMAC_h + +#include "pgpPubTypes.h" + +PGP_BEGIN_C_DECLARATIONS + +/*____________________________________________________________________________ + Create a new HMAC of the specified algorithm. + + If the algorithm is not available then kPGPError_AlgorithmNotAvailable is + returned. +____________________________________________________________________________*/ + +PGPError PGPNewHMACContext( PGPContextRef context, + PGPHashAlgorithm algorithm, PGPByte *secret, + PGPSize secretLen, PGPHMACContextRef *outRef ); + +/*____________________________________________________________________________ + Any existing intermediate HMAC is lost. +____________________________________________________________________________*/ + +PGPError PGPFreeHMACContext( PGPHMACContextRef ref ); + +/*____________________________________________________________________________ + Reset an HMAC as if it had been created anew. Any existing intermediate + hash is lost. +____________________________________________________________________________*/ + +PGPError PGPResetHMAC( PGPHMACContextRef ref ); + +/*____________________________________________________________________________ + Continue the HMAC, accumulating an intermediate result +____________________________________________________________________________*/ + +PGPError PGPContinueHMAC( PGPHMACContextRef ref, const void *in, + PGPSize numBytes ); + +/*____________________________________________________________________________ + Finalize the HMAC, depositing the result into 'hmacOut'. + + This size of the output will be the same size as the hash + algorithm output. +____________________________________________________________________________*/ + +PGPError PGPFinalizeHMAC( PGPHMACContextRef ref, void *hmacOut ); + +PGP_END_C_DECLARATIONS + +#endif /* ] Included_pgpHMAC_h */ + + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk8/include/pgpHash.h b/CryptoPP/PGPw/sdk8/include/pgpHash.h new file mode 100644 index 0000000..4422534 --- /dev/null +++ b/CryptoPP/PGPw/sdk8/include/pgpHash.h @@ -0,0 +1,86 @@ +/*____________________________________________________________________________ + Copyright (C) 2002 PGP Corporation + All rights reserved. + + $Id: pgpHash.h,v 1.6 2002/08/06 20:11:16 dallen Exp $ +____________________________________________________________________________*/ + +#ifndef Included_pgpHashing_h /* [ */ +#define Included_pgpHashing_h + +#include "pgpPubTypes.h" + +PGP_BEGIN_C_DECLARATIONS + +/*____________________________________________________________________________ + Create a new hash of the specified algorithm. + + If the algorithm is not available then kPGPError_AlgorithmNotAvailable is + returned. +____________________________________________________________________________*/ + +PGPError PGPNewHashContext( PGPContextRef context, + PGPHashAlgorithm algorithm, + PGPHashContextRef * outRef ); + +/*____________________________________________________________________________ + Any existing intermediate hash is lost. +____________________________________________________________________________*/ + +PGPError PGPFreeHashContext( PGPHashContextRef ref ); + +/*____________________________________________________________________________ + An exact duplicate of the hash is made. +____________________________________________________________________________*/ + +PGPError PGPCopyHashContext( PGPHashContextRef ref, + PGPHashContextRef * outRef); + +/*____________________________________________________________________________ + Reset a hash as if it had been created anew. Any existing intermediate + hash is lost. +____________________________________________________________________________*/ + +PGPError PGPResetHash( PGPHashContextRef ref ); + +/*____________________________________________________________________________ + Continue the hash, accumulating an intermediate result +____________________________________________________________________________*/ + +PGPError PGPContinueHash( PGPHashContextRef ref, const void *in, + PGPSize numBytes ); + +/*____________________________________________________________________________ + Finalize the hash, depositing the result into 'hashOut'. + + After calling this routine, the hash is reset via PGPResetHash(). + If you want an intermediate result, use PGPCopyHash() and finalize the + copy. +____________________________________________________________________________*/ + +PGPError PGPFinalizeHash( PGPHashContextRef ref, void *hashOut ); + +/*____________________________________________________________________________ + Determine size of resulting hash in bytes e.g. a 160 bit hash yields 20. + Used for generic code which may not know how big a hash is being produced. + + Question: can we reasonably assume 8 bits per byte? If not, how does + PGPFinalizeHash return its result? +____________________________________________________________________________*/ + +PGPError PGPGetHashSize( PGPHashContextRef ref, PGPSize *hashSize ); + + +PGP_END_C_DECLARATIONS + +#endif /* ] Included_pgpHashing_h */ + + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk8/include/pgpHashWords.h b/CryptoPP/PGPw/sdk8/include/pgpHashWords.h new file mode 100644 index 0000000..4c3c82c --- /dev/null +++ b/CryptoPP/PGPw/sdk8/include/pgpHashWords.h @@ -0,0 +1,40 @@ +/*____________________________________________________________________________ + Copyright (C) 2002 PGP Corporation + All rights reserved. + + $Id: pgpHashWords.h,v 1.2 2004/01/03 02:25:31 bgaiser Exp $ +____________________________________________________________________________*/ +#ifndef HASHWORDLIST_H +#define HASHWORDLIST_H + +#include "pgpBase.h" + +PGP_BEGIN_C_DECLARATIONS + +/*____________________________________________________________________________ + Hash word list types +____________________________________________________________________________*/ +enum PGPHashWordList_ +{ + kPGPHashWordList_Even = 0, + kPGPHashWordList_Odd = 1, + + PGP_ENUM_FORCE( PGPHashWordList_ ) +}; +PGPENUM_TYPEDEF( PGPHashWordList_, PGPHashWordList ); + +/*____________________________________________________________________________ + Hash word functions +____________________________________________________________________________*/ + + PGPError +PGPGetHashWordString( + PGPUInt32 index, + PGPHashWordList list, + PGPChar8 hashWordString[ 12 ]); + + +PGP_END_C_DECLARATIONS + +#endif + diff --git a/CryptoPP/PGPw/sdk8/include/pgpIKE.h b/CryptoPP/PGPw/sdk8/include/pgpIKE.h new file mode 100644 index 0000000..23a28c8 --- /dev/null +++ b/CryptoPP/PGPw/sdk8/include/pgpIKE.h @@ -0,0 +1,784 @@ +/*____________________________________________________________________________ + Copyright (C) 2002 PGP Corporation + All rights reserved. + + $Id: pgpIKE.h,v 1.39 2003/09/24 03:09:32 ajivsov Exp $ +____________________________________________________________________________*/ +#ifndef Included_PGPike_h /* [ */ +#define Included_PGPike_h + +#include "pgpPubTypes.h" + +PGP_BEGIN_C_DECLARATIONS + +#if PGP_WIN32 +# pragma pack(push, 8) +#endif + +#ifdef _MSC_VER +#pragma warning (disable:4200) +#endif + +typedef struct PGPikeContext * PGPikeContextRef; + +#define kInvalidPGPikeContextRef ((PGPikeContextRef) NULL) +#define PGPikeContextRefIsValid( ref ) ( (ref) != kInvalidPGPikeContextRef ) + +#define kPGPike_CommonPort 500 +#define kPGPike_AuthMaximumKeySize (512/8) +#define kPGPike_ESPMaximumKeySize 32 /* 256 bits */ +#define kPGPike_MaxExplicitIVSize 16 +#define kPGPike_MaxTransforms 3 +#define kPGPike_DefaultKBLife 1048576 /* 1GB */ +#define kPGPike_DefaultSecLife 86400 /* 1 Day */ +#define kPGPike_UserDataSize 96 +#define kPGPike_XAuthStringLen 128 +#define kPGPike_XAuthMessageLen 256 + +typedef PGPByte PGPipsecSPI[4]; + +enum PGPikeDOI_ +{ + kPGPike_DOI_IKE = 0, + kPGPike_DOI_IPSEC = 1, + + PGP_ENUM_FORCE( PGPikeDOI_ ) +}; +PGPENUM_TYPEDEF( PGPikeDOI_, PGPikeDOI ); + +enum PGPikeAlert_ +{ + kPGPike_AL_None = 0, + + /* Error Types */ + kPGPike_AL_InvalidPayload = 1, + kPGPike_AL_DOIUnsupported = 2, + kPGPike_AL_SituationUnsupported = 3, + kPGPike_AL_InvalidCookie = 4, + kPGPike_AL_InvalidMajorVersion = 5, + kPGPike_AL_InvalidMinorVersion = 6, + kPGPike_AL_InvalidExchange = 7, + kPGPike_AL_InvalidFlags = 8, + kPGPike_AL_InvalidMessageID = 9, + kPGPike_AL_InvalidProtocolID = 10, + kPGPike_AL_InvalidSPI = 11, + kPGPike_AL_InvalidTransform = 12, + kPGPike_AL_InvalidAttribute = 13, + kPGPike_AL_NoProposalChoice = 14, + kPGPike_AL_BadProposal = 15, + kPGPike_AL_PayloadMalformed = 16, + kPGPike_AL_InvalidKey = 17, + kPGPike_AL_InvalidID = 18, + kPGPike_AL_InvalidCertEncoding = 19, + kPGPike_AL_InvalidCert = 20, + kPGPike_AL_UnsupportedCert = 21, + kPGPike_AL_InvalidCertAuthority = 22, + kPGPike_AL_InvalidHash = 23, + kPGPike_AL_AuthenticationFailed = 24, + kPGPike_AL_InvalidSignature = 25, + kPGPike_AL_AddressNotification = 26, + kPGPike_AL_NotifySALifetime = 27, + kPGPike_AL_CertUnavailable = 28, + kPGPike_AL_UnsupportedExchange = 29, + kPGPike_AL_UnequalPayloadLengths = 30, + + kPGPike_AL_NATTranslationFailure = 16300, + kPGPike_AL_LastErrorType = 16301, + + /* Status Types */ + kPGPike_AL_Connected = 16384, + kPGPike_AL_ResponderLifetime = 24576, /* IPSEC DOI */ + kPGPike_AL_ReplayStatus = 24577, /* IPSEC DOI */ + kPGPike_AL_InitialContact = 24578, /* IPSEC DOI */ + + PGP_ENUM_FORCE( PGPikeAlert_ ) +}; +PGPENUM_TYPEDEF( PGPikeAlert_, PGPikeAlert ); + +enum PGPikeInternalAlert_ +{ + kPGPike_IA_None = 0, + + kPGPike_IA_ResponseTimeout = 1, + kPGPike_IA_NoProposals = 2, + kPGPike_IA_NewPhase1SA = 3, + kPGPike_IA_NewPhase2SA = 4, + kPGPike_IA_DeadPhase1SA = 5, + kPGPike_IA_DeadPhase2SA = 6, + kPGPike_IA_TooManyExchanges = 7, + kPGPike_IA_XAuthSuccess = 8, + kPGPike_IA_XAuthFailed = 9, + + PGP_ENUM_FORCE( PGPikeInternalAlert_ ) +}; +PGPENUM_TYPEDEF( PGPikeInternalAlert_, PGPikeInternalAlert ); + +enum PGPikePref_ +{ + kPGPike_PF_None = 0, + + kPGPike_PF_Expiration = 1, + kPGPike_PF_AllowedAlgorithms = 2, + kPGPike_PF_IKEProposals = 3, + kPGPike_PF_IPSECProposals = 4, + + PGP_ENUM_FORCE( PGPikePref_ ) +}; +PGPENUM_TYPEDEF( PGPikePref_, PGPikePref ); + +enum PGPipsecEncapsulation_ +{ + kPGPike_PM_None = 0, + + kPGPike_PM_Tunnel = 1, + kPGPike_PM_Transport = 2, + kPGPike_PM_UDPencapsulatedTunnel = 61443, + kPGPike_PM_UDPencapsulatedTransport = 61444, + + PGP_ENUM_FORCE( PGPipsecEncapsulation_ ) +}; +PGPENUM_TYPEDEF( PGPipsecEncapsulation_, PGPipsecEncapsulation ); + +enum PGPikeLifeType_ +{ + kPGPike_LT_None = 0, + + kPGPike_LT_Seconds = 1, + kPGPike_LT_Kilobytes = 2, + + PGP_ENUM_FORCE( PGPikeLifeType_ ) +}; +PGPENUM_TYPEDEF( PGPikeLifeType_, PGPikeLifeType ); + +enum PGPipsecIdentity_ +{ + kPGPike_ID_None = 0, + + kPGPike_ID_IPV4_Addr, + kPGPike_ID_FQDN, + kPGPike_ID_UserFQDN, + kPGPike_ID_IPV4_Addr_Subnet, + kPGPike_ID_IPV6_Addr, + kPGPike_ID_IPV6_Addr_Subnet, + kPGPike_ID_IPV4_Addr_Range, + kPGPike_ID_IPV6_Addr_Range, + kPGPike_ID_DER_ASN1_DN, + kPGPike_ID_DER_ASN1_GN, + kPGPike_ID_Key_ID, /* used for PGP fingerprint */ + + PGP_ENUM_FORCE( PGPipsecIdentity_ ) +}; +PGPENUM_TYPEDEF( PGPipsecIdentity_, PGPipsecIdentity ); + +/* If it doesn't say supported, it isn't. */ +enum PGPipsecAHTransformID_ +{ + kPGPike_AH_None = 0, + + kPGPike_AH_MD5 = 2, /* supported */ + kPGPike_AH_SHA = 3, /* supported */ + kPGPike_AH_DES = 4, + kPGPike_AH_SHA2_256 = 5, /* supported */ + kPGPike_AH_SHA2_384 = 6, /* supported */ + kPGPike_AH_SHA2_512 = 7, /* supported */ + + PGP_ENUM_FORCE( PGPipsecAHTransformID_ ) +}; +PGPENUM_TYPEDEF( PGPipsecAHTransformID_, PGPipsecAHTransformID ); + +enum PGPipsecAuthAttribute_ +{ + kPGPike_AA_None = 0, + + kPGPike_AA_HMAC_MD5 = 1, /* supported */ + kPGPike_AA_HMAC_SHA = 2, /* supported */ + kPGPike_AA_DES_MAC = 3, + kPGPike_AA_KPDK = 4, + kPGPike_AA_HMAC_SHA2_256 = 5, /* supported */ + kPGPike_AA_HMAC_SHA2_384 = 6, /* supported */ + kPGPike_AA_HMAC_SHA2_512 = 7, /* supported */ + + PGP_ENUM_FORCE( PGPipsecAuthAttribute_ ) +}; +PGPENUM_TYPEDEF( PGPipsecAuthAttribute_, PGPipsecAuthAttribute ); + +enum PGPipsecESPTransformID_ +{ + kPGPike_ET_DES_IV64 = 1, /* supported */ + kPGPike_ET_DES = 2, /* supported */ + kPGPike_ET_3DES = 3, /* supported */ + kPGPike_ET_RC5 = 4, + kPGPike_ET_IDEA = 5, + kPGPike_ET_CAST = 6, /* supported */ + kPGPike_ET_Blowfish = 7, + kPGPike_ET_3IDEA = 8, + kPGPike_ET_DES_IV32 = 9, + kPGPike_ET_RC4 = 10, + kPGPike_ET_NULL = 11, /* supported */ + kPGPike_ET_AES = 12, + + PGP_ENUM_FORCE( PGPipsecESPTransformID_ ) +}; +PGPENUM_TYPEDEF( PGPipsecESPTransformID_, PGPipsecESPTransformID ); + +/* IPCOMP is not supported by this version of PGPike */ +enum PGPipsecIPCOMPTransformID_ +{ + kPGPike_IC_None = 0, + + kPGPike_IC_OUI = 1, + kPGPike_IC_Deflate = 2, /* supported */ + kPGPike_IC_LZS = 3, /* supported */ + kPGPike_IC_V42bis = 4, + + PGP_ENUM_FORCE( PGPipsecIPCOMPTransformID_ ) +}; +PGPENUM_TYPEDEF( PGPipsecIPCOMPTransformID_, PGPipsecIPCOMPTransformID ); + +enum PGPipsecProtocol_ +{ + kPGPike_PR_None = 0, + kPGPike_PR_IKE = 1, + kPGPike_PR_AH = 2, + kPGPike_PR_ESP = 3, + kPGPike_PR_IPCOMP = 4, + + PGP_ENUM_FORCE( PGPipsecProtocol_ ) +}; +PGPENUM_TYPEDEF( PGPipsecProtocol_, PGPipsecProtocol ); + +enum PGPikeGroupID_ +{ + kPGPike_GR_None = 0, /* supported */ + + kPGPike_GR_MODPOne = 1, /* supported */ + kPGPike_GR_MODPTwo = 2, /* supported */ + kPGPike_GR_MODPFive = 5, /* supported */ + + kPGPike_GR_ECSix = 6, /* supported */ + kPGPike_GR_ECSeven = 7, /* supported */ + + kPGPike_GR_ECEight = 8, /* supported */ + kPGPike_GR_ECNine = 9, /* supported */ + + kPGPike_GR_MODP2048 = 42048,/* unassigned */ + kPGPike_GR_MODP3072 = 43072,/* unassigned */ + kPGPike_GR_MODP4096 = 44096,/* unassigned */ + kPGPike_GR_MODP6144 = 46144,/* unassigned */ + kPGPike_GR_MODP8192 = 48192,/* unassigned */ + + PGP_ENUM_FORCE( PGPikeGroupID_ ) +}; +PGPENUM_TYPEDEF( PGPikeGroupID_, PGPikeGroupID ); + +enum PGPikeCipher_ +{ + kPGPike_SC_None = 0, + + kPGPike_SC_DES_CBC = 1, /* supported */ + kPGPike_SC_IDEA_CBC = 2, + kPGPike_SC_Blowfish_CBC = 3, + kPGPike_SC_RC5_R16_B64_CBC = 4, + kPGPike_SC_3DES_CBC = 5, /* supported */ + kPGPike_SC_CAST_CBC = 6, /* supported */ + kPGPike_SC_AES_CBC = 7, + + PGP_ENUM_FORCE( PGPikeCipher_ ) +}; +PGPENUM_TYPEDEF( PGPikeCipher_, PGPikeCipher ); + +enum PGPikeHash_ +{ + kPGPike_HA_None = 0, + + kPGPike_HA_MD5 = 1, /* supported */ + kPGPike_HA_SHA1 = 2, /* supported */ + kPGPike_HA_Tiger = 3, + kPGPike_HA_SHA2_256 = 4, + kPGPike_HA_SHA2_384 = 5, + kPGPike_HA_SHA2_512 = 6, + + PGP_ENUM_FORCE( PGPikeHash_ ) +}; +PGPENUM_TYPEDEF( PGPikeHash_, PGPikeHash ); + +enum PGPikeAuthMethod_ +{ + kPGPike_AM_None = 0, + + kPGPike_AM_PreSharedKey = 1, /* supported */ + kPGPike_AM_DSS_Sig = 2, /* supported */ + kPGPike_AM_RSA_Sig = 3, /* supported */ + kPGPike_AM_RSA_Encrypt = 4, + kPGPike_AM_RSA_Encrypt_R = 5, + + kPGPike_AM_HAuth_InitRSA = 64221, + kPGPike_AM_HAuth_RespRSA = 64222, + kPGPike_AM_HAuth_InitDSS = 64223, + kPGPike_AM_HAuth_RespDSS = 64224, + + kPGPike_AM_XAuth_InitPreShared = 65001, + kPGPike_AM_XAuth_RespPreShared = 65002, + kPGPike_AM_XAuth_InitDSS = 65003, + kPGPike_AM_XAuth_RespDSS = 65004, + kPGPike_AM_XAuth_InitRSA = 65005, + kPGPike_AM_XAuth_RespRSA = 65006, + kPGPike_AM_XAuth_InitRSAEncryption = 65007, + kPGPike_AM_XAuth_RespRSAEncryption = 65008, + kPGPike_AM_XAuth_InitRSAREncryption = 65009, + kPGPike_AM_XAuth_RespRSAREncryption = 65010, + + PGP_ENUM_FORCE( PGPikeAuthMethod_ ) +}; +PGPENUM_TYPEDEF( PGPikeAuthMethod_, PGPikeAuthMethod ); + +enum PGPikeAuthStyle_ +{ + kPGPike_AS_Normal = 0, + + kPGPike_AS_XAuth = 1, + kPGPike_AS_HybridAuth = 2, + + PGP_ENUM_FORCE( PGPikeAuthStyle_ ) +}; +PGPENUM_TYPEDEF( PGPikeAuthStyle_, PGPikeAuthStyle ); + +enum PGPikeXAuthType_ +{ + kPGPike_XT_Generic = 0, + + kPGPike_XT_RADIUS_CHAP = 1, + kPGPike_XT_OTP = 2, + kPGPike_XT_SKEY = 3, + + PGP_ENUM_FORCE( PGPikeXAuthType_ ) +}; +PGPENUM_TYPEDEF( PGPikeXAuthType_, PGPikeXAuthType ); + +enum PGPikeEncapsulateMode_ +{ + kPGPike_EM_Auto = 0, + + kPGPike_EM_Always = 1, + kPGPike_EM_Never = 2, + + PGP_ENUM_FORCE( PGPikeEncapsulateMode_ ) +}; +PGPENUM_TYPEDEF( PGPikeEncapsulateMode_, PGPikeEncapsulateMode ); + +typedef struct PGPipsecESPTransform +{ + PGPipsecESPTransformID cipher; + PGPUInt32 keyLength; + /* cipher key bit size, must be 0 for all except AES */ + PGPipsecAuthAttribute authAttr; + PGPipsecEncapsulation mode; +} PGPipsecESPTransform; + +typedef struct PGPipsecAHTransform +{ + PGPipsecAHTransformID authAlg; + PGPipsecAuthAttribute authAttr; + PGPipsecEncapsulation mode; +} PGPipsecAHTransform; + +typedef struct PGPipsecIPCOMPTransform +{ + PGPipsecIPCOMPTransformID compAlg; +} PGPipsecIPCOMPTransform; + +typedef struct PGPikeTransform +{ + PGPikeAuthMethod authMethod; + PGPikeHash hash; + PGPikeCipher cipher; + PGPUInt32 keyLength; /* cipher key bit size, must be 0 for all except AES */ + PGPikeGroupID groupID; +} PGPikeTransform; + +typedef struct PGPipsecTransform +{ + PGPBoolean useESP; + PGPipsecESPTransform esp; + + PGPBoolean useAH; + PGPipsecAHTransform ah; + + PGPBoolean useIPCOMP; + PGPipsecIPCOMPTransform ipcomp; + + PGPikeGroupID groupID; +} PGPipsecTransform; + +typedef struct PGPipsecDOIParams +{ + PGPipsecSPI inSPI; + PGPipsecSPI outSPI; + PGPipsecProtocol protocol; + + union + { + struct + { + PGPipsecAHTransform t; + PGPByte inAuthKey[kPGPike_AuthMaximumKeySize]; + PGPByte outAuthKey[kPGPike_AuthMaximumKeySize]; + } ah; + + struct + { + PGPipsecESPTransform t; + PGPByte inESPKey[kPGPike_ESPMaximumKeySize]; + PGPByte outESPKey[kPGPike_ESPMaximumKeySize]; + PGPByte inAuthKey[kPGPike_AuthMaximumKeySize]; + PGPByte outAuthKey[kPGPike_AuthMaximumKeySize]; + PGPByte explicitIV[kPGPike_MaxExplicitIVSize]; + } esp; + + struct + { + PGPipsecIPCOMPTransform t; + } ipcomp; + } u; +} PGPipsecDOIParams; + +typedef struct PGPipsecSA +{ + struct PGPipsecSA * nextSA; /* INTERNAL USE ONLY */ + struct PGPipsecSA * prevSA; /* INTERNAL USE ONLY */ + PGPUInt32 ipAddress; /* PreNATted(Original) IP Address */ + PGPBoolean destIsRange; /* dest is IP range */ + PGPUInt32 ipAddrStart; /* IP address */ + PGPUInt32 ipMaskEnd; /* mask or end range IP address */ + PGPByte ipProtocol; /* 0 if all protocols */ + PGPUInt16 ipPort; /* 0 if all ports */ + + PGPBoolean bNATTraversal; /* NAT Encapsulation is enabled if true */ + PGPBoolean bIsLocalIPNAT; /* if non-zero, our local IP is natted */ + PGPBoolean bIsRemoteIPNAT; /* if non-zero, remote IP is NATed */ + PGPUInt32 natIPAddress; /* NATed Dest IP Address, 0 if not NATed */ + PGPUInt16 nboNATPort; /* NATed Dest Port value */ + + PGPUInt32 assignedIP; /* if non-zero, use as tunnel IP */ + PGPUInt32 assignedDNS; /* if non-zero, use as tunnel DNS */ + PGPUInt32 assignedWINS; /* if non-zero, use as tunnel WINS */ + + PGPBoolean initiator; /* was this SA initiated locally */ + PGPBoolean activeIn; /* use for inbound data */ + PGPBoolean activeOut; /* use for outbound data */ + PGPUInt32 kbLifeTime; /* max KB to be sent on this SA */ + PGPUInt32 secLifeTime; /* max seconds this SA will live */ + /* 0 means no limit for either */ + PGPTime birthTime; + + PGPUInt16 numTransforms; + PGPipsecDOIParams transform[kPGPike_MaxTransforms]; + + PGPTime termSchedule; /* SA will be terminated, private */ + PGPByte userData[kPGPike_UserDataSize];/* for your use */ +} PGPipsecSA; + +/* When sent a kPGPike_MT_SARequest, pgpIKE will expect that + all fields below will be filled in. The approved member is + irrelevant in that case. + + When you are called with kPGPike_MT_PolicyCheck, pgpIKE will + set everything to 0 except the IP address. You are expected + to fill in the other fields with local policy. The PolicyCheck + is used for remote-initiated SA negotiation. Since you cannot + predict which remote network might be trying to communicate + with us, you should leave the destIsRange/ipAddrStart/ipMaskEnd + and ipPort/ipProtocol fields set to 0 for this message. You + will be called to check those later with the ClientIDCheck. +*/ +typedef struct PGPikeMTSASetup +{ + PGPBoolean approved; /* > */ + + PGPUInt32 ipAddress; /* destination */ + PGPUInt32 localIPAddress; /* source */ + PGPByte ipProtocol; + PGPUInt16 ipPort; + PGPByte * sharedKey; /* null if none, data will be copied */ + PGPSize sharedKeySize; /* w/o NULL-terminate */ + PGPBoolean aggressive; /* set for aggressive mode */ + PGPBoolean lightweight; /* only for SARequest, set to + TRUE for only 1 retry */ + /* set the fields below to use tunnel mode */ + PGPBoolean destIsRange; + PGPUInt32 ipAddrStart; + PGPUInt32 ipMaskEnd; + + PGPBoolean virtualIP; /* whether to use mode-cfg */ + PGPikeAuthStyle authStyle; /* whether to use xauth/hybrid */ + PGPikeEncapsulateMode encapsulateMode; /* Force NAT Traversal mode */ + + PGPipsecIdentity idType; /* only useful in shared key mode */ + PGPByte * idData; /* data will be copied */ + PGPSize idDataSize; /* this is the Phase 1 ID */ +} PGPikeMTSASetup; + +/* + When you are called with a kPGPike_MT_ClientIDCheck, all fields + will be set appropriately. If the destIsRange/ipAddrStart/ipMaskEnd + triad is permitted to be represented by the IP address, set + the approved field to true. This message is only sent in the case + where the remote side is the initiator and you have already been + called with a kPGPike_MT_PolicyCheck message. +*/ +typedef struct PGPikeMTClientIDCheck +{ + PGPBoolean approved; /* > */ + + PGPUInt32 ipAddress; + PGPByte ipProtocol; + PGPUInt16 ipPort; + + PGPBoolean destIsRange; + PGPUInt32 ipAddrStart; + PGPUInt32 ipMaskEnd; +} PGPikeMTClientIDCheck; + +typedef struct PGPikeMTSAEstablished +{ + PGPipsecSA * sa; + PGPBoolean remoteValid; + PGPByte * remoteAuthKey; /* binary exported key data */ + PGPSize remoteAuthKeySize; +} PGPikeMTSAEstablished; + +typedef struct PGPikeMTSAFailed +{ + PGPUInt32 ipAddress; /* destination */ + PGPByte ipProtocol; + PGPUInt16 ipPort; + + PGPBoolean destIsRange; + PGPUInt32 ipAddrStart; + PGPUInt32 ipMaskEnd; + +} PGPikeMTSAFailed; + +typedef struct PGPikeMTCert +{ + PGPUInt32 ipAddress; /* < */ + PGPKeyDBRef baseKeyDB; /* > */ + PGPKeyDBObjRef authObj; /* > PGP key or X.509 cert */ + + PGPBoolean isPassKey; /* > */ + void * pass; /* > null-term if passphrase, Unicode, copied */ + PGPSize passLength; /* > in PGPChar8s */ +} PGPikeMTCert; + +typedef struct PGPikeMTRemoteCert +{ + PGPBoolean approved; /* > */ + PGPBoolean valid; /* > */ + PGPUInt32 ipAddress; /* < */ + PGPKeyDBObjRef remoteObj; /* < PGPkey or X.509 cert */ + PGPKeyDBRef remoteKeyDB; /* < any other keys/certs are part of + this cert's chain */ +} PGPikeMTRemoteCert; + +typedef struct PGPikeMTPacket +{ + PGPUInt32 ipAddress; /* source or destination */ + PGPUInt16 port; /* usually UDP 500, but might not be */ + PGPSize packetSize; + PGPByte * packet; /* msg *sender* must free this */ +} PGPikeMTPacket; + +typedef struct PGPikeMTIdentity +{ + PGPBoolean active; /* TRUE = set it, FALSE= dead */ + PGPUInt32 ipAddress; /* Gateway IP */ + PGPUInt32 assignedIP; + PGPUInt32 assignedDNS; + PGPUInt32 assignedWINS; +} PGPikeMTIdentity; + +typedef struct PGPikeMTAlert +{ + PGPikeAlert alert; + PGPUInt32 ipAddress; + PGPikeInternalAlert value; /* used if alert is kPGPike_AL_None */ + PGPBoolean remoteGenerated; +} PGPikeMTAlert; + +typedef PGPUInt32 PGPikeAESKeyLengthMask; + +#define kPGPike_AESKeyLength128 1 +#define kPGPike_AESKeyLength192 2 +#define kPGPike_AESKeyLength256 4 +#define kPGPike_AESKeyLengthAll 7 + +typedef struct PGPikeAllowedAlgorithms +{ + PGPBoolean cast5; + PGPBoolean tripleDES; + PGPBoolean singleDES; + PGPikeAESKeyLengthMask aes; + PGPBoolean espNULL; + + PGPBoolean sha1; + PGPBoolean md5; + PGPBoolean sha2_256; + PGPBoolean sha2_384; + PGPBoolean sha2_512; + PGPBoolean noAuth; + + PGPBoolean lzs; + PGPBoolean deflate; + + PGPBoolean modpOne768; + PGPBoolean modpTwo1024; + PGPBoolean modpFive1536; + + PGPBoolean ec2n163; + PGPBoolean ec2n283; + + PGPBoolean modp2048; + PGPBoolean modp3072; + PGPBoolean modp4096; + PGPBoolean modp6144; + PGPBoolean modp8192; + +} PGPikeAllowedAlgorithms; + +typedef struct PGPikeMTPref +{ + PGPikePref pref; + + union + { + struct + { + PGPUInt32 kbLifeTimeIKE; + PGPUInt32 secLifeTimeIKE; + PGPUInt32 kbLifeTimeIPSEC; + PGPUInt32 secLifeTimeIPSEC; + } expiration; /* kPGPike_PF_Expiration */ + + struct + { + PGPUInt32 numTransforms; + PGPikeTransform * t; + } ikeProposals; /* kPGPike_PF_IKEProposals */ + + + struct + { + PGPUInt32 numTransforms; + PGPipsecTransform * t; + } ipsecProposals; /* kPGPike_PF_IPSECProposals */ + + PGPikeAllowedAlgorithms allowedAlgorithms; + /*kPGPike_PF_AllowedAlgorithms*/ + } u; +} PGPikeMTPref; + +/* This message will be sent to check extended authentication. The buffer + will be freed after your callback is called, so if you need it, + copy the data elsewhere. You must retrieve the information and then + send an AuthCheck message back to IKE with the contents filled in, + and all contents preserved other than what you filled in. The message + you send back is your memory, IKE will not free it. */ +typedef struct PGPikeMTAuthCheck +{ + PGPBoolean success; /* set to true unless user aborts */ + PGPUInt32 gatewayIP; + PGPikeXAuthType xauthType; + PGPUInt16 transactionID; /* private */ + PGPBoolean includeType; /* private */ + + PGPBoolean useUserName; + PGPBoolean usePassword; + PGPBoolean usePasscode; + PGPBoolean useMessage; + PGPBoolean useChallenge; + PGPBoolean useDomain; + + PGPChar8 userName[kPGPike_XAuthStringLen]; + PGPChar8 password[kPGPike_XAuthStringLen]; + PGPChar8 passcode[kPGPike_XAuthStringLen]; + PGPChar8 message[kPGPike_XAuthMessageLen]; + PGPChar8 challenge[kPGPike_XAuthStringLen]; + PGPChar8 domain[kPGPike_XAuthStringLen]; + PGPSize challengeSize; +} PGPikeMTAuthCheck; + +enum PGPikeMessageType_ +{ + /* + Message types followed by ">" may be sent to PGPike + Message typed followed by "<" may be sent by PGPike + */ + kPGPike_MT_Idle = 0, /* > call this often */ + kPGPike_MT_SARequest, /* > PGPikeMTSASetup */ + kPGPike_MT_SARequestFailed, /* < PGPikeMTSAFailed */ + kPGPike_MT_SAEstablished, /* < PGPikeMTSAEstablished */ + kPGPike_MT_SARekey, /* > PGPipsecSA */ + kPGPike_MT_SADied, /* >< PGPipsecSA */ + kPGPike_MT_SAUpdate, /* < PGPipsecSA */ + kPGPike_MT_SAKillAll, /* > none */ + + kPGPike_MT_PolicyCheck, /* < PGPikeMTSASetup */ + kPGPike_MT_ClientIDCheck, /* < PGPikeMTClientIDCheck */ + kPGPike_MT_AuthCheck, /* >< PGPikeMTAuthCheck */ + kPGPike_MT_LocalPGPCert, /* < PGPikeMTCert */ + kPGPike_MT_LocalX509Cert, /* < PGPikeMTCert */ + kPGPike_MT_RemoteCert, /* < PGPikeMTRemoteCert */ + kPGPike_MT_Identity, /* < PGPikeMTIdentity */ + + kPGPike_MT_Packet, /* >< PGPikeMTPacket */ + kPGPike_MT_Alert, /* < PGPikeMTAlert */ + + kPGPike_MT_Pref, /* > PGPikeMTPref */ + + kPGPike_MT_DebugLog, /* < PGPChar8 * */ + + PGP_ENUM_FORCE( PGPikeMessageType_ ) +}; +PGPENUM_TYPEDEF( PGPikeMessageType_, PGPikeMessageType ); + +typedef PGPError (* PGPikeMessageProcPtr)( + PGPikeContextRef ike, + void * inUserData, + PGPikeMessageType msg, + void * data ); + +PGPError PGPNewIKEContext( + PGPContextRef context, + PGPikeMessageProcPtr ikeMessageProc, + void * inUserData, + PGPikeContextRef * outRef ); + +PGPError PGPFreeIKEContext( + PGPikeContextRef ref ); + +/* Any error from PGPikeProcessMessage is fatal. Non-fatal + errors are sent through the kPGPike_MT_Alert message. */ + +PGPError PGPikeProcessMessage( + PGPikeContextRef ref, + PGPikeMessageType msg, + void * data ); + + +#if PGP_WIN32 +# pragma pack(pop) +#endif + +PGP_END_C_DECLARATIONS + +#endif /* ] Included_PGPike_h */ + + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk8/include/pgpKeyServer.h b/CryptoPP/PGPw/sdk8/include/pgpKeyServer.h new file mode 100644 index 0000000..27594ea --- /dev/null +++ b/CryptoPP/PGPw/sdk8/include/pgpKeyServer.h @@ -0,0 +1,339 @@ +/*____________________________________________________________________________ + Copyright (C) 2002 PGP Corporation + All rights reserved. + + $Id: pgpKeyServer.h,v 1.20 2004/01/23 08:12:49 dallen Exp $ +____________________________________________________________________________*/ + +#ifndef Included_pgpKeyServer_h +#define Included_pgpKeyServer_h + +#include "pgpOptionList.h" +#include "pgpErrors.h" +#include "pgpGroups.h" +#include "pgpTLS.h" + + +enum PGPKeyServerState_ +{ + kPGPKeyServerState_Invalid = 0, + kPGPKeyServerState_Opening = 1, + kPGPKeyServerState_Querying = 2, + kPGPKeyServerState_ReceivingResults = 3, + kPGPKeyServerState_ProcessingResults = 4, + kPGPKeyServerState_Uploading = 5, + kPGPKeyServerState_Deleting = 6, + kPGPKeyServerState_Disabling = 7, + kPGPKeyServerState_Closing = 8, + + kPGPKeyServerState_TLSUnableToSecureConnection = 9, + kPGPKeyServerState_TLSConnectionSecured = 10, + + PGP_ENUM_FORCE(PGPKeyServerState_) +}; + +PGPENUM_TYPEDEF(PGPKeyServerState_, PGPKeyServerState); + +enum PGPKeyServerProtocol_ +{ + kPGPKeyServerProtocol_Invalid = 0, + kPGPKeyServerProtocol_LDAP = 1, + kPGPKeyServerProtocol_HTTP = 2, + kPGPKeyServerProtocol_LDAPS = 3, + kPGPKeyServerProtocol_HTTPS = 4, + + PGP_ENUM_FORCE( PGPKeyServerProtocol_ ) +}; + +PGPENUM_TYPEDEF( PGPKeyServerProtocol_, PGPKeyServerProtocol ); + +enum PGPKeyServerClass_ +{ + kPGPKeyServerClass_Invalid = 0, + kPGPKeyServerClass_PGP = 1, + kPGPKeyServerClass_LDAPX509 = 2, + kPGPKeyServerClass_LDAPPGP = 3, /* deprecated, use kPGPKeyServerClass_PGP instead */ + + /* CA types */ + kPGPKeyServerClass_NetToolsCA = 10, + kPGPKeyServerClass_Verisign = 11, + kPGPKeyServerClass_Entrust = 12, + kPGPKeyServerClass_Netscape = 13, + kPGPKeyServerClass_Microsoft = 14, + + PGP_ENUM_FORCE( PGPKeyServerClass_ ) +}; + +PGPENUM_TYPEDEF( PGPKeyServerClass_, PGPKeyServerClass ); + +enum PGPKeyServerKeySpace_ /* These are only valid for LDAP keyservers */ +{ + kPGPKeyServerKeySpace_Invalid = 0, + kPGPKeyServerKeySpace_Default = 1, + kPGPKeyServerKeySpace_Normal = 2, + kPGPKeyServerKeySpace_Pending = 3, + + PGP_ENUM_FORCE( PGPKeyServerKeySpace_ ) +}; + +PGPENUM_TYPEDEF( PGPKeyServerKeySpace_, PGPKeyServerKeySpace ); + +enum PGPKeyServerAccessType_ /* These are only valid for LDAP keyservers */ +{ + kPGPKeyServerAccessType_Invalid = 0, + kPGPKeyServerAccessType_Default = 1, + kPGPKeyServerAccessType_Normal = 2, + kPGPKeyServerAccessType_Administrator = 3, + + PGP_ENUM_FORCE( PGPKeyServerAccessType_ ) +}; + +PGPENUM_TYPEDEF( PGPKeyServerAccessType_, PGPKeyServerAccessType ); + +enum PGPProxyServerType_ +{ + kPGPProxyServerType_Invalid = 0, + kPGPProxyServerType_HTTP = 1, + kPGPProxyServerType_HTTPS = 2, + + PGP_ENUM_FORCE(PGPProxyServerType_) +}; + +PGPENUM_TYPEDEF(PGPProxyServerType_, PGPProxyServerType); + +/* PGPKeyServerMonitorValues are null terminated linked lists. + The values member is a null terminated array of char*s. +*/ + +typedef struct PGPKeyServerMonitorValues +{ + PGPChar8 * name; + PGPChar8 ** values; + struct PGPKeyServerMonitorValues * next; +} PGPKeyServerMonitorValues; + +typedef struct PGPKeyServerMonitor +{ + PGPKeyServerRef keyServerRef; + PGPKeyServerMonitorValues * valuesHead; +} PGPKeyServerMonitor; + + +typedef struct PGPKeyServerThreadStorage * PGPKeyServerThreadStorageRef; +# define kInvalidPGPKeyServerThreadStorageRef \ + ((PGPKeyServerThreadStorageRef) NULL) +#define PGPKeyServerThreadStorageRefIsValid(ref) \ + ((ref) != kInvalidPGPKeyServerThreadStorageRef) + +PGP_BEGIN_C_DECLARATIONS + + +/* Use the idle event handler to receive periodic idle events during + network calls. Usually this is used only in non-preemptive multi-tasking + OSes to allow yielding in threads. Pre-emptive multi-tasking systems + should probably not use the call as it interrupts the efficient wait state + of threads waiting on network calls. + + Idle event handlers need to be added on a per thread basis. + + Returning an error from the idle event handler will cause the keyserver + to quit processing and to return a kPGPError_UserAbort. */ +PGPError PGPSetKeyServerIdleEventHandler( + PGPEventHandlerProcPtr inCallback, + PGPUserValue inUserData); + +PGPError PGPGetKeyServerIdleEventHandler( + PGPEventHandlerProcPtr * outCallback, + PGPUserValue * outUserData); + +/* Network library options */ + +#undef PGPONetURL +PGPOptionListRef PGPONetURL(PGPContextRef context, const PGPChar8 *url); + +#undef PGPONetHostName +PGPOptionListRef PGPONetHostName(PGPContextRef context, + const PGPChar8 *hostName, PGPUInt16 port); + +PGPOptionListRef PGPONetHostAddress(PGPContextRef context, + PGPUInt32 hostAddress, PGPUInt16 port); + +PGPOptionListRef PGPONetConnectTimeout(PGPContextRef context, + PGPUInt32 timeout); + +PGPOptionListRef PGPONetReadTimeout(PGPContextRef context, + PGPUInt32 timeout); + +PGPOptionListRef PGPONetWriteTimeout(PGPContextRef context, + PGPUInt32 timeout); + +PGPOptionListRef PGPOKeyServerProtocol(PGPContextRef context, + PGPKeyServerProtocol serverProtocol); + +PGPOptionListRef PGPOKeyServerKeySpace(PGPContextRef context, + PGPKeyServerKeySpace serverSpace); + +#undef PGPOKeyServerKeyStoreDN +PGPOptionListRef PGPOKeyServerKeyStoreDN(PGPContextRef context, + const PGPChar8 *szKeyStoreDn); + +PGPOptionListRef PGPOKeyServerAccessType(PGPContextRef context, + PGPKeyServerAccessType accessType); + +PGPOptionListRef PGPOKeyServerCAKey(PGPContextRef context, + PGPKeyDBObjRef caKeyDBObjRef); + +PGPOptionListRef PGPOKeyServerRequestKey(PGPContextRef context, + PGPKeyDBObjRef requestKeyDBObjRef); + +PGPOptionListRef PGPOKeyServerSearchKey(PGPContextRef context, + PGPKeyDBObjRef searchKeyDBObjRef); + +PGPOptionListRef PGPOKeyServerSearchFilter(PGPContextRef context, + PGPFilterRef searchFilter); + +/* Static storage creation */ +PGPError PGPKeyServerCreateThreadStorage( + PGPKeyServerThreadStorageRef * outPreviousStorage); +PGPError PGPKeyServerDisposeThreadStorage( + PGPKeyServerThreadStorageRef inPreviousStorage); + +/* Initialize and close the keyserver library */ +PGPError PGPKeyServerInit(void); + +PGPError PGPKeyServerCleanup(void); + + +/* Creating and freeing a keyserver ref. */ +PGPError PGPNewKeyServer( + PGPContextRef inContext, + PGPKeyServerClass inClass, + PGPKeyServerRef *outKeyServerRef, + PGPOptionListRef firstOption, + ... ); + +PGPError PGPFreeKeyServer(PGPKeyServerRef inKeyServerRef); +PGPError PGPIncKeyServerRefCount(PGPKeyServerRef inKeyServerRef); + + +/* Set and get the keyserver's event handler. Note that returning an error + for a keyserver event will abort the current call. */ +PGPError PGPSetKeyServerEventHandler( + PGPKeyServerRef inKeyServerRef, + PGPEventHandlerProcPtr inCallback, + PGPUserValue inUserData); + +PGPError PGPGetKeyServerEventHandler( + PGPKeyServerRef inKeyServerRef, + PGPEventHandlerProcPtr * outCallback, + PGPUserValue * outUserData); + + +/* Canceling a call to a keyserver. This is the only call that can be made + to a keyserver that is currently in another call. Also, once you have + returned from a canceled call, you may only close the keyserver. */ +PGPError PGPCancelKeyServerCall(PGPKeyServerRef inKeyServerRef); + + +/* Opening and closing the keyserver. A keyserver ref can be opened and + closed multiple times as necessary. */ +PGPError PGPKeyServerOpen(PGPKeyServerRef inKeyServerRef, + PGPtlsSessionRef inTLSSessionRef); + +PGPError PGPKeyServerClose(PGPKeyServerRef inKeyServerRef); + + +/* Get keyserver info. */ +PGPError PGPGetKeyServerTLSSession(PGPKeyServerRef inKeyServerRef, + PGPtlsSessionRef * outTLSSessionRef); + +PGPError PGPGetKeyServerProtocol(PGPKeyServerRef inKeyServerRef, + PGPKeyServerProtocol * outType); + +PGPError PGPGetKeyServerAccessType(PGPKeyServerRef inKeyServerRef, + PGPKeyServerAccessType * outAccessType); + +PGPError PGPGetKeyServerKeySpace(PGPKeyServerRef inKeyServerRef, + PGPKeyServerKeySpace * outKeySpace); + +PGPError PGPGetKeyServerPort(PGPKeyServerRef inKeyServerRef, + PGPUInt16 * outPort); + +#undef PGPGetKeyServerHostName +PGPError PGPGetKeyServerHostName(PGPKeyServerRef inKeyServerRef, + PGPChar8 ** outHostName); /* Use PGPFreeData to free */ + +PGPError PGPGetKeyServerAddress(PGPKeyServerRef inKeyServerRef, + PGPUInt32 * outAddress); + +#undef PGPGetKeyServerPath +PGPError PGPGetKeyServerPath(PGPKeyServerRef inKeyServerRef, + PGPChar8 ** outPath); /* Use PGPFreeData to free */ + +PGPContextRef PGPGetKeyServerContext(PGPKeyServerRef inKeyServerRef); + +/* If there was an error string returned from the server, you can get it with + this function. Note that if there is no string, the function will return + kPGPError_NoErr and *outErrorString will be NULL */ +#undef PGPGetLastKeyServerErrorString +PGPError PGPGetLastKeyServerErrorString( + PGPKeyServerRef inKeyServerRef, + PGPChar8 ** outErrorString); /* Use PGPFreeData to free */ + + +/* These functions may be used with both HTTP and LDAP keyservers */ +PGPError PGPQueryKeyServer(PGPKeyServerRef inKeyServerRef, + PGPFilterRef inFilterRef, + PGPKeyDBRef *searchResultsDB); + +PGPError PGPUploadToKeyServer(PGPKeyServerRef inKeyServerRef, + PGPKeySetRef inKeysToUpload, + PGPKeySetRef * outKeysThatFailed); + + +/* These functions may only be used with LDAP keyservers */ +PGPError PGPDeleteFromKeyServer(PGPKeyServerRef inKeyServerRef, + PGPKeySetRef inKeysToDelete, + PGPKeySetRef * outKeysThatFailed); + +PGPError PGPDisableFromKeyServer(PGPKeyServerRef inKeyServerRef, + PGPKeySetRef inKeysToDisable, + PGPKeySetRef * outKeysThatFailed); + +PGPError PGPSendGroupsToServer(PGPKeyServerRef inKeyServerRef, + PGPGroupSetRef inGroupSetRef); + +PGPError PGPRetrieveGroupsFromServer( + PGPKeyServerRef inKeyServerRef, + PGPGroupSetRef * outGroupSetRef); + +PGPError PGPNewServerMonitor(PGPKeyServerRef inKeyServerRef, + PGPKeyServerMonitor ** outMonitor); + +PGPError PGPFreeServerMonitor(PGPKeyServerMonitor * inMonitor); + +/* X.509 Certificate Request functions */ + +PGPError PGPSendCertificateRequest( + PGPKeyServerRef inKeyServerRef, + PGPOptionListRef firstOption, + ... ); + +PGPError PGPRetrieveCertificate( + PGPKeyServerRef inKeyServerRef, + PGPOptionListRef firstOption, + ... ); + +PGPError PGPRetrieveCertificateRevocationList( + PGPKeyServerRef inKeyServerRef, + PGPOptionListRef firstOption, + ... ); +/* Queries HTTP proxy information. proxyAddress must be freed with PGPFreeData */ +#undef PGPGetProxyServer +PGPError PGPGetProxyServer( + PGPContextRef context, PGPProxyServerType type, + PGPChar8 **proxyAddress, PGPUInt16 *proxyPort ); + +PGP_END_C_DECLARATIONS + +#endif diff --git a/CryptoPP/PGPw/sdk8/include/pgpKeys.h b/CryptoPP/PGPw/sdk8/include/pgpKeys.h new file mode 100644 index 0000000..8700cee --- /dev/null +++ b/CryptoPP/PGPw/sdk8/include/pgpKeys.h @@ -0,0 +1,831 @@ +/*____________________________________________________________________________ + Copyright (C) 2002 PGP Corporation + All rights reserved. + + $Id: pgpKeys.h,v 1.76 2004/05/19 00:09:07 ajivsov Exp $ +____________________________________________________________________________*/ + +#ifndef Included_pgpKeys_h /* [ */ +#define Included_pgpKeys_h + +#include "pgpPubTypes.h" +#include "pgpHash.h" +#include "pgpOptionList.h" + +/* Key ordering */ + +enum PGPKeyOrdering_ +{ + kPGPKeyOrdering_Invalid = 0, + kPGPKeyOrdering_Any = 1, + kPGPKeyOrdering_UserID = 2, + kPGPKeyOrdering_KeyID = 3, + kPGPKeyOrdering_Validity = 4, + kPGPKeyOrdering_Trust = 5, + kPGPKeyOrdering_EncryptionKeySize = 6, + kPGPKeyOrdering_SigningKeySize = 7, + kPGPKeyOrdering_CreationDate = 8, + kPGPKeyOrdering_ExpirationDate = 9, + + PGP_ENUM_FORCE( PGPKeyOrdering_ ) +} ; +PGPENUM_TYPEDEF( PGPKeyOrdering_, PGPKeyOrdering ); + + +/* Key properties */ + +enum PGPKeyDBObjProperty_ +{ + kPGPKeyDBObjProperty_Invalid = 0, + + /* Generic numeric properties */ + kPGPKeyDBObjProperty_ObjectType = 20, + + /* Key boolean properties */ + kPGPKeyProperty_IsSecret = 100, + kPGPKeyProperty_IsAxiomatic = 101, + kPGPKeyProperty_IsRevoked = 102, + kPGPKeyProperty_IsDisabled = 103, + kPGPKeyProperty_IsNotCorrupt = 104, + kPGPKeyProperty_IsExpired = 105, + kPGPKeyProperty_NeedsPassphrase = 106, + kPGPKeyProperty_HasUnverifiedRevocation = 107, + kPGPKeyProperty_CanEncrypt = 108, + kPGPKeyProperty_CanDecrypt = 109, + kPGPKeyProperty_CanSign = 110, + kPGPKeyProperty_CanVerify = 111, + kPGPKeyProperty_IsEncryptionKey = 112, + kPGPKeyProperty_IsSigningKey = 113, + kPGPKeyProperty_IsSecretShared = 114, + kPGPKeyProperty_IsRevocable = 115, + kPGPKeyProperty_HasThirdPartyRevocation = 116, + kPGPKeyProperty_HasCRL = 117, + kPGPKeyProperty_IsOnToken = 118, + kPGPKeyProperty_IsStubKey = 119, /* used to filter dummy keys from inclusive key set */ + + /* Key numeric properties */ + kPGPKeyProperty_AlgorithmID = 200, + kPGPKeyProperty_Bits = 201, + kPGPKeyProperty_Trust = 202, + kPGPKeyProperty_Validity = 203, + kPGPKeyProperty_LockingAlgorithmID = 204, + kPGPKeyProperty_LockingBits = 205, + kPGPKeyProperty_Flags = 206, + kPGPKeyProperty_HashAlgorithmID = 207, + kPGPKeyProperty_Version = 208, + kPGPKeyProperty_KeyServerPreferences = 209, + kPGPKeyProperty_TokenNum = 210, + kPGPKeyProperty_Features = 211, + + /* Key time properties */ + kPGPKeyProperty_Creation = 300, + kPGPKeyProperty_Expiration = 301, + kPGPKeyProperty_CRLThisUpdate = 302, + kPGPKeyProperty_CRLNextUpdate = 303, + + /* Key data (variable sized) properties */ + kPGPKeyProperty_Fingerprint = 401, + kPGPKeyProperty_KeyID = 402, + kPGPKeyProperty_PreferredAlgorithms = 403, + kPGPKeyProperty_ThirdPartyRevocationKeyID = 404, + kPGPKeyProperty_KeyData = 405, + kPGPKeyProperty_X509MD5Hash = 406, + kPGPKeyProperty_PreferredKeyServer = 407, + kPGPKeyProperty_PreferredCompressionAlgorithms = 408, + + /* SubKey boolean properties */ + kPGPSubKeyProperty_IsRevoked = 501, + kPGPSubKeyProperty_IsNotCorrupt = 502, + kPGPSubKeyProperty_IsExpired = 503, + kPGPSubKeyProperty_NeedsPassphrase = 504, + kPGPSubKeyProperty_HasUnverifiedRevocation = 505, + kPGPSubKeyProperty_IsRevocable = 506, + kPGPSubKeyProperty_HasThirdPartyRevocation = 507, + kPGPSubKeyProperty_IsOnToken = 508, + + /* SubKey numeric properties */ + kPGPSubKeyProperty_AlgorithmID = 600, + kPGPSubKeyProperty_Bits = 601, + kPGPSubKeyProperty_LockingAlgorithmID = 602, + kPGPSubKeyProperty_LockingBits = 603, + kPGPSubKeyProperty_Version = 604, + kPGPSubKeyProperty_Flags = 605, + + /* SubKey time properties */ + kPGPSubKeyProperty_Creation = 700, + kPGPSubKeyProperty_Expiration = 701, + + /* SubKey data (variable sized) properties */ + kPGPSubKeyProperty_KeyData = 800, + kPGPSubKeyProperty_KeyID = 801, + + /* User ID boolean properties */ + kPGPUserIDProperty_IsAttribute = 900, + kPGPUserIDProperty_IsRevoked = 901, + + /* User ID numeric properties */ + kPGPUserIDProperty_Validity = 1000, + kPGPUserIDProperty_Confidence = 1001, + kPGPUserIDProperty_AttributeType = 1002, + + /* No User ID time properties */ + + /* User ID data (variable sized) properties */ + kPGPUserIDProperty_Name = 1200, + kPGPUserIDProperty_AttributeData = 1201, + kPGPUserIDProperty_CommonName = 1202, + kPGPUserIDProperty_EmailAddress = 1203, + kPGPUserIDProperty_SMIMEPreferredAlgorithms = 1204, + + /* Signature boolean properties */ + kPGPSigProperty_IsRevoked = 1300, + kPGPSigProperty_IsNotCorrupt = 1301, + kPGPSigProperty_IsTried = 1302, + kPGPSigProperty_IsVerified = 1303, + kPGPSigProperty_IsMySig = 1304, + kPGPSigProperty_IsExportable = 1305, + kPGPSigProperty_HasUnverifiedRevocation = 1306, + kPGPSigProperty_IsExpired = 1307, + kPGPSigProperty_IsX509 = 1308, + + /* Signature numeric properties */ + kPGPSigProperty_AlgorithmID = 1400, + kPGPSigProperty_TrustLevel = 1401, + kPGPSigProperty_TrustValue = 1402, + + /* Signature time properties */ + kPGPSigProperty_Creation = 1500, + kPGPSigProperty_Expiration = 1501, + + /* Signature data (variable sized) properties */ + kPGPSigProperty_KeyID = 1600, + kPGPSigProperty_X509Certificate = 1601, + kPGPSigProperty_X509IASN = 1602, + kPGPSigProperty_X509LongName = 1603, + kPGPSigProperty_X509IssuerLongName = 1604, + kPGPSigProperty_X509DNSName = 1605, + kPGPSigProperty_X509IPAddress = 1606, + kPGPSigProperty_X509DERDName = 1607, + kPGPSigProperty_RegularExpression = 1608, + + PGP_ENUM_FORCE( PGPKeyDBObjProperty_ ) +} ; +PGPENUM_TYPEDEF( PGPKeyDBObjProperty_, PGPKeyDBObjProperty ); + + +/* For kPGPKeyProperty_Version */ +enum PGPKeyVersion_ +{ + kPGPKeyVersion_V3 = 3, + kPGPKeyVersion_V4 = 4, + + PGP_ENUM_FORCE( PGPKeyVersion_ ) +} ; +PGPENUM_TYPEDEF( PGPKeyVersion_, PGPKeyVersion ); + + +/* kPGPKeyPropFlags bits */ + +enum /* PGPKeyPropertyFlags */ +{ + kPGPKeyPropertyFlags_UsageSignUserIDs = (1UL << 0 ), + kPGPKeyPropertyFlags_UsageSignMessages = (1UL << 1 ), + kPGPKeyPropertyFlags_UsageEncryptCommunications = (1UL << 2 ), + kPGPKeyPropertyFlags_UsageEncryptStorage = (1UL << 3 ), + + kPGPKeyPropertyFlags_PrivateSplit = (1UL << 4 ), + kPGPKeyPropertyFlags_PrivateShared = (1UL << 7 ) +} ; +typedef PGPFlags PGPKeyPropertyFlags; +#define kPGPKeyPropertyFlags_UsageSign \ + (kPGPKeyPropertyFlags_UsageSignUserIDs | \ + kPGPKeyPropertyFlags_UsageSignMessages) +#define kPGPKeyPropertyFlags_UsageEncrypt \ + (kPGPKeyPropertyFlags_UsageEncryptCommunications | \ + kPGPKeyPropertyFlags_UsageEncryptStorage) +#define kPGPKeyPropertyFlags_UsageSignEncrypt \ + (kPGPKeyPropertyFlags_UsageSign | \ + kPGPKeyPropertyFlags_UsageEncrypt) + +/* Attribute types, for use with kPGPUserIDPropAttributeType */ +enum PGPAttributeType_ +{ + kPGPAttribute_Image = 1, + kPGPAttribute_IPAddress = 10, + kPGPAttribute_DNSName = 11, + kPGPAttribute_Notation = 20, + + PGP_ENUM_FORCE( PGPAttributeType_ ) +} ; +PGPENUM_TYPEDEF( PGPAttributeType_, PGPAttributeType ); + +/* kPGPKeyPropFlags bits */ + +enum /* PGPKeyServerPreferencesFlags */ +{ + kPGPKeyServerPreferences_NoModify = (1UL << 7 ) +} ; +typedef PGPFlags PGPKeyServerPreferencesFlags; + +/* Implementation features like Modification Detection support */ + +enum +{ + kPGPKeyFeatures_ModificationDetection = 1 +} ; +typedef PGPFlags PGPKeyFeaturesFlags; + + +/* Key DB object types for the property kPGPKeyDBObjProperty_ObjectType */ +enum PGPKeyDBObjType_ +{ + kPGPKeyDBObjType_Invalid = 0, + kPGPKeyDBObjType_Key = (1UL << 0), + kPGPKeyDBObjType_SubKey = (1UL << 1), + kPGPKeyDBObjType_UserID = (1UL << 2), + kPGPKeyDBObjType_Signature = (1UL << 3), +#ifdef __MVS__ + kPGPKeyDBObjType_Any = -1, +#else + kPGPKeyDBObjType_Any = 0xFFFFFFFF, +#endif + + PGP_ENUM_FORCE( PGPKeyDBObjType_ ) +} ; +PGPENUM_TYPEDEF( PGPKeyDBObjType_, PGPKeyDBObjType ); + +/* + * Used by filtering functions to specify type of match. + */ + +enum PGPMatchCriterion_ +{ + kPGPMatchCriterion_Equal = 1, /* searched == val */ + kPGPMatchCriterion_GreaterOrEqual = 2, /* searched >= val */ + kPGPMatchCriterion_LessOrEqual = 3, /* searched <= val */ + kPGPMatchCriterion_SubString = 4, /* searched is contained in supplied */ + + PGP_ENUM_FORCE( PGPMatchCriterion_ ) +} ; +PGPENUM_TYPEDEF( PGPMatchCriterion_, PGPMatchCriterion ); + + +/* This is the value of the expiration time which means "never expires" */ +#define kPGPExpirationTime_Never ( (PGPTime)0 ) + +enum PGPOpenKeyDBFileOptions_ +{ + kPGPOpenKeyDBFileOptions_None = 0, + kPGPOpenKeyDBFileOptions_Mutable = (1UL << 0 ), + kPGPOpenKeyDBFileOptions_Create = (1UL << 1 ), + + PGP_ENUM_FORCE( PGPOpenKeyDBFileOptions_ ) +} ; + +PGPENUM_TYPEDEF( PGPOpenKeyDBFileOptions_, PGPOpenKeyDBFileOptions ); + +/* Public entry points */ + +PGP_BEGIN_C_DECLARATIONS + +/*____________________________________________________________________________ + Key DB functions +____________________________________________________________________________*/ + +/* Creat a new, in-memory temporary key DB */ +PGPError PGPNewKeyDB( PGPContextRef context, PGPKeyDBRef *keyDBRef ); + +/* Open a (possibly) existing key ring pair on disk */ +PGPError PGPOpenKeyDBFile( PGPContextRef context, + PGPOpenKeyDBFileOptions options, + PGPFileSpecRef pubKeysFileSpec, + PGPFileSpecRef privKeysFileSpec, + PGPKeyDBRef *keyDBRef ); + +PGPError PGPFreeKeyDB( PGPKeyDBRef keyDBRef ); + +PGPError PGPFlushKeyDB( PGPKeyDBRef keyDBRef ); + +PGPError PGPIncKeyDBRefCount( PGPKeyDBRef keyDBRef ); + +PGPBoolean PGPKeyDBIsMutable( PGPKeyDBRef keyDBRef ); + +PGPError PGPFindKeyByKeyID( PGPKeyDBRef keyDBRef, const PGPKeyID * keyID, + PGPKeyDBObjRef *keyRef); + +PGPError PGPCountKeysInKeyDB( PGPKeyDBRef keyDBRef, PGPUInt32 *numKeys ); + +PGPError PGPKeyDBIsUpdated( PGPKeyDBRef keyDBRef, PGPBoolean *isUpdated ); + +/* Cache a keydb in memory for specified number of seconds */ +PGPError PGPCacheKeyDB( PGPKeyDBRef keyDBRef, PGPUInt32 timeoutSeconds ); + +/* Remove all cached keydbs from memory */ +PGPError PGPPurgeKeyDBCache( PGPContextRef context ); + +/*____________________________________________________________________________ + Key set functions +____________________________________________________________________________*/ + +/* Create a new key set containing all of the keys in the key DB */ +PGPError PGPNewKeySet( PGPKeyDBRef keyDB, PGPKeySetRef *keySet ); + +/* Create a new, empty key set */ +PGPError PGPNewEmptyKeySet( PGPKeyDBRef keyDB, PGPKeySetRef *keySet ); + +/* Create a new key set containing a single key */ +PGPError PGPNewOneKeySet( PGPKeyDBObjRef key, PGPKeySetRef *keySet ); + +/* Like PGPNewKeySet but allows certain stub key objects */ +PGPError PGPNewEmptyInclusiveKeySet( PGPKeyDBRef keyDB, PGPKeySetRef *pset ); + +/* Like PGPNewOneKeySet but allows certain stub key objects */ +PGPError PGPNewOneInclusiveKeySet( PGPKeyDBObjRef key, PGPKeySetRef *keySet ); + +PGPError PGPFreeKeySet( PGPKeySetRef keys); + +PGPError PGPIncKeySetRefCount( PGPKeySetRef keys); + +PGPBoolean PGPKeySetIsMember( PGPKeyDBObjRef key, PGPKeySetRef set ); + +PGPError PGPCountKeys( PGPKeySetRef keys, PGPUInt32 *numKeys ); + +PGPError PGPAddKey( PGPKeyDBObjRef keyToAdd, PGPKeySetRef set ); + +PGPError PGPAddKeys( PGPKeySetRef keysToAdd, PGPKeySetRef set ); + +PGPKeyDBRef PGPPeekKeySetKeyDB( PGPKeySetRef keySet ); +PGPKeySetRef PGPPeekKeyDBRootKeySet( PGPKeyDBRef keyDB ); + +/*____________________________________________________________________________ + Key DB object properties +____________________________________________________________________________*/ + +PGPError PGPGetKeyDBObjBooleanProperty( PGPKeyDBObjRef key, + PGPKeyDBObjProperty whichProperty, PGPBoolean *prop ); + +PGPError PGPGetKeyDBObjNumericProperty( PGPKeyDBObjRef key, + PGPKeyDBObjProperty whichProperty, PGPInt32 *prop ); + +PGPError PGPGetKeyDBObjTimeProperty( PGPKeyDBObjRef key, + PGPKeyDBObjProperty whichProperty, PGPTime *prop); +/* +** Get the data for a binary property. Returns kPGPError_BufferTooSmall if +** the buffer is too small. Both buffer and dataSize can be NULL. +*/ + +#undef PGPGetKeyDBObjDataProperty +PGPError PGPGetKeyDBObjDataProperty( PGPKeyDBObjRef key, + PGPKeyDBObjProperty whichProperty, void *buffer, + PGPSize bufferSize, PGPSize *dataSize); +/* +** Get the data for a binary property using an allocated output buffer. The +** allocated buffer must be freed with PGPFreeData(). For convenience, the +** allocated buffer is null-terminated. The terminating null byte is NOT included +** is the output dataSize parameter. +*/ + +PGPError PGPGetKeyDBObjAllocatedDataProperty( PGPKeyDBObjRef key, + PGPKeyDBObjProperty whichProperty, void **buffer, + PGPSize *dataSize); + +PGPError PGPSetKeyEnabled( PGPKeyDBObjRef key, PGPBoolean enable ); + +PGPError PGPSetKeyAxiomatic( PGPKeyDBObjRef key, PGPBoolean setAxiomatic, + PGPOptionListRef firstOption, ...); + +/*____________________________________________________________________________ + Key DB object property convenience functions +____________________________________________________________________________*/ + +/* Get the key ID of a key or subkey key DB object */ +PGPError PGPGetKeyID( PGPKeyDBObjRef key, PGPKeyID *keyID ); + +PGPError PGPGetPrimaryUserID( PGPKeyDBObjRef key, PGPKeyDBObjRef *outRef ); + +PGPError PGPGetPrimaryAttributeUserID (PGPKeyDBObjRef key, + PGPAttributeType attributeType, PGPKeyDBObjRef *outRef); + +PGPError PGPGetPrimaryUserIDValidity(PGPKeyDBObjRef key, + PGPValidity *validity); + +PGPError PGPGetPrimaryUserIDName(PGPKeyDBObjRef key, void *buffer, + PGPSize bufferSize, PGPSize *dataSize); + +PGPError PGPGetKeyForUsage( PGPKeyDBObjRef key, PGPUInt32 usageFlags, + PGPKeyDBObjRef *outRef ); + + + +/*____________________________________________________________________________ + Key filters +____________________________________________________________________________*/ + +PGPError PGPNewKeyDBObjBooleanFilter( PGPContextRef context, + PGPKeyDBObjProperty whichProperty, PGPBoolean match, + PGPFilterRef *outFilter ); + +PGPError PGPNewKeyDBObjNumericFilter( PGPContextRef context, + PGPKeyDBObjProperty whichProperty, PGPUInt32 matchValue, + PGPMatchCriterion matchCriteria, PGPFilterRef *outFilter ); + +PGPError PGPNewKeyDBObjTimeFilter( PGPContextRef context, + PGPKeyDBObjProperty whichProperty, PGPTime matchValue, + PGPMatchCriterion matchCriteria, PGPFilterRef *outFilter ); + +PGPError PGPNewKeyDBObjDataFilter( PGPContextRef context, + PGPKeyDBObjProperty whichProperty, const void *matchData, + PGPSize matchDataSize, PGPMatchCriterion matchCriteria, + PGPFilterRef *outFilter ); + +PGPError PGPFreeFilter( PGPFilterRef filter ); + +PGPError PGPIncFilterRefCount( PGPFilterRef filter ); + +PGPError PGPFilterChildObjects( PGPFilterRef filter, + PGPBoolean filterChildren ); + +/* freeing outfilter will call PGPFreeFilter on filter */ +PGPError PGPNegateFilter( PGPFilterRef filter, PGPFilterRef *outFilter); + +/* freeing outfilter will call PGPFreeFilter on filter1, filter2 */ +PGPError PGPIntersectFilters( PGPFilterRef filter1, PGPFilterRef filter2, + PGPFilterRef *outFilter); + +/* freeing outfilter will call PGPFreeFilter on filter1, filter2 */ +PGPError PGPUnionFilters( PGPFilterRef filter1, PGPFilterRef filter2, + PGPFilterRef *outFilter); + +PGPError PGPFilterKeySet( PGPKeySetRef origSet, PGPFilterRef filter, + PGPKeySetRef *resultSet ); + +PGPError PGPFilterKeyDB( PGPKeyDBRef keyDB, PGPFilterRef filter, + PGPKeySetRef *resultSet ); + +/* Keyserver filter functions */ +#undef PGPLDAPQueryFromFilter +PGPError PGPLDAPQueryFromFilter( PGPFilterRef filter, PGPChar8 **queryOut ); + +#undef PGPLDAPX509QueryFromFilter +PGPError PGPLDAPX509QueryFromFilter( PGPFilterRef filter, + PGPChar8 **queryOut ); + +#undef PGPHKSQueryFromFilter +PGPError PGPHKSQueryFromFilter( PGPFilterRef filter, PGPChar8 **queryOut ); + +#undef PGPNetToolsCAHTTPQueryFromFilter +PGPError PGPNetToolsCAHTTPQueryFromFilter( PGPFilterRef filter, + PGPChar8 **queryOut ); + +/*____________________________________________________________________________ + Key/signature validation +____________________________________________________________________________*/ + +PGPError PGPCalculateTrust( PGPKeySetRef keySet, PGPKeyDBRef optionalKeyDB); + +PGPError PGPCheckKeyRingSigs( PGPKeySetRef keysToCheck, + PGPKeyDBRef optionalSigningKeyDB, PGPBoolean checkAll, + PGPEventHandlerProcPtr eventHandler, + PGPUserValue eventHandlerData ); + +/*____________________________________________________________________________ + Key DB object creation/deletion +____________________________________________________________________________*/ + +PGPError PGPGenerateKey( PGPContextRef context, PGPKeyDBObjRef *key, + PGPOptionListRef firstOption, ...); + +PGPError PGPGenerateSubKey( PGPContextRef context, PGPKeyDBObjRef *subkey, + PGPOptionListRef firstOption, ...); + +PGPUInt32 PGPGetKeyEntropyNeeded( PGPContextRef context, + PGPOptionListRef firstOption, ...); + +#undef PGPAddUserID +PGPError PGPAddUserID( PGPKeyDBObjRef key, PGPChar8 const *userID, + PGPOptionListRef firstOption, ...); + +PGPError PGPAddAttributeUserID( PGPKeyDBObjRef key, + PGPAttributeType attributeType, + PGPByte *attributeData, PGPSize attributeLength, + PGPOptionListRef firstOption, ...); + +PGPError PGPCertifyUserID( PGPKeyDBObjRef userID, + PGPKeyDBObjRef certifyingKey, + PGPOptionListRef firstOption, ...); + +PGPError PGPCopyKeyDBObj( PGPKeyDBObjRef keyDBObj, PGPKeyDBRef destKeyDB, + PGPKeyDBObjRef *destKeyDBObj ); + +PGPError PGPCopyKeys( PGPKeySetRef keySet, PGPKeyDBRef destKeyDB, + PGPKeySetRef *destKeySet ); + +PGPError PGPDeleteKeyDBObj( PGPKeyDBObjRef keyDBObj ); + +PGPError PGPDeleteKeys( PGPKeySetRef keySet ); + +/*____________________________________________________________________________ + Key manipulation +____________________________________________________________________________*/ + +PGPError PGPSetPrimaryUserID( PGPKeyDBObjRef userID, + PGPOptionListRef firstOption, ...); + +PGPError PGPGetSigCertifierKey( PGPKeyDBObjRef cert, + PGPKeyDBRef searchKeyDB, PGPKeyDBObjRef *certkey); + +PGPError PGPGetSigX509CertifierSig( PGPKeyDBObjRef cert, + PGPKeyDBRef searchKeyDB, PGPKeyDBObjRef *certsig); + +PGPError PGPGetSigX509TopSig( PGPKeyDBObjRef sig, + PGPKeyDBRef otherdb, PGPKeyDBRef cadb, + PGPBoolean *knownCA, PGPKeyDBObjRef *certsig ); + +PGPError PGPGetKnownX509CAs( PGPContextRef context, PGPKeyDBRef *keydbout ); + +PGPError PGPX509MatchNetworkName( PGPKeyDBObjRef sig, const PGPByte *networkName, + PGPBoolean *matched ); + +PGPError PGPCountAdditionalRecipientRequests( PGPKeyDBObjRef basekey, + PGPUInt32 * numARKeys); + +PGPError PGPGetIndexedAdditionalRecipientRequestKey( PGPKeyDBObjRef basekey, + PGPUInt32 nth, PGPKeyDBObjRef *arkey, + PGPKeyID *arkeyid, PGPByte *arclass ); + +PGPError PGPGetAdditionalRecipientRequests( PGPKeyDBObjRef basekey, + PGPKeySetRef keySet ); + +PGPError PGPCountRevocationKeys( PGPKeyDBObjRef basekey, + PGPUInt32 * numRevKeys); + +PGPError PGPGetIndexedRevocationKey( PGPKeyDBObjRef basekey, PGPUInt32 nth, + PGPKeyDBObjRef *revkey, PGPKeyID *revkeyid ); + +PGPError PGPGetRevocationKeys( PGPKeyDBObjRef basekey, PGPKeySetRef keySet ); + +PGPError PGPGetCRLDistributionPoints( PGPKeyDBObjRef cakey, + PGPUInt32 *pnDistPoints, PGPByte **pDpoints, + PGPSize **pdpointLengths ); + +PGPError PGPGetCRLDistributionPointsPrintable( PGPKeyDBObjRef cakey, + PGPUInt32 *pnDistPoints, PGPByte **pDpoints ); + +PGPError PGPExport( PGPContextRef context, + PGPOptionListRef firstOption, ... ); + +PGPError PGPImport( PGPContextRef context, PGPKeyDBRef *importedKeysDB, + PGPOptionListRef firstOption, ...); + +PGPError PGPRevokeSig( PGPKeyDBObjRef cert, + PGPOptionListRef firstOption, ...); + +PGPError PGPRevoke( PGPKeyDBObjRef key, + PGPOptionListRef firstOption, ...); + +PGPError PGPChangePassphrase( PGPKeyDBObjRef key, + PGPOptionListRef firstOption, ...); + +PGPBoolean PGPPassphraseIsValid( PGPKeyDBObjRef key, + PGPOptionListRef firstOption, ...); + +PGPError PGPPurgePassphraseCache( PGPContextRef context ); + +PGPError PGPCountCachedPassphrases( PGPContextRef context, + PGPUInt32 *pnLocal, PGPUInt32 *pnGlobal, + PGPUInt32 *pnOtherLocal ); + +PGPBoolean PGPTokenAuthIsValid( PGPContextRef context, + PGPOptionListRef firstOption, ... ); + +/* + * Trust values for PGPSetKeyTrust and kPGPKeyPropTrust property: + * + * kPGPKeyTrust_Undefined (do not pass to PGPSetKeyTrust) + * kPGPKeyTrust_Unknown (unknown) + * kPGPKeyTrust_Never (never) + * kPGPKeyTrust_Marginal (sometimes) + * kPGPKeyTrust_Complete (always) + * kPGPKeyTrust_Ultimate (do not pass to PGPSetKeyTrust) + */ + +PGPError PGPSetKeyTrust( PGPKeyDBObjRef key, PGPUInt32 trust); + +PGPInt32 PGPCompareKeys( PGPKeyDBObjRef a, PGPKeyDBObjRef b, + PGPKeyOrdering order ); + +#undef PGPCompareUserIDStrings +PGPInt32 PGPCompareUserIDStrings(PGPChar8 const *a, PGPChar8 const *b); + +/*____________________________________________________________________________ + Key lists +____________________________________________________________________________*/ + +PGPError PGPOrderKeySet( PGPKeySetRef src, PGPKeyOrdering order, + PGPBoolean reverseOrder, PGPKeyListRef *outRef ); + +PGPError PGPIncKeyListRefCount( PGPKeyListRef keys); + +PGPError PGPFreeKeyList( PGPKeyListRef keys ); + +/*____________________________________________________________________________ + Key list iteration +____________________________________________________________________________*/ + +PGPError PGPNewKeyIter( PGPKeyListRef keys, PGPKeyIterRef *outRef); + +PGPError PGPNewKeyIterFromKeySet( PGPKeySetRef keys, PGPKeyIterRef *outRef); + +PGPError PGPNewKeyIterFromKeyDB( PGPKeyDBRef keyDB, PGPKeyIterRef *outRef); + +PGPError PGPCopyKeyIter( PGPKeyIterRef orig, PGPKeyIterRef *outRef); + +PGPError PGPFreeKeyIter( PGPKeyIterRef iter); + +PGPInt32 PGPKeyIterIndex( PGPKeyIterRef iter); + +PGPError PGPKeyIterRewind( PGPKeyIterRef iter, PGPKeyDBObjType objectType); + +PGPInt32 PGPKeyIterSeek( PGPKeyIterRef iter, PGPKeyDBObjRef key); + +PGPError PGPKeyIterMove( PGPKeyIterRef iter, PGPInt32 relOffset, + PGPKeyDBObjRef *outRef); + +PGPError PGPKeyIterNextKeyDBObj( PGPKeyIterRef iter, + PGPKeyDBObjType objectType, PGPKeyDBObjRef *outRef); + +PGPError PGPKeyIterPrevKeyDBObj( PGPKeyIterRef iter, + PGPKeyDBObjType objectType, PGPKeyDBObjRef *outRef); + +PGPError PGPKeyIterGetKeyDBObj( PGPKeyIterRef iter, + PGPKeyDBObjType objectType, PGPKeyDBObjRef *outRef); + + +/*____________________________________________________________________________ + Get/set user value +____________________________________________________________________________*/ + +PGPError PGPSetKeyDBObjUserValue( PGPKeyDBObjRef key, + PGPUserValue userValue); + +PGPError PGPGetKeyDBObjUserValue( PGPKeyDBObjRef key, + PGPUserValue *userValue); + +/* Passphrase conversion to passkeybuffer */ +/* The size of the output buffer is from the kPGPKeyPropLockingBits property */ + +PGPError PGPGetPasskeyBuffer ( PGPKeyDBObjRef key, + void *passkeyBuffer, PGPOptionListRef firstOption,...); + +/* Change key options which are stored in self signatures internally */ + +PGPError PGPAddKeyOptions( PGPKeyDBObjRef key, + PGPOptionListRef firstOption, ...); + +PGPError PGPRemoveKeyOptions( PGPKeyDBObjRef key, + PGPOptionListRef firstOption, ...); + +PGPError PGPUpdateKeyOptions( PGPKeyDBObjRef key, + PGPOptionListRef firstOption, ...); + +/*____________________________________________________________________________ + Key IDs +____________________________________________________________________________*/ + +PGPError PGPNewKeyID( const PGPByte *keyIDBytes, PGPSize numKeyIDBytes, + PGPPublicKeyAlgorithm pkalg, PGPKeyID *id ); +#undef PGPNewKeyIDFromString +PGPError PGPNewKeyIDFromString( const PGPChar8 *string, + PGPPublicKeyAlgorithm pkalg, PGPKeyID *id ); +PGPError PGPGetKeyIDAlgorithm( const PGPKeyID *keyID, + PGPPublicKeyAlgorithm *pkalg ); + +enum PGPKeyIDStringType_ +{ + kPGPKeyIDString_Abbreviated = 1, + kPGPKeyIDString_Full = 2, + + PGP_ENUM_FORCE( PGPKeyIDStringType_ ) +}; +PGPENUM_TYPEDEF( PGPKeyIDStringType_, PGPKeyIDStringType ); + + +#define kPGPMaxKeyIDStringSize ( 127 + 1 ) +#undef PGPGetKeyIDString +PGPError PGPGetKeyIDString( PGPKeyID const * ref, PGPKeyIDStringType type, + PGPChar8 outString[ kPGPMaxKeyIDStringSize ] ); + +/* returns 0 if equal, -1 if key1 < key2, 1 if key1 > key2 */ +PGPInt32 PGPCompareKeyIDs( PGPKeyID const * key, PGPKeyID const * key2); + +/*____________________________________________________________________________ + Token functions +____________________________________________________________________________*/ + +PGPError PGPCountTokens( PGPContextRef context, PGPUInt32 *numTokens ); + +PGPError PGPDeleteKeyOnToken( PGPKeyDBObjRef key, + PGPUInt32 tokNumber /*-1 for any token*/, + const PGPByte *pin, PGPSize pinLen ); +PGPError PGPWipeToken( PGPContextRef context, PGPUInt32 tokNumber, + PGPByte const *passphrase, PGPSize passphraseLength ); +PGPError PGPFormatToken( PGPContextRef context, PGPUInt32 tokNumber, + PGPByte const * adminPin, PGPSize adminPinLen, + PGPByte const * newUserPin, PGPSize newUserPinLen ); +PGPError PGPTokenPassphraseIsValid( PGPContextRef context, + PGPUInt32 tokNumber, PGPByte const *passphrase, + PGPSize passphraseLength ); + +#undef PGPSetPKCS11DrvFile +PGPError PGPSetPKCS11DrvFile( PGPChar8 *module ); + +PGPError PGPSyncTokenKeys( PGPContextRef context, PGPUInt32 tokenNum, + PGPKeyDBRef destKeyDB, PGPBoolean *hadChanges ); + +PGPError PGPGetTokenInfoBooleanProperty( PGPContextRef context, + PGPUInt32 tokenNumber, PGPTokenProperty prop, + PGPBoolean *value ); +PGPError PGPGetTokenInfoNumericProperty( PGPContextRef context, + PGPUInt32 tokenNumber, PGPTokenProperty prop, + PGPUInt32 *value ); +#undef PGPGetTokenInfoDataProperty +PGPError PGPGetTokenInfoDataProperty( PGPContextRef context, + PGPUInt32 tokenNumber, PGPTokenProperty prop, + void *value, PGPSize size, PGPSize *sizeout ); + +/* Deprecated, use PGPGetTokenInfo*() */ +PGPError PGPGetTokenInfo( PGPContextRef context, + PGPUInt32 tokNumber, PGPTokenInfo *tokenInfo); + +/*____________________________________________________________________________ + Getting contexts back from key related items. +____________________________________________________________________________*/ + +PGPContextRef PGPPeekKeyDBContext( PGPKeyDBRef ref ); +PGPContextRef PGPPeekKeyDBObjContext( PGPKeyDBObjRef ref ); +PGPContextRef PGPPeekKeyListContext( PGPKeyListRef ref ); +PGPContextRef PGPPeekKeySetContext( PGPKeySetRef ref ); +PGPContextRef PGPPeekKeyIterContext( PGPKeyIterRef ref ); + +/*____________________________________________________________________________ + Getting parent objects from key related items. If the input is invalid, + you get kInvalidPGPKeyDBObjRef back. +____________________________________________________________________________*/ + +PGPKeyDBRef PGPPeekKeyDBObjKeyDB( PGPKeyDBObjRef ref ); +PGPKeyDBObjRef PGPPeekKeyDBObjKey( PGPKeyDBObjRef ref ); +PGPKeyDBObjRef PGPPeekKeyDBObjUserID( PGPKeyDBObjRef ref ); + +/*____________________________________________________________________________ + Secret sharing functionality +____________________________________________________________________________*/ + +PGPError PGPSecretShareData(PGPContextRef context, + void const * input, PGPSize inputBytes, + PGPUInt32 threshold, PGPUInt32 nShares, void * output); + +PGPError PGPSecretReconstructData(PGPContextRef context, + void * input, PGPSize outputBytes, + PGPUInt32 nShares, void * output); + +/*____________________________________________________________________________ + X509 certificate specific +____________________________________________________________________________*/ + +PGPError PGPVerifyX509CertificateChain (PGPContextRef context, + PGPByte *certchain, PGPByte *rootcerts); + +#undef PGPCreateDistinguishedName +PGPError PGPCreateDistinguishedName( PGPContextRef context, + PGPChar8 const *str, PGPByte **pdname, PGPSize *pdnamelen ); + +PGPError PGPCreateX509Certificate(PGPKeyDBObjRef signingSig, + PGPKeyDBObjRef signedKey, PGPKeyDBObjRef *newSig, + PGPOptionListRef firstOption, ...); + +/* Pass PKCS-10 format request in PGPOInput.... */ +PGPError PGPCreateX509CertificateFromRequest(PGPKeyDBObjRef signingSig, + PGPKeyDBObjRef *newSig, PGPOptionListRef firstOption, ...); + +PGPError PGPCreateSelfSignedX509Certificate(PGPKeyDBObjRef signingKey, + PGPKeyDBObjRef *newSig, PGPOptionListRef firstOption, ...); + +PGPError PGPCreateX509CRL(PGPKeyDBObjRef signingKey, + PGPKeySetRef revokedSigs, + PGPOptionListRef firstOption, ...); + + + +PGP_END_C_DECLARATIONS + + +#endif /* ] Included_pgpKeys_h */ + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk8/include/pgpLDAP.h b/CryptoPP/PGPw/sdk8/include/pgpLDAP.h new file mode 100644 index 0000000..1cdce41 --- /dev/null +++ b/CryptoPP/PGPw/sdk8/include/pgpLDAP.h @@ -0,0 +1,722 @@ +/*____________________________________________________________________________ + Copyright (C) 2002 PGP Corporation + All rights reserved. + + $Id: pgpLDAP.h,v 1.24 2004/01/23 08:12:49 dallen Exp $ +____________________________________________________________________________*/ +#ifndef Included_pgpLDAP_h /* [ */ +#define Included_pgpLDAP_h + +#include "pgpBase.h" +#include "pgpPubTypes.h" +#include "pgpMemoryMgr.h" +#include "pgpSockets.h" +#include "pgpBER.h" + +PGP_BEGIN_C_DECLARATIONS + +/* LDAP parameters and constants */ +#define kPGPldap_DefaultPort 389 +#define kPGPldap_DefaultSecurePort 636 +#define kPGPldap_DefaultVersion 2 + +#define kPGPldapScopeString_Base PGPTXT_MACHINE8("base") +#define kPGPldapScopeString_OneLevel PGPTXT_MACHINE8("one") +#define kPGPldapScopeString_Subtree PGPTXT_MACHINE8("sub") + +#define kPGPldap_DefaultFilterString PGPTXT_MACHINE8("(objectclass=*)") + + + +/* Session options */ +#define kPGPldapOpt_Deref 1 +#define kPGPldapOpt_Sizelimit 2 +#define kPGPldapOpt_Timelimit 3 +#define kPGPldapOpt_Desc 4 + +#define kPGPldapOpt_ON ((void *) 1) +#define kPGPldapOpt_OFF ((void *) 0) + +enum PGPldapResult_ +{ + kPGPldapResult_Success = 0x00, + kPGPldapResult_OperationsError = 0x01, + kPGPldapResult_ProtocolError = 0x02, + kPGPldapResult_TimelimitExceeded = 0x03, + kPGPldapResult_SizelimitExceeded = 0x04, + kPGPldapResult_CompareFalse = 0x05, + kPGPldapResult_CompareTrue = 0x06, + kPGPldapResult_StrongAuthNotSupported = 0x07, + kPGPldapResult_StrongAuthRequired = 0x08, + kPGPldapResult_PartialResults = 0x09, + kPGPldapResult_NoSuchAttribute = 0x10, + kPGPldapResult_UndefinedType = 0x11, + kPGPldapResult_InappropriateMatching = 0x12, + kPGPldapResult_ConstraintViolation = 0x13, + kPGPldapResult_TypeOrValueExists = 0x14, + kPGPldapResult_InvalidSyntax = 0x15, + kPGPldapResult_NoSuchObject = 0x20, + kPGPldapResult_AliasProblem = 0x21, + kPGPldapResult_InvalidDNSyntax = 0x22, + kPGPldapResult_IsLeaf = 0x23, + kPGPldapResult_AliasDerefProblem = 0x24, + kPGPldapResult_InappropriateAuth = 0x30, + kPGPldapResult_InvalidCredentials = 0x31, + kPGPldapResult_InsufficientAccess = 0x32, + kPGPldapResult_Busy = 0x33, + kPGPldapResult_Unavailable = 0x34, + kPGPldapResult_UnwillingToPerform = 0x35, + kPGPldapResult_LoopDetect = 0x36, + kPGPldapResult_NamingViolation = 0x40, + kPGPldapResult_ObjectClassViolation = 0x41, + kPGPldapResult_NotAllowedOnNonleaf = 0x42, + kPGPldapResult_NotAllowedOnRDN = 0x43, + kPGPldapResult_AlreadyExists = 0x44, + kPGPldapResult_NoObjectClassMods = 0x45, + kPGPldapResult_ResultsTooLarge = 0x46, + kPGPldapResult_Other = 0x50, + kPGPldapResult_ServerDown = 0x51, + kPGPldapResult_LocalError = 0x52, + kPGPldapResult_EncodingError = 0x53, + kPGPldapResult_DecodingError = 0x54, + kPGPldapResult_Timeout = 0x55, + kPGPldapResult_AuthUnknown = 0x56, + kPGPldapResult_FilterError = 0x57, + kPGPldapResult_UserCancelled = 0x58, + kPGPldapResult_ParamError = 0x59, + kPGPldapResult_NoMemory = 0x5a, + kPGPldapResult_ConnectError = 0x5b, + + kPGPldapResult_None = 0xFFFFFFFF +}; +PGPENUM_TYPEDEF (PGPldapResult_, PGPldapResult); + +enum PGPldapType_ +{ + kPGPldapType_None = 0, + + kPGPldapRequest_Bind = 0x60, /* application + constructed */ + kPGPldapRequest_Unbind = 0x42, /* application + primitive */ + kPGPldapRequest_Search = 0x63, /* application + constructed */ + kPGPldapRequest_Modify = 0x66, /* application + constructed */ + kPGPldapRequest_Add = 0x68, /* application + constructed */ + kPGPldapRequest_Delete = 0x4A, /* application + primitive */ + kPGPldapRequest_ModifyRDN = 0x6C, /* application + constructed */ + kPGPldapRequest_Compare = 0x6E, /* application + constructed */ + kPGPldapRequest_Abandon = 0x50, /* application + primitive */ + + kPGPldapResponse_Bind = 0x61, /* application + constructed */ + kPGPldapResponse_SearchEntry = 0x64, /* application + constructed */ + kPGPldapResponse_SearchResult = 0x65, /* application + constructed */ + kPGPldapResponse_Modify = 0x67, /* application + constructed */ + kPGPldapResponse_Add = 0x69, /* application + constructed */ + kPGPldapResponse_Delete = 0x6B, /* application + constructed */ + kPGPldapResponse_ModifyRDN = 0x6D, /* application + constructed */ + kPGPldapResponse_Compare = 0x6F, /* application + constructed */ + + kPGPldapResponse_Any = 0xFFFFFFFF +}; +PGPENUM_TYPEDEF (PGPldapType_, PGPldapType); + +enum PGPldapScope_ +{ + kPGPldapScope_Base = 0, + kPGPldapScope_OneLevel = 1, + kPGPldapScope_Subtree = 2, + + kPGPldapScope_None = -1 +}; +PGPENUM_TYPEDEF (PGPldapScope_, PGPldapScope); + +enum PGPldapDeref_ +{ + kPGPldapDeref_Never = 0, + kPGPldapDeref_Searching = 1, + kPGPldapDeref_Finding = 2, + kPGPldapDeref_Always = 3 +}; +PGPENUM_TYPEDEF (PGPldapDeref_, PGPldapDeref); + +enum PGPldapAuth_ +{ + kPGPldapAuth_Simple = 0x80 /* context-specific + primitive, tag = 0 */ + /* Not implemented -- kPGPldapAuth_Kerb41 = 0x81, */ + /* Not implemented -- kPGPldapAuth_Kerb42 = 0x82 */ +}; +PGPENUM_TYPEDEF (PGPldapAuth_, PGPldapAuth); + +enum PGPldapFilter_ +{ + kPGPldapFilter_And = 0xA0, /* context specific + constructed, tag = 0 */ + kPGPldapFilter_Or = 0xA1, /* context specific + constructed, tag = 1 */ + kPGPldapFilter_Not = 0xA2, /* context specific + constructed, tag = 2 */ + kPGPldapFilter_Equal = 0xA3, /* context specific + constructed, tag = 3 */ + kPGPldapFilter_Substrings = 0xA4, /* context specific + constructed, tag = 4 */ + kPGPldapFilter_GE = 0xA5, /* context specific + constructed, tag = 5 */ + kPGPldapFilter_LE = 0xA6, /* context specific + constructed, tag = 6 */ + kPGPldapFilter_Present = 0x87, /* context specific + primitive, tag = 7 */ + kPGPldapFilter_Approx = 0xA8, /* context specific + constructed, tag = 8 */ + + kPGPldapFilter_None = (-1L) +}; +PGPENUM_TYPEDEF( PGPldapFilter_, PGPldapFilter ); + +enum PGPldapSubstring_ +{ + kPGPldapSubstring_Initial = 0x80, /* context specific + primitive, tag = 0 */ + kPGPldapSubstring_Any = 0x81, /* context specific + primitive, tag = 1 */ + kPGPldapSubstring_Final = 0x82, /* context specific + primitive, tag = 2 */ + + kPGPldapSubstring_None = (-1L) +}; +PGPENUM_TYPEDEF( PGPldapSubstring_, PGPldapSubstring ); + +enum PGPldapModOp_ +{ + kPGPldapModOp_Add = 0x00, + kPGPldapModOp_Delete = 0x01, + kPGPldapModOp_Replace = 0x02, + + kPGPldapModOp_None = (-1L) +}; +PGPENUM_TYPEDEF( PGPldapModOp_, PGPldapModOp ); + +#define kPGPldapModOpMask_UseBERValues 0x10 + + +/* LDAP Data types: typedefs, structs, and whatnot */ + +typedef PGPUInt32 PGPldapMessageID; + +#define kPGPldapMessageID_Any ( (PGPldapMessageID) -1 ) +#define kInvalidPGPldapMessageID ( (PGPldapMessageID) 0 ) +#define PGPldapMessageIDIsValid(messageID) \ + ( (messageID) != kInvalidPGPldapMessageID ) +#define PGPValidateLDAPMessageID(messageID) \ + PGPValidateParam( PGPldapMessageIDIsValid( messageID ) ) + +typedef struct PGPldapContext * PGPldapContextRef; + +#define kInvalidPGPldapContextRef ( (PGPldapContextRef) NULL ) +#define PGPldapContextRefIsValid(pgpLDAP) \ + ( (pgpLDAP) != kInvalidPGPldapContextRef ) +#define PGPValidateLDAPContextRef(context) \ + PGPValidateParam( PGPldapContextRefIsValid( context ) ) + +typedef struct PGPldapMessage * PGPldapMessageRef; + +#define kInvalidPGPldapMessageRef ( (PGPldapMessageRef) NULL) +#define PGPldapMessageRefIsValid(message) \ + ( (message) != kInvalidPGPldapMessageRef ) +#define PGPValidateLDAPMessageRef(message) \ + PGPValidateParam( PGPldapMessageRefIsValid( message ) ) + + +#define IsPGPldapError(err) \ + ( ( (err) >= kPGPError_LDAPMIN ) && ( (err) <= kPGPError_LDAPMAX ) ) + + +/* Callbacks for using LDAP functions in multithreaded apps */ +typedef struct PGPldapThreadFns +{ + void * (*pgpLDAPThread_MutexAlloc) (void); + void (*pgpLDAPThread_MutexFree) (void *); + PGPError (*pgpLDAPThread_MutexLock) (void *); + PGPError (*pgpLDAPThread_MutexUnlock) (void *); + void (*pgpLDAPThread_SetErrno) (int); + PGPError (*pgpLDAPThread_GetErrno) (void); + void (*pgpLDAPThread_SetLDAPErrno) (PGPInt32, PGPChar8 *, PGPChar8 *); + PGPInt32 (*pgpLDAPThread_GetLDAPErrno) (PGPChar8 **, PGPChar8 **); +} PGPldapThreadFns; + +typedef struct PGPldapMod +{ + PGPldapModOp op; + PGPChar8 * type; + + PGPChar8 ** value; + PGPberValue ** bvalue; +} PGPldapMod; + +typedef struct PGPldapURLDesc +{ + PGPChar8 * host; + PGPUInt16 port; + + PGPChar8 * dn; + PGPChar8 ** attrs; + + PGPldapScope scope; + PGPChar8 * filter; + +} PGPldapURLDesc; + +typedef PGPError (* PGPldapRebindProcPtr )( + PGPldapContextRef pgpLDAP, + PGPChar8 ** dnp, + PGPChar8 ** pwp, + PGPInt32 * method, + PGPBoolean freeIt, + PGPChar8 * arg ); + + +/* LDAP function prototypes */ +/* + * Above each function is the name of the analogous function + * in the UMich or Netscape LDAP SDK. While there are some subtle + * differences, for the most part, each function works basically + * the same as it's UMich/Netscape SDK counterpart. + */ + +/* Memory management functions */ + PGPError +PGPNewLDAPContext( + PGPContextRef context, + PGPldapContextRef *pgpLDAP ); + + PGPError +PGPNewLDAPMessage( + PGPldapContextRef pgpLDAP, + PGPldapMessageRef * message ); + + PGPError +PGPFreeLDAPContext( + PGPldapContextRef pgpLDAP ); + + PGPError +PGPFreeLDAPMessage( + PGPldapMessageRef message ); + + /* ldap_value_free */ + PGPError +PGPFreeLDAPValues( + PGPChar8 ** vals ); + + /* ldap_value_free_len */ + PGPError +PGPFreeLDAPValuesLen( + PGPberValue ** bvals ); + + PGPError +PGPFreeLDAPURLDesc( + PGPldapURLDesc * lud ); + + +/* Result-handling functions */ + /* ldap_get_lderrno */ + PGPError +PGPldapGetErrno( + PGPldapContextRef pgpLDAP, + PGPChar8 ** matched, + PGPChar8 ** message, + PGPldapResult * result ); + + PGPError +PGPldapResultToError( + PGPldapContextRef pgpLDAP, + PGPldapResult result ); + +/* LDAP option functions */ + /* ldap_set_option */ + PGPError +PGPldapSetOption( + PGPldapContextRef pgpLDAP, + PGPUInt32 option, + void * value ); + + /* ldap_get_option */ + PGPError +PGPldapGetOption( + PGPldapContextRef pgpLDAP, + PGPUInt32 option, + void * value ); + + +/* Connection starting and stopping functions */ + /* ldap_open */ + PGPError +PGPldapOpen( + PGPldapContextRef pgpLDAP, + PGPChar8 * host, + PGPUInt16 port ); + + PGPError +PGPldapOpenTimeout( + PGPldapContextRef pgpLDAP, + PGPChar8 * host, + PGPUInt16 port, + PGPSocketsTimeValue *tv ); + + /* ldap_simple_bind_s */ + PGPError +PGPldapSimpleBindSync( + PGPldapContextRef pgpLDAP, + PGPChar8 * dn, + PGPChar8 * password ); + + /* ldap_simple_bind_st (extension) */ + PGPError +PGPldapSimpleBindSyncTimeout( + PGPldapContextRef pgpLDAP, + PGPChar8 * dn, + PGPChar8 * password, + PGPSocketsTimeValue *tv); + + /* ldap_simple_bind */ + PGPError +PGPldapSimpleBind( + PGPldapContextRef pgpLDAP, + PGPChar8 * dn, + PGPChar8 * password, + PGPldapMessageID * messageID ); + + /* ldap_bind_s */ + PGPError +PGPldapBindSync( + PGPldapContextRef pgpLDAP, + PGPChar8 * dn, + PGPChar8 * password, + PGPldapAuth method ); + + /* ldap_bind */ + PGPError +PGPldapBind( + PGPldapContextRef pgpLDAP, + PGPChar8 * dn, + PGPChar8 * password, + PGPldapAuth method, + PGPldapMessageID * messageID ); + + /* ldap_unbind */ + PGPError +PGPldapUnbind( + PGPldapContextRef pgpLDAP ); + + +/* Searching functions */ + /* ldap_search_s */ + PGPError +PGPldapSearchSync( + PGPldapContextRef pgpLDAP, + PGPChar8 * base, + PGPldapScope scope, + PGPChar8 * filter, + PGPChar8 * attrs[], + PGPBoolean attrsOnly, + PGPldapMessageRef resultMessage ); + + /* ldap_search_st */ + PGPError +PGPldapSearchSyncTimeout( + PGPldapContextRef pgpLDAP, + PGPChar8 * base, + PGPldapScope scope, + PGPChar8 * filter, + PGPChar8 * attrs[], + PGPBoolean attrsOnly, + PGPSocketsTimeValue * tv, + PGPldapMessageRef resultMessage ); + + /* ldap_search */ + PGPError +PGPldapSearch( + PGPldapContextRef pgpLDAP, + PGPChar8 * base, + PGPldapScope scope, + PGPChar8 * filter, + PGPChar8 * attrs[], + PGPBoolean attrsOnly, + PGPldapMessageID * messageID ); + + /* ldap_count_entries */ + PGPError +PGPldapCountEntries( + PGPldapContextRef pgpLDAP, + PGPldapMessageRef result, + PGPInt32 * num ); + + /* ldap_first_entry */ + PGPError +PGPldapFirstEntry( + PGPldapContextRef pgpLDAP, + PGPldapMessageRef result, + PGPldapMessageRef * outMessage ); + + /* ldap_next_entry */ + PGPError +PGPldapNextEntry( + PGPldapContextRef pgpLDAP, + PGPldapMessageRef prevEntry, + PGPldapMessageRef * outMessage ); + + /* ldap_get_dn */ + PGPError +PGPldapGetDN( + PGPldapContextRef pgpLDAP, + PGPldapMessageRef entry, + PGPChar8 ** dn ); /* Should be freed by PGPFreeData */ + + /* ldap_first_attribute */ + PGPError +PGPldapFirstAttribute( + PGPldapContextRef pgpLDAP, + PGPldapMessageRef entry, + PGPberElementRef * ber, + PGPChar8 ** attr ); /* Should be freed by PGPFreeData */ + + /* ldap_next_attribute */ + PGPError +PGPldapNextAttribute( + PGPldapContextRef pgpLDAP, + PGPldapMessageRef entry, + PGPberElementRef ber, + PGPChar8 ** attr ); /* Should be freed by PGPFreeData */ + + /* ldap_get_values */ + PGPError +PGPldapGetValues( + PGPldapContextRef pgpLDAP, + PGPldapMessageRef entry, + PGPChar8 * attr, + PGPChar8 *** values ); /* Should be freed by PGPFreeLDAPValues */ + + /* ldap_get_values_len */ + PGPError +PGPldapGetValuesLen( + PGPldapContextRef pgpLDAP, + PGPldapMessageRef entry, + PGPChar8 * attr, + PGPberValue *** values ); /* Should be freed by PGPFreeLDAPValuesLen */ + + /* ldap_count_values */ + PGPError +PGPldapCountValues( + PGPldapContextRef pgpLDAP, + PGPChar8 ** values, + PGPSize * num ); + + /* ldap_count_values_len */ + PGPError +PGPldapCountValuesLen( + PGPldapContextRef pgpLDAP, + PGPberValue ** values, + PGPSize * num ); + + +/* Update functions */ + + /* ldap_modify */ + PGPError +PGPldapModify( + PGPldapContextRef pgpLDAP, + PGPChar8 * dn, + PGPldapMod * mod[], + PGPldapMessageID * messageID ); + + /* ldap_modify_s */ + PGPError +PGPldapModifySync( + PGPldapContextRef pgpLDAP, + PGPChar8 * dn, + PGPldapMod * mod[] ); + + /* ldap_modify_st (extension) */ + PGPError +PGPldapModifySyncTimeout( + PGPldapContextRef pgpLDAP, + PGPChar8 * dn, + PGPldapMod * mod[], + PGPSocketsTimeValue *tv); + + /* ldap_add */ + PGPError +PGPldapAdd( + PGPldapContextRef pgpLDAP, + PGPChar8 * dn, + PGPldapMod * mod[], + PGPldapMessageID * messageID ); + + /* ldap_add_s */ + PGPError +PGPldapAddSync( + PGPldapContextRef pgpLDAP, + PGPChar8 * dn, + PGPldapMod * mod[] ); + + /* ldap_add_st (extension) */ + PGPError +PGPldapAddSyncTimeout( + PGPldapContextRef pgpLDAP, + PGPChar8 * dn, + PGPldapMod * mod[], + PGPSocketsTimeValue *tv ); + + /* ldap_delete */ + PGPError +PGPldapDelete( + PGPldapContextRef pgpLDAP, + PGPChar8 * dn, + PGPldapMessageID * messageID ); + + /* ldap_delete_s */ + PGPError +PGPldapDeleteSync( + PGPldapContextRef pgpLDAP, + PGPChar8 * dn ); + + /* ldap_delete_st (extension) */ + PGPError +PGPldapDeleteSyncTimeout( + PGPldapContextRef pgpLDAP, + PGPChar8 * dn, + PGPSocketsTimeValue *tv); + + /* ldap_modrdn2 */ + PGPError +PGPldapModifyRDN( + PGPldapContextRef pgpLDAP, + PGPChar8 * dn, + PGPChar8 * newRDN, + PGPBoolean deleteOldRDN, + PGPldapMessageID * messageID ); + + /* ldap_modrdn2_s */ + PGPError +PGPldapModifyRDNSync( + PGPldapContextRef pgpLDAP, + PGPChar8 * dn, + PGPChar8 * newRDN, + PGPBoolean deleteOldRDN ); + + /* ldap_compare */ + PGPError +PGPldapCompare( + PGPldapContextRef pgpLDAP, + PGPChar8 * dn, + PGPChar8 * type, + PGPChar8 * value, + PGPldapMessageID * messageID ); + + /* ldap_compare_s */ + PGPError +PGPldapCompareSync( + PGPldapContextRef pgpLDAP, + PGPChar8 * dn, + PGPChar8 * type, + PGPChar8 * value, + PGPBoolean * equal ); + + PGPError +PGPldapGetCompareResult( + PGPldapContextRef pgpLDAP, + PGPldapMessageID messageID, + PGPBoolean * equal ); + + +/* Other functions */ + /* ldap_result */ + PGPError +PGPldapGetResult( + PGPldapContextRef pgpLDAP, + PGPldapMessageID messageID, + PGPBoolean all, + PGPSocketsTimeValue * timeout, + PGPldapMessageRef result, + PGPldapType * messageType ); + + /* ldap_abandon */ + PGPError +PGPldapAbandon( + PGPldapContextRef pgpLDAP, + PGPldapMessageID messageID ); + + /* ldap_msgid */ + PGPError +PGPldapGetMessageID( + PGPldapContextRef pgpLDAP, + PGPldapMessageRef result, + PGPldapMessageID * messageID ); + + /* ldap_is_ldap_url */ + PGPError +PGPldapIsLDAPURL( + PGPldapContextRef pgpLDAP, + PGPChar8 * url, + PGPBoolean * isURL ); + + /* ldap_url_parse */ + PGPError +PGPldapURLParse( + PGPldapContextRef pgpLDAP, + PGPChar8 * url, + PGPldapURLDesc ** outLDAPDesc ); /* Should be freed by PGPFreeLDAPURLDesc */ + + /* ldap_url_search */ + PGPError +PGPldapURLSearch( + PGPldapContextRef pgpLDAP, + PGPChar8 * url, + PGPBoolean attrsOnly, + PGPldapMessageID * messageID ); + + /* ldap_url_search */ + PGPError +PGPldapURLSearchSync( + PGPldapContextRef pgpLDAP, + PGPChar8 * url, + PGPBoolean attrsOnly, + PGPldapMessageRef resultMessage ); + + /* ldap_url_search */ + PGPError +PGPldapURLSearchSyncTimeout( + PGPldapContextRef pgpLDAP, + PGPChar8 * url, + PGPBoolean attrsOnly, + PGPSocketsTimeValue * tv, + PGPldapMessageRef resultMessage ); + + /* ldap_explode_dn */ + PGPError +PGPldapExplodeDN( + PGPldapContextRef pgpLDAP, + PGPChar8 * dn, + PGPBoolean noTypes, + PGPChar8 *** components ); /* Should be freed by PGPFreeLDAPValues */ + + /* ldap_sort_entries */ + PGPError +PGPldapSortEntries( + PGPldapContextRef pgpLDAP, + PGPldapMessageRef chain, + PGPChar8 * attr, + PGPInt32 (*compare)( PGPChar8 ** a, PGPChar8 ** b ), + PGPldapMessageRef sortedChain ); + + /* ldap_sort_values */ + PGPError +PGPldapSortValues( + PGPldapContextRef pgpLDAP, + PGPChar8 ** vals, + PGPInt32 (*compare)( PGPChar8 ** a, PGPChar8 ** b ), + PGPChar8 *** sortedVals ); + + /* ldap_sort_strcasecmp */ + PGPInt32 +PGPldapCompareStringsIgnoreCase( + PGPChar8 ** s1, + PGPChar8 ** s2 ); + +PGP_END_C_DECLARATIONS + +#endif /* ] Included_pgpLDAP_h */ + + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk8/include/pgpMemoryMgr.h b/CryptoPP/PGPw/sdk8/include/pgpMemoryMgr.h new file mode 100644 index 0000000..1a86a22 --- /dev/null +++ b/CryptoPP/PGPw/sdk8/include/pgpMemoryMgr.h @@ -0,0 +1,220 @@ +/*____________________________________________________________________________ + Copyright (C) 2002 PGP Corporation + All rights reserved. + + $Id: pgpMemoryMgr.h,v 1.9 2003/11/08 04:04:49 ajivsov Exp $ +____________________________________________________________________________*/ + +#ifndef Included_pgpMemoryMgr_h /* [ */ +#define Included_pgpMemoryMgr_h + +#include "pgpBase.h" + +/*____________________________________________________________________________ + Mini-tutorial: + + A PGPMemoryMgr is an object which implements memory management, including + allocation, reallocation, deallocation, and secure versions of the same. + + *** Using it *** + A typical sequence of calls is as follows: + PGPNewMemoryMgr + ... + PGPNewData or PGPNewSecureData + PGPFreeData + ... + PGPFreeMemoryMgr + + Typically, a program will create one PGPMemoryMgr per thread at + thread creation time and use that memory mgr until the thread dies. + Generally, an individual PGPMemoryMgr instance is not thread-safe; + you must either synchronize or use one PGPMemoryMgr per thread. + + + *** Custom Allocators *** + + Default allocators are supplied, but the client can create a custom + PGPMemoryMgr using PGPNewMemoryMgrCustom() which uses client-supplied + routines. + Custom routines need only concern themselves with the actual + allocation and deallocation. + The following should be kept in mind for user supplied routines: + - they can ignore the allocation flags passed + - leaks, memory clearing, etc is done by the PGPMemoryMgr + - secure allocator must set 'isNonPageable' to TRUE only if the + memory really can't be paged. + - the user value is not interpreted by the PGPMemoryMgr. Typically, + it would be a pointer to some data the allocation routines use + to store state. + + + *** Secure memory allocation *** + + Blocks can be allocated as "Secure" blocks. Secure blocks are guaranteed + to be wiped when they are deallocated. Additionally, if the operating + system and the current conditions allow, the block will be allocated + in non-pageable memory. You can determine the attributes of a block using + PGPGetMemoryMgrDataInfo(). + + + *** Leaks tracking *** + + Leaks tracking is implemented when debugging is on, + but currently reporting is limited to reporting the number of leaks + outstanding when the PGPMemoryMgr is disposed. + + + *** Debugging *** + + For debugging purposes, blocks may be larger in debug mode to accomodate + various schemes to detect stray pointers, etc. +____________________________________________________________________________*/ + +#if PGP_MACINTOSH +#pragma options align=mac68k +#endif + +enum +{ + kPGPMemoryMgrFlags_None = 0, + kPGPMemoryMgrFlags_Clear = 1 +}; + +typedef PGPFlags PGPMemoryMgrFlags; + +typedef struct PGPMemoryMgr * PGPMemoryMgrRef; + +#define kInvalidPGPMemoryMgrRef ((PGPMemoryMgrRef) NULL) +#define PGPMemoryMgrRefIsValid(ref) ((ref) != kInvalidPGPMemoryMgrRef) + +typedef void *(*PGPMemoryMgrAllocationProc)( PGPMemoryMgrRef mgr, + PGPUserValue userValue, + PGPSize requestSize, PGPMemoryMgrFlags flags ); + +/* realloc not be implemented using PGPNewData() */ +typedef PGPError (*PGPMemoryMgrReallocationProc)( PGPMemoryMgrRef mgr, + PGPUserValue userValue, + void **allocation, PGPSize newAllocationSize, + PGPMemoryMgrFlags flags, PGPSize existingSize ); + +typedef PGPError (*PGPMemoryMgrDeallocationProc)( PGPMemoryMgrRef mgr, + PGPUserValue userValue, + void *allocation, PGPSize allocationSize ); + + +typedef void *(*PGPMemoryMgrSecureAllocationProc)( PGPMemoryMgrRef mgr, + PGPUserValue userValue, + PGPSize requestSize, PGPMemoryMgrFlags flags, + PGPBoolean *isNonPageable ); + + +/* deallocation proc need not clear the memory upon deallocation since + PGPFreeData() does it automatically */ +typedef PGPError (*PGPMemoryMgrSecureDeallocationProc)( PGPMemoryMgrRef mgr, + PGPUserValue userValue, + void *allocation, PGPSize allocationSize, + PGPBoolean wasLocked ); + +typedef struct PGPNewMemoryMgrStruct +{ + /* sizeofStruct must be inited to sizeof( PGPNewMemoryMgrStruct ) */ + PGPUInt32 sizeofStruct; + PGPFlags reservedFlags; + + PGPMemoryMgrAllocationProc allocProc; + PGPMemoryMgrReallocationProc reallocProc; + PGPMemoryMgrDeallocationProc deallocProc; + + PGPMemoryMgrSecureAllocationProc secureAllocProc; + void * reserved; /* MUST be zeroed */ + PGPMemoryMgrSecureDeallocationProc secureDeallocProc; + + PGPUserValue customValue; + void * pad[ 8 ]; /* MUST be zeroed */ +} PGPNewMemoryMgrStruct; + +PGP_BEGIN_C_DECLARATIONS + + +/*____________________________________________________________________________ + Memory Mgr routines +____________________________________________________________________________*/ + +PGPError PGPNewMemoryMgr( PGPFlags reserved, PGPMemoryMgrRef *newMemoryMgr ); + +PGPError PGPNewMemoryMgrCustom( PGPNewMemoryMgrStruct const * custom, + PGPMemoryMgrRef *newMemoryMgr ); + +PGPError PGPFreeMemoryMgr( PGPMemoryMgrRef mgr ); + +PGPError PGPGetMemoryMgrCustomValue( PGPMemoryMgrRef mgr, + PGPUserValue *customValue ); +PGPError PGPSetMemoryMgrCustomValue( PGPMemoryMgrRef mgr, + PGPUserValue customValue ); + +PGPError PGPValidateMemoryMgr( PGPMemoryMgrRef mgr ); + +/* allocate a block of the specified size */ +void * PGPNewData( PGPMemoryMgrRef mgr, + PGPSize requestSize, PGPMemoryMgrFlags flags ); + +/* allocate a block of the specified size in non-pageable memory */ +/* *isSecure is TRUE if the block definitely can't be paged */ +void * PGPNewSecureData( PGPMemoryMgrRef mgr, + PGPSize requestSize, PGPMemoryMgrFlags flags ); + +/* properly reallocs secure or non-secure blocks */ +/* WARNING: the block may move, even if its size is being reduced */ +PGPError PGPReallocData( PGPMemoryMgrRef mgr, + void **allocation, PGPSize newAllocationSize, + PGPMemoryMgrFlags flags ); + +/* properly frees secure or non-secure blocks */ +PGPError PGPFreeData( void *allocation ); + + +/*____________________________________________________________________________ + Block Info: + kPGPMemoryMgrBlockInfo_Valid it's a valid block + kPGPMemoryMgrBlockInfo_Secure block is a secure allocation + kPGPMemoryMgrBlockInfo_NonPageable block cannot be paged by VM + + Secure blocks are always wiped before being disposed, + but may or may not be pageable, depending on the OS facilities. Some + OSs may not provide the ability to make blocks non-pageable. + + You should check these flags if the information matters to you. +____________________________________________________________________________*/ +#define kPGPMemoryMgrBlockInfo_Valid ( ((PGPFlags)1) << 0 ) +#define kPGPMemoryMgrBlockInfo_Secure ( ((PGPFlags)1) << 1 ) +#define kPGPMemoryMgrBlockInfo_NonPageable ( ((PGPFlags)1) << 2 ) +PGPFlags PGPGetMemoryMgrDataInfo( void *allocation ); + + +/*____________________________________________________________________________ + Default memory manager routines: +____________________________________________________________________________*/ + +PGPMemoryMgrRef PGPGetDefaultMemoryMgr(void); +PGPError PGPSetDefaultMemoryMgr(PGPMemoryMgrRef memoryMgr); + + +PGP_END_C_DECLARATIONS + + + +#if PGP_MACINTOSH +#pragma options align=reset +#endif + + +#endif /* ] Included_pgpMemoryMgr_h */ + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk8/include/pgpOptionList.h b/CryptoPP/PGPw/sdk8/include/pgpOptionList.h new file mode 100644 index 0000000..a0ef6ce --- /dev/null +++ b/CryptoPP/PGPw/sdk8/include/pgpOptionList.h @@ -0,0 +1,542 @@ +/*____________________________________________________________________________ + Copyright (C) 2002 PGP Corporation + All rights reserved. + + This file contains the types and prototypes for functions which manipulate + PGPOptionList data structures. + + $Id: pgpOptionList.h,v 1.43 2004/05/15 02:48:39 ajivsov Exp $ +____________________________________________________________________________*/ + +#ifndef Included_pgpOptionList_h /* [ */ +#define Included_pgpOptionList_h + +#include + +#include "pgpPubTypes.h" + +#if PGP_MACINTOSH +#include +#elif PGP_OSX + struct FSSpec; +#endif + +/* Standard event callback declaration */ +struct PGPEvent; +typedef PGPError (*PGPEventHandlerProcPtr)(PGPContextRef context, + struct PGPEvent *event, PGPUserValue userValue); + +/* Export formats for exporting functions */ +enum PGPExportFormat_ +{ + kPGPExportFormat_Basic = 1, + kPGPExportFormat_Complete = 255, + + kPGPExportFormat_TokenKeyContainer = 256, + + kPGPExportFormat_X509Cert = 10000, + kPGPExportFormat_PKCS8, + + kPGPExportFormat_X509CertReq = 11000, + kPGPExportFormat_NetToolsCAV1_CertReq, + kPGPExportFormat_VerisignV1_CertReq, + kPGPExportFormat_EntrustV1_CertReq, + kPGPExportFormat_NetscapeV1_CertReq, + kPGPExportFormat_MicrosoftV1_CertReq, + + kPGPExportFormat_X509GetCertInitial = 11010, + kPGPExportFormat_NetToolsCAV1_GetCertInitial, + kPGPExportFormat_VerisignV1_GetCertInitial, + kPGPExportFormat_EntrustV1_GetCertInitial, + kPGPExportFormat_NetscapeV1_GetCertInitial, + kPGPExportFormat_MicrosoftV1_GetCertInitial, + + kPGPExportFormat_X509GetCRL = 11020, + kPGPExportFormat_NetToolsCAV1_GetCRL, + kPGPExportFormat_VerisignV1_GetCRL, + kPGPExportFormat_EntrustV1_GetCRL, + kPGPExportFormat_NetscapeV1_GetCRL, + kPGPExportFormat_MicrosoftV1_GetCRL, + + PGP_ENUM_FORCE( PGPExportFormat_ ) +}; +PGPENUM_TYPEDEF( PGPExportFormat_, PGPExportFormat ); + +/* Input formats for PGPOInputFormat */ +enum PGPInputFormat_ +{ + kPGPInputFormat_Unknown = 0, + kPGPInputFormat_PGP = 1, + + kPGPInputFormat_X509DataInPKCS7 = 10000, + kPGPInputFormat_NetToolsCAV1_DataInPKCS7, + kPGPInputFormat_VerisignV1_DataInPKCS7, + kPGPInputFormat_EntrustV1_DataInPKCS7, + kPGPInputFormat_MicrosoftV1_DataInPKCS7, + kPGPInputFormat_NetscapeV1_DataInPKCS7, + + kPGPInputFormat_PEMEncodedX509Cert, + kPGPInputFormat_NetToolsCAV1_PEMEncoded, + kPGPInputFormat_VerisignV1_PEMEncoded, + kPGPInputFormat_EntrustV1_PEMEncoded, + kPGPInputFormat_MicrosoftV1_PEMEncoded, + kPGPInputFormat_NetscapeV1_PEMEncoded, + + /* Input formats for X.509 private keys */ + kPGPInputFormat_PrivateKeyInfo, + kPGPInputFormat_PKCS12, + + kPGPInputFormat_SMIMEBody = 12000, + kPGPInputFormat_SMIMEBodySignedData = 12001, + kPGPInputFormat_SMIMEBodyEncryptedData = 12002, + + PGP_ENUM_FORCE( PGPInputFormat_ ) +}; +PGPENUM_TYPEDEF( PGPInputFormat_, PGPInputFormat ); + +/* Output formats for PGPOOutputFormat */ +enum PGPOutputFormat_ +{ + kPGPOutputFormat_Unknown = 0, + kPGPOutputFormat_PGP = 1, + + kPGPOutputFormat_X509CertReqInPKCS7 = 10000, + kPGPOutputFormat_NetToolsCAV1_CertReqInPKCS7, + kPGPOutputFormat_VerisignV1_CertReqInPKCS7, + kPGPOutputFormat_EntrustV1_CertReqInPKCS7, + kPGPOutputFormat_NetscapeV1_CertReqInPKCS7, + kPGPOutputFormat_MicrosoftV1_CertReqInPKCS7, + + kPGPOutputFormat_X509GetCertInitialInPKCS7 = 10010, + kPGPOutputFormat_NetToolsCAV1_GetCertInitialInPKCS7, + kPGPOutputFormat_VerisignV1_GetCertInitialInPKCS7, + kPGPOutputFormat_EntrustV1_GetCertInitialInPKCS7, + kPGPOutputFormat_NetscapeV1_GetCertInitialInPKCS7, + kPGPOutputFormat_MicrosoftV1_GetCertInitialInPKCS7, + + kPGPOutputFormat_X509GetCRLInPKCS7 = 10020, + kPGPOutputFormat_NetToolsCAV1_GetCRLInPKCS7, + kPGPOutputFormat_VerisignV1_GetCRLInPKCS7, + kPGPOutputFormat_EntrustV1_GetCRLInPKCS7, + kPGPOutputFormat_NetscapeV1_GetCRLInPKCS7, + kPGPOutputFormat_MicrosoftV1_GetCRLInPKCS7, + + kPGPOutputFormat_SMIMEBodySignedData = 12001, + kPGPOutputFormat_SMIMEBodyEncryptedData = 12002, + + PGP_ENUM_FORCE( PGPOutputFormat_ ) +}; +PGPENUM_TYPEDEF( PGPOutputFormat_, PGPOutputFormat ); + +/* Attribute-Value structure for PGPOAttributeValue */ +enum PGPAVAttribute_ +{ + /* Pointer properties */ + kPGPAVAttributeFirstPointer = 0, + kPGPAVAttribute_CommonName = kPGPAVAttributeFirstPointer, + kPGPAVAttribute_Email, + kPGPAVAttribute_OrganizationName, + kPGPAVAttribute_OrganizationalUnitName, + kPGPAVAttribute_SurName, + kPGPAVAttribute_SerialNumber, + kPGPAVAttribute_Country, + kPGPAVAttribute_Locality, + kPGPAVAttribute_State, + kPGPAVAttribute_StreetAddress, + kPGPAVAttribute_Title, + kPGPAVAttribute_Description, + kPGPAVAttribute_PostalCode, + kPGPAVAttribute_POBOX, + kPGPAVAttribute_PhysicalDeliveryOfficeName, + kPGPAVAttribute_TelephoneNumber, + kPGPAVAttribute_X121Address, + kPGPAVAttribute_ISDN, + kPGPAVAttribute_DestinationIndicator, + kPGPAVAttribute_Name, + kPGPAVAttribute_GivenName, + kPGPAVAttribute_Initials, + kPGPAVAttribute_HouseIdentifier, + kPGPAVAttribute_DirectoryManagementDomain, + kPGPAVAttribute_DomainComponent, + kPGPAVAttribute_UnstructuredName, + kPGPAVAttribute_UnstructuredAddress, + kPGPAVAttribute_RFC822Name, + kPGPAVAttribute_DNSName, + kPGPAVAttribute_AnotherName, + kPGPAVAttribute_IPAddress, + kPGPAVAttribute_CertificateExtension, + kPGPAVAttribute_SCEPChallenge, + + /* Verisign specific */ + kPGPAVAttribute_Challenge, + kPGPAVAttribute_CertType, + kPGPAVAttribute_MailFirstName, + kPGPAVAttribute_MailMiddleName, + kPGPAVAttribute_MailLastName, + kPGPAVAttribute_EmployeeID, + kPGPAVAttribute_MailStop, + kPGPAVAttribute_AdditionalField4, + kPGPAVAttribute_AdditionalField5, + kPGPAVAttribute_AdditionalField6, + kPGPAVAttribute_Authenticate, + + /* Generic pointer properties continue */ + kPGPAVAttribute_KeyID = kPGPAVAttribute_Authenticate+100, + + kPGPAVAttributeLastPointer = kPGPAVAttribute_KeyID, + + /* Boolean properties */ + kPGPAVAttributeFirstBoolean = 1000, + + /* Verisign specific */ + kPGPAVAttribute_EmbedEmail, + + + /* Numeric (PGPUInt32) properties */ + kPGPAVAttributeFirstNumber = 2000, + + PGP_ENUM_FORCE( PGPAVAttribute_ ) +} ; +PGPENUM_TYPEDEF( PGPAVAttribute_, PGPAVAttribute ); + +typedef struct PGPAttributeValue +{ + PGPAVAttribute attribute; + PGPUInt32 size; + union + { + PGPBoolean booleanvalue; + PGPUInt32 longvalue; + void *pointervalue; + + } value; + + PGPUInt32 unused; +} PGPAttributeValue ; + +enum PGPSMIMEMatchCriterion_ +{ + kPGPSMIMEMatchCriterion_Exact = 1, /* exact matching per SMIME spec (default) */ + kPGPSMIMEMatchCriterion_Related = 2, /* use Issuer from IASN, use Exact first then Any for keyIdentifier */ + kPGPSMIMEMatchCriterion_Any = 3, /* try all */ + + PGP_ENUM_FORCE( PGPSMIMEMatchCriterion_ ) +} ; +PGPENUM_TYPEDEF( PGPSMIMEMatchCriterion_, PGPSMIMEMatchCriterion ); + +PGP_BEGIN_C_DECLARATIONS + + +PGPError PGPNewOptionList( PGPContextRef context, PGPOptionListRef *outList ); +PGPError PGPAppendOptionList( PGPOptionListRef optionList, + PGPOptionListRef firstOption, ... ); +PGPError PGPBuildOptionList( PGPContextRef context, + PGPOptionListRef *outList, + PGPOptionListRef firstOption, ... ); +PGPError PGPCopyOptionList( PGPOptionListRef optionList, + PGPOptionListRef *outList ); +PGPError PGPFreeOptionList( PGPOptionListRef optionList ); + +/* +** The following functions are used to create PGPOptionListRef's for +** specifying the various options to several SDK functions. The +** functions can be used as inline parameters in a temporary manner or +** used with PGPBuildOptionList() to create persistent lists. +*/ + +/* +** Special PGPOptionListRef to mark last option passed to those functions +** which take variable lists of PGPOptionListRef's: +*/ + +PGPOptionListRef PGPOLastOption( PGPContextRef context ); + +/* Special PGPOptionListRef which is always ignored: */ + +PGPOptionListRef PGPONullOption( PGPContextRef context); + +/* Data input (required): */ + +PGPOptionListRef PGPOInputFile( PGPContextRef context, + PGPFileSpecRef fileRef ); +PGPOptionListRef PGPOInputBuffer( PGPContextRef context, + void const *buffer, PGPSize bufferSize ); +#if PGP_MACINTOSH || PGP_OSX +PGPOptionListRef PGPOInputFileFSSpec( PGPContextRef context, + const struct FSSpec *fileSpec ); +#endif + +/* Data output (optional, generates event if missing): */ + +PGPOptionListRef PGPOOutputFile( PGPContextRef context, + PGPFileSpecRef fileRef ); +PGPOptionListRef PGPOOutputBuffer( PGPContextRef context, + void *buffer, PGPSize bufferSize, + PGPSize *outputDataLength ); +PGPOptionListRef PGPOOutputDirectory( PGPContextRef context, + PGPFileSpecRef fileRef ); +#if PGP_MACINTOSH || PGP_OSX +PGPOptionListRef PGPOOutputFileFSSpec( PGPContextRef context, + const struct FSSpec *fileSpec ); +#endif + +/* Filepath modifiers (used for Archiving )*/ + +PGPOptionListRef PGPORelativePath( PGPContextRef context, + PGPFileSpecRef dirRef ); + +PGPOptionListRef PGPORootPath( PGPContextRef context, + PGPFileSpecRef dirRef ); + +/* '*buffer' must be disposed of via PGPFreeData() */ +/* maximum memory usage will be no more than maximumBufferSize */ +PGPOptionListRef PGPOAllocatedOutputBuffer(PGPContextRef context, + void **buffer, PGPSize maximumBufferSize, + PGPSize *actualBufferSize); +PGPOptionListRef PGPOAppendOutput( PGPContextRef context, + PGPBoolean appendOutput ); +PGPOptionListRef PGPODiscardOutput( PGPContextRef context, + PGPBoolean discardOutput ); +PGPOptionListRef PGPOAllocatedOutputKeyContainer(PGPContextRef context, + void **keyContName, PGPSize maximumKeyContNameSize, + PGPSize *actualKeyContNameSize ); + +/* Encrypting and signing */ + +PGPOptionListRef PGPOEncryptToKeyDBObj( PGPContextRef context, + PGPKeyDBObjRef keyDBObjRef); +PGPOptionListRef PGPOEncryptToKeySet( PGPContextRef context, + PGPKeySetRef keySetRef); +PGPOptionListRef PGPOIntegrityProtection( PGPContextRef context, + PGPBoolean integrity); +PGPOptionListRef PGPOSignWithKey( PGPContextRef context, + PGPKeyDBObjRef keyDBObjRef, + PGPOptionListRef firstOption, ...); +PGPOptionListRef PGPOConventionalEncrypt( PGPContextRef context, + PGPOptionListRef firstOption, + ...); +#undef PGPOPassphraseBuffer +PGPOptionListRef PGPOPassphraseBuffer( PGPContextRef context, + const PGPChar8 *passphrase, + PGPSize passphraseLength); +#undef PGPOPassphrase +PGPOptionListRef PGPOPassphrase( PGPContextRef context, + const PGPChar8 *passphrase); +PGPOptionListRef PGPOPasskeyBuffer( PGPContextRef context, + const void *passkey, PGPSize passkeyLength); + +PGPOptionListRef PGPOCachePassphrase( PGPContextRef context, + PGPUInt32 timeOutSeconds, PGPBoolean globalCache); +PGPOptionListRef PGPOSessionKey( PGPContextRef context, + const void *sessionKey, PGPSize sessionKeyLength); +PGPOptionListRef PGPOSignedHash( PGPContextRef context, + void const *hash, PGPSize hashSize ); +PGPOptionListRef PGPOAllowBareESKs( PGPContextRef context, + PGPBoolean allowBareESKs ); +PGPOptionListRef PGPOAskUserForEntropy( PGPContextRef context, + PGPBoolean askUserForEntropy ); +PGPOptionListRef PGPORawPGPInput( PGPContextRef context, + PGPBoolean rawPGPInput ); +PGPOptionListRef PGPOCompression( PGPContextRef context, + PGPBoolean compression ); + +PGPOptionListRef PGPOLocalEncoding( PGPContextRef context, + PGPLocalEncodingFlags localEncode); +PGPOptionListRef PGPOOutputLineEndType(PGPContextRef context, + PGPLineEndType lineEnd); +#undef PGPOPGPMIMEEncoding +PGPOptionListRef PGPOPGPMIMEEncoding(PGPContextRef context, + PGPBoolean mimeEncoding, PGPSize *mimeBodyOffset, + PGPChar8 mimeSeparator[ kPGPMimeSeparatorSize ]); +PGPOptionListRef PGPOOmitMIMEVersion( PGPContextRef context, + PGPBoolean omitVersion); +PGPOptionListRef PGPOX509Encoding( PGPContextRef context, + PGPBoolean x509Encoding); + +PGPOptionListRef PGPODetachedSig( PGPContextRef context, + PGPOptionListRef firstOption, + ...); + +PGPOptionListRef PGPOCipherAlgorithm( PGPContextRef context, + PGPCipherAlgorithm algorithm); +PGPOptionListRef PGPOHashAlgorithm( PGPContextRef context, + PGPHashAlgorithm algorithm); +PGPOptionListRef PGPOCompressionAlgorithm( PGPContextRef context, + PGPCompressionAlgorithm algorithm); + +PGPOptionListRef PGPOFailBelowValidity( PGPContextRef context, + PGPValidity minValidity); +PGPOptionListRef PGPOWarnBelowValidity( PGPContextRef context, + PGPValidity minValidity); + + +PGPOptionListRef PGPOEventHandler( PGPContextRef context, + PGPEventHandlerProcPtr eventHandler, + PGPUserValue eventHandlerData); +PGPOptionListRef PGPOSendNullEvents( PGPContextRef context, + PGPTimeInterval approxInterval); + +PGPOptionListRef PGPOArmorOutput( PGPContextRef context, + PGPBoolean armorOutput ); +PGPOptionListRef PGPODataIsASCII( PGPContextRef context, + PGPBoolean dataIsASCII ); +PGPOptionListRef PGPOClearSign( PGPContextRef context, + PGPBoolean clearSign ); +PGPOptionListRef PGPOForYourEyesOnly( PGPContextRef context, + PGPBoolean forYourEyesOnly ); +PGPOptionListRef PGPOKeyDBRef( PGPContextRef context, + PGPKeyDBRef keydbRef); + +PGPOptionListRef PGPOExportKeySet( PGPContextRef context, + PGPKeySetRef keysetRef); +PGPOptionListRef PGPOExportKeyDBObj( PGPContextRef context, + PGPKeyDBObjRef keyDBObjRef); + +PGPOptionListRef PGPOImportKeysTo( PGPContextRef context, + PGPKeyDBRef keydbRef); +PGPOptionListRef PGPOSendEventIfKeyFound( PGPContextRef context, + PGPBoolean sendEventIfKeyFound ); +PGPOptionListRef PGPOPassThroughIfUnrecognized( PGPContextRef context, + PGPBoolean passThroughIfUnrecognized ); +PGPOptionListRef PGPOPassThroughClearSigned( PGPContextRef context, + PGPBoolean passThroughClearSigned ); +PGPOptionListRef PGPOPassThroughKeys( PGPContextRef context, + PGPBoolean passThroughKeys ); +PGPOptionListRef PGPORecursivelyDecode( PGPContextRef context, + PGPBoolean recurse ); + +PGPOptionListRef PGPOKeyGenParams( PGPContextRef context, + PGPPublicKeyAlgorithm pubKeyAlg, + PGPUInt32 bits); + +#undef PGPOKeyGenName +PGPOptionListRef PGPOKeyGenName( PGPContextRef context, + const void *name, PGPSize nameLength); + +PGPOptionListRef PGPOCreationDate( PGPContextRef context, + PGPTime creationDate); +PGPOptionListRef PGPOExpiration( PGPContextRef context, + PGPUInt32 expirationDays); + +PGPOptionListRef PGPOAdditionalRecipientRequestKeySet( + PGPContextRef context, + PGPKeySetRef arKeySetRef, PGPByte arkClass); + +PGPOptionListRef PGPORevocationKeySet(PGPContextRef context, + PGPKeySetRef raKeySetRef); + +PGPOptionListRef PGPOKeyGenMasterKey( PGPContextRef context, + PGPKeyDBObjRef masterKeyDBObjRef); + +PGPOptionListRef PGPOPreferredAlgorithms( + PGPContextRef context, + PGPCipherAlgorithm const *prefAlg, + PGPUInt32 numAlgs); + +#undef PGPOPreferredKeyServer +PGPOptionListRef PGPOPreferredKeyServer( + PGPContextRef context, + PGPChar8 const * server ); + +PGPOptionListRef PGPOKeyFeatures( PGPContextRef context, + PGPUInt32 features); + +PGPOptionListRef PGPOKeyFlags( PGPContextRef context, + PGPUInt32 flags); + +PGPOptionListRef PGPOKeyServerPreferences( PGPContextRef context, + PGPUInt32 preferences); + +PGPOptionListRef PGPOKeyGenFast( PGPContextRef context, + PGPBoolean fastGen); + +PGPOptionListRef PGPOTokenNumber( PGPContextRef context, + PGPUInt32 tokenID); +#define PGPOKeyGenOnToken PGPOTokenNumber + +PGPOptionListRef PGPOOutputToken( PGPContextRef context, PGPUInt32 token ); + +PGPOptionListRef PGPOKeyContainer( PGPContextRef context, + const PGPByte *keyContainerName, + PGPSize keyContainerNameSize ); + +PGPOptionListRef PGPOKeyGenUseExistingEntropy( PGPContextRef context, + PGPBoolean useExistingEntropy); + +PGPOptionListRef PGPOPreferredCompressionAlgorithms( + PGPContextRef context, + PGPCompressionAlgorithm const *prefAlg, + PGPUInt32 numAlgs); + +#undef PGPOCommentString +PGPOptionListRef PGPOCommentString( PGPContextRef context, + PGPChar8 const *comment); + +#undef PGPOVersionString +PGPOptionListRef PGPOVersionString( PGPContextRef context, + PGPChar8 const *version); + +#undef PGPOFileNameString +PGPOptionListRef PGPOFileNameString( PGPContextRef context, + PGPChar8 const *fileName); + +#undef PGPOSigRegularExpression +PGPOptionListRef PGPOSigRegularExpression(PGPContextRef context, + PGPChar8 const *regularExpression); + +PGPOptionListRef PGPOExportPrivateKeys( PGPContextRef context, + PGPBoolean exportKeys); + +PGPOptionListRef PGPOExportPrivateSubkeys( PGPContextRef context, + PGPBoolean exportSubkeys); + +PGPOptionListRef PGPOExportFormat(PGPContextRef context, + PGPExportFormat exportFormat); + +PGPOptionListRef PGPOExportable( PGPContextRef context, + PGPBoolean exportable); + +PGPOptionListRef PGPOSigTrust( PGPContextRef context, + PGPUInt32 trustLevel, + PGPUInt32 trustValue); + +PGPOptionListRef PGPOInputFormat( PGPContextRef context, + PGPInputFormat inputFormat ); + +PGPOptionListRef PGPOOutputFormat( PGPContextRef context, + PGPOutputFormat outputFormat ); + +PGPOptionListRef PGPOAttributeValue( PGPContextRef context, + PGPAttributeValue *attributeValue, + PGPUInt32 attributeValueCount); + +PGPOptionListRef PGPOInputTARCache( PGPContextRef context, + PGPFileSpecRef cacheFileRef, + const PGPByte *sessionKey, + PGPSize sessionKeySize ); + +PGPOptionListRef PGPOOutputTARCache( PGPContextRef context, + PGPFileSpecRef cacheFileRef ); + +PGPOptionListRef PGPOIssueRevocations( PGPContextRef context, + PGPBoolean issueRevocations ); + +PGPOptionListRef PGPOSMIMEMatchCriterion( PGPContextRef context, + PGPSMIMEMatchCriterion criterion ); + +PGPOptionListRef PGPOSMIMESigner( PGPContextRef context, + PGPKeyDBObjRef signer ); + + +PGP_END_C_DECLARATIONS + +#endif /* ] Included_pgpOptionList_h */ + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk8/include/pgpPFLConfig.h b/CryptoPP/PGPw/sdk8/include/pgpPFLConfig.h new file mode 100644 index 0000000..8474d66 --- /dev/null +++ b/CryptoPP/PGPw/sdk8/include/pgpPFLConfig.h @@ -0,0 +1,52 @@ +/*____________________________________________________________________________ + pgpPFLConfig.h (Win32 version) + + Copyright (C) 2002 PGP Corporation + All rights reserved. + + This file contains the Win32 version of the configuration file + normally generated by the automatic configure script on Unix. + + $Id: pgpPFLConfig.h,v 1.3 2002/08/06 20:10:45 dallen Exp $ +____________________________________________________________________________*/ +#ifndef Included_pgpPFLConfig_h /* [ */ +#define Included_pgpPFLConfig_h + +#define HAVE_STDARG_H 1 +#define HAVE_STDLIB_H 1 +#define HAVE_SYS_STAT_H 1 +#define HAVE_UNISTD_H 0 +#define HAVE_USHORT 0 +#define HAVE_UINT 0 +#define HAVE_ULONG 0 +#define NO_LIMITS_H 0 +#define NO_POPEN 1 + +#if defined( __MWERKS__ ) + + #define PGP_HAVE64 0 + + +#elif defined( _MSC_VER ) + // wjb-for FileOffsets to be 64 bit + #define PGP_HAVE64 1 + typedef __int64 PGPInt64; + typedef unsigned __int64 PGPUInt64; + + + +#endif + + + + +#endif /* ] Included_pgpPFLConfig_h */ + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk8/include/pgpPFLErrors.h b/CryptoPP/PGPw/sdk8/include/pgpPFLErrors.h new file mode 100644 index 0000000..f0264ca --- /dev/null +++ b/CryptoPP/PGPw/sdk8/include/pgpPFLErrors.h @@ -0,0 +1,116 @@ +/*____________________________________________________________________________ + Copyright (C) 2002 PGP Corporation + All rights reserved. + + $Id: pgpPFLErrors.h,v 1.20 2004/04/25 03:31:03 bzhao Exp $ +____________________________________________________________________________*/ + +#ifndef Included_pgpPFLErrors_h /* [ */ +#define Included_pgpPFLErrors_h + +#include "pgpBase.h" + +#define kPGPPFLErrorBase -12000 +#define kPGPPFLErrorRange 500 + +enum +{ + /* + NOTE: error numbers must not be changed as compile clients depend on them. + */ + + kPGPError_NoErr = 0, + + kPGPError_BadParams = -12000, + kPGPError_OutOfMemory = -11999, + kPGPError_BufferTooSmall = -11998, + + kPGPError_FileNotFound = -11997, + kPGPError_CantOpenFile = -11996, + kPGPError_FilePermissions = -11995, + kPGPError_FileLocked = -11994, + /* Unused = -11993, */ + kPGPError_IllegalFileOp = -11992, + kPGPError_FileOpFailed = -11991, + kPGPError_ReadFailed = -11990, + kPGPError_WriteFailed = -11989, + kPGPError_EOF = -11988, + + kPGPError_UserAbort = -11987, + kPGPError_UnknownRequest = -11986, + kPGPError_LazyProgrammer = -11985, + kPGPError_ItemNotFound = -11984, + kPGPError_ItemAlreadyExists = -11983, + kPGPError_AssertFailed = -11982, + kPGPError_BadMemAddress = -11981, + kPGPError_UnknownError = -11980, + + kPGPError_PrefNotFound = -11979, + kPGPError_EndOfIteration = -11978, + kPGPError_ImproperInitialization = -11977, + kPGPError_CorruptData = -11976, + kPGPError_FeatureNotAvailable = -11975, + kPGPError_MatchNotFound = -11974, + kPGPError_ResourceUnavailable = -11973, + kPGPError_InsufficientPrivileges = -11972, + kPGPError_AlreadyInUse = -11971, + kPGPError_Deadlocked = -11970, + kPGPError_NotConnected = -11969, + kPGPError_BufferTooLarge = -11968, + kPGPError_SizeTooLarge = -11967, + + kPGPError_DiskFull = -11960, + kPGPError_DiskLocked = -11959, + + kPGPError_GraphicsOpFailed = -11956, + kPGPError_MemoryOpFailed = -11955, + kPGPError_NetworkOpFailed = -11954, + kPGPError_SecurityOpFailed = -11953, + kPGPError_StringOpFailed = -11952, + kPGPError_SyncObjOpFailed = -11951, + kPGPError_ThreadOpFailed = -11950, + kPGPError_VolumeOpFailed = -11949, + + kPGPError_NTDrvIopOpFailed = -11947, + kPGPError_NTDrvObjectOpFailed = -11946, + + kPGPError_Win32COMOpFailed = -11945, + kPGPError_Win32CommCtrlOpFailed = -11944, + kPGPError_Win32DllOpFailed = -11943, + kPGPError_Win32RegistryOpFailed = -11942, + kPGPError_Win32ResourceOpFailed = -11941, + kPGPError_Win32WindowOpFailed = -11940, + kPGPError_RPCFailed = -11939, + kPGPError_RPCGarbledMsg = -11938, + kPGPError_NoUnicodeEquivalent = -11937, + + kPGPError_NetLARefused = -11936, + kPGPError_NetLAMismatch = -11935, + kPGPError_NetLATooManyRetrievals = -11934, + kPGPError_LNCorrupt = -11933, + kPGPError_LACorrupt = -11932, + kPGPError_LNInvalid = -11931, + kPGPError_NetInvalidProdID = -11930, + // PGPwde error code + kPGPError_DiskNotFound = -11929, + kPGPError_LastPFLError = kPGPPFLErrorBase + kPGPPFLErrorRange - 1 +}; + +#define IsPGPError( err ) ( (err) != kPGPError_NoErr ) +#define IsntPGPError( err ) ( (err) == kPGPError_NoErr ) + +PGP_BEGIN_C_DECLARATIONS + +PGP_END_C_DECLARATIONS + +#endif /* ] Included_pgpPFLErrors_h */ + + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk8/include/pgpPubTypes.h b/CryptoPP/PGPw/sdk8/include/pgpPubTypes.h new file mode 100644 index 0000000..6082d4b --- /dev/null +++ b/CryptoPP/PGPw/sdk8/include/pgpPubTypes.h @@ -0,0 +1,350 @@ +/*____________________________________________________________________________ + Copyright (C) 2002 PGP Corporation + All rights reserved. + + $Id: pgpPubTypes.h,v 1.22 2004/04/13 20:50:53 ajivsov Exp $ +____________________________________________________________________________*/ + +#ifndef Included_pgpPubTypes_h /* [ */ +#define Included_pgpPubTypes_h + +#include "pgpConfig.h" +#include "pgpBase.h" + +/*____________________________________________________________________________ + General data types used by PGPsdk +____________________________________________________________________________*/ + +typedef struct PGPContext * PGPContextRef; +typedef struct PGPFileSpec * PGPFileSpecRef; +typedef struct PGPOptionList * PGPOptionListRef; + +/*____________________________________________________________________________ + Data types used by the key manipulation functions +____________________________________________________________________________*/ + +typedef struct PGPKeyDB * PGPKeyDBRef; +typedef struct PGPKeyDBObj * PGPKeyDBObjRef; +typedef struct PGPKeySet * PGPKeySetRef; +typedef struct PGPKeyList * PGPKeyListRef; +typedef struct PGPKeyIter * PGPKeyIterRef; +typedef struct PGPFilter * PGPFilterRef; + +typedef struct PGPKeyID +{ + /* do not attempt to interpret these bytes; they *will* change */ + PGPByte opaqueBytes[ 36 ]; +} PGPKeyID; + +/*____________________________________________________________________________ + Data types used by symmetric ciphers, cipher modes, hashing +____________________________________________________________________________*/ + +typedef struct PGPHashContext * PGPHashContextRef; +typedef struct PGPHMACContext * PGPHMACContextRef; +typedef struct PGPPublicKeyContext * PGPPublicKeyContextRef; +typedef struct PGPPrivateKeyContext * PGPPrivateKeyContextRef; +typedef struct PGPCBCContext * PGPCBCContextRef; +typedef struct PGPCFBContext * PGPCFBContextRef; +typedef struct PGPSymmetricCipherContext * PGPSymmetricCipherContextRef; + +/*____________________________________________________________________________ +Disk Wiping Patterns +____________________________________________________________________________*/ + +typedef struct PGPWipePatternContext * PGPWipePatternContextRef; + +/*____________________________________________________________________________ +PGP Tar Cache, Objects and Iterators +____________________________________________________________________________*/ +typedef struct PGPTARCache * PGPTARCacheRef; +typedef struct PGPTARCacheIter * PGPTARCacheIterRef; +typedef struct PGPTARCacheObj * PGPTARCacheObjRef; + +/*____________________________________________________________________________ + Data types used by keyserver code +____________________________________________________________________________*/ + +typedef struct PGPKeyServer * PGPKeyServerRef; + +/*____________________________________________________________________________ + Invalid values for each of the "ref" data types. Use these for assignment + and initialization only. Use the PGPXXXRefIsValid macros (below) to test + for valid/invalid values. +____________________________________________________________________________*/ + +#define kInvalidPGPContextRef ((PGPContextRef) NULL) +#define kInvalidPGPFileSpecRef ((PGPFileSpecRef) NULL) +#define kInvalidPGPOptionListRef ((PGPOptionListRef) NULL) +#define kInvalidPGPKeyDBRef ((PGPKeyDBRef) NULL) +#define kInvalidPGPKeyDBObjRef ((PGPKeyDBObjRef) NULL) +#define kInvalidPGPKeySetRef ((PGPKeySetRef) NULL) +#define kInvalidPGPKeyListRef ((PGPKeyListRef) NULL) +#define kInvalidPGPKeyIterRef ((PGPKeyIterRef) NULL) +#define kInvalidPGPFilterRef ((PGPFilterRef) NULL) +#define kInvalidPGPKeyServerRef ((PGPKeyServerRef) NULL) +#define kInvalidPGPHashContextRef ((PGPHashContextRef) NULL) +#define kInvalidPGPHMACContextRef ((PGPHMACContextRef) NULL) +#define kInvalidPGPCFBContextRef ((PGPCFBContextRef) NULL) +#define kInvalidPGPCBCContextRef ((PGPCBCContextRef) NULL) + +#define kInvalidPGPSymmetricCipherContextRef \ + ((PGPSymmetricCipherContextRef) NULL) +#define kInvalidPGPPublicKeyContextRef \ + ((PGPPublicKeyContextRef) NULL) +#define kInvalidPGPPrivateKeyContextRef \ + ((PGPPrivateKeyContextRef) NULL) +#define kInvalidPGWipePatternContextRef \ + ((PGPWipePatternContextRef) NULL) +#define kInvalidPGPTARCacheRef \ + ((PGPTARCacheRef) NULL) +#define kInvalidPGPTARCacheIterRef \ + ((PGPTARCacheIterRef) NULL) +#define kInvalidPGPTARCacheObjRef \ + ((PGPTARCacheObjRef) NULL) + + +/*____________________________________________________________________________ + Macros to test for ref validity. Use these in preference to comparing + directly with the kInvalidXXXRef values. +____________________________________________________________________________*/ + +#define PGPContextRefIsValid( ref ) ( (ref) != kInvalidPGPContextRef ) +#define PGPFileSpecRefIsValid( ref ) ( (ref) != kInvalidPGPFileSpecRef ) +#define PGPOptionListRefIsValid( ref ) ( (ref) != kInvalidPGPOptionListRef ) +#define PGPKeyDBRefIsValid( ref ) ( (ref) != kInvalidPGPKeyDBRef ) +#define PGPKeyDBObjRefIsValid( ref ) ( (ref) != kInvalidPGPKeyDBObjRef ) +#define PGPKeySetRefIsValid( ref ) ( (ref) != kInvalidPGPKeySetRef ) +#define PGPKeyListRefIsValid( ref ) ( (ref) != kInvalidPGPKeyListRef ) +#define PGPKeyIterRefIsValid( ref ) ( (ref) != kInvalidPGPKeyIterRef ) +#define PGPFilterRefIsValid( ref ) ( (ref) != kInvalidPGPFilterRef ) +#define PGPKeyServerRefIsValid( ref ) ( (ref) != kInvalidPGPKeyServerRef ) +#define PGPHashContextRefIsValid( ref ) ( (ref) != kInvalidPGPHashContextRef ) +#define PGPHMACContextRefIsValid( ref ) ( (ref) != kInvalidPGPHMACContextRef ) +#define PGPCFBContextRefIsValid( ref ) ( (ref) != kInvalidPGPCFBContextRef ) +#define PGPCBCContextRefIsValid( ref ) ( (ref) != kInvalidPGPCBCContextRef ) + +#define PGPSymmetricCipherContextRefIsValid( ref ) \ + ( (ref) != kInvalidPGPSymmetricCipherContextRef ) +#define PGPPublicKeyContextRefIsValid( ref ) \ + ( (ref) != kInvalidPGPPublicKeyContextRef ) +#define PGPPrivateKeyContextRefIsValid( ref ) \ + ( (ref) != kInvalidPGPPrivateKeyContextRef ) +#define PGPWipePatternContextRefIsValid( ref ) \ + ( (ref) != kInvalidPGWipePatternContextRef ) + #define PGPTARCacheRefIsValid( ref ) \ + ( (ref) != kInvalidPGPTARCacheRef ) +#define PGPTARCacheObjRefIsValid( ref ) \ + ( (ref) != kInvalidPGPTARCacheObjRef ) +#define PGPTARCacheIterRefIsValid( ref) \ + ( (ref) != kInvalidPGPTARCacheIterRef ) + +/*____________________________________________________________________________ + Symmetric Ciphers +____________________________________________________________________________*/ + +enum PGPCipherAlgorithm_ +{ + kPGPCipherAlgorithm_None = 0, + kPGPCipherAlgorithm_IDEA = 1, + kPGPCipherAlgorithm_3DES = 2, + kPGPCipherAlgorithm_CAST5 = 3, + kPGPCipherAlgorithm_Blowfish = 4, + kPGPCipherAlgorithm_AES128 = 7, + kPGPCipherAlgorithm_AES192 = 8, + kPGPCipherAlgorithm_AES256 = 9, + kPGPCipherAlgorithm_Twofish256 = 10, + + PGP_ENUM_FORCE( PGPCipherAlgorithm_ ) +}; +PGPENUM_TYPEDEF( PGPCipherAlgorithm_, PGPCipherAlgorithm ); + +/*____________________________________________________________________________ + Hash algorithms +____________________________________________________________________________*/ + +enum PGPHashAlgorithm_ +{ + kPGPHashAlgorithm_Invalid = 0, + kPGPHashAlgorithm_MD5 = 1, + kPGPHashAlgorithm_SHA = 2, + kPGPHashAlgorithm_RIPEMD160 = 3, + kPGPHashAlgorithm_SHA256 = 8, /* from draft-ietf-openpgp-rfc2440bis-03.txt */ + kPGPHashAlgorithm_SHA384 = 9, + kPGPHashAlgorithm_SHA512 = 10, + + PGP_ENUM_FORCE( PGPHashAlgorithm_ ) +}; +PGPENUM_TYPEDEF( PGPHashAlgorithm_, PGPHashAlgorithm ); + +/*____________________________________________________________________________ + Public/Private key algorithms +____________________________________________________________________________*/ +enum PGPPublicKeyAlgorithm_ +{ +#ifdef __MVS__ + kPGPPublicKeyAlgorithm_Invalid = -1, +#else + kPGPPublicKeyAlgorithm_Invalid = 0xFFFFFFFF, +#endif + kPGPPublicKeyAlgorithm_RSA = 1, + kPGPPublicKeyAlgorithm_RSAEncryptOnly = 2, + kPGPPublicKeyAlgorithm_RSASignOnly = 3, + kPGPPublicKeyAlgorithm_ElGamal = 0x10, /* A.K.A.Diffie-Hellman */ + kPGPPublicKeyAlgorithm_DSA = 0x11, + kPGPPublicKeyAlgorithm_ECEncrypt = 0x12, + kPGPPublicKeyAlgorithm_ECSign = 0x13, + + PGP_ENUM_FORCE( PGPPublicKeyAlgorithm_ ) +}; +PGPENUM_TYPEDEF( PGPPublicKeyAlgorithm_, PGPPublicKeyAlgorithm ); + +/*____________________________________________________________________________ + Trust values, used to set validity values +____________________________________________________________________________*/ + +#define kPGPKeyTrust_Mask 0x7u +#define kPGPKeyTrust_Undefined 0x0u +#define kPGPKeyTrust_Unknown 0x1u +#define kPGPKeyTrust_Never 0x2u +#define kPGPKeyTrust_Marginal 0x5u +#define kPGPKeyTrust_Complete 0x6u +#define kPGPKeyTrust_Ultimate 0x7u + +#define kPGPUserIDTrust_Mask 0x3u +#define kPGPUserIDTrust_Unknown 0x0u +#define kPGPUserIDTrust_Untrusted 0x1u +#define kPGPUserIDTrust_Marginal 0x2u +#define kPGPUserIDTrust_Complete 0x3u + +/*____________________________________________________________________________ + Validity levels, used for thresholds in options +____________________________________________________________________________*/ + +enum PGPValidity_ +{ + kPGPValidity_Unknown = kPGPUserIDTrust_Unknown, + kPGPValidity_Invalid = kPGPUserIDTrust_Untrusted, + kPGPValidity_Marginal = kPGPUserIDTrust_Marginal, + kPGPValidity_Complete = kPGPUserIDTrust_Complete, + + PGP_ENUM_FORCE( PGPValidity_ ) +} ; +PGPENUM_TYPEDEF( PGPValidity_, PGPValidity ); + +/*____________________________________________________________________________ + Line endings types +____________________________________________________________________________*/ + +enum PGPLineEndType_ +{ + kPGPLineEnd_Default = 0, + kPGPLineEnd_LF = 1, + kPGPLineEnd_CR = 2, + kPGPLineEnd_CRLF = (kPGPLineEnd_LF | kPGPLineEnd_CR), + + PGP_ENUM_FORCE( PGPLineEndType_ ) +}; +PGPENUM_TYPEDEF( PGPLineEndType_, PGPLineEndType ); + +/*____________________________________________________________________________ + Local encoding types + + Only one of Force or Auto should be used. The other values are modifiers +____________________________________________________________________________*/ + +#define kPGPLocalEncoding_None 0x0 /* nothing on */ +#define kPGPLocalEncoding_Force 0x01 +#define kPGPLocalEncoding_Auto 0x02 +#define kPGPLocalEncoding_NoMacBinCRCOkay 0x04 + +typedef PGPFlags PGPLocalEncodingFlags; + + +/* max length is 255; the +1 is for the trailing \0 */ +#define kPGPMaxUserIDSize ( (PGPSize)255 + 1 ) + +/* Size of buffer for PGP-MIME separator (null terminated) */ +#define kPGPMimeSeparatorSize 81 + +enum PGPTokenProperty_ +{ + kPGPTokenProperty_Invalid = 0, + + /* boolean properties */ + kPGPTokenProperty_DirectAuth = 1, + + /* numeric properties */ + kPGPTokenProperty_KeyGenAlgorithm = 100, + kPGPTokenProperty_PrivateKeys = 101, + kPGPTokenProperty_PublicKeys = 102, + kPGPTokenProperty_SlotID = 103, + kPGPTokenProperty_MinPINSize = 104, + kPGPTokenProperty_MaxPINSize = 105, + kPGPTokenProperty_MinKeySize = 106, + kPGPTokenProperty_MaxKeySize = 107, + + /* string / data properties */ + kPGPTokenProperty_SerialNumber = 500, + kPGPTokenProperty_Model = 501, + kPGPTokenProperty_ManufacturerID = 502, + kPGPTokenProperty_TokenLabel = 503, + + PGP_ENUM_FORCE( PGPTokenProperty_ ) +}; +PGPENUM_TYPEDEF( PGPTokenProperty_, PGPTokenProperty ); + +/* Token capabilities / information. 4 byte packing. + * Deprecated, use PGPTokenInfoGet*() with PGPTokenProperty + * + */ +typedef struct _PGPTokenInfo { + /* The size of the structure, including this field. + Must be the first field */ + PGPUInt32 size; + + /* Identification information */ + PGPByte manufacturerID[32]; + PGPByte model[16]; + PGPByte serialNumber[16]; + + PGPBoolean bRsa; + PGPUInt32 minRsaKeySize; + PGPUInt32 maxRsaKeySize; + + /* General capabilities */ + PGPUInt32 minPinLen; + PGPUInt32 maxPinLen; + + /* Number of objects */ + PGPUInt32 numPrivKeys; /* Possibly, non-PGP keys */ + PGPUInt32 numPubKeys; /* Possibly, non-PGP keys */ + + PGPByte reserved[4]; +} PGPTokenInfo; + +/*____________________________________________________________________________ + Compression algorithms +____________________________________________________________________________*/ + +enum PGPCompressionAlgorithm_ +{ + kPGPCompressionAlgorithm_None = 0, + kPGPCompressionAlgorithm_ZIP = 1, + kPGPCompressionAlgorithm_ZLIB = 2, + kPGPCompressionAlgorithm_BZIP2 = 3, + + PGP_ENUM_FORCE( PGPCompressionAlgorithm_ ) +}; +PGPENUM_TYPEDEF( PGPCompressionAlgorithm_, PGPCompressionAlgorithm ); + +#endif /* ] Included_pgpPubTypes_h */ + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk8/include/pgpPublicKey.h b/CryptoPP/PGPw/sdk8/include/pgpPublicKey.h new file mode 100644 index 0000000..8ed1adc --- /dev/null +++ b/CryptoPP/PGPw/sdk8/include/pgpPublicKey.h @@ -0,0 +1,207 @@ +/*____________________________________________________________________________ + Copyright (C) 2002 PGP Corporation + All rights reserved. + + $Id: pgpPublicKey.h,v 1.9 2003/10/03 00:38:40 vinnie Exp $ +____________________________________________________________________________*/ + +#ifndef Included_pgpPublicKey_h /* [ */ +#define Included_pgpPublicKey_h + +#include "pgpPubTypes.h" +#include "pgpOptionList.h" + +/*____________________________________________________________________________ + Encryption/Signature Message Formats +____________________________________________________________________________*/ + +enum PGPPublicKeyMessageFormat_ +{ + kPGPPublicKeyMessageFormat_PGP = 1, + kPGPPublicKeyMessageFormat_PKCS1 = 2, + kPGPPublicKeyMessageFormat_X509 = 3, + kPGPPublicKeyMessageFormat_IKE = 4, + + kPGPPublicKeyMessageFormat_PKCS1_OAEP = 5, /* default is MGF1 with SHA1 */ + + PGP_ENUM_FORCE( PGPPublicKeyMessageFormat_ ) +}; +PGPENUM_TYPEDEF( PGPPublicKeyMessageFormat_, PGPPublicKeyMessageFormat ); + +PGP_BEGIN_C_DECLARATIONS + +/*____________________________________________________________________________ + Public-key operations + + Return a context for public-key operations based on the specified key. + The specified message format is used for all operations with this + context. +____________________________________________________________________________*/ + +PGPError PGPNewPublicKeyContext( PGPKeyDBObjRef publicKeyDBObjRef, + PGPPublicKeyMessageFormat messageFormat, + PGPPublicKeyContextRef *outRef ); + +/*____________________________________________________________________________ + Dispose of a public-key context. +____________________________________________________________________________*/ + +PGPError PGPFreePublicKeyContext( PGPPublicKeyContextRef ref ); + +/*____________________________________________________________________________ + Determine maximum sizes for inputs and outputs. +____________________________________________________________________________*/ + +PGPError PGPGetPublicKeyOperationSizes( PGPPublicKeyContextRef ref, + PGPSize *maxDecryptedBufferSize, + PGPSize *maxEncryptedBufferSize, + PGPSize *maxSignatureSize ); + +/*____________________________________________________________________________ + Encrypt one block of data, using PKCS-1 padding. Output buffer must + be of size maxEncryptedBufferSize from PGPGetPublicKeyEncryptionSize. + outSize is a return parameter. For some formatting modes the actual + output size may be less than the maximum possible. +____________________________________________________________________________*/ + +PGPError PGPPublicKeyEncrypt( PGPPublicKeyContextRef ref, + void const *in, PGPSize inSize, void *out, + PGPSize *outSize ); + +/*____________________________________________________________________________ + Verify a signature on a message hash. Returns kPGPError_NoErr on + correct verification, else an error code. The message hash is + finalized and freed by this call (and should not have been finalized + prior to the call). +____________________________________________________________________________*/ + +PGPError PGPPublicKeyVerifySignature( PGPPublicKeyContextRef ref, + PGPHashContextRef hashContext, void const *signature, + PGPSize signatureSize ); + +/*____________________________________________________________________________ + Verify a signature on a low-level buffer. Returns kPGPError_NOErr + correct verification, else an error code. Not valid with + kPGPPublicKeyMessageFormat_PGP contexts. +____________________________________________________________________________*/ + +PGPError PGPPublicKeyVerifyRaw( PGPPublicKeyContextRef ref, + void const *signedData, PGPSize signedDataSize, + void const *signature, PGPSize signatureSize ); + +/*____________________________________________________________________________ + Private-key operations + + Return a context for private-key operations based on the specified + key (which must have a private part). The specified message + format is used for all operations with this context. Unlocks key + data using passphrase. +____________________________________________________________________________*/ + +PGPError PGPNewPrivateKeyContext( PGPKeyDBObjRef privateKeyDBObjRef, + PGPPublicKeyMessageFormat messageFormat, + PGPPrivateKeyContextRef *outRef, + PGPOptionListRef firstOption, ...); + +/*____________________________________________________________________________ + Dispose of a private-key context. All sensitive data is wiped before + being deleted. +____________________________________________________________________________*/ + +PGPError PGPFreePrivateKeyContext( PGPPrivateKeyContextRef ref ); + +/*____________________________________________________________________________ + Determine maximum sizes for inputs and outputs. +____________________________________________________________________________*/ + +PGPError PGPGetPrivateKeyOperationSizes( PGPPrivateKeyContextRef ref, + PGPSize *maxDecryptedBufferSize, + PGPSize *maxEncryptedBufferSize, + PGPSize *maxSignatureSize); + +/*____________________________________________________________________________ + Decrypt one block of data. Output buffer must be of size at least + maxDecryptedBufferSize from PGPGetPrivateKeyDecryptionSize. + outSize is a return parameter. For some formatting modes the actual + output size may be less than the maximum possible. +____________________________________________________________________________*/ + +PGPError PGPPrivateKeyDecrypt( PGPPrivateKeyContextRef ref, void const *in, + PGPSize inSize, void *out, PGPSize *outSize ); + +/*____________________________________________________________________________ + Sign a message hash. Output signature buffer must be of size at + least maxSignatureSize from PGPGetPrivateKeyDecryptionSize. + signatureSize is a return parameter. For some formatting modes + the actual signature size may be less than the maximum possible. + The message hash is finalized and freed by this call (and should + not have been finalized prior to the call). +____________________________________________________________________________*/ + +PGPError PGPPrivateKeySign( PGPPrivateKeyContextRef ref, + PGPHashContextRef hashContext, void *signature, + PGPSize *signatureSize ); + +/*____________________________________________________________________________ + Sign a low level signedData buffer. Output signature buffer must be + of size at least maxSignatureSize from PGPGetPrivateKeyDecryptionSize. + signatureSize is a return parameter. Not valid with + kPGPPublicKeyMessageFormat_PGP contexts. +____________________________________________________________________________*/ + +PGPError PGPPrivateKeySignRaw( PGPPrivateKeyContextRef ref, + void const *signedData, PGPSize signedDataSize, + void *signature, PGPSize *signatureSize ); + +/*____________________________________________________________________________ + Miscellaneous operations +____________________________________________________________________________*/ + +/*____________________________________________________________________________ + Given the size of a prime modulus in bits, this returns an appropriate + size for an exponent in bits, such that the work factor to find a + discrete log modulo the modulus is approximately equal to half the + length of the exponent. This makes the exponent an appropriate size + for a subgroup in a discrete log signature scheme. For encryption + schemes, where decryption attacks can be stealthy and undetected, we + use 3/2 times the returned exponent size. +____________________________________________________________________________*/ + +PGPError PGPDiscreteLogExponentBits( PGPUInt32 modulusBits, + PGPUInt32 *exponentBits ); + + +/*____________________________________________________________________________ + Low level Function used for verifying FIPS 186-2 DSA signatures + using P, Q, G, Y key values. +____________________________________________________________________________*/ + +PGPError PGPDSAKeyVerifyRaw( + PGPContextRef context, + PGPByte const* P, + PGPSize PLen, + PGPByte const* Q, + PGPSize QLen, + PGPByte const* G, + PGPSize GLen, + PGPByte const* Y, + PGPSize YLen, + PGPByte const* sig, + PGPSize sigLen, + PGPByte const * hash, + PGPSize hashLen); + + +PGP_END_C_DECLARATIONS + +#endif /* ] Included_pgpPublicKey_h */ + + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk8/include/pgpRandomPool.h b/CryptoPP/PGPw/sdk8/include/pgpRandomPool.h new file mode 100644 index 0000000..b965b49 --- /dev/null +++ b/CryptoPP/PGPw/sdk8/include/pgpRandomPool.h @@ -0,0 +1,46 @@ +/*____________________________________________________________________________ + Copyright (C) 2002 PGP Corporation + All rights reserved. + + $Id: pgpRandomPool.h,v 1.7 2002/08/06 20:11:16 dallen Exp $ +____________________________________________________________________________*/ + +#ifndef Included_pgpRandomPool_h /* [ */ +#define Included_pgpRandomPool_h + +#include "pgpBase.h" +#include "pflTypes.h" + +PGP_BEGIN_C_DECLARATIONS + +PGPError PGPSetRandSeedFile( PFLFileSpecRef randSeedFile ); + +PGPUInt32 PGPGlobalRandomPoolAddKeystroke( PGPInt32 event); +PGPUInt32 PGPGlobalRandomPoolMouseMoved(void); +PGPError PGPGlobalRandomPoolAddSystemState(void); +PGPBoolean PGPGlobalRandomPoolHasIntelRNG(void); + +/* Extra functions for entropy estimation */ +PGPUInt32 PGPGlobalRandomPoolGetEntropy( void ); +PGPUInt32 PGPGlobalRandomPoolGetSize( void ); +PGPUInt32 PGPGlobalRandomPoolGetMinimumEntropy( void ); +PGPBoolean PGPGlobalRandomPoolHasMinimumEntropy( void ); + + +#if PGP_DEPRECATED +PGPUInt32 PGPGlobalRandomPoolAddMouse( PGPUInt32 x, PGPUInt32 y); +#endif + +PGP_END_C_DECLARATIONS + +#endif /* ] Included_pgpRandomPool_h */ + + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk8/include/pgpReconstruct.h b/CryptoPP/PGPw/sdk8/include/pgpReconstruct.h new file mode 100644 index 0000000..756a196 --- /dev/null +++ b/CryptoPP/PGPw/sdk8/include/pgpReconstruct.h @@ -0,0 +1,117 @@ +/*____________________________________________________________________________ + Copyright (C) 2002 PGP Corporation + All rights reserved. + + $Id: pgpReconstruct.h,v 1.1 2003/12/29 08:12:20 wprice Exp $ +____________________________________________________________________________*/ +#ifndef Included_pgpReconstruct_h /* [ */ +#define Included_pgpReconstruct_h + +#include "pgpPubTypes.h" +#include "pgpKeyServer.h" + +#define kPGPRecon_NumShares 5 +#define kPGPRecon_Threshold 3 +#define kPGPRecon_MaxPromptLen ( 96 - 1 ) +#define kPGPRecon_MaxURLLen ( 256 - 1 ) +#define kPGPRecon_MaxPassLen ( 256 - 1 ) +#define kPGPRecon_MaxUserNameLen ( 128 - 1 ) +#define kPGPRecon_MaxPasswordLen ( 128 - 1 ) + + +typedef struct PGPReconContext * PGPReconContextRef; + +#define kInvalidPGPReconContextRef ((PGPReconContextRef) NULL) +#define PGPReconContextRefIsValid( ref ) ( (ref) != kInvalidPGPReconContextRef ) + +typedef char PGPReconPrompts[kPGPRecon_NumShares][kPGPRecon_MaxPromptLen + 1]; + +typedef char PGPReconPasses[kPGPRecon_NumShares][kPGPRecon_MaxPassLen + 1]; + +typedef PGPError (*PGPReconstructEventHandler)(PGPContextRef recon, + PGPEvent *event, PGPUserValue userValue); + +/* inAuthUser and inAuthPass are not needed if the server class + is kPGPKeyServerClass_PGP. */ + PGPError +PGPNewReconstruct( + PGPKeyDBObjRef inTargetKey, + PGPUTF8 *inAuthUser, /* can be NULL */ + PGPUTF8 *inAuthPass, /* can be NULL */ + PGPReconstructEventHandler inHandler, + PGPUserValue inUserValue, + PGPReconContextRef *outRef ); + +/* This is only needed if you have to change the event handler after + allocating the PGPReconContextRef */ + PGPError +PGPSetReconstructionEventHandler( + PGPReconContextRef reconRef, + PGPReconstructEventHandler inHandler, + PGPUserValue inUserValue ); + + +/* I don't think it makes sense to support split keys for reconstruction, + so we only take a passphrase below */ + PGPError +PGPMakeReconstruction( + PGPReconContextRef reconRef, + PGPReconPrompts inPromptInfo, + PGPReconPasses inPassInfo, + PGPUTF8 *inPassphrase ); + + PGPError +PGPGetReconstruction( + PGPReconContextRef reconRef, + PGPByte **reconData, /* must be freed by caller */ + PGPSize *reconDataSize ); + + PGPError +PGPSendReconstruction( + PGPReconContextRef reconRef ); + + PGPError +PGPGetReconstructionPrompts( + PGPReconContextRef reconRef, + PGPReconPrompts outPromptInfo ); + + PGPError +PGPGetReconstructionData( + PGPReconContextRef reconRef, + PGPReconPasses inPassInfo, + PGPByte **outReconData, /* must be freed by caller */ + PGPSize *outReconSize ); + +/* Reconstructed private key will be returned in + outReconstructedKey if successful. The imported + key will have no passphrase and thus the user must + then be forced to choose a new passphrase. */ + PGPError +PGPReconstruct( + PGPReconContextRef reconRef, + PGPReconPasses inPassInfo, + PGPByte *inReconData, + PGPSize inReconDataSize, + PGPKeyDBRef *outReconstructedKey ); + + PGPError +PGPFreeReconstruct( + PGPReconContextRef reconRef ); + + PGPError +PGPSetReconstructionServerURL( + PGPReconContextRef reconRef, + PGPUTF8 *pszServerURL, + PGPKeyServerClass dwServerType ); + +#endif /* ] Included_pgpReconstruct_h */ + + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk8/include/pgpSECSH.h b/CryptoPP/PGPw/sdk8/include/pgpSECSH.h new file mode 100644 index 0000000..4a964f4 --- /dev/null +++ b/CryptoPP/PGPw/sdk8/include/pgpSECSH.h @@ -0,0 +1,308 @@ +/*____________________________________________________________________________ + Copyright (C) 2002 PGP Corporation + All rights reserved. + + $Id: pgpSECSH.h,v 1.5 2002/08/06 20:11:16 dallen Exp $ +____________________________________________________________________________*/ +#ifndef Included_PGPsecsh_h /* [ */ +#define Included_PGPsecsh_h + +#include "pgpPubTypes.h" + +PGP_BEGIN_C_DECLARATIONS + + +/* Message Types */ +#define kPGPsecsh_Msg_None 0 +#define kPGPsecsh_Msg_Disconnect 1 +#define kPGPsecsh_SMsg_PublicKey 2 +#define kPGPsecsh_CMsg_SessionKey 3 +#define kPGPsecsh_CMsg_User 4 +#define kPGPsecsh_CMsg_AuthRHosts 5 +#define kPGPsecsh_CMsg_AuthRSA 6 +#define kPGPsecsh_SMsg_AuthRSAChallenge 7 +#define kPGPsecsh_CMsg_AuthRSAResponse 8 +#define kPGPsecsh_CMsg_AuthRSAPassword 9 +#define kPGPsecsh_CMsg_RequestPTY 10 +#define kPGPsecsh_CMsg_WindowSize 11 +#define kPGPsecsh_CMsg_ExecShell 12 +#define kPGPsecsh_CMsg_ExecCommand 13 +#define kPGPsecsh_SMsg_Success 14 +#define kPGPsecsh_SMsg_Failure 15 +#define kPGPsecsh_CMsg_StdinData 16 +#define kPGPsecsh_SMsg_StdoutData 17 +#define kPGPsecsh_SMsg_StderrData 18 +#define kPGPsecsh_CMsg_EOF 19 +#define kPGPsecsh_SMsg_ExitStatus 20 +#define kPGPsecsh_Msg_ChannelOpenConfirm 21 +#define kPGPsecsh_Msg_ChannelOpenFailure 22 +#define kPGPsecsh_Msg_ChannelData 23 +#define kPGPsecsh_Msg_ChannelClose 24 +#define kPGPsecsh_Msg_ChannelCloseConfirm 25 +#define kPGPsecsh_SMsg_X11Open 27 +#define kPGPsecsh_CMsg_PortForwardRequest 28 +#define kPGPsecsh_Msg_PortOpen 29 +#define kPGPsecsh_CMsg_AgentRequestForwarding 30 +#define kPGPsecsh_SMsg_AgentOpen 31 +#define kPGPsecsh_Msg_Ignore 32 +#define kPGPsecsh_CMsg_ExitConfirm 33 +#define kPGPsecsh_CMsg_X11RequestForwarding 34 +#define kPGPsecsh_CMsg_AuthRHostsRSA 35 +#define kPGPsecsh_SMsg_Debug 36 +#define kPGPsecsh_CMsg_RequestCompression 37 +#define kPGPsecsh_CMsg_MaxPacketSize 38 +#define kPGPsecsh_CMsg_AuthTIS 39 +#define kPGPsecsh_SMsg_AuthTISChallenge 40 +#define kPGPsecsh_CMsg_AuthTISResponse 41 +#define kPGPsecsh_CMsg_AuthKerberos 42 +#define kPGPsecsh_SMsg_AuthKerberosResponse 43 +#define kPGPsecsh_CMsg_HaveKerberosTgt 44 + + +typedef struct PGPsecshContext * PGPsecshContextRef; +typedef const struct PGPsecshContext * PGPsecshConstContextRef; + +#define kInvalidPGPsecshContextRef ((PGPsecshContextRef) NULL) +#define PGPsecshContextRefIsValid( ref ) ( (ref) != kInvalidPGPsecshContextRef ) + +typedef struct PGPsecshSession * PGPsecshSessionRef; +typedef const struct PGPsecshSession * PGPsecshConstSessionRef; + +#define kInvalidPGPsecshSessionRef ((PGPsecshSessionRef) NULL) +#define PGPsecshSessionRefIsValid( ref ) ( (ref) != kInvalidPGPsecshSessionRef ) + + +typedef PGPFlags PGPsecshFlags; +#define kPGPsecshFlags_ServerSide 0x01 +#define kPGPsecshFlags_ClientSide 0x02 +#define kPGPsecshFlags_NonBlockingIO 0x04 + +typedef PGPFlags PGPsecshProtocolFlags; +#define kPGPsecshProtocolFlags_ScreenNumber 0x01 +#define kPGPsecshProtocolFlags_HostInFwdOpen 0x02 + +enum PGPsecshProtocolState_ +{ + kPGPsecsh_IdleState = 0, + kPGPsecsh_FatalErrorState = 1, + kPGPsecsh_ClosedState = 2, + kPGPsecsh_HandshakeState = 3, + kPGPsecsh_ReadyState = 4, + + PGP_ENUM_FORCE( PGPsecshProtocolState_ ) +}; +PGPENUM_TYPEDEF( PGPsecshProtocolState_, PGPsecshProtocolState ); + +enum PGPsecshAlert_ +{ + kPGPsecsh_AT_CloseNotify = 0, + kPGPsecsh_AT_UnexpectedMessage = 10, /* FATAL */ + kPGPsecsh_AT_BadRecordCRC = 20, /* FATAL */ + kPGPsecsh_AT_DecryptionFailed = 21, /* FATAL */ + kPGPsecsh_AT_RecordOverflow = 22, /* FATAL */ + kPGPsecsh_AT_DecompressionFailure = 30, /* FATAL */ + kPGPsecsh_AT_HandshakeFailure = 40, /* FATAL */ + kPGPsecsh_AT_IDFailure = 41, + kPGPsecsh_AT_UnsupportedVersion = 42, + kPGPsecsh_AT_UnsupportedCert = 43, + kPGPsecsh_AT_CertRevoked = 44, + kPGPsecsh_AT_CertExpired = 45, + kPGPsecsh_AT_CertUnknown = 46, + kPGPsecsh_AT_IllegalParameter = 47, /* FATAL */ + kPGPsecsh_AT_UnknownCA = 48, /* FATAL */ + kPGPsecsh_AT_AccessDenied = 49, /* FATAL */ + kPGPsecsh_AT_DecodeError = 50, /* FATAL */ + kPGPsecsh_AT_DecryptError = 51, + kPGPsecsh_AT_ExportRestriction = 60, /* FATAL */ + kPGPsecsh_AT_ProtocolVersion = 70, /* FATAL */ + kPGPsecsh_AT_InsufficientSecurity = 71, /* FATAL */ + kPGPsecsh_AT_InternalError = 80, /* FATAL */ + kPGPsecsh_AT_UserCancelled = 90, + kPGPsecsh_AT_NoRenegotiation = 100, + + kPGPsecsh_AT_None = 255, + + PGP_ENUM_FORCE( PGPsecshAlert_ ) +}; +PGPENUM_TYPEDEF( PGPsecshAlert_, PGPsecshAlert ); + +/* The Send and Receive function pointers should return + kPGPError_SECSHWouldBlock when the socket is non-blocking and the + call would block. The Send and Receive functions passed in will + need to translate the platform-specific socket error in appropriate + cases by using calls such as WSAGetLastError() on Win32. Remember + to call PGPsecshSendQueueIdle for non-blocking sockets also if + kPGPError_SECSHWouldBlock is returned from a send on a non-blocking + socket. */ + +typedef PGPInt32 (* PGPsecshReceiveProcPtr)(void *inData, void *outBuffer, + PGPInt32 inBufferSize); +typedef PGPInt32 (* PGPsecshSendProcPtr)(void *inData, const void *inBuffer, + PGPInt32 inBufferLength); + + +PGPError PGPNewSECSHContext( PGPContextRef context, + PGPsecshContextRef *outRef ); + +PGPError PGPFreeSECSHContext( PGPsecshContextRef ref ); + +/*____________________________________________________________________________ + The following function activates or deactivates the session key cache + for SECSH sessions. This defaults to on but can be deactivated with this + function to force all connections to proceed through the entire + handshake. +____________________________________________________________________________*/ +PGPError PGPsecshSetCache( PGPsecshContextRef ref, PGPBoolean useCache ); + +PGPError PGPsecshClearCache( PGPsecshContextRef ref ); + +PGPError PGPNewSECSHSession( PGPsecshContextRef ref, PGPsecshSessionRef *outRef ); + +PGPError PGPFreeSECSHSession( PGPsecshSessionRef ref ); + +PGPError PGPCopySECSHSession( PGPsecshSessionRef ref, PGPsecshSessionRef *outRef ); + +/* Default options are: client side, no protocol flags */ +PGPError PGPsecshSetProtocolOptions( PGPsecshSessionRef ref, + PGPsecshFlags options, + PGPsecshProtocolFlags pflags ); + + +/*____________________________________________________________________________ + The following function must be called to cleanly close a SECSH + connection. If it is not called, the session will not be able + to be resumed from the session cache. + + In the event the application determines any problem with the + connection such as the remote key not being valid, call this + function with dontCache set to true in order to not cache the + session keys. +____________________________________________________________________________*/ +PGPError PGPsecshClose( PGPsecshSessionRef ref, + PGPBoolean dontCache ); + +/*____________________________________________________________________________ + The following function must be called to initiate the PGPsecsh session. + Once a SECSH session has been assigned to a socket, no data can be sent + over that socket by the application until the handshake is completed. + Handshake completion is indicated by completion of this call without + error or by checking the state of the PGPsecshSession. It will be + kPGPsecsh_ReadyState when the application layer may send and receive + data securely. + + This function performs all negotiation of the SECSH connection. +____________________________________________________________________________*/ +PGPError PGPsecshHandshake( PGPsecshSessionRef ref ); + +/*____________________________________________________________________________ + The following function sets the local private authenticating key, + as well as other relevant data. + + The passphrase, key etc. are retained in memory. + It is an error not to specify a key. + This function must be passed either PGPOPassphrase or PGPOPasskeyBuffer. + inKeyObject must be in a PGP private key. inHostKeys should be a keyset + where the host key of the remote system is found, if we are checking + for consistency of that key. See PGPsecshGetRemoteAuthenticatedKey + for how to learn what host key was used. + inUserName is used to log in on the remote system. + inHostName is used for the username on the host key if it isn't found + on the inHostKeys keyset. +____________________________________________________________________________*/ +PGPError PGPsecshSetLocalPrivateKey( PGPsecshSessionRef ref, + char * inUserName, + PGPKeyDBObjRef inKeyObject, + char * inHostName, + PGPKeySetRef inHostKeys, + PGPOptionListRef firstOption, ... ); + +/*____________________________________________________________________________ + The following function gets the authenticated remote host key after a + successful handshake. You can call this function after a successful + handshake to verify that the remote key is authorized to make the + connection. The key returned will be on the inHostKeys keyset if it + matched one of the keys there; if it is a new host key which was not + in that keyset then it will be in a keyset & keydb of its own. +____________________________________________________________________________*/ +PGPError PGPsecshGetRemoteAuthenticatedKey( PGPsecshSessionRef ref, + PGPKeyDBObjRef *outKey, + PGPKeyDBRef * outKeyDB ); + +/*____________________________________________________________________________ + The following function exports a PGP key in SECSH format. The resulting + line can be copied into the SECSH host file. inKey is the key to + export, and inUserName is the name which is put at the end of the line, + which is used only as a convenient label by SECSH software. + The data is returned in a null-terminated allocated buffer which the + caller should free. +____________________________________________________________________________*/ + PGPError +PGPsecshExportPublicKey( + PGPKeyDBObjRef inKey, + char * inUserName, + char ** outBuffer, + PGPSize * outLength); + +/*____________________________________________________________________________ + The following two functions process data through SECSH. + + It is an error to call these functions without having set a + Read function pointer or Write function pointer. +____________________________________________________________________________*/ +PGPError PGPsecshReceive( PGPsecshSessionRef ref, + PGPByte * outType, + void ** outBuffer, + PGPSize * bufferSize ); + +PGPError PGPsecshSend( PGPsecshSessionRef ref, + PGPByte pktType, + const void * inBuffer, + PGPSize inBufferLength ); + +/*____________________________________________________________________________ + The following two functions set the callbacks which do the actual I/O. + + The inData parameter is passed to the callback and may be e.g. a socket + handle. +____________________________________________________________________________*/ +PGPError PGPsecshSetReceiveCallback( PGPsecshSessionRef ref, + PGPsecshReceiveProcPtr secshReceiveProc, + void * inData ); + +PGPError PGPsecshSetSendCallback( PGPsecshSessionRef ref, + PGPsecshSendProcPtr secshSendProc, + void * inData ); + + +/*____________________________________________________________________________ + The following function is necessary *only* on a non-blocking socket. + If a call to PGPsecshSend returns kPGPError_SECSHWouldBlock, call + the following function repeatedly until that error is no longer + returned in order to make sure data is sent. Another call to + PGPsecshSend will also call this function automatically and queue + any new data if necessary. +____________________________________________________________________________*/ +PGPError PGPsecshSendQueueIdle( PGPsecshSessionRef ref ); + +PGPSize PGPsecshReceiveBufferSize( PGPsecshSessionRef ref ); + +/*____________________________________________________________________________ + The following function gets the ID of the fatal alert which caused + the SECSH session to abort and go into the kPGPsecsh_FatalErrorState. +____________________________________________________________________________*/ +PGPError PGPsecshGetAlert( PGPsecshSessionRef ref, PGPsecshAlert *outAlert ); + + +PGP_END_C_DECLARATIONS + +#endif /* ] Included_PGPsecsh_h */ + + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk8/include/pgpSKEP.h b/CryptoPP/PGPw/sdk8/include/pgpSKEP.h new file mode 100644 index 0000000..217c88e --- /dev/null +++ b/CryptoPP/PGPw/sdk8/include/pgpSKEP.h @@ -0,0 +1,120 @@ +/*____________________________________________________________________________ + Copyright (C) 2002 PGP Corporation + All rights reserved. + + $Id: pgpSKEP.h,v 1.1 2004/04/01 11:45:40 wprice Exp $ +____________________________________________________________________________*/ +#ifndef Included_pgpSKEP_h /* [ */ +#define Included_pgpSKEP_h + +#include "pgpConfig.h" +#include "pgpBase.h" +#include "pgpErrors.h" +#include "pgpShare.h" +#include "pgpKeys.h" +#include "pgpTLS.h" + +typedef struct PGPskep * PGPskepRef; + +#define kInvalidPGPskepRef ((PGPskepRef) NULL) +#define PGPskepRefIsValid( ref ) ( (ref) != kInvalidPGPskepRef ) + +typedef enum _PGPskepEventType +{ + kPGPskepEvent_NullEvent = 0, /* Nothing is happening */ + kPGPskepEvent_ListenEvent = 1, /* Listening for data */ + kPGPskepEvent_ConnectEvent = 2, /* Connection established */ + kPGPskepEvent_AuthenticateEvent = 3, /* Remote site authenticated */ + kPGPskepEvent_ProgressEvent = 4, /* Data flow progress */ + kPGPskepEvent_CloseEvent = 5, /* Connection closing */ + kPGPskepEvent_ShareEvent = 6, /* Share received */ + kPGPskepEvent_PassphraseEvent = 7 /* Passphrase needed */ +} PGPskepEventType; + +typedef struct _PGPskepEventAuthenticateData +{ + PGPKeyDBObjRef remoteKey; + const char * remoteHostname; + const char * remoteIPAddress; + PGPtlsCipherSuiteNum tlsCipher; +} PGPskepEventAuthenticateData; + +typedef struct _PGPskepEventProgressData +{ + PGPUInt32 bytesSoFar; + PGPUInt32 bytesTotal; +} PGPskepEventProgressData; + +typedef struct _PGPskepEventShareData +{ + PGPShareRef shares; +} PGPskepEventShareData; + +typedef struct _PGPskepEventPassphraseData +{ + char * passphrase; + PGPByte * passkey; + PGPSize passkeySize; +} PGPskepEventPassphraseData; + +typedef union _PGPskepEventData +{ + PGPskepEventAuthenticateData ad; + PGPskepEventProgressData pd; + PGPskepEventShareData sd; + PGPskepEventPassphraseData ppd; +} PGPskepEventData; + +typedef struct _PGPskepEvent +{ + PGPskepEventType type; + PGPskepEventData data; +} PGPskepEvent; + +typedef PGPError (*PGPskepEventHandler)(PGPskepRef skep, + PGPskepEvent *event, PGPUserValue userValue); + + +PGP_BEGIN_C_DECLARATIONS + +#if PRAGMA_IMPORT_SUPPORTED +#pragma import on +#endif + +PGPError PGPNewSKEP(PGPContextRef context, + PGPtlsContextRef tlsContext, + PGPskepRef *skep); + +PGPError PGPskepSetEventHandler(PGPskepRef skep, + PGPskepEventHandler handler, PGPUserValue userValue); + +PGPError PGPskepSendShares(PGPskepRef skep, PGPKeyDBObjRef authKey, + const char *passphrase, PGPShareRef shares, + const char *destSocketAddress); + +PGPError PGPskepReceiveShares(PGPskepRef skep, PGPKeyDBObjRef authKey, + const char *passphrase); + +PGPError PGPskepCancel(PGPskepRef skep); + +PGPError PGPFreeSKEP(PGPskepRef skep); + +PGPContextRef PGPGetSKEPContext(PGPskepRef skep); + +#if PRAGMA_IMPORT_SUPPORTED +#pragma import reset +#endif + +PGP_END_C_DECLARATIONS + +#endif /* ] Included_pgpSKEP_h */ + + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk8/include/pgpShare.h b/CryptoPP/PGPw/sdk8/include/pgpShare.h new file mode 100644 index 0000000..04d6da5 --- /dev/null +++ b/CryptoPP/PGPw/sdk8/include/pgpShare.h @@ -0,0 +1,80 @@ +/*____________________________________________________________________________ + Copyright (C) 2002 PGP Corporation + All rights reserved. + + $Id: pgpShare.h,v 1.1 2004/04/01 11:45:40 wprice Exp $ +____________________________________________________________________________*/ +#ifndef Included_pgpShare_h /* [ */ +#define Included_pgpShare_h + +#include "pgpConfig.h" +#include "pgpBase.h" +#include "pgpKeys.h" + +typedef struct PGPShare * PGPShareRef; + +typedef struct PGPShareID_ +{ + PGPByte data[8]; +} PGPShareID; + +#define kInvalidPGPShareRef ((PGPShareRef) NULL) +#define PGPShareRefIsValid( ref ) ( (ref) != kInvalidPGPShareRef ) + +PGP_BEGIN_C_DECLARATIONS +#if PRAGMA_IMPORT_SUPPORTED +#pragma import on +#endif + +PGPError PGPCreateShares(PGPContextRef context, PGPKeyDBObjRef key, + PGPUInt32 threshold, PGPUInt32 numShares, + PGPShareRef *share); + +/* The passkey needs to be freed with PGPFreeData(passkey) */ +PGPError PGPGetPasskeyFromShares(PGPShareRef share, PGPByte **passkey, + PGPSize *passkeySize); + +PGPError PGPSplitShares(PGPShareRef share, PGPUInt32 numShares, + PGPShareRef *splitShares); + +/* The share objects being combined are NOT freed by this function */ +PGPError PGPCombineShares(PGPShareRef firstShare, PGPShareRef secondShare, + PGPShareRef *combinedShares); + +PGPError PGPFreeShares(PGPShareRef share); + +PGPError PGPGetKeyIDFromShares(PGPShareRef share, PGPKeyID *id); + +PGPError PGPGetShareID(PGPShareRef share, PGPShareID *id); + +PGPUInt32 PGPGetShareThreshold(PGPShareRef share); + +/* This is the number of shares contained in the share object */ +PGPUInt32 PGPGetNumberOfShares(PGPShareRef share); + +/* The share object may contain less than the total number of shares */ +PGPUInt32 PGPGetTotalNumberOfShares(PGPShareRef share); + +PGPBoolean IsSamePGPShares(PGPShareRef firstShare, PGPShareRef secondShare); + +/* If firstID < secondID, -1 */ +/* If firstID > secondID, 1 */ +/* If firstID = secondID, 0 */ +PGPInt32 PGPCompareShareIDs(PGPShareID firstID, PGPShareID secondID); + +#if PRAGMA_IMPORT_SUPPORTED +#pragma import reset +#endif +PGP_END_C_DECLARATIONS + +#endif /* ] Included_pgpShare_h */ + + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk8/include/pgpShareFile.h b/CryptoPP/PGPw/sdk8/include/pgpShareFile.h new file mode 100644 index 0000000..4a7aa3e --- /dev/null +++ b/CryptoPP/PGPw/sdk8/include/pgpShareFile.h @@ -0,0 +1,95 @@ +/*____________________________________________________________________________ + Copyright (C) 2002 PGP Corporation + All rights reserved. + + $Id: pgpShareFile.h,v 1.1 2004/04/01 11:45:40 wprice Exp $ +____________________________________________________________________________*/ +#ifndef Included_pgpShareFile_h /* [ */ +#define Included_pgpShareFile_h + +#include "pgpConfig.h" +#include "pgpBase.h" +#include "pgpErrors.h" +#include "pgpPubTypes.h" +#include "pflTypes.h" +#include "pgpShare.h" + +typedef struct PGPShareFile * PGPShareFileRef; + +#define kInvalidPGPShareFileRef ((PGPShareFileRef) NULL) +#define PGPShareFileRefIsValid( ref ) ( (ref) != kInvalidPGPShareFileRef ) + +PGP_BEGIN_C_DECLARATIONS +#if PRAGMA_IMPORT_SUPPORTED +#pragma import on +#endif + +PGPError PGPNewShareFile(PFLFileSpecRef shareFileSpec, + PGPShareFileRef *shareFileRef); + +PGPError PGPFreeShareFile(PGPShareFileRef shareFileRef); + +/* The share object needs to be freed with PGPFreeShares(shares) */ +PGPError PGPCopySharesFromFile(PGPContextRef context, + PGPShareFileRef shareFileRef, PGPOptionListRef optionList, + PGPShareRef *shares); + +PGPError PGPCopySharesToFile(PGPContextRef context, + PGPShareFileRef shareFileRef, PGPOptionListRef optionList, + PGPShareRef shares); + +PGPError PGPGetShareFileUserID(PGPShareFileRef shareFileRef, + PGPSize bufferSize, PGPUTF8 *userID, PGPSize *fullSize); + +PGPError PGPSetShareFileUserID(PGPShareFileRef shareFileRef, + const PGPUTF8 *userID); + +PGPError PGPOpenShareFile(PFLFileSpecRef shareFileSpec, + PGPShareFileRef *shareFileRef); + +PGPError PGPSaveShareFile(PGPShareFileRef shareFileRef); + +PGPError PGPGetShareFileSpec(PGPShareFileRef shareFileRef, + PFLFileSpecRef *shareFileSpec); + +PGPError PGPGetShareFileShareID(PGPShareFileRef shareFileRef, + PGPShareID *id); + +PGPError PGPGetShareFileOwnerKeyID(PGPShareFileRef shareFileRef, + PGPKeyID *id); + +PGPError PGPSetShareFileOwnerKeyID(PGPShareFileRef shareFileRef, + const PGPKeyID id); + +PGPError PGPGetShareFileOwnerFingerprint(PGPShareFileRef shareFileRef, + PGPSize bufferSize, void *fingerprint, PGPSize *fullSize); + +PGPError PGPSetShareFileOwnerFingerprint(PGPShareFileRef shareFileRef, + PGPSize bufferSize, const void *fingerprint); + +PGPError PGPGetShareFileSharedKeyID(PGPShareFileRef shareFileRef, + PGPKeyID *id); + +PGPUInt32 PGPGetShareThresholdInFile(PGPShareFileRef shareFileRef); + +PGPUInt32 PGPGetNumSharesInFile(PGPShareFileRef shareFileRef); + +PGPBoolean IsSamePGPSharesInFiles(PGPShareFileRef firstFile, + PGPShareFileRef secondFile); + +#if PRAGMA_IMPORT_SUPPORTED +#pragma import reset +#endif +PGP_END_C_DECLARATIONS + +#endif /* ] Included_pgpShareFile_h */ + + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk8/include/pgpSockets.h b/CryptoPP/PGPw/sdk8/include/pgpSockets.h new file mode 100644 index 0000000..e82ab45 --- /dev/null +++ b/CryptoPP/PGPw/sdk8/include/pgpSockets.h @@ -0,0 +1,464 @@ +/*____________________________________________________________________________ + Copyright (C) 2002 PGP Corporation + All rights reserved. + + $Id: pgpSockets.h,v 1.8 2003/12/13 01:20:39 dallen Exp $ +____________________________________________________________________________*/ + +#ifndef Included_pgpSockets_h /* [ */ +#define Included_pgpSockets_h + +#include + +#include "pgpOptionList.h" +#include "pgpTLS.h" +#include "pgpErrors.h" + +#if PGP_UNIX +# include +# include +# include /* Needed for struct timeval */ +#if PGP_UNIX_LINUX +# include /* Need FIONREAD */ +#elif PGP_UNIX_SOLARIS || PGP_UNIX_DARWIN +# include +#elif PGP_UNIX_AIX +#include +#endif /* ! PGP_UNIX_LINUX */ +# include +# include +#endif + +#if PGP_WIN32 +# include +#endif + +PGP_BEGIN_C_DECLARATIONS + +#if PGP_UNIX +typedef int PGPSocketRef; +#else +typedef SOCKET PGPSocketRef; +#endif + + +/* + * Unix and Windows share the same Berkeley socket interface. This isn't + * the most efficient Windows implmentation of TCP/IP, but it is + * compatible with UNIX berkeley sockets, making cross-platform possible. + * + * Trying to write cross-platform win32 TCP/IP code using all the fancy + * dancy Win32 network functions would be nearly impossible IMHO + * + * The Mac doesn't have the berkeley stuff, so we roll our own for all + * of the structures. + * + * Start with Unix and Win32 + */ +#if PGP_UNIX || PGP_WIN32 + +# define kInvalidPGPSocketRef ((PGPSocketRef) (~0)) + + typedef struct hostent PGPHostEntry; + typedef struct protoent PGPProtocolEntry; + typedef struct servent PGPServiceEntry; + typedef struct sockaddr_in PGPSocketAddressInternet; + typedef struct sockaddr PGPSocketAddress; + typedef struct in_addr PGPInternetAddress; + typedef fd_set PGPSocketSet; + typedef struct timeval PGPSocketsTimeValue; + +# define PGPSOCKETSET_CLEAR(socketRef, set) FD_CLR((int) (socketRef), (set)) +# define PGPSOCKETSET_SET(socketRef, set) FD_SET((int) (socketRef), (set)) +# define PGPSOCKETSET_ZERO(set) FD_ZERO((set)) +# define PGPSOCKETSET_ISSET(socketRef, set) FD_ISSET((int) (socketRef), (set)) + + /* Address families */ + enum { + kPGPAddressFamilyUnspecified = AF_UNSPEC, + kPGPAddressFamilyInternet = AF_INET + }; + + /* Protocol families */ + enum { + kPGPProtocolFamilyInternet = PF_INET + }; + + /* Types */ + enum { + kPGPSocketTypeStream = SOCK_STREAM, + kPGPSocketTypeDatagram = SOCK_DGRAM + }; + + /* Commands for PGPIOControlSocket */ + enum { + kPGPSocketCommandGetUnreadData = FIONREAD + }; + + /* Levels for PGPGetSocketOptions and PGPSetSocketOptions */ + enum { + kPGPSocketOptionLevelSocket = SOL_SOCKET + }; + + /* Options for PGPGetSocketOptions and PGPSetSocketOptions */ + enum { + kPGPSocketOptionAcceptingConnections = SO_ACCEPTCONN, + kPGPSocketOptionType = SO_TYPE + }; + + /* Protocols */ + enum { + kPGPTCPProtocol = IPPROTO_TCP, + kPGPUDPProtocol = IPPROTO_UDP + }; + + /* Send flags */ + enum { + kPGPSendFlagNone = 0 + }; + + /* Receive flags */ + enum { + kPGPReceiveFlagNone = 0 + }; + + /* Internet Addresses */ + enum { + kPGPInternetAddressAny = INADDR_ANY + }; + +#endif /* PGP_UNIX || PGP_WIN32 */ + +/* + * Onto the Mac, where we need to create our own versions of the various + * structures. + */ +#if PGP_MACINTOSH + +# define kInvalidPGPSocketRef ((PGPSocketRef) NULL) + + typedef struct PGPInternetAddress { + union { + struct { + PGPByte s_b1; + PGPByte s_b2; + PGPByte s_b3; + PGPByte s_b4; + } S_un_b; + struct { + PGPUInt16 s_w1; + PGPUInt16 s_w2; + } S_un_w; + PGPUInt32 S_addr; + } S_un; +# define s_addr S_un.S_addr + } PGPInternetAddress; + + typedef struct PGPSocketAddressInternet { + PGPInt16 sin_family; + PGPUInt16 sin_port; + PGPInternetAddress sin_addr; + PGPByte sin_zero[8]; + } PGPSocketAddressInternet; + + typedef struct PGPSocketAddress { + PGPUInt16 sa_family; + PGPByte sa_data[14]; + } PGPSocketAddress; + + typedef struct PGPHostEntry { + char * h_name; + char ** unused; + PGPInt16 h_addrtype; + PGPInt16 h_length; + char ** h_addr_list; +# define h_addr h_addr_list[0] + } PGPHostEntry; + + typedef struct PGPProtocolEntry { + char * p_name; + char ** p_aliases; + PGPInt16 p_proto; + } PGPProtocolEntry; + + typedef struct PGPServiceEntry { + char * s_name; + char ** s_aliases; + PGPUInt16 s_port; + char * s_proto; + } PGPServiceEntry; + + /* Select types and defines */ +# ifndef PGPSOCKETSET_SETSIZE +# define PGPSOCKETSET_SETSIZE 64 +# endif + + typedef struct PGPSocketSet { + PGPUInt16 fd_count; + PGPSocketRef fd_array[PGPSOCKETSET_SETSIZE]; + } PGPSocketSet; + +# define PGPSOCKETSET_CLEAR(socketRef, set) do { \ + PGPUInt16 __i; \ + for (__i = 0; __i < ((PGPSocketSet * (set))->fd_count; __i++) { \ + if (((PGPSocketSet *) (set))->fd_array[__i] == socketRef) { \ + while (__i < (((PGPSocketSet *) (set))->fd_count - 1)) { \ + ((PGPSocketSet *) (set))->fd_array[__i] = \ + ((PGPSocketSet *) (set))->fd_array[__i + 1]; \ + __i++; \ + } \ + ((PGPSocketSet *) (set))->fd_count--; \ + break; \ + } \ + } \ + } while (0) + +# define PGPSOCKETSET_SET(socketRef, set) do { \ + if (((PGPSocketSet *) (set))->fd_count < PGPSOCKETSET_SETSIZE) { \ + ((PGPSocketSet *) (set))->fd_array[((PGPSocketSet *) \ + (set))->fd_count++] = (socketRef); \ + } \ + } while (0) + +# define PGPSOCKETSET_ZERO(set) (((PGPSocketSet *) (set))->fd_count = 0) + + PGPInt32 __PGPSocketsIsSet(PGPSocketRef, PGPSocketSet *); + +# define PGPSOCKETSET_ISSET(socketRef, set) __PGPSocketsIsSet( \ + (socketRef),(set)) + + typedef struct PGPSocketsTimeValue { + PGPInt32 tv_sec; /* seconds */ + PGPInt32 tv_usec; /* and microseconds */ + } PGPSocketsTimeValue; + + /* Address families */ + enum { + kPGPAddressFamilyUnspecified = 0, + kPGPAddressFamilyInternet = 2 + }; + + /* Protocol families */ + enum { + kPGPProtocolFamilyInternet = kPGPAddressFamilyInternet + }; + + /* Types */ + enum { + kPGPSocketTypeStream = 1, + kPGPSocketTypeDatagram = 2 + }; + + /* Commands for PGPIOControlSocket */ + enum { + kPGPSocketCommandGetUnreadData = (0x40000000 + | (((long) sizeof(PGPUInt32) & 0x7F) << 16) | ('f' << 8) | 127) + }; + + /* Levels for PGPGetSocketOptions and PGPSetSocketOptions */ + enum { + kPGPSocketOptionLevelSocket = 0xFFFFFFFF + }; + + /* Options for PGPGetSocketOptions and PGPSetSocketOptions */ + enum { + kPGPSocketOptionAcceptingConnections = 0x00000002, + kPGPSocketOptionType = 0x00001008 + }; + + /* Protocols */ + enum { + kPGPTCPProtocol = 6, + kPGPUDPProtocol = 17 + }; + + /* Send flags */ + enum { + kPGPSendFlagNone = 0 + }; + + /* Receive flags */ + enum { + kPGPReceiveFlagNone = 0 + }; + + /* Internet Addresses */ + enum { + kPGPInternetAddressAny = 0x00000000 + }; + +#endif /* PGP_MACINTOSH */ + +/* + * Some global things for all platforms + */ + +#define PGPSocketRefIsValid(ref) ((ref) != kInvalidPGPSocketRef) + +typedef struct PGPSocketsThreadStorage * PGPSocketsThreadStorageRef; +# define kInvalidPGPSocketsThreadStorageRef \ + ((PGPSocketsThreadStorageRef) NULL) +#define PGPSocketsThreadStorageRefIsValid(ref) \ + ((ref) != kInvalidPGPSocketsThreadStorageRef) + +extern PGPSocketAddressInternet kPGPAddressAny; + +/* Errors */ +#define kPGPSockets_Error -1 + +/* Net byte ordering macros (PGP_WORDSBIGENDIAN defined by configure) */ +#if PGP_WORDSBIGENDIAN +# define PGPHostToNetLong(x) (x) +# define PGPHostToNetShort(x) (x) +# define PGPNetToHostLong(x) (x) +# define PGPNetToHostShort(x) (x) +#else + PGPInt32 PGPHostToNetLong(PGPInt32 x); + PGPInt16 PGPHostToNetShort(PGPInt16 x); + PGPInt32 PGPNetToHostLong(PGPInt32 x); + PGPInt16 PGPNetToHostShort(PGPInt16 x); +#endif /* PGP_WORDSBIGENDIAN */ + +/* + * Shared function interface (except for idle handler code) + */ + +/* + * Use the idle event handler to receive periodic idle events during + * network calls. Usually this is used only in non-preemptive multi-tasking + * OSes to allow yielding in threads. Pre-emptive multi-tasking systems + * should probably not use the call as it interrupts the efficient wait state + * of threads waiting on network calls. + * + * Idle event handlers need to be added on a per thread basis. + * + * Returning an error from the idle event handler will cause the socket + * that is blocking to close. + * + */ +PGPError PGPSetSocketsIdleEventHandler( + PGPEventHandlerProcPtr inCallback, + PGPUserValue inUserData); + +PGPError PGPGetSocketsIdleEventHandler( + PGPEventHandlerProcPtr * outCallback, + PGPUserValue * outUserData); + +/* Static storage creation */ +PGPError PGPSocketsCreateThreadStorage( + PGPSocketsThreadStorageRef * outPreviousStorage); +PGPError PGPSocketsDisposeThreadStorage( + PGPSocketsThreadStorageRef inPreviousStorage); + +/* Stack based class for saving and restoring thread storage */ +#ifdef __cplusplus /* [ */ +class StPGPPreserveSocketsStorage { +public: + StPGPPreserveSocketsStorage() : mStorage(NULL) + { PGPSocketsCreateThreadStorage(&mStorage); } + ~StPGPPreserveSocketsStorage() + { PGPSocketsDisposeThreadStorage(mStorage); } + +protected: + PGPSocketsThreadStorageRef mStorage; +}; +#endif /* ] __cplusplus */ + + +/* Initialization and termination */ +PGPError PGPSocketsInit(void); +void PGPSocketsCleanup(void); + +/* Socket creation and destruction */ +PGPSocketRef PGPOpenSocket(PGPInt32 inAddressFamily, PGPInt32 inSocketType, + PGPInt32 inSocketProtocol); +PGPInt32 PGPCloseSocket(PGPSocketRef inSocketRef); + +/* Endpoint binding */ +PGPInt32 PGPBindSocket(PGPSocketRef inSocketRef, + const PGPSocketAddress * inAddress, + PGPInt32 inAddressLength); +PGPInt32 PGPConnect(PGPSocketRef inSocketRef, + const PGPSocketAddress * inServerAddress, + PGPInt32 inAddressLength); + +/* Send functions */ +PGPInt32 PGPSend(PGPSocketRef inSocketRef, const void * inBuffer, + PGPInt32 inBufferLength, PGPInt32 inFlags); +PGPInt32 PGPWrite(PGPSocketRef inSocketRef, const void * inBuffer, + PGPInt32 inBufferLength); +PGPInt32 PGPSendTo(PGPSocketRef inSocketRef, const void * inBuffer, + PGPInt32 inBufferLength, PGPInt32 inFlags, + PGPSocketAddress * inAddress, + PGPInt32 inAddressLength); + +/* Receive functions */ +PGPInt32 PGPReceive(PGPSocketRef inSocketRef, void * outBuffer, + PGPInt32 inBufferSize, PGPInt32 inFlags); +PGPInt32 PGPRead(PGPSocketRef inSocketRef, void * outBuffer, + PGPInt32 inBufferSize); +PGPInt32 PGPReceiveFrom(PGPSocketRef inSocketRef, void * outBuffer, + PGPInt32 inBufferSize, PGPInt32 inFlags, + PGPSocketAddress * outAddress, + PGPInt32 * ioAddressLength); + +/* Server functions */ +PGPInt32 PGPListen(PGPSocketRef inSocketRef, PGPInt32 inMaxBacklog); +PGPSocketRef PGPAccept(PGPSocketRef inSocketRef, + PGPSocketAddress * outAddress, + PGPInt32 * ioAddressLength); + +/* Select */ +/* Note that inNumSetCount is not used under Mac and Windows */ +PGPInt32 PGPSelect(PGPInt32 inNumSetCount, + PGPSocketSet * ioReadSet, + PGPSocketSet * ioWriteSet, + PGPSocketSet * ioErrorSet, + const PGPSocketsTimeValue * inTimeout); + +/* DNS and protocol services */ +PGPHostEntry * PGPGetHostByName(const PGPChar8 * inName); +PGPHostEntry * PGPGetHostByAddress(const PGPChar8 * inAddress, + PGPInt32 inLength, + PGPInt32 inType); +PGPInt32 PGPGetHostName(PGPChar8 * outName, PGPInt32 inNameLength); +PGPProtocolEntry * PGPGetProtocolByName(const PGPChar8 * inName); +PGPProtocolEntry * PGPGetProtocolByNumber(PGPInt32 inNumber); +PGPServiceEntry * PGPGetServiceByName(const PGPChar8 * inName, + const PGPChar8 * inProtocol); +PGPServiceEntry * PGPGetServiceByPort(PGPInt32 inPort, + const PGPChar8 * inProtocol); + +/* Error reporting */ +PGPError PGPGetLastSocketsError(void); + +/* Utilities */ +PGPInt32 PGPGetSocketName(PGPSocketRef inSocketRef, + PGPSocketAddress * outName, + PGPInt32 * ioNameLength); +PGPInt32 PGPGetPeerName(PGPSocketRef inSocketRef, + PGPSocketAddress * outName, + PGPInt32 * ioNameLength); +PGPUInt32 PGPDottedToInternetAddress(const PGPChar8 * inAddress); +PGPChar8 * PGPInternetAddressToDottedString(PGPInternetAddress inAddress); + +/* Control and options */ +PGPInt32 PGPIOControlSocket(PGPSocketRef inSocketRef, + PGPInt32 inCommand, PGPUInt32 * ioParam); +PGPInt32 PGPGetSocketOptions(PGPSocketRef inSocketRef, PGPInt32 inLevel, + PGPInt32 inOptionName, + PGPChar8 * outOptionValue, + PGPInt32 * ioOptionLength); +PGPInt32 PGPSetSocketOptions(PGPSocketRef inSocketRef, PGPInt32 inLevel, + PGPInt32 inOptionName, + const PGPChar8 * inOptionValue, + PGPInt32 inOptionLength); + +/* TLS */ +PGPError PGPSocketsEstablishTLSSession(PGPSocketRef inSocketRef, + PGPtlsSessionRef inTLSSession); + + +PGP_END_C_DECLARATIONS + +#endif /* Included_pgpSockets_h */ diff --git a/CryptoPP/PGPw/sdk8/include/pgpSymmetricCipher.h b/CryptoPP/PGPw/sdk8/include/pgpSymmetricCipher.h new file mode 100644 index 0000000..61a700e --- /dev/null +++ b/CryptoPP/PGPw/sdk8/include/pgpSymmetricCipher.h @@ -0,0 +1,114 @@ +/*____________________________________________________________________________ + Copyright (C) 2002 PGP Corporation + All rights reserved. + + $Id: pgpSymmetricCipher.h,v 1.7 2003/10/07 01:29:44 ajivsov Exp $ +____________________________________________________________________________*/ + +#ifndef Included_pgpSymmetricCipher_h /* [ */ +#define Included_pgpSymmetricCipher_h + +#include "pgpPubTypes.h" + +PGP_BEGIN_C_DECLARATIONS + +/*____________________________________________________________________________ + Create a new cipher of the specified algorithm. The cipher cannot be used + until PGPInitSymmetricCipher() has been called. + + If the algorithm is not available then kPGPError_AlgorithmNotAvailable is + returned. +____________________________________________________________________________*/ + +PGPError PGPNewSymmetricCipherContext( PGPContextRef context, + PGPCipherAlgorithm algorithm, + PGPSymmetricCipherContextRef *outRef ); + +/*____________________________________________________________________________ + Disposal clears all data in memory before releasing it. +____________________________________________________________________________*/ + +PGPError PGPFreeSymmetricCipherContext( PGPSymmetricCipherContextRef ref ); + +/*____________________________________________________________________________ + Make an exact copy of the cipher, including the key. +____________________________________________________________________________*/ + +PGPError PGPCopySymmetricCipherContext( PGPSymmetricCipherContextRef ref, + PGPSymmetricCipherContextRef *outRef ); + +/*____________________________________________________________________________ + The key must be set before using; a cipher can be repeatedly reset and + reused with different keys to avoid having to create and destroy new + contexts each time (and it's also cryptographically better not to reuse + a key). + Key size is implicit based on algorithm. 'key' is *copied*. Caller + may want to destroy the original after passing it in. +____________________________________________________________________________*/ + +PGPError PGPInitSymmetricCipher( PGPSymmetricCipherContextRef ref, + const void *key ); + +/*____________________________________________________________________________ + Wipe any sensitive data in the cipher. Cipher remains alive, but + key must be set before any data is encrypted. +____________________________________________________________________________*/ + +PGPError PGPWipeSymmetricCipher( PGPSymmetricCipherContextRef ref ); + +/*____________________________________________________________________________ + "Wash" the symmetric cipher +____________________________________________________________________________*/ + +PGPError PGPWashSymmetricCipher( PGPSymmetricCipherContextRef ref, + void const *buf, PGPSize len); + +/*____________________________________________________________________________ + Encrypt or decrypt one "block" of data. The block size is determined + by the cipher (see PGPGetSymmetricCipherSizes()). +____________________________________________________________________________*/ + +PGPError PGPSymmetricCipherEncrypt( PGPSymmetricCipherContextRef ref, + const void *in, void *out ); + +PGPError PGPSymmetricCipherDecrypt( PGPSymmetricCipherContextRef ref, + const void *in, void *out ); + +/*____________________________________________________________________________ + Determine key and block size for specified algorithm. Stateless routine + does not need a context. +____________________________________________________________________________*/ +PGPError PGPGetSymmetricCipherSizes( PGPSymmetricCipherContextRef ref, + PGPSize *keySize, PGPSize *blockSize ); + +/*____________________________________________________________________________ + * This function integrates stream ciphers into framework of block API. + * To encrypt/decrypt data, the caller works with stream cipher in ECB block + * mode and calls this function before and after the last block. + * There is a feedback between the previous block and the current + * block for stream ciphers, so ECB for stream ciphers is similiar to CBC + * with fixed IV for block ciphers. + * + * To indicate the real size of input data the caller must call this function + * with 'size'=0xffffffff before the last block to save a state and then + * call this function again after the last block was encrypted/decrypted + * with the 'size' set to the real number of bytes in the buffer. This + * operation is similiar to padding for block ciphers. +____________________________________________________________________________*/ +PGPError PGPSymmetricCipherRollback( PGPSymmetricCipherContextRef ref, + PGPSize size ); + + +PGP_END_C_DECLARATIONS + +#endif /* ] Included_pgpSymmetricCipher_h */ + + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk8/include/pgpTLS.h b/CryptoPP/PGPw/sdk8/include/pgpTLS.h new file mode 100644 index 0000000..f901b1b --- /dev/null +++ b/CryptoPP/PGPw/sdk8/include/pgpTLS.h @@ -0,0 +1,336 @@ +/*____________________________________________________________________________ + Copyright (C) 2002 PGP Corporation + All rights reserved. + + $Id: pgpTLS.h,v 1.13 2004/04/06 05:00:58 wprice Exp $ +____________________________________________________________________________*/ +#ifndef Included_PGPtls_h /* [ */ +#define Included_PGPtls_h + +#include "pgpPubTypes.h" + +PGP_BEGIN_C_DECLARATIONS + + +typedef struct PGPtlsContext * PGPtlsContextRef; +typedef const struct PGPtlsContext * PGPtlsConstContextRef; + +#define kInvalidPGPtlsContextRef ((PGPtlsContextRef) NULL) +#define PGPtlsContextRefIsValid( ref ) ( (ref) != kInvalidPGPtlsContextRef ) + +typedef struct PGPtlsSession * PGPtlsSessionRef; +typedef const struct PGPtlsSession * PGPtlsConstSessionRef; + +#define kInvalidPGPtlsSessionRef ((PGPtlsSessionRef) NULL) +#define PGPtlsSessionRefIsValid( ref ) ( (ref) != kInvalidPGPtlsSessionRef ) + + +typedef PGPFlags PGPtlsFlags; +#define kPGPtlsFlags_ServerSide 0x01 +#define kPGPtlsFlags_ClientSide 0x02 +#define kPGPtlsFlags_RequestClientCert 0x04 +#define kPGPtlsFlags_NonBlockingIO 0x08 + +enum PGPtlsCipherSuiteNum_ +{ + kPGPtls_TLS_NULL_WITH_NULL_NULL = 0, + kPGPtls_TLS_PGP_DHE_DSS_WITH_CAST_CBC_SHA = 1, + kPGPtls_TLS_PGP_DHE_RSA_WITH_CAST_CBC_SHA = 2, + kPGPtls_TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA = 3, + kPGPtls_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = 4, + kPGPtls_TLS_RSA_WITH_3DES_EDE_CBC_SHA = 5, + kPGPtls_TLS_RSA_WITH_IDEA_CBC_SHA = 6, + kPGPtls_TLS_PGP_RSA_WITH_CAST_CBC_SHA = 7, + kPGPtls_TLS_PGP_DHE_DSS_WITH_NULL_SHA = 8, + kPGPtls_TLS_DHE_DSS_WITH_NULL_SHA = 9, + kPGPtls_TLS_RSA_WITH_ARC4_128_SHA = 10, + + kPGPtls_TLS_RSA_WITH_AES_128_CBC_SHA = 11, + kPGPtls_TLS_DHE_DSS_WITH_AES_128_CBC_SHA = 12, + kPGPtls_TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 13, + + kPGPtls_TLS_RSA_WITH_AES_256_CBC_SHA = 15, + kPGPtls_TLS_DHE_DSS_WITH_AES_256_CBC_SHA = 16, + kPGPtls_TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 17, + + PGP_ENUM_FORCE( PGPtlsCipherSuiteNum_ ) +}; +PGPENUM_TYPEDEF( PGPtlsCipherSuiteNum_, PGPtlsCipherSuiteNum ); + +enum PGPtlsProtocolState_ +{ + kPGPtls_IdleState = 0, + kPGPtls_FatalErrorState = 1, + kPGPtls_ClosedState = 2, + kPGPtls_HandshakeState = 3, + kPGPtls_ReadyState = 4, + + PGP_ENUM_FORCE( PGPtlsProtocolState_ ) +}; +PGPENUM_TYPEDEF( PGPtlsProtocolState_, PGPtlsProtocolState ); + +enum PGPtlsPrime_ +{ + kPGPtls_DHPrime1024 = 0, + kPGPtls_DHPrime1536 = 1, + kPGPtls_DHPrime2048 = 2, + kPGPtls_DHPrime3072 = 3, + kPGPtls_DHPrime4096 = 4, + + PGP_ENUM_FORCE( PGPtlsPrime_ ) +}; +PGPENUM_TYPEDEF( PGPtlsPrime_, PGPtlsPrime ); + +enum PGPtlsAlert_ +{ + kPGPtls_AT_CloseNotify = 0, + kPGPtls_AT_UnexpectedMessage = 10, /* FATAL */ + kPGPtls_AT_BadRecordMAC = 20, /* FATAL */ + kPGPtls_AT_DecryptionFailed = 21, /* FATAL */ + kPGPtls_AT_RecordOverflow = 22, /* FATAL */ + kPGPtls_AT_DecompressionFailure = 30, /* FATAL */ + kPGPtls_AT_HandshakeFailure = 40, /* FATAL */ + kPGPtls_AT_NoCertificate = 41, /* SSL3 */ + kPGPtls_AT_BadCertificate = 42, + kPGPtls_AT_UnsupportedCert = 43, + kPGPtls_AT_CertRevoked = 44, + kPGPtls_AT_CertExpired = 45, + kPGPtls_AT_CertUnknown = 46, + kPGPtls_AT_IllegalParameter = 47, /* FATAL */ + kPGPtls_AT_UnknownCA = 48, /* FATAL */ + kPGPtls_AT_AccessDenied = 49, /* FATAL */ + kPGPtls_AT_DecodeError = 50, /* FATAL */ + kPGPtls_AT_DecryptError = 51, + kPGPtls_AT_ExportRestriction = 60, /* FATAL */ + kPGPtls_AT_ProtocolVersion = 70, /* FATAL */ + kPGPtls_AT_InsufficientSecurity = 71, /* FATAL */ + kPGPtls_AT_InternalError = 80, /* FATAL */ + kPGPtls_AT_UserCancelled = 90, + kPGPtls_AT_NoRenegotiation = 100, + + kPGPtls_AT_None = 255, + + PGP_ENUM_FORCE( PGPtlsAlert_ ) +}; +PGPENUM_TYPEDEF( PGPtlsAlert_, PGPtlsAlert ); + +/* The Send and Receive function pointers should return + kPGPError_TLSWouldBlock when the socket is non-blocking and the + call would block. The Send and Receive functions passed in will + need to translate the platform-specific socket error in appropriate + cases by using calls such as WSAGetLastError() on Win32. Remember + to call PGPtlsSendQueueIdle for non-blocking sockets also if + kPGPError_TLSWouldBlock is returned from a send on a non-blocking + socket. */ + +typedef PGPInt32 (* PGPtlsReceiveProcPtr)(void *inData, void *outBuffer, + PGPInt32 outBufferSize); +typedef PGPInt32 (* PGPtlsSendProcPtr)(void *inData, const void *inBuffer, + PGPInt32 inBufferLength); +typedef PGPInt32 (* PGPtlsPeekProcPtr)(void *inData, void *outBuffer, + PGPInt32 outBufferSize); + +PGPError PGPNewTLSContext( PGPContextRef context, + PGPtlsContextRef *outRef ); + +PGPError PGPFreeTLSContext( PGPtlsContextRef ref ); + +/*____________________________________________________________________________ + The following function activates or deactivates the session key cache + for TLS sessions. This defaults to on but can be deactivated with this + function to force all connections to proceed through the entire + handshake. +____________________________________________________________________________*/ +PGPError PGPtlsSetCache( PGPtlsContextRef ref, PGPBoolean useCache ); + +PGPError PGPtlsClearCache( PGPtlsContextRef ref ); + +PGPError PGPNewTLSSession( PGPtlsContextRef ref, PGPtlsSessionRef *outRef ); + +PGPError PGPFreeTLSSession( PGPtlsSessionRef ref ); + +PGPError PGPCopyTLSSession( PGPtlsSessionRef ref, PGPtlsSessionRef *outRef ); + +/* Default options are client side and no client cert request */ +PGPError PGPtlsSetProtocolOptions( PGPtlsSessionRef ref, + PGPtlsFlags options ); + + +/*____________________________________________________________________________ + The following function must be called to cleanly close a TLS + connection. If it is not called, the session will not be able + to be resumed from the session cache. + + In the event the application determines any problem with the + connection such as the remote key not being valid, call this + function with dontCache set to true in order to not cache the + session keys. +____________________________________________________________________________*/ +PGPError PGPtlsClose( PGPtlsSessionRef ref, + PGPBoolean dontCache ); + +/*____________________________________________________________________________ + The following function must be called to identify cached TLS session. + + During a handshake resulting in reused TLS sessions no certificate exchange + is taking place, so certificate or certificate chain cannot be queried by + a call to PGPtlsGetRemoteAuthenticatedKey(). Remote peer's authentication + keys are assumed to be authorized by the application when it earlier placed + a session into a cache by calling PGPtlsClose(session, FALSE), so the "TRUE" + return value means "already authorized session". + + There is no need to call this function if no caching is done, for example, + if PGPtlsClose(session, FALSE) is never called or cache is + disabled / cleared in PGPtlsContextRef. +____________________________________________________________________________*/ +PGPError PGPtlsIsReusedSession( PGPtlsSessionRef ref, PGPBoolean *reused ); + +/*____________________________________________________________________________ + The following function must be called to initiate the PGPtls session. + Once a TLS session has been assigned to a socket, no data can be sent + over that socket by the application until the handshake is completed. + Handshake completion is indicated by completion of this call without + error or by checking the state of the PGPtlsSession. It will be + kPGPtls_ReadyState when the application layer may send and receive + data securely. + + This function performs all negotiation of the TLS connection. +____________________________________________________________________________*/ +PGPError PGPtlsHandshake( PGPtlsSessionRef ref ); + +/*____________________________________________________________________________ + The following function should be called before PGPtlsHandshake. + In the general case, the remoteID will be an IP address. This + is provided to PGPtls in order to allow it to cache the current + session and be able to look it up later. If the remoteID passed + into a future session is the same as a previously cached session, + PGPtls will attempt to resume the session. +____________________________________________________________________________*/ +PGPError PGPtlsSetRemoteUniqueID( PGPtlsSessionRef ref, + PGPUInt32 remoteID ); + +/*____________________________________________________________________________ + The following function sets the local private authenticating key. + + The passphrase and key are retained in memory. By default, no + key is specified and a client side session will return no key in the + client key exchange message to the server. + It is an error not to specify a key on a server side TLS session. + This function must be passed either PGPOPassphrase or PGPOPasskeyBuffer. + You may pass in just a PGP key, PGP w/ X.509 cert, or both -- and they + must be the same -- the cert must be from the key. For an X.509 cert, + the inCertChain keyset must contain the keys of all keys in the + certificate chain for that certificate up to the root. The inCertChain + keyset must remain valid for the lifetime of the TLS connection. +____________________________________________________________________________*/ +PGPError PGPtlsSetLocalPrivateKey( PGPtlsSessionRef ref, + PGPKeyDBObjRef inKeyObject, + PGPKeySetRef inCertChain, + PGPOptionListRef firstOption, ... ); + +/*____________________________________________________________________________ + The following function sets the preferred cipher suite. + + There is no guarantee that cipher will actually be negotiated, + but it will be attempted in preference to others. +____________________________________________________________________________*/ +PGPError PGPtlsSetPreferredCipherSuite( PGPtlsSessionRef ref, + PGPtlsCipherSuiteNum cipher ); + +/*____________________________________________________________________________ + The following function sets the desired DH prime. + + The requested primes are drawn from a set of primes hard-coded + into PGPtls. New primes can be added in a fully compatible + fashion since the server sends the prime to the client, but this + version of the API does not support passing in a desired prime. The + default prime if this function is not called is kPGPtls_DHPrime2048. +____________________________________________________________________________*/ +PGPError PGPtlsSetDHPrime( PGPtlsSessionRef ref, + PGPtlsPrime prime ); + +/*____________________________________________________________________________ + The following function gets the authenticated remote key after a + successful handshake. You must call this function after a successful + handshake to verify that the remote key is authorized to make the + connection. +____________________________________________________________________________*/ +PGPError PGPtlsGetRemoteAuthenticatedKey( PGPtlsSessionRef ref, + PGPKeyDBObjRef *outKey, + PGPKeyDBRef * outKeyDB ); + +/*____________________________________________________________________________ + The following function returns the negotiated symmetric cipher. + + This function will return an error if called before a successful + handshake. +____________________________________________________________________________*/ +PGPError PGPtlsGetNegotiatedCipherSuite( PGPtlsSessionRef ref, + PGPtlsCipherSuiteNum *outCipher ); + +PGPError PGPtlsGetState( PGPtlsSessionRef ref, + PGPtlsProtocolState *outState ); + +/*____________________________________________________________________________ + The following two functions process data through TLS. + + It is an error to call these functions without having set a + Read function pointer or Write function pointer. Most applications + will never need to use these functions as the function pointers + are automatically configured by PGPsockets, and these functions + are automatically called by the PGPsockets implementations of + PGPWrite and PGPRead whenever a PGPtlsSessionRef has been set for + a given socket. +____________________________________________________________________________*/ +PGPError PGPtlsReceive( PGPtlsSessionRef ref, + void * outBuffer, + PGPSize * bufferSize ); + +PGPError PGPtlsSend( PGPtlsSessionRef ref, + const void * inBuffer, + PGPSize inBufferLength ); + +PGPError PGPtlsSetReceiveCallback( PGPtlsSessionRef ref, + PGPtlsReceiveProcPtr tlsReceiveProc, + void * inData ); + +PGPError PGPtlsSetSendCallback( PGPtlsSessionRef ref, + PGPtlsSendProcPtr tlsSendProc, + void * inData ); + +PGPError PGPtlsSetPeekCallback( PGPtlsSessionRef ref, + PGPtlsPeekProcPtr tlsPeekProc, + void * inData ); + +/*____________________________________________________________________________ + The following function is necessary *only* on a non-blocking socket. + If a call to PGPtlsSend returns kPGPError_TLSWouldBlock, call + the following function repeatedly until that error is no longer + returned in order to make sure data is sent. Another call to + PGPtlsSend will also call this function automatically and queue + any new data if necessary. +____________________________________________________________________________*/ +PGPError PGPtlsSendQueueIdle( PGPtlsSessionRef ref ); + +PGPSize PGPtlsReceiveBufferSize( PGPtlsSessionRef ref ); + +/*____________________________________________________________________________ + The following function gets the ID of the fatal alert which caused + the TLS session to abort and go into the kPGPtls_FatalErrorState. +____________________________________________________________________________*/ +PGPError PGPtlsGetAlert( PGPtlsSessionRef ref, PGPtlsAlert *outAlert ); +const PGPChar * PGPtlsGetAlertString( PGPtlsAlert alert ); + +PGP_END_C_DECLARATIONS + +#endif /* ] Included_PGPtls_h */ + + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk8/include/pgpUserInterface.h b/CryptoPP/PGPw/sdk8/include/pgpUserInterface.h new file mode 100644 index 0000000..210f165 --- /dev/null +++ b/CryptoPP/PGPw/sdk8/include/pgpUserInterface.h @@ -0,0 +1,284 @@ +/*____________________________________________________________________________ + Copyright (C) 2002 PGP Corporation + All rights reserved. + + This file contains the prototypes for functions which use UI to interact + with the user. + + $Id: pgpUserInterface.h,v 1.21 2003/09/24 03:09:32 ajivsov Exp $ +____________________________________________________________________________*/ + +#ifndef Included_pgpUserInterface_h /* [ */ +#define Included_pgpUserInterface_h + +#include "pgpPubTypes.h" +#include "pgpTLS.h" + +#if PGP_WIN32 +#include "windows.h" +#endif + +PGP_BEGIN_C_DECLARATIONS + +#if PGP_MACINTOSH +#pragma options align=mac68k +#endif + +enum PGPAdditionalRecipientRequestEnforcement_ +{ + kPGPARREnforcement_Invalid = 0, + kPGPARREnforcement_None = 1, + kPGPARREnforcement_Warn = 2, + kPGPARREnforcement_Strict = 3, + + PGP_ENUM_FORCE( PGPAdditionalRecipientRequestEnforcement_ ) +}; +PGPENUM_TYPEDEF( PGPAdditionalRecipientRequestEnforcement_, + PGPAdditionalRecipientRequestEnforcement ); + +enum PGPRecipientSpecType_ +{ + kPGPRecipientSpecType_Invalid = 0, + kPGPRecipientSpecType_Key = 1, + kPGPRecipientSpecType_UserID = 2, + kPGPRecipientSpecType_KeyID = 3, + + PGP_ENUM_FORCE( PGPRecipientSpecType_ ) +}; +PGPENUM_TYPEDEF( PGPRecipientSpecType_, PGPRecipientSpecType ); + +enum PGPRecipientSpecFlags_ +{ + kPGPRecipientSpecFlags_Locked = (1UL << 0), + + PGP_ENUM_FORCE( PGPRecipientSpecFlags_ ) +}; + +typedef PGPFlags PGPRecipientSpecFlags; + +typedef struct PGPRecipientSpec +{ + PGPRecipientSpecType type; + PGPRecipientSpecFlags flags; + PGPUInt32 reserved32[3]; /* Must be zero */ + + union + { + PGPKeyDBObjRef key; + PGPChar8 userIDStr[256]; /* Null terminated string */ + PGPKeyID keyID; + } u; + +} PGPRecipientSpec; + +typedef struct PGPKeyServerSpec +{ + PGPKeyServerRef server; + const PGPChar8 *serverName; /* Optional */ + const PGPChar8 *serverDomain; /* Optional */ + +} PGPKeyServerSpec; + +#if PGP_MACINTOSH +#pragma options align=reset +#endif + +PGPError PGPRecipientDialog( PGPContextRef context, PGPKeyDBRef sourceKeys, + PGPBoolean alwaysDisplayDialog, PGPKeyDBRef *recipientKeys, + PGPOptionListRef firstOption, ... ); + +PGPError PGPPassphraseDialog( PGPContextRef context, + PGPOptionListRef firstOption, ... ); + +PGPError PGPConfirmationPassphraseDialog( PGPContextRef context, + PGPOptionListRef firstOption, ... ); + +PGPError PGPKeyPassphraseDialog( PGPContextRef context, + PGPKeyDBObjRef keyDBObject, PGPOptionListRef firstOption, ... ); + +PGPError PGPSigningPassphraseDialog( PGPContextRef context, + PGPKeyDBRef sourceKeys, PGPKeyDBObjRef *signingKey, + PGPOptionListRef firstOption, ... ); + +PGPError PGPDecryptionPassphraseDialog( PGPContextRef context, + PGPKeySetRef recipientKeys, PGPUInt32 keyIDCount, + const PGPKeyID keyIDList[], PGPKeyDBObjRef *decryptionKey, + PGPOptionListRef firstOption, ... ); + +PGPError PGPConventionalEncryptionPassphraseDialog( PGPContextRef context, + PGPOptionListRef firstOption, ... ); + +PGPError PGPConventionalDecryptionPassphraseDialog( PGPContextRef context, + PGPOptionListRef firstOption, ... ); + +PGPError PGPOptionsDialog( PGPContextRef context, + PGPOptionListRef firstOption, ... ); + +PGPError PGPCollectRandomDataDialog( PGPContextRef context, + PGPUInt32 neededEntropyBits, + PGPOptionListRef firstOption, ... ); + +PGPError PGPSearchKeyServerDialog( + PGPContextRef context, + PGPUInt32 serverCount, + const PGPKeyServerSpec serverList[], + PGPtlsContextRef tlsContext, + PGPBoolean searchAllServers, + PGPKeyDBRef *foundKeys, + PGPOptionListRef firstOption, ... ); + +PGPError PGPSendToKeyServerDialog( + PGPContextRef context, + const PGPKeyServerSpec *server, + PGPtlsContextRef tlsContext, + PGPKeySetRef keysToSend, + PGPKeySetRef *failedKeys, + PGPOptionListRef firstOption, ... ); + +/* +** Returns a value in the range 0-100 which crudely estimates +** the "quality" of a passphrase. +*/ + +#undef PGPEstimatePassphraseQuality +PGPUInt32 PGPEstimatePassphraseQuality( const PGPChar8 *passphrase ); + +/* General dialog options */ + +#undef PGPOUIDialogPrompt +PGPOptionListRef PGPOUIDialogPrompt( PGPContextRef context, + const PGPChar8 *prompt ); + +#undef PGPOUIWindowTitle +PGPOptionListRef PGPOUIWindowTitle( PGPContextRef context, + const PGPChar8 *title ); + +PGPOptionListRef PGPOUIDialogOptions( PGPContextRef context, + PGPOptionListRef firstOption, ... ); + +PGPOptionListRef PGPOUIDialogContextHelpButton(PGPContextRef context, + PGPBoolean showDialogContextHelpButton); + +#if PGP_WIN32 +PGPOptionListRef PGPOUIParentWindowHandle( PGPContextRef context, + HWND hwndParent ); +#endif + +/* All passphrase dialogs */ + +/* Caller should free passphrase with PGPFreeData() */ +#undef PGPOUIOutputPassphrase +PGPOptionListRef PGPOUIOutputPassphrase( PGPContextRef context, + PGPChar8 **passphrase ); + +PGPOptionListRef PGPOUIMinimumPassphraseQuality( PGPContextRef context, + PGPUInt32 minimumPassphraseQuality ); + +PGPOptionListRef PGPOUIMinimumPassphraseLength( PGPContextRef context, + PGPUInt32 minimumPassphraseLength ); + +/* Will cause the dialog to cancel if there has been no activity for x seconds */ +PGPOptionListRef PGPOUIDialogTimeout( PGPContextRef context, + PGPUInt32 seconds); + +/* PGPConfirmationPassphraseDialog() options */ + +PGPOptionListRef PGPOUIShowPassphraseQuality( PGPContextRef context, + PGPBoolean showPassphraseQuality ); + +/* PGPSigningPassphraseDialog() and PGPDecryptionPassphraseDialog() options */ + +PGPOptionListRef PGPOUIDefaultKey( PGPContextRef context, + PGPKeyDBObjRef defaultKey ); + +PGPOptionListRef PGPOUIVerifyPassphrase( PGPContextRef context, + PGPBoolean verifyPassphrase ); + +PGPOptionListRef PGPOUIFindMatchingKey( PGPContextRef context, + PGPBoolean findMatchingKey ); + +PGPOptionListRef PGPOUITextUI( PGPContextRef context, PGPBoolean textUI ); + +/* PGPRecipientDialog() options: */ + +PGPOptionListRef PGPOUIRecipientList( PGPContextRef context, + PGPUInt32 *recipientCount, + PGPRecipientSpec **recipientList ); + +PGPOptionListRef PGPOUIDefaultRecipients( PGPContextRef context, + PGPUInt32 recipientCount, + const PGPRecipientSpec recipientList[] ); + +PGPOptionListRef PGPOUIDisplayMarginalValidity( PGPContextRef context, + PGPBoolean displayMarginalValidity ); + +PGPOptionListRef PGPOUIIgnoreMarginalValidity( PGPContextRef context, + PGPBoolean ignoreMarginalValidity ); + +PGPOptionListRef PGPOUIEnforceAdditionalRecipientRequests( + PGPContextRef context, + PGPAdditionalRecipientRequestEnforcement enforcement, + PGPBoolean alwaysDisplayDialogWithARRs); + +/* PGPDecryptionPassphraseDialog() and PGPRecipientDialog() only: */ + +PGPOptionListRef PGPOUIKeyServerUpdateParams(PGPContextRef context, + PGPUInt32 serverCount, + const PGPKeyServerSpec serverList[], + PGPtlsContextRef tlsContext, + PGPBoolean searchBeforeDisplay, + PGPKeyDBRef *foundKeys, + PGPOptionListRef firstOption, ...); + +/* Key server search dialog options */ + +PGPOptionListRef PGPOUIKeyServerSearchFilter(PGPContextRef context, + PGPFilterRef filter); + +PGPOptionListRef PGPOUIKeyServerSearchKey(PGPContextRef context, + PGPKeyDBObjRef searchKeyObject); + +PGPOptionListRef PGPOUIKeyServerSearchKeySet(PGPContextRef context, + PGPKeySetRef keySet); + +PGPOptionListRef PGPOUIKeyServerSearchKeyIDList(PGPContextRef context, + PGPUInt32 keyIDCount, const PGPKeyID keyIDList[] ); + +/* +** These options are used to build the options dialog and are only +** applicable for the PGPOptionsDialog() and PGPOUIDialogOptions() calls. +** The "description" parameters are optional. +*/ +#undef PGPOUICheckbox +PGPOptionListRef PGPOUICheckbox(PGPContextRef context, PGPUInt32 itemID, + const PGPChar8 *title, const PGPChar8 *description, + PGPUInt32 initialValue, PGPUInt32 *resultPtr, + PGPOptionListRef firstOption, ...); +#undef PGPOUIPopupList +PGPOptionListRef PGPOUIPopupList(PGPContextRef context, PGPUInt32 itemID, + const PGPChar8 *title, const PGPChar8 *description, + PGPUInt32 listItemCount, const PGPChar8 *listItems[], + PGPUInt32 initialValue, PGPUInt32 *resultPtr, + PGPOptionListRef firstOption, ...); + +#if PGP_DEPRECATED + +#include "pgpGroups.h" + +PGPOptionListRef PGPOUIRecipientGroups(PGPContextRef context, + PGPGroupSetRef groupSet); +#endif + +PGP_END_C_DECLARATIONS + +#endif /* ] Included_pgpUserInterface_h */ + + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk8/include/pgpUtilities.h b/CryptoPP/PGPw/sdk8/include/pgpUtilities.h new file mode 100644 index 0000000..dc1ca20 --- /dev/null +++ b/CryptoPP/PGPw/sdk8/include/pgpUtilities.h @@ -0,0 +1,464 @@ +/*____________________________________________________________________________ + Copyright (C) 2002 PGP Corporation + All rights reserved. + + This file contains miscellaneous utility functions needed for the PGPsdk. + + $Id: pgpUtilities.h,v 1.54.2.1 2004/05/05 17:02:51 vinnie Exp $ +____________________________________________________________________________*/ + +#ifndef Included_pgpUtilities_h /* [ */ +#define Included_pgpUtilities_h + +#include +#include "pgpBase.h" +#include "pflTypes.h" +#include "pgpPubTypes.h" +#include "pgpMemoryMgr.h" + +#if PGP_MACINTOSH /* [ */ +#include +#elif PGP_OSX + struct FSSpec; +#endif /* ] PGP_MACINTOSH */ + +#if PGP_MACINTOSH +#pragma options align=mac68k /* [ */ +#endif + +enum +{ + kPGPsdk20APIVersion = 0x01000000, + + kPGPsdkAPIVersion = kPGPsdk20APIVersion +}; + +enum PGPNotificationReason_ +{ + kPGPNotification_KeyDBChanged = 0, + kPGPNotification_PassphraseCacheChanged = 1, + + PGP_ENUM_FORCE( PGPNotificationReason_ ) +}; + +PGPENUM_TYPEDEF( PGPNotificationReason_, PGPNotificationReason ); + +typedef PFLLanguage PGPLanguage; + +enum PGPLanguage_ +{ + kPGPLanguage_Default = 0, + kPGPLanguage_English = 1, + kPGPLanguage_Japanese = 2, + kPGPLanguage_German = 3, + kPGPLanguage_Spanish = 4, + + PGP_ENUM_FORCE( PGPLanguage_ ) +}; + +#if PGP_MACINTOSH || PGP_OSX /* [ */ + +#define kPGPMacFileCreator_PGPkeys 'pgpK' +#define kPGPMacFileCreator_PGPtools 'pgpM' +#define kPGPMacFileCreator_PGPnet 'PGPn' +#define kPGPMacFileCreator_PGPdisk 'pgpD' +#define kPGPMacFileCreator_PGPadmin 'PGPa' +#define kPGPMacFileCreator_DecryptedBinary '\?\?\?\?' +#define kPGPMacFileCreator_DecryptedText 'ttxt' + +#define kPGPMacFileType_ArmorFile 'TEXT' +#define kPGPMacFileType_EncryptedData 'pgEF' +#define kPGPMacFileType_SignedData 'pgSF' +#define kPGPMacFileType_DetachedSig 'pgDS' +#define kPGPMacFileType_RandomSeed 'pgRS' +#define kPGPMacFileType_PrivRing 'pgRR' +#define kPGPMacFileType_PubRing 'pgPR' +#define kPGPMacFileType_Groups 'pgGR' +#define kPGPMacFileType_NetHosts 'pgHO' +#define kPGPMacFileType_NetRules 'pgRU' +#define kPGPMacFileType_Preferences 'pref' +#define kPGPMacFileType_DecryptedText 'TEXT' +#define kPGPMacFileType_DecryptedBinary 'BINA' +#define kPGPMacFileType_KeyShares 'pgSK' +#define kPGPMacFileType_Exported509Keys 'pgX5' + +#endif /* ] PGP_MACINTOSH */ + +PGP_BEGIN_C_DECLARATIONS + +/*____________________________________________________________________________ + PGPsdk initialization + + Call PGPsdkXXXInit() before using that particular library. + Call PGPsdkXXXCleanup() when you are done (but after disposing of any + PGPContexts). + + You may call PGPsdkXXXInit multiple times (with no effect), but be sure + to call the matching PGPsdkXXXCleanup() for each call to PGPsdkXXXInit(). +____________________________________________________________________________*/ +#define kPGPFlags_ForceLocalExecution 0x2 +#define kPGPFlags_SuppressCacheThread 0x4 + +PGPError PGPsdkInit( PGPFlags options ) ; +PGPError PGPsdkSetLanguage( PGPFileSpecRef langStringsHome, PGPLanguage lang ); +PGPError PGPsdkCleanup( void ); + +PGPError PGPsdkNetworkLibInit( PGPFlags options ); +PGPError PGPsdkNetworkLibCleanup( void ); + +PGPError PGPsdkUILibInit( PGPFlags options ); +PGPError PGPsdkUILibCleanup( void ); + +PGPError PGPLoadPluginModule( PGPContextRef context, + PGPFileSpecRef moduleFile, PGPFileSpecRef sigFile, + PGPUInt32 *nCipher, PGPUInt32 *nHash, PGPUInt32 *nPubkey ); + + +/*____________________________________________________________________________ + PGPsdk version information + + A version in the PGPsdk is expressed as follows: + + Major version (1 byte) + Minor version (1 byte) + Bug fix revision (1 byte) + Reserved (1 byte) + + example: 1.7.1 = 0x01070100 +____________________________________________________________________________*/ + +PGPUInt32 PGPGetPGPsdkVersion( void ); + +/*____________________________________________________________________________ + PGPsdk version string + + Return a C string of the form: + + "PGPsdk 3.0 Copyright (C) 2003 PGP Corporation +____________________________________________________________________________*/ + +#undef PGPGetPGPsdkVersionString +PGPError PGPGetPGPsdkVersionString( PGPChar8 versionString[ 256 ] ); + +/*____________________________________________________________________________ + PGPsdk API version information + + The API version of the PGPsdk is distinct from the externally visible + version number. The API version is revised only when API changes are made, + while the external version is changed whenever any code is changed, API or + otherwise. The format of the API version is identical to the format of the + external version. A change in the major API version implies incompatability + with previous API versions while a change in the minor version implies API + additions which maintain backwards compatability. +_____________________________________________________________________________*/ + +PGPUInt32 PGPGetPGPsdkAPIVersion( void ); + +/*____________________________________________________________________________ + PGPsdk context manipulation +_____________________________________________________________________________*/ + +typedef struct PGPCustomContextInfo +{ + PGPUInt32 sdkAPIVersion; /* Use kPGPsdkAPIVersion */ + PGPMemoryMgrRef memoryMgr; + PGPUserValue userValue; + +} PGPCustomContextInfo; + + +PGPError PGPNewContext( PGPUInt32 sdkAPIVersion, PGPContextRef *newContext ); +PGPError PGPNewContextCustom( const PGPCustomContextInfo *contextInfo, + PGPContextRef *newContext ); + +PGPError PGPFreeContext( PGPContextRef context ); + +PGPError PGPGetContextUserValue( PGPContextRef context, + PGPUserValue *userValue ); +PGPError PGPSetContextUserValue( PGPContextRef context, + PGPUserValue userValue ); + +PGPError PGPContextGetRandomBytes(PGPContextRef context, + void *buf, PGPSize len ); + +PGPUInt32 PGPContextReserveRandomBytes(PGPContextRef context, + PGPUInt32 minSize ); + +PGPMemoryMgrRef PGPPeekContextMemoryMgr( PGPContextRef context ); + +/*____________________________________________________________________________ + PGP file management + + All files in PGP are represented using an opage data type PGPFileSpecRef. + These data types are created using a fully qualified path or, on the + Macintosh, an FSSpec. The +____________________________________________________________________________*/ + +#if PGP_MACINTOSH || PGP_OSX /* [ */ + +PGPError PGPNewFileSpecFromFSSpec( PGPContextRef context, const struct FSSpec *spec, + PGPFileSpecRef *ref ); +PGPError PGPGetFSSpecFromFileSpec( PGPFileSpecRef fileRef, struct FSSpec *spec ); + +#endif + +#if ! PGP_MACINTOSH + +#undef PGPNewFileSpecFromFullPath +PGPError PGPNewFileSpecFromFullPath( PGPContextRef context, + const PGPChar8 *path, PGPFileSpecRef *ref ); +/* +** The full path is an allocated object which needs to be deallocated with +** PGPFreeData() +*/ + +#undef PGPGetFullPathFromFileSpec +PGPError PGPGetFullPathFromFileSpec( PGPFileSpecRef fileRef, + PGPChar8 **fullPathPtr); + +#endif + +PGPError PGPCopyFileSpec( PGPFileSpecRef fileRef, PGPFileSpecRef *ref ); +PGPError PGPFreeFileSpec( PGPFileSpecRef fileRef ); + +#undef PGPRenameFile +PGPError PGPRenameFile( PGPFileSpecRef fileRef, const PGPChar8 *newName ); +PGPError PGPDeleteFile( PGPFileSpecRef fileRef ); + +/*____________________________________________________________________________ + PGP time/date functions +____________________________________________________________________________*/ + +PGPTime PGPGetTime(void); + +/* these use time_t type as returned by time() in Std C libraries */ +time_t PGPGetStdTimeFromPGPTime( PGPTime theTime ); +PGPTime PGPGetPGPTimeFromStdTime( time_t theTime ); + +/* year, month, day may be NULL if desired */ +void PGPGetYMDFromPGPTime( PGPTime theTime, PGPUInt16 *year, + PGPUInt16 *month, PGPUInt16 *day ); + +#if PGP_MACINTOSH || PGP_OSX /* [ */ + +PGPUInt32 PGPTimeToMacTime( PGPTime theTime ); +PGPTime PGPTimeFromMacTime( PGPUInt32 theTime ); + +#endif /* ] PGP_MACINTOSH */ + +/*____________________________________________________________________________ + MacBinary support + + Examine the input file to see if it's a MacBinary file. If it is + not a MacBinary file, then the original file is unaltered. + Otherwise, the file is converted and the original file is deleted. + + The resulting file is designated by 'outPGPSpec' and may have a different + name than the original. + + If the file is a TEXT file, appropriate line-end conversion is done. + + creator and type code pointers may be + null but otherwise contain the mac creator and type. + + This routine can be called on a Mac, but generally doesn't need to be. +____________________________________________________________________________*/ + +PGPError PGPMacBinaryToLocal( PGPFileSpecRef inSpec, + PGPFileSpecRef * outSpec, PGPUInt32 * macCreator, + PGPUInt32 * macTypeCode ); + +/*____________________________________________________________________________ + Notification callbacks on PGPKeyDB changes from SDK Service +_____________________________________________________________________________*/ + +typedef void (*PGPNotificationHandlerProc)( PGPUserValue userValue, + PGPNotificationReason reason, + PGPUInt32 param1, + PGPUInt32 param2 ); + +PGPError PGPSetNotificationCallback( PGPNotificationHandlerProc proc, + PGPUserValue userValue ); + +/*____________________________________________________________________________ +Disk and File Wipe Pattern Support +____________________________________________________________________________*/ + +PGPError PGPNewWipePatternContext ( PGPContextRef context, + PGPInt32 numPasses, + PGPWipePatternContextRef *outRef); + +/* fill a 1024 byte, long word alligned buffer with a pattern to wipe with */ +PGPError PGPWipePatternNext( PGPWipePatternContextRef ref, + void * buffer, PGPSize bufferSize); + +PGPError PGPWipePatternRewind( PGPWipePatternContextRef wipeRef); + +PGPError PGPFreeWipePatternContext(PGPWipePatternContextRef ref); + +PGPError PGPWipeFile( PGPContextRef context, + PGPInt32 numPasses, + PGPOptionListRef firstOption, + ...); + +/*____________________________________________________________________________ + PGP TAR/UnTAR functions that work with TAR cache +____________________________________________________________________________*/ + +enum PGPTARCacheObjAttributeType_ +{ + kPGPTARCacheObjAttribute_Invalid = 0, + kPGPTARCacheObjAttribute_File = 1, + kPGPTARCacheObjAttribute_SymLink = 2, + kPGPTARCacheObjAttribute_Directory = 3, + kPGPTARCacheObjAttribute_Deleted = 4, + + PGP_ENUM_FORCE( PGPTARCacheObjAttributeType_ ) +} ; + +PGPENUM_TYPEDEF( PGPTARCacheObjAttributeType_, PGPTARCacheObjAttributeType ); + +enum PGPTARCacheObjProperty_ +{ + kPGPTARCacheObjProperty_Invalid = 0, + + /* string properties */ + kPGPTARCacheObjProperty_Name = 100, + kPGPTARCacheObjProperty_User = 101, + kPGPTARCacheObjProperty_Group = 102, + kPGPTARCacheObjProperty_Contents = 103, + kPGPTARCacheObjProperty_Link = 104, + kPGPTARCacheObjProperty_Size = 105, /* PGPUInt64 */ + kPGPTARCacheObjProperty_FilePos = 106, /* PGPFileOffset */ + + /* PGPTime properties */ + kPGPTARCacheObjProperty_Date = 200, + + /* Numeric properties */ + kPGPTARCacheObjProperty_Mode = 302, + kPGPTARCacheObjProperty_Attribute = 303, + + PGP_ENUM_FORCE( PGPTARCacheObjProperty_ ) +} ; + +PGPENUM_TYPEDEF( PGPTARCacheObjProperty_, PGPTARCacheObjProperty ); +enum PGPOpenTARCacheFileOptions_ +{ + kPGPOpenTARCacheFileOptions_None = 0, + kPGPOpenTARCacheFileOptions_Mutable = (1UL << 0 ), + kPGPOpenTARCacheFileOptions_Create = (1UL << 1 ), + kPGPOpenTARCacheFileOptions_PreloadAll = (1UL << 2 ), + + PGP_ENUM_FORCE( PGPOpenTARCacheFileOptions_ ) +} ; + +PGPENUM_TYPEDEF( PGPOpenTARCacheFileOptions_, PGPOpenTARCacheFileOptions ); + + +PGPError PGPOpenTARCacheFile( PGPContextRef context, + PGPOpenTARCacheFileOptions options, + PGPFileSpecRef tarcache, + void *sessionKey, + PGPSize sessionKeyBufferSize, + PGPSize *sessionKeySize, /* can be NULL if not kPGPOpenTARCacheFileOptions_Create */ + PGPTARCacheRef *outRef, + PGPOptionListRef firstOption, + ...); + +PGPError PGPFreeTARCache(PGPTARCacheRef ref); + +PGPError PGPNewTARCacheIter( PGPTARCacheRef tar, PGPTARCacheIterRef *outRef); + +PGPError PGPFreeTARCacheIter( PGPTARCacheIterRef iter); + +PGPInt32 PGPTARCacheIterIndex( PGPTARCacheIterRef iter); + +PGPError PGPTARCacheIterRewind( PGPTARCacheIterRef iter); + +PGPError PGPTARCacheIterMove( PGPTARCacheIterRef iter, PGPInt32 relOffset, PGPTARCacheObjRef *outRef); + +PGPError PGPTARCacheIterNextTARCacheObj( PGPTARCacheIterRef iter, PGPTARCacheObjRef *outRef); + +PGPError PGPTARCacheIterPrevTARCacheObj( PGPTARCacheIterRef iter, PGPTARCacheObjRef *outRef); + +PGPError PGPTARCacheIterGetTARCacheObj( PGPTARCacheIterRef iter, PGPTARCacheObjRef *outRef); + +PGPError PGPGetTARCacheObjNumericProperty( PGPTARCacheObjRef obj, + PGPTARCacheObjProperty whichProperty, PGPInt32 *prop ); + +PGPError PGPGetTARCacheObjTimeProperty( PGPTARCacheObjRef obj, + PGPTARCacheObjProperty whichProperty, PGPTime *prop); + + PGPError PGPGetTARCacheObjDataProperty( PGPTARCacheObjRef obj, + PGPTARCacheObjProperty whichProperty, void *buffer, + PGPSize bufferSize, PGPSize *dataSize); + +PGPError PGPGetTARCacheObjAllocatedDataProperty( PGPTARCacheObjRef obj, + PGPTARCacheObjProperty whichProperty, void **buffer, + PGPSize *dataSize); + + +PGPError PGPDeleteTARCacheObj( PGPTARCacheObjRef tarObj ); + +PGPError PGPExportTARCacheObj( PGPTARCacheObjRef tarObj, + PGPFileSpecRef fileRef, + PGPOptionListRef firstOption, + ...); + + +PGPError PGPCountObjsInTARCache( PGPTARCacheRef ref, PGPUInt32 *numItems ); + +PGPError PGPImportTARCacheObj( PGPTARCacheRef tarCache, + PGPFileSpecRef fileRef, + PGPTARCacheObjRef *outRef, + PGPOptionListRef firstOption, + ...); + +/*____________________________________________________________________________ +FIPS 140-2 Support +____________________________________________________________________________*/ + +enum PGPsdkSelfTest_ +{ + kPGPsdkSelfTest_Invalid = 0, + kPGPsdkSelfTest_FirstTest = 1, + + kPGPsdkSelfTest_3DES = 1, + kPGPsdkSelfTest_DSA = 2, + kPGPsdkSelfTest_AES = 3, + kPGPsdkSelfTest_RSA = 4, + kPGPsdkSelfTest_SHA = 5, + kPGPsdkSelfTest_HMAC = 6, + kPGPsdkSelfTest_EC = 7, + kPGPsdkSelfTest_PRNG = 8, + kPGPsdkSelfTest_Integrity = 9, + + kPGPsdkSelfTest_LastTest = kPGPsdkSelfTest_Integrity, + + PGP_ENUM_FORCE( PGPsdkSelfTest_ ) +}; + +PGPENUM_TYPEDEF( PGPsdkSelfTest_, PGPsdkSelfTest ); + +PGPError PGPEnableFIPSMode(void); +PGPError PGPGetSDKErrorState(void); +PGPError PGPResetSDKErrorState(void); +PGPError PGPRunSDKSelfTest(PGPsdkSelfTest whichTest); +PGPError PGPRunAllSDKSelfTests(void); + +PGP_END_C_DECLARATIONS + +#if PGP_MACINTOSH +#pragma options align=reset /* ] */ +#endif + +#endif /* ] Included_pgpUtilities_h */ + +/*__Editor_settings____ + + Local Variables: + tab-width: 4 + End: + vi: ts=4 sw=4 + vim: si +_____________________*/ diff --git a/CryptoPP/PGPw/sdk8/lib/PGPsdk.lib b/CryptoPP/PGPw/sdk8/lib/PGPsdk.lib new file mode 100644 index 0000000..c0950de Binary files /dev/null and b/CryptoPP/PGPw/sdk8/lib/PGPsdk.lib differ diff --git a/CryptoPP/PGPw/sdk8/lib/PGPsdkNL.lib b/CryptoPP/PGPw/sdk8/lib/PGPsdkNL.lib new file mode 100644 index 0000000..09b4a34 Binary files /dev/null and b/CryptoPP/PGPw/sdk8/lib/PGPsdkNL.lib differ diff --git a/CryptoPP/PGPw/sdk8/lib/PGPsdkUI.lib b/CryptoPP/PGPw/sdk8/lib/PGPsdkUI.lib new file mode 100644 index 0000000..9a9ae7f Binary files /dev/null and b/CryptoPP/PGPw/sdk8/lib/PGPsdkUI.lib differ diff --git a/CryptoPP/base16.cpp b/CryptoPP/base16.cpp new file mode 100644 index 0000000..b8c813e --- /dev/null +++ b/CryptoPP/base16.cpp @@ -0,0 +1,64 @@ +#include "commonheaders.h" + + +char *base16encode(const char *inBuffer, int count) { + + char *outBuffer = (char *) malloc(count*2+1); + char *outBufferPtr = outBuffer; + BYTE *inBufferPtr = (BYTE *) inBuffer; + + while(count){ + *outBufferPtr++ = encode16(((*inBufferPtr)>>4)&0x0F); + *outBufferPtr++ = encode16((*inBufferPtr++)&0x0F); + count--; + } + *outBufferPtr = '\0'; + + return outBuffer; +} + + +char *base16decode(const char *inBuffer, int *count) { + + char *outBuffer = (char *) malloc(*count); + BYTE *outBufferPtr = (BYTE *) outBuffer; + bool big_endian = false; + + if(*inBuffer == '0' && *(inBuffer+1) == 'x') { + inBuffer += *count; + big_endian = true; + *count -= 2; + } + while(*count>1){ + BYTE c0,c1; + if(big_endian) { + c1 = decode16(*--inBuffer); + c0 = decode16(*--inBuffer); + } + else { + c0 = decode16(*inBuffer++); + c1 = decode16(*inBuffer++); + } + if((c0 | c1) == BERR) { + free(outBuffer); + *count = 0; + return(NULL); + } + *outBufferPtr++ = (c0<<4) | c1; + *count -= 2; + } + *outBufferPtr = '\0'; + *count = (int)(outBufferPtr-(BYTE *)outBuffer); + + return outBuffer; +} + + +char *base16decode(const char *inBuffer) { + + int count = (int)strlen(inBuffer); + return base16decode(inBuffer, &count); +} + + +// EOF diff --git a/CryptoPP/base16.h b/CryptoPP/base16.h new file mode 100644 index 0000000..f5f368e --- /dev/null +++ b/CryptoPP/base16.h @@ -0,0 +1,53 @@ +#ifndef __BASE_16__ +#define __BASE_16__ + +#define BERR 0xFF /* Illegal char marker */ +#define BEOF 0x7F /* EOF marker (padding char or EOL) */ + +typedef unsigned char byte; + +static const byte asciiToBin16[] = + { BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BEOF, BERR, BERR, BEOF, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, BERR, BERR, BERR, BEOF, BERR, BERR, + BERR, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR + }; + +static const byte binToAscii16[] = "0123456789ABCDEF"; + +char *base16encode(const char *, const int); +char *base16decode(const char *, int *); +char *base16decode(const char *); + +#define encode16(data) binToAscii16[data] +#define decode16(data) asciiToBin16[data] + +#endif diff --git a/CryptoPP/base64.cpp b/CryptoPP/base64.cpp new file mode 100644 index 0000000..f639799 --- /dev/null +++ b/CryptoPP/base64.cpp @@ -0,0 +1,96 @@ +#include "commonheaders.h" + + +string base64encode(const string buf) { + string out; + char *base64 = base64encode(buf.data(), buf.length()); + out.assign(base64); + free(base64); + return out; +} + + +char *base64encode(const char *inBuffer, const int count) { + + int srcIndex = 0, destIndex = 0, remainder = count % 3; + char *outBuffer = (char *) malloc(count*2+1); + BYTE *inBufferPtr = (BYTE *) inBuffer; + + while(srcIndex < count) { + outBuffer[destIndex++] = encode64(inBufferPtr[srcIndex] >> 2); + outBuffer[destIndex++] = encode64(((inBufferPtr[srcIndex] << 4) & 0x30) | ((inBufferPtr[srcIndex + 1] >> 4) & 0x0F)); + srcIndex++; + outBuffer[destIndex++] = encode64(((inBufferPtr[srcIndex] << 2) & 0x3C) | ((inBufferPtr[srcIndex + 1] >> 6) & 0x03)); + srcIndex++; + outBuffer[destIndex++] = encode64(inBufferPtr[srcIndex++] & 0x3F); + } + + if(remainder == 2) { + outBuffer[destIndex - 1] = BPAD; + outBuffer[destIndex - 2] = encode64((inBufferPtr[srcIndex - 2] << 2) & 0x3C); + } + else if(remainder == 1) { + outBuffer[destIndex - 2] = outBuffer[destIndex - 1] = BPAD; + outBuffer[destIndex - 3] = encode64((inBufferPtr[srcIndex - 3] << 4) & 0x30); + } + destIndex -= (3 - remainder) % 3; + outBuffer[destIndex] = '\0'; + + return outBuffer; +} + + +string base64decode(const string buf) { + string out; + int len = buf.length(); + char *plain = base64decode(buf.data(), &len); + out.assign(plain,len); + free(plain); + return out; +} + + +string base64decode(const char *buf) { + string out; + int len = strlen(buf); + char *plain = base64decode(buf, &len); + out.assign(plain,len); + free(plain); + return out; +} + + +char *base64decode(const char *inBuffer, int *count) { + + int srcIndex = 0, destIndex = 0; + char *outBuffer = (char *) malloc(*count); + + while(srcIndex < *count) { + BYTE c0, c1, c2 = 0, c3 = 0; + const int delta = *count - srcIndex; + c0 = decode64(inBuffer[srcIndex++]); + c1 = decode64(inBuffer[srcIndex++]); + if(delta > 2) { + c2 = decode64(inBuffer[srcIndex++]); + if(delta > 3) + c3 = decode64(inBuffer[srcIndex++]); + } + if((c0 | c1 | c2 | c3) == BERR) { + free(outBuffer); + return(NULL); + } + outBuffer[destIndex++] = (c0 << 2) | (c1 >> 4); + if(delta > 2) { + outBuffer[destIndex++] = (c1 << 4) | (c2 >> 2); + if(delta > 3 ) + outBuffer[destIndex++] = (c2 << 6) | (c3); + } + } + outBuffer[destIndex] = '\0'; + *count = destIndex; + + return outBuffer; +} + + +// EOF diff --git a/CryptoPP/base64.h b/CryptoPP/base64.h new file mode 100644 index 0000000..b075627 --- /dev/null +++ b/CryptoPP/base64.h @@ -0,0 +1,58 @@ +#ifndef __BASE_64__ +#define __BASE_64__ + +#define BPAD '=' /* Padding for odd-sized output */ +#define BERR 0xFF /* Illegal char marker */ +#define BEOF 0x7F /* EOF marker (padding char or EOL) */ + +typedef unsigned char byte; + +static const byte asciiToBin64[] = + { BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BEOF, BERR, BERR, BEOF, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BERR, 0x3E, BERR, BERR, BERR, 0x3F, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, + 0x3C, 0x3D, BERR, BERR, BERR, BEOF, BERR, BERR, + BERR, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, + 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, + 0x17, 0x18, 0x19, BERR, BERR, BERR, BERR, BERR, + BERR, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, + 0x31, 0x32, 0x33, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR, + BERR, BERR, BERR, BERR, BERR, BERR, BERR, BERR + }; + +static const byte binToAscii64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +char *base64encode(const char *, const int); +char *base64decode(const char *, int *); + +string base64encode(const string); +string base64decode(const string); + +string base64decode(const char *); + +#define encode64(data) binToAscii64[data] +#define decode64(data) asciiToBin64[data] + +#endif diff --git a/CryptoPP/commonheaders.cpp b/CryptoPP/commonheaders.cpp new file mode 100644 index 0000000..4ba0c99 --- /dev/null +++ b/CryptoPP/commonheaders.cpp @@ -0,0 +1,125 @@ +#include "commonheaders.h" + +LPCSTR szModuleName = MODULENAME; +LPCSTR szVersionStr = MODULENAME" DLL ("__VERSION_STRING")"; +HINSTANCE g_hInst; +PLUGINLINK *pluginLink; +MM_INTERFACE mmi={0}; +MUUID interfaces[] = {MIID_CRYPTOPP, MIID_LAST}; + +HANDLE hPGPPRIV = NULL; +HANDLE hRSA4096 = NULL; + +CRITICAL_SECTION localQueueMutex; +CRITICAL_SECTION localContextMutex; + +char TEMP[MAX_PATH]; +int TEMP_SIZE = 0; +BOOL isVista = 0; + +PLUGININFO pluginInfo = { + sizeof(PLUGININFO), + MODULENAME, + __VERSION_DWORD, + MODULENAME" library for SecureIM plugin ("__DATE__")", + "Baloo", + "baloo@bk.ru", + "© 2006-09 Baloo", + "http://miranda-im.org/download/details.php?action=viewfile&id=2669", + 0, 0 +}; + +PLUGININFOEX pluginInfoEx = { + sizeof(PLUGININFOEX), + MODULENAME, + __VERSION_DWORD, + MODULENAME" library for SecureIM plugin ("__DATE__")", + "Baloo", + "baloo@bk.ru", + "© 2006-09 Baloo", + "http://miranda-im.org/download/details.php?action=viewfile&id=2669", + 0, 0, + MIID_CRYPTOPP +}; + + +BOOL ExtractFileFromResource( HANDLE FH, int ResType, int ResId, DWORD* Size ) +{ + HRSRC RH; + PBYTE RP; + DWORD s,x; + + RH = FindResource( g_hInst, MAKEINTRESOURCE( ResId ), MAKEINTRESOURCE( ResType ) ); + + if( RH == NULL ) return FALSE; + RP = (PBYTE) LoadResource( g_hInst, RH ); + if( RP == NULL ) return FALSE; + s = SizeofResource( g_hInst, RH ); + if( !WriteFile( FH, RP, s, &x, NULL ) ) return FALSE; + if( x != s ) return FALSE; + if( Size ) *Size = s; + return TRUE; +} + + +void ExtractFile( char *FileName, int ResType, int ResId ) +{ + HANDLE FH; + FH = CreateFile( FileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL ); + if( FH == INVALID_HANDLE_VALUE ) return; + if (!ExtractFileFromResource( FH, ResType, ResId, NULL )) MessageBoxA(0,"Can't extract","!!!",MB_OK); + CloseHandle( FH ); +} + + +int rtrim(LPCSTR str) { + int len = strlen(str); + LPSTR ptr = (LPSTR)str+len-1; + + while( len ) { + char c = *ptr; + if( c != '\x20' && c != '\x09' && c != '\x0A' && c != '\x0D' ) { + *(ptr+1) = '\0'; + break; + } + len--; ptr--; + } + return len; +} + + +#if defined(_DEBUG) || defined(NETLIB_LOG) +HANDLE hNetlibUser; + +void InitNetlib() { + NETLIBUSER nl_user; + memset(&nl_user,0,sizeof(nl_user)); + nl_user.cbSize = sizeof(nl_user); + nl_user.szSettingsModule = (LPSTR)szModuleName; + nl_user.szDescriptiveName = (LPSTR)szModuleName; + nl_user.flags = NUF_NOOPTIONS; + + hNetlibUser = (HANDLE)CallService(MS_NETLIB_REGISTERUSER, 0, (LPARAM)&nl_user); +} + +void DeinitNetlib() { + if(hNetlibUser) + CallService(MS_NETLIB_CLOSEHANDLE, (WPARAM)hNetlibUser, 0); +} + +int Sent_NetLog(const char *fmt,...) +{ + va_list va; + char szText[1024]; + + va_start(va,fmt); + mir_vsnprintf(szText,sizeof(szText),fmt,va); + va_end(va); + if(hNetlibUser) + return CallService(MS_NETLIB_LOG,(WPARAM)hNetlibUser,(LPARAM)szText); + return 0; +} +#endif + + +// EOF diff --git a/CryptoPP/commonheaders.h b/CryptoPP/commonheaders.h new file mode 100644 index 0000000..c0d6954 --- /dev/null +++ b/CryptoPP/commonheaders.h @@ -0,0 +1,200 @@ +// Windows API + +#define WIN32_LEAN_AND_MEAN +#define NETLIB_LOG + +#ifdef _MSC_VER +#pragma once +#define _CRT_SECURE_NO_WARNINGS +#define _SCL_SECURE_NO_WARNINGS +#if _MSC_VER >= 1300 +//#pragma comment (compiler,"/GS-") +//#pragma comment (linker,"/NODEFAULTLIB:libcmt.lib") +//#pragma comment (lib,"../../lib/msvcrt.lib") +//#pragma comment (lib,"../../lib/msvcrt71.lib") +#else +#ifndef _DEBUG +#pragma optimize("gsy", on) +#endif +#endif +#endif + +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x0501 +#endif + +#ifndef _WIN32_IE +#define _WIN32_IE 0x0501 +#endif + +#define MIRANDA_VER 0x0700 +#include + +#if _MSC_VER > 1000 +#include +#else +#include +#endif +#include +#include +#include +#include +#include + +//#pragma comment(linker,"/filealign:16") +//#pragma comment(linker,"/align:16") +//#pragma optimize("gsy", on) +#ifdef _DEBUG +#if _MSC_VER >= 1300 +#pragma comment(lib,"crypto/Debug9/cryptlib.lib") +#else +#pragma comment(lib,"crypto/Debug/cryptlib.lib") +#endif +#else +#if _MSC_VER >= 1300 +#pragma comment(lib,"crypto/Release9/cryptlib.lib") +#else +#pragma comment(lib,"crypto/Release/cryptlib.lib") +#endif +#endif +#pragma comment(lib,"kernel32.lib") +#pragma comment(lib,"user32.lib") + +#ifndef M_API_H__ +#define M_API_H__ + +// Miranda API +#include "newpluginapi.h" +#include "m_stdhdr.h" +#include "m_plugins.h" +#include "m_system.h" +#include "m_database.h" +#include "m_protomod.h" +#include "m_protosvc.h" +#include "m_utils.h" +#include "m_netlib.h" +#include "sdk/m_updater.h" + +#endif + +#include "cryptopp.h" +#include "version.h" +#include "resource.h" +#include "dllloader.h" +#include "mmi.h" +#include "utf8.h" +#include "base16.h" +#include "base64.h" +#include "gettime.h" +#include "cpp_rsam.h" +#include "cpp_rsau.h" + +#define MODULENAME "Crypto++" + +extern LPCSTR szModuleName; +extern LPCSTR szVersionStr; +extern char TEMP[MAX_PATH]; +extern int TEMP_SIZE; +extern BOOL isVista; + +// shared vars +extern HINSTANCE g_hInst; +extern PLUGINLINK *pluginLink; +extern PLUGININFO pluginInfo; +extern PLUGININFOEX pluginInfoEx; +//extern MM_INTERFACE mmi; +extern MUUID interfaces[]; + +extern HANDLE hPGPPRIV; +extern HANDLE hRSA4096; + +extern CRITICAL_SECTION localQueueMutex; +extern CRITICAL_SECTION localContextMutex; + +void ExtractFile(char*,int,int); +int rtrim(LPCSTR); + +#if defined(_DEBUG) || defined(NETLIB_LOG) +extern HANDLE hNetlibUser; +void InitNetlib(); +void DeinitNetlib(); +int Sent_NetLog(const char *,...); +#endif + +#define MIID_CRYPTOPP {0x3613F2D9, 0xC040, 0x4361, { 0xA4, 0x4F, 0xDF, 0x7B, 0x5A, 0xAA, 0xCF, 0x6E }} //3613F2D9-C040-4361-A44F-DF7B5AAACF6E + +#define DLLEXPORT __declspec(dllexport) + +PBYTE cpp_alloc_pdata(pCNTX); + +extern "C" { + + DLLEXPORT int Load(PLUGINLINK *); + DLLEXPORT PLUGININFO *MirandaPluginInfo(DWORD); + DLLEXPORT PLUGININFOEX *MirandaPluginInfoEx(DWORD); + DLLEXPORT MUUID* MirandaPluginInterfaces(void); + DLLEXPORT int Unload(); + + DLLEXPORT HANDLE __cdecl cpp_create_context(int); // create crypt-context + DLLEXPORT void __cdecl cpp_delete_context(HANDLE); // delete crypt-context + DLLEXPORT void __cdecl cpp_reset_context(HANDLE); // reset crypt-context (free all data) + DLLEXPORT LPSTR __cdecl cpp_init_keya(HANDLE,int); // make KeyA + DLLEXPORT int __cdecl cpp_init_keyb(HANDLE,LPCSTR); // load KeyB + DLLEXPORT int __cdecl cpp_calc_keyx(HANDLE); // calculate KeyX + DLLEXPORT int __cdecl cpp_init_keyp(HANDLE,LPCSTR); // make KeyP from password + DLLEXPORT LPSTR __cdecl cpp_encodeA(HANDLE,LPCSTR); // encode ANSIz string + DLLEXPORT LPSTR __cdecl cpp_encodeW(HANDLE,LPWSTR); // encode USC2z string + DLLEXPORT LPSTR __cdecl cpp_encodeU(HANDLE,LPCSTR); // encode UTF8z string + DLLEXPORT LPSTR __cdecl cpp_decode(HANDLE,LPCSTR); // decode as ANSIzUCS2z + DLLEXPORT LPSTR __cdecl cpp_decodeU(HANDLE,LPCSTR); // decode as UTF8z + DLLEXPORT int __cdecl cpp_encrypt_file(HANDLE,LPCSTR,LPCSTR); // encrypt file + DLLEXPORT int __cdecl cpp_decrypt_file(HANDLE,LPCSTR,LPCSTR); // decrypt file + DLLEXPORT int __cdecl cpp_get_features(HANDLE); // get features field from client + DLLEXPORT int __cdecl cpp_get_error(HANDLE); // get last error code + DLLEXPORT int __cdecl cpp_get_version(void); // get dll version + DLLEXPORT int __cdecl cpp_size_keyx(void); + DLLEXPORT void __cdecl cpp_get_keyx(HANDLE,byte*); // get crypto key + DLLEXPORT void __cdecl cpp_set_keyx(HANDLE,byte*); // set crypto key + DLLEXPORT int __cdecl cpp_size_keyp(void); + DLLEXPORT void __cdecl cpp_get_keyp(HANDLE,byte*); // get pre-shared key + DLLEXPORT void __cdecl cpp_set_keyp(HANDLE,byte*); // set pre-shared key + DLLEXPORT int __cdecl cpp_keya(HANDLE); // KeyA exist ? + DLLEXPORT int __cdecl cpp_keyb(HANDLE); // KeyB exist ? + DLLEXPORT int __cdecl cpp_keyx(HANDLE); // KeyX exist ? + DLLEXPORT int __cdecl cpp_keyp(HANDLE); // KeyP exist ? + + DLLEXPORT int __cdecl pgp_init(void); + DLLEXPORT int __cdecl pgp_done(void); + DLLEXPORT int __cdecl pgp_open_keyrings(LPSTR,LPSTR); + DLLEXPORT int __cdecl pgp_close_keyrings(void); + DLLEXPORT int __cdecl pgp_get_version(void); + DLLEXPORT LPSTR __cdecl pgp_get_error(void); + DLLEXPORT int __cdecl pgp_set_priv_key(LPCSTR); + DLLEXPORT int __cdecl pgp_set_key(HANDLE,LPCSTR); + DLLEXPORT int __cdecl pgp_set_keyid(HANDLE,PVOID); + DLLEXPORT int __cdecl pgp_size_keyid(void); + DLLEXPORT PVOID __cdecl pgp_select_keyid(HWND,LPSTR); + DLLEXPORT LPSTR __cdecl pgp_encode(HANDLE,LPCSTR); + DLLEXPORT LPSTR __cdecl pgp_decode(HANDLE,LPCSTR); + + DLLEXPORT int __cdecl gpg_init(void); + DLLEXPORT int __cdecl gpg_done(void); + DLLEXPORT int __cdecl gpg_open_keyrings(LPSTR,LPSTR); + DLLEXPORT int __cdecl gpg_close_keyrings(void); + DLLEXPORT void __cdecl gpg_set_log(LPCSTR); + DLLEXPORT void __cdecl gpg_set_tmp(LPCSTR); + DLLEXPORT LPSTR __cdecl gpg_get_error(void); + DLLEXPORT int __cdecl gpg_set_key(HANDLE,LPCSTR); + DLLEXPORT int __cdecl gpg_set_keyid(HANDLE,LPCSTR); + DLLEXPORT int __cdecl gpg_size_keyid(void); + DLLEXPORT int __cdecl gpg_select_keyid(HWND,LPSTR); + DLLEXPORT LPSTR __cdecl gpg_encode(HANDLE,LPCSTR); + DLLEXPORT LPSTR __cdecl gpg_decode(HANDLE,LPCSTR); + DLLEXPORT LPSTR __cdecl gpg_get_passphrases(); + DLLEXPORT void __cdecl gpg_set_passphrases(LPCSTR); + + DLLEXPORT int __cdecl rsa_init(pRSA_EXPORT*,pRSA_IMPORT); + DLLEXPORT int __cdecl rsa_done(void); +} + +// EOF diff --git a/CryptoPP/cpp_cntx.cpp b/CryptoPP/cpp_cntx.cpp new file mode 100644 index 0000000..eba8837 --- /dev/null +++ b/CryptoPP/cpp_cntx.cpp @@ -0,0 +1,184 @@ +#include "commonheaders.h" + + +list CL; // CL.size() CL.empty() + +HANDLE thread_timeout = 0; + +unsigned __stdcall sttTimeoutThread(LPVOID); + + +// get context data on context id +pCNTX get_context_on_id(HANDLE context) { + + if( !thread_timeout ) { + unsigned int tID; + thread_timeout = (HANDLE) _beginthreadex(NULL, 0, sttTimeoutThread, NULL, 0, &tID); + } + + if( context ) { + pCNTX cntx = (pCNTX) context; + if( cntx->header == HEADER && cntx->footer == FOOTER ) + return cntx; +#if defined(_DEBUG) || defined(NETLIB_LOG) + else + Sent_NetLog("get_context_on_id: corrupted context %08X", cntx); +#endif + } + return NULL; +} + +/* +pCNTX get_context_on_id(HANDLE context) { + return get_context_on_id((int)context); +} +*/ + +// create context, return context id +HANDLE __cdecl cpp_create_context(int mode) { + + list::iterator i; + pCNTX cntx = NULL; + + EnterCriticalSection(&localContextMutex); + + if( !CL.empty() ) { + for(i=CL.begin(); i!=CL.end(); ++i) { // ищем пустой + if( (*i)->header==EMPTYH && (*i)->footer==EMPTYH ) { + cntx = (pCNTX) *i; + break; + } + } + } + + if( !cntx ) { // не нашли - создаем новый + cntx = (pCNTX) malloc(sizeof(CNTX)); + CL.push_back(cntx); // добавили в конец списка + } + + memset(cntx,0,sizeof(CNTX)); // очищаем выделенный блок + cntx->header = HEADER; + cntx->footer = FOOTER; + cntx->mode = mode; + + LeaveCriticalSection(&localContextMutex); + + return (HANDLE)cntx; +} + + +// delete context +void __cdecl cpp_delete_context(HANDLE context) { + + pCNTX tmp = get_context_on_id(context); + if(tmp) { // помечаем на удаление + tmp->deleted = gettime()+10; // будет удален через 10 секунд + } +} + + +// reset context +void __cdecl cpp_reset_context(HANDLE context) { + + pCNTX tmp = get_context_on_id(context); + if(tmp) cpp_free_keys(tmp); +} + + +// allocate pdata +PBYTE cpp_alloc_pdata(pCNTX ptr) { + if( !ptr->pdata ) { + if( ptr->mode & MODE_PGP ) { + ptr->pdata = (PBYTE) malloc(sizeof(PGPDATA)); + memset(ptr->pdata,0,sizeof(PGPDATA)); + } + else + if( ptr->mode & MODE_GPG ) { + ptr->pdata = (PBYTE) malloc(sizeof(GPGDATA)); + memset(ptr->pdata,0,sizeof(GPGDATA)); + } + else + if( ptr->mode & MODE_RSA ) { + rsa_alloc(ptr); + } + else { + ptr->pdata = (PBYTE) malloc(sizeof(SIMDATA)); + memset(ptr->pdata,0,sizeof(SIMDATA)); + } + } + return ptr->pdata; +} + + +// free memory from keys +void cpp_free_keys(pCNTX ptr) { + + SAFE_FREE(ptr->tmp); + cpp_alloc_pdata(ptr); + if( ptr->mode & MODE_PGP ) { + pPGPDATA p = (pPGPDATA) ptr->pdata; + SAFE_FREE(p->pgpKeyID); + SAFE_FREE(p->pgpKey); + SAFE_FREE(ptr->pdata); + } + else + if( ptr->mode & MODE_GPG ) { + pGPGDATA p = (pGPGDATA) ptr->pdata; + SAFE_FREE(p->gpgKeyID); + SAFE_FREE(ptr->pdata); + } + else + if( ptr->mode & MODE_RSA ) { + rsa_free(ptr); + SAFE_DELETE(ptr->pdata); + } + else { + pSIMDATA p = (pSIMDATA) ptr->pdata; + SAFE_FREE(p->PubA); + SAFE_FREE(p->KeyA); + SAFE_FREE(p->KeyB); + SAFE_FREE(p->KeyX); + SAFE_FREE(p->KeyP); + SAFE_DELETE(p->dh); + SAFE_FREE(ptr->pdata); + } +} + + +// search not established RSA/AES contexts && clear deleted contexts +unsigned __stdcall sttTimeoutThread( LPVOID ) { + + list::iterator i; + while(1) { + Sleep( 1000 ); // раз в секунду + if( CL.empty() ) continue; + u_int time = gettime(); + // пробегаем все контексты + EnterCriticalSection(&localContextMutex); + for(i=CL.begin(); i!=CL.end(); ++i) { + pCNTX tmp = *i; + if( tmp->header!=HEADER || tmp->footer!=FOOTER ) continue; + // пропускаем приватные ключи + if( tmp->mode&MODE_PRIV_KEY ) continue; + else + if( tmp->deleted && tmp->deleted < time ) { + // удалить помеченный для удаления контекст + cpp_free_keys(tmp); + tmp->deleted = 0; + tmp->header = tmp->footer = EMPTYH; + } + else + if( tmp->mode&MODE_RSA && tmp->pdata ) { + // проверяем не протухло ли соединение + pRSADATA p = (pRSADATA) tmp->pdata; + if( p->time && p->time < time ) { + rsa_timeout((HANDLE)tmp,p); + } + } + } // for + LeaveCriticalSection(&localContextMutex); + } //while +} + + +// EOF diff --git a/CryptoPP/cpp_gpgw.cpp b/CryptoPP/cpp_gpgw.cpp new file mode 100644 index 0000000..f053ef8 --- /dev/null +++ b/CryptoPP/cpp_gpgw.cpp @@ -0,0 +1,334 @@ +#include "commonheaders.h" + + +HMODULE hgpg; +HRSRC hRS_gpg; +PBYTE pRS_gpg; + +extern DLLEXPORT int __cdecl _gpg_init(void); +extern DLLEXPORT int __cdecl _gpg_done(void); +extern DLLEXPORT int __cdecl _gpg_open_keyrings(LPSTR,LPSTR); +extern DLLEXPORT int __cdecl _gpg_close_keyrings(void); +extern DLLEXPORT void __cdecl _gpg_set_log(LPCSTR); +extern DLLEXPORT void __cdecl _gpg_set_tmp(LPCSTR); +extern DLLEXPORT LPSTR __cdecl _gpg_get_error(void); +extern DLLEXPORT int __cdecl _gpg_size_keyid(void); +extern DLLEXPORT int __cdecl _gpg_select_keyid(HWND,LPSTR); +extern DLLEXPORT LPSTR __cdecl _gpg_encrypt(LPCSTR,LPCSTR); +extern DLLEXPORT LPSTR __cdecl _gpg_decrypt(LPCSTR); +extern DLLEXPORT LPSTR __cdecl _gpg_get_passphrases(); +extern DLLEXPORT void __cdecl _gpg_set_passphrases(LPCSTR); + +int __cdecl _gpg_init(void); +int __cdecl _gpg_done(void); +int __cdecl _gpg_open_keyrings(LPSTR,LPSTR); +int __cdecl _gpg_close_keyrings(void); +void __cdecl _gpg_set_log(LPCSTR); +void __cdecl _gpg_set_tmp(LPCSTR); +LPSTR __cdecl _gpg_get_error(void); +int __cdecl _gpg_size_keyid(void); +int __cdecl _gpg_select_keyid(HWND,LPSTR); +LPSTR __cdecl _gpg_encrypt(LPCSTR,LPCSTR); +LPSTR __cdecl _gpg_decrypt(LPCSTR); +LPSTR __cdecl _gpg_get_passphrases(); +void __cdecl _gpg_set_passphrases(LPCSTR); + +int (__cdecl *p_gpg_init)(void); +int (__cdecl *p_gpg_done)(void); +int (__cdecl *p_gpg_open_keyrings)(LPSTR,LPSTR); +int (__cdecl *p_gpg_close_keyrings)(void); +void (__cdecl *p_gpg_set_log)(LPCSTR); +void (__cdecl *p_gpg_set_tmp)(LPCSTR); +LPSTR (__cdecl *p_gpg_get_error)(void); +int (__cdecl *p_gpg_size_keyid)(void); +int (__cdecl *p_gpg_select_keyid)(HWND,LPSTR); +LPSTR (__cdecl *p_gpg_encrypt)(LPCSTR,LPCSTR); +LPSTR (__cdecl *p_gpg_decrypt)(LPCSTR); +LPSTR (__cdecl *p_gpg_get_passphrases)(); +void (__cdecl *p_gpg_set_passphrases)(LPCSTR); + + +#define GPA(x) \ + { \ + *((PVOID*)&p##x) = (PVOID)GetProcAddress(mod, TEXT(#x)); \ + if (!p##x) { \ + return 0; \ + } \ + } + +int load_gpg_dll(HMODULE mod) { + + GPA(_gpg_init); + GPA(_gpg_done); + GPA(_gpg_open_keyrings); + GPA(_gpg_close_keyrings); + GPA(_gpg_set_log); + GPA(_gpg_set_tmp); + GPA(_gpg_get_error); + GPA(_gpg_size_keyid); + GPA(_gpg_select_keyid); + GPA(_gpg_encrypt); + GPA(_gpg_decrypt); + GPA(_gpg_get_passphrases); + GPA(_gpg_set_passphrases); + + return 1; +} + +#undef GPA + + +#define GPA(x) \ + { \ + *((PVOID*)&p##x) = (PVOID)MemGetProcAddress(mod, TEXT(#x)); \ + if (!p##x) { \ + return 0; \ + } \ + } + +int load_gpg_mem(HMODULE mod) { + + GPA(_gpg_init); + GPA(_gpg_done); + GPA(_gpg_open_keyrings); + GPA(_gpg_close_keyrings); + GPA(_gpg_set_log); + GPA(_gpg_set_tmp); + GPA(_gpg_get_error); + GPA(_gpg_size_keyid); + GPA(_gpg_select_keyid); + GPA(_gpg_encrypt); + GPA(_gpg_decrypt); + GPA(_gpg_get_passphrases); + GPA(_gpg_set_passphrases); + + return 1; +} + +#undef GPA + + +int __cdecl gpg_init() +{ + int r; char t[MAX_PATH]; + if( isVista ){ + sprintf(t,"%s\\gnupgw.dll",TEMP); + ExtractFile(t,666,1); + hgpg = LoadLibraryA(t); + } + else { + hRS_gpg = FindResource( g_hInst, MAKEINTRESOURCE(1), MAKEINTRESOURCE(666) ); + pRS_gpg = (PBYTE) LoadResource( g_hInst, hRS_gpg ); LockResource( pRS_gpg ); + hgpg = MemLoadLibrary( pRS_gpg ); + } + if (hgpg) { + if( isVista ) load_gpg_dll(hgpg); + else load_gpg_mem(hgpg); + r = p_gpg_init(); + if(r) { + return r; + } + if( isVista ){ + FreeLibrary(hgpg); + } + else { + MemFreeLibrary(hgpg); + UnlockResource( pRS_gpg ); + FreeResource( pRS_gpg ); + } + } + + hgpg = 0; + + return 0; +} + + +int __cdecl gpg_done() +{ + int r = 0; + if(hgpg) { + r = p_gpg_done(); + if( isVista ){ + FreeLibrary(hgpg); + } + else { + MemFreeLibrary(hgpg); + UnlockResource( pRS_gpg ); + FreeResource( pRS_gpg ); + } + hgpg = 0; + } + return r; +} + + +int __cdecl gpg_open_keyrings(LPSTR ExecPath, LPSTR HomePath) +{ + return p_gpg_open_keyrings(ExecPath, HomePath); +} + + +int __cdecl gpg_close_keyrings() +{ + return p_gpg_close_keyrings(); +} + + +void __cdecl gpg_set_log(LPCSTR LogPath) +{ + p_gpg_set_log(LogPath); +} + + +void __cdecl gpg_set_tmp(LPCSTR TmpPath) +{ + p_gpg_set_tmp(TmpPath); +} + + +LPSTR __cdecl gpg_get_error() +{ + return p_gpg_get_error(); +} + + +LPSTR __cdecl gpg_encrypt(pCNTX ptr, LPCSTR szPlainMsg) +{ + ptr->error = ERROR_NONE; + pGPGDATA p = (pGPGDATA) ptr->pdata; + SAFE_FREE(ptr->tmp); + + LPSTR szEncMsg; + szEncMsg = p_gpg_encrypt(szPlainMsg,(LPCSTR)p->gpgKeyID); + if(!szEncMsg) return 0; + + ptr->tmp = (LPSTR) strdup(szEncMsg); + LocalFree((LPVOID)szEncMsg); + + return ptr->tmp; +} + + +LPSTR __cdecl gpg_decrypt(pCNTX ptr, LPCSTR szEncMsg) +{ + ptr->error = ERROR_NONE; + SAFE_FREE(ptr->tmp); + + LPSTR szPlainMsg = p_gpg_decrypt(szEncMsg); +/* if(!szPlainMsg) { + ptr = get_context_on_id(hPGPPRIV); // find private pgp keys + if(ptr && ptr->pgpKey) + szPlainMsg = p_gpg_decrypt_key(szEncMsg,(LPCSTR)ptr->pgpKey); + if(!szPlainMsg) return NULL; + }*/ + + ptr->tmp = (LPSTR) strdup(szPlainMsg); + LocalFree((LPVOID)szPlainMsg); + + return ptr->tmp; +} + + +LPSTR __cdecl gpg_encode(HANDLE context, LPCSTR szPlainMsg) +{ + pCNTX ptr = get_context_on_id(context); if(!ptr) return NULL; + pGPGDATA p = (pGPGDATA) cpp_alloc_pdata(ptr); + if(!p->gpgKeyID) { ptr->error = ERROR_NO_GPG_KEY; return NULL; } + + // utf8 message: encrypt. + LPSTR szUtfMsg; + if( ptr->mode & MODE_GPG_ANSI ) { + LPWSTR wszMsg = utf8decode(szPlainMsg); + int wlen = wcslen(wszMsg)+1; + szUtfMsg = (LPSTR) alloca(wlen); + WideCharToMultiByte(CP_ACP, 0, wszMsg, -1, szUtfMsg, wlen, 0, 0); + } + else { + szUtfMsg = (LPSTR)szPlainMsg; + } + return gpg_encrypt(ptr, szUtfMsg); +} + + +LPSTR __cdecl gpg_decode(HANDLE context, LPCSTR szEncMsg) +{ + pCNTX ptr = get_context_on_id(context); + if(!ptr) return NULL; + + LPSTR szNewMsg = NULL; + LPSTR szOldMsg = gpg_decrypt(ptr, szEncMsg); + + if(szOldMsg) { + if( !is_7bit_string(szOldMsg) && !is_utf8_string(szOldMsg) ) { + int slen = strlen(szOldMsg)+1; + LPWSTR wszMsg = (LPWSTR) alloca(slen*sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, szOldMsg, -1, wszMsg, slen*sizeof(WCHAR)); + szNewMsg = _strdup(utf8encode(wszMsg)); + } + else { + szNewMsg = _strdup(szOldMsg); + } + } + SAFE_FREE(ptr->tmp); + ptr->tmp = szNewMsg; + return szNewMsg; +} + + +int __cdecl gpg_set_key(HANDLE context, LPCSTR RemoteKey) +{ +/* pCNTX ptr = get_context_on_id(context); + if(!ptr) return 0; + ptr->error = ERROR_NONE; + +// if(!p_gpg_check_key(RemoteKey)) return 0; + + SAFE_FREE(ptr->pgpKey); + ptr->pgpKey = (BYTE *) malloc(strlen(RemoteKey)+1); + strcpy((LPSTR)ptr->pgpKey,RemoteKey); + + return 1; +*/ + return 0; +} + + +int __cdecl gpg_set_keyid(HANDLE context, LPCSTR RemoteKeyID) +{ + pCNTX ptr = get_context_on_id(context); if(!ptr) return 0; + pGPGDATA p = (pGPGDATA) cpp_alloc_pdata(ptr); + ptr->error = ERROR_NONE; + + SAFE_FREE(p->gpgKeyID); + p->gpgKeyID = (PBYTE) strdup(RemoteKeyID); + + return 1; +} + + +int __cdecl gpg_size_keyid() +{ + return p_gpg_size_keyid(); +} + + +int __cdecl gpg_select_keyid(HWND hDlg,LPSTR szKeyID) +{ + return p_gpg_select_keyid(hDlg,szKeyID); +} + + +LPSTR __cdecl gpg_get_passphrases() +{ + return p_gpg_get_passphrases(); +} + + +void __cdecl gpg_set_passphrases(LPCSTR buffer) +{ + p_gpg_set_passphrases(buffer); +} + + +// EOF \ No newline at end of file diff --git a/CryptoPP/cpp_gzip.cpp b/CryptoPP/cpp_gzip.cpp new file mode 100644 index 0000000..c819779 --- /dev/null +++ b/CryptoPP/cpp_gzip.cpp @@ -0,0 +1,57 @@ +#include "commonheaders.h" + +// gzip data +BYTE *cpp_gzip(BYTE *pData, int nLen, int& nCompressedLen) { + + string zipped; + Gzip gzip(new StringSink(zipped),5); // 1 is fast, 9 is slow + gzip.Put(pData, nLen); + gzip.MessageEnd(); + + nCompressedLen = (int) zipped.length(); + PBYTE pCompressed = (PBYTE) malloc(nCompressedLen+1); + memcpy(pCompressed,zipped.data(),nCompressedLen); + + return pCompressed; +} + +// gunzip data +BYTE *cpp_gunzip(BYTE *pCompressedData, int nCompressedLen, int& nLen) { + + string unzipped; + Gunzip gunzip(new StringSink(unzipped)); + gunzip.Put((PBYTE)pCompressedData,nCompressedLen); + gunzip.MessageEnd(); + + nLen = (int) unzipped.length(); + PBYTE pData = (PBYTE) malloc(nLen+1); + memcpy(pData,unzipped.data(),nLen); + + return pData; +} + +// zlibc data +string cpp_zlibc(string& pData) { + + string zipped; + + ZlibCompressor zlib(new StringSink(zipped),5); // 1 is fast, 9 is slow + zlib.Put((PBYTE)pData.data(), pData.length()); + zlib.MessageEnd(); + + return zipped; +} + +// zlibd data +string cpp_zlibd(string& pData) { + + string unzipped; + + ZlibDecompressor zlib(new StringSink(unzipped)); + zlib.Put((PBYTE)pData.data(),pData.length()); + zlib.MessageEnd(); + + return unzipped; +} + +// EOF diff --git a/CryptoPP/cpp_keys.cpp b/CryptoPP/cpp_keys.cpp new file mode 100644 index 0000000..51ac724 --- /dev/null +++ b/CryptoPP/cpp_keys.cpp @@ -0,0 +1,199 @@ +#include "commonheaders.h" + +const unsigned char IV[] = "PSKhell@MIRANDA!"; + + +// generate KeyA pair, return public key as ASCII +LPSTR __cdecl cpp_init_keya(HANDLE context, int features) { + + pCNTX ptr = get_context_on_id(context); if(!ptr) return NULL; + pSIMDATA p = (pSIMDATA) cpp_alloc_pdata(ptr); + + int send_features = FEATURES; + if(p->KeyP) send_features |= FEATURES_PSK; + + SAFE_DELETE(p->dh); + if(features & FEATURES_NEWPG) { + Integer p0("0x865734026113B4DF0082CED84C197718516088FBDA406CFDFD7F033694E11E46F01C8F01E0E5AE6B09F6284691C7DD30A5BA8A74BA4B780198624B84BC8DAF6E0DFF874C0440ABB5C043C82E9E9C9E6F1A470B6A2A6BCEAC9460C43B1BB1331DF0FFD898DB74D22E8A71DB2659F1B0F52F337718D233DED611DA25AEAA90F3BE0C42FA9E541D0487DF58A77E2F44D295AD0C54C369CE260C969CA12F690EAAFAEEF8676C631AF29A3DE3389D3000B94EFA775E31FCA879AEB00A4D05EEF50D4C084A049EB12EF4CDFBD48E36B29CEAF8978D535D6C70BB274D1FEA02ABD521D2EF482A76326C17AF597FCB9B8BF37D9110E22AB0746D6A9779DF5133822E3F15"); + Integer q0("0xF1515160E1BFC7636338C13AD5BA775318E287147A1F96B73CF0FB4D97EFFB9D1FCDCF31AB9D92C4F49C9F8D50F06E697D2313E2EBAC7781312A51F458D66FFC687960CAA86BDF150A36ED53D79FBDB4F501FD25E37C181B45F9555D7F1C6124CAB29A822AD1E7BF5DA93C2FDB12A61919B5E5359793CBB16E71516919040A7F"); + Integer g0("0x434158F2FF2CF667E3CC1A707770DDE7B56048F6C5005473C6DC4A5E3FC490667F2908C44F9ADC2071EB8A8A1EC6AD6901CDAAAFE806626E3F4C5E69D4FCBF9DF1B67D574DC61C687C4BEF3ACF77A7256752F4D3A7EAEEE5874ED4912AB10C5B122A24E698B14CAC3E0FD006E0DB02714E028AECCA25BAB9DDCA2CF6405E862B403C61BC381D64B46BD96D3FEFBE22B7497FCBDA2B49C840C1B2853502A5216B036F83D2EAD8F835B603FC5BA1EFB816C7634915B1D43963FDD1B1ED626F48CCF8F152392E4693D38C566016708FA9E9598AECF95A8B067212669247552418E538A706564F855D3D5D50717D356259A20D8FD0C6B2A9FCC045D3F7AED1E857C5"); + p->dh = new DH(p0,q0,g0); + } + else { + Integer p0("0xD494AAFBCD2EAC6A36DB8E7DD4A2A64512A5BBB15B9BFB581C7C1CAFB647D4612973C3770C2166D75EEA695F67EA8261557591DB78BCF5A886AA5294F3AEE4D25B57C8EE8C7FE8DBF70C132CD7FFCB6F89426F807F552C5DAE2FB1F329E340094E4B30D8EF6265AB4D350E9837B151C86AC524DE4E1FC04746C668BE318275E420D51AEDDFBDF887D435CDEEF6AC81293DB45287132F8236A43AD8F4D6642D7CA6732DA06A1DE008259008C9D74403B68ADAC788CF8AB5BEFFC310DCCCD32901D1F290E5B7A993D2CF6A652AF81B6DA0FD2E70678D1AE086150E41444522F20621195AD2A1F0975652B4AF7DE5261A9FD46B9EA8B443641F3BBA695B9B020103"); + Integer g0("0x12A567BC9ABCDEF1234567823BCDEF1E"); + p->dh = new DH(p0,g0); + } + + BYTE priv1[KEYSIZE]; // private key of 2048 bit + BYTE publ1[KEYSIZE+2]; // public key of 2048 bit + faetures field + + memset(priv1,0,sizeof(priv1)); + memset(publ1,0,sizeof(publ1)); + + AutoSeededRandomPool autorng; + p->dh->GenerateKeyPair(autorng, priv1, publ1); + + SAFE_FREE(p->PubA); + p->PubA = (PBYTE) malloc(KEYSIZE); + memcpy(p->PubA,publ1,KEYSIZE); + + SAFE_FREE(p->KeyA); + p->KeyA = (PBYTE) malloc(KEYSIZE); + memcpy(p->KeyA,priv1,KEYSIZE); + + if(p->KeyP) { + // encrypt PUBLIC use PSK + string ciphered; + CFB_Mode::Encryption enc(p->KeyP,Tiger::DIGESTSIZE,IV); + StreamTransformationFilter cbcEncryptor(enc,new StringSink(ciphered)); + + cbcEncryptor.Put(publ1,KEYSIZE); + cbcEncryptor.MessageEnd(); + memcpy(publ1,ciphered.data(),ciphered.length()); +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("cpp_init_keya: %d %d",KEYSIZE,ciphered.length()); +#endif + } + memcpy((PVOID)&publ1[KEYSIZE],(PVOID)&send_features,2); + + SAFE_FREE(ptr->tmp); + if(ptr->mode & MODE_BASE64 || features & FEATURES_NEWPG) + ptr->tmp = base64encode((LPSTR)&publ1,KEYSIZE+2); + else + ptr->tmp = base16encode((LPSTR)&publ1,KEYSIZE+2); + + return ptr->tmp; +} + + +// store KeyB +int __cdecl cpp_init_keyb(HANDLE context, LPCSTR key) { + + pCNTX ptr = get_context_on_id(context); if(!ptr) return 0; + pSIMDATA p = (pSIMDATA) cpp_alloc_pdata(ptr); + + int clen = rtrim(key); + ptr->features = 0; + + LPSTR pub_binary; + if((clen==KEYSIZE*2) || (clen==(KEYSIZE+2)*2)) + pub_binary = base16decode(key,&clen); + else + pub_binary = base64decode(key,&clen); + + if( !pub_binary || (clen!=KEYSIZE && clen!=KEYSIZE+2) ) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("cpp_init_keyb: error bad_keyb"); +#endif + ptr->error = ERROR_BAD_KEYB; + SAFE_FREE(pub_binary); + return 0; + } + + if(clen==KEYSIZE+2) + memcpy((PVOID)&ptr->features,(PVOID)(pub_binary+KEYSIZE),2); + + if(p->KeyP) { + if(!(ptr->features & FEATURES_PSK)) { // if NO PSK on other side +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("cpp_init_keyb: error no_psk"); +#endif + ptr->error = ERROR_NO_PSK; + return 0; + } + ptr->error = ERROR_BAD_PSK; + try { + // decrypt PUBLIC use PSK + string unciphered; + CFB_Mode::Decryption dec(p->KeyP,Tiger::DIGESTSIZE,IV); + StreamTransformationFilter cbcDecryptor(dec,new StringSink(unciphered)); + + cbcDecryptor.Put((PBYTE)pub_binary,KEYSIZE); + cbcDecryptor.MessageEnd(); + memcpy(pub_binary,unciphered.data(),unciphered.length()); + } + catch (...) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("cpp_init_keyb: error bad_psk"); +#endif + return 0; + } + } + + SAFE_FREE(p->KeyB); + p->KeyB = (PBYTE) pub_binary; + + if(p->PubA && memcmp(p->PubA,p->KeyB,KEYSIZE)==0) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("cpp_init_keyb: error bad_keyb keya==keyb"); +#endif + SAFE_FREE(p->KeyB); + ptr->error = ERROR_BAD_KEYB; + return 0; + } + + ptr->error = ERROR_NONE; + return 1; +} + + +// calculate secret key, return true or false +int __cdecl cpp_calc_keyx(HANDLE context) { + + pCNTX ptr = get_context_on_id(context); if(!ptr) return 0; + pSIMDATA p = (pSIMDATA) cpp_alloc_pdata(ptr); + + if(!p->KeyA) { ptr->error = ERROR_NO_KEYA; return 0; } + if(!p->KeyB) { ptr->error = ERROR_NO_KEYB; return 0; } + ptr->error = ERROR_NONE; + + BYTE agreeVal[KEYSIZE]; + memset(agreeVal,0,sizeof(agreeVal)); + + BYTE agr = p->dh->Agree(agreeVal, p->KeyA, p->KeyB, true); // calculate key + if (agr) { + // not needed anymore + SAFE_FREE(p->PubA); + SAFE_FREE(p->KeyA); + SAFE_FREE(p->KeyB); +// SAFE_DELETE(p->dh); + + BYTE buffer[Tiger::DIGESTSIZE]; // buffer for hash + memset(buffer,0,sizeof(buffer)); + + // do this only if key exchanged is ok + // we use a 192bit key (24*8) + Tiger().CalculateDigest(buffer, agreeVal, KEYSIZE); // calculate hash + + // store key + SAFE_FREE(p->KeyX); + p->KeyX = (PBYTE) malloc(Tiger::DIGESTSIZE); + memcpy(p->KeyX,buffer,Tiger::DIGESTSIZE); + } + return (int)agr; +} + + +// create pre-shared key from password +int __cdecl cpp_init_keyp(HANDLE context, LPCSTR password) { + + pCNTX ptr = get_context_on_id(context); if(!ptr) return 0; + pSIMDATA p = (pSIMDATA) cpp_alloc_pdata(ptr); + + BYTE buffer[Tiger::DIGESTSIZE]; // buffer for hash + memset(buffer,0,sizeof(buffer)); + + // calculate hash + Tiger().CalculateDigest(buffer,(PBYTE)password,strlen(password)); + + // store pre-shared key + SAFE_FREE(p->KeyP); + p->KeyP = (PBYTE) malloc(Tiger::DIGESTSIZE); + memcpy(p->KeyP,buffer,Tiger::DIGESTSIZE); + + return 1; +} + + +// EOF diff --git a/CryptoPP/cpp_misc.cpp b/CryptoPP/cpp_misc.cpp new file mode 100644 index 0000000..526cebf --- /dev/null +++ b/CryptoPP/cpp_misc.cpp @@ -0,0 +1,97 @@ +#include "commonheaders.h" + + +int __cdecl cpp_get_features(HANDLE context) { + pCNTX ptr = get_context_on_id(context); if(!ptr) return 0; + return ptr->features; +} + + +int __cdecl cpp_get_error(HANDLE context) { + pCNTX ptr = get_context_on_id(context); if(!ptr) return 0; + return ptr->error; +} + + +int __cdecl cpp_get_version(void) { + return __VERSION_DWORD; +} + + +BOOL cpp_get_simdata(HANDLE context, pCNTX *ptr, pSIMDATA *p) { + *ptr = get_context_on_id(context); +// if(!*ptr || !(*ptr)->pdata || (*ptr)->mode&(MODE_PGP|MODE_GPG|MODE_RSA)) return FALSE; + if(!*ptr || (*ptr)->mode&(MODE_PGP|MODE_GPG|MODE_RSA)) return FALSE; + *p = (pSIMDATA) cpp_alloc_pdata(*ptr); + return TRUE; +} + + +int __cdecl cpp_size_keyx(void) { + return(Tiger::DIGESTSIZE+2); +} + + +void __cdecl cpp_get_keyx(HANDLE context, BYTE *key) { + pCNTX ptr; pSIMDATA p; if(!cpp_get_simdata(context,&ptr,&p)) return; + memcpy(key,p->KeyX,Tiger::DIGESTSIZE); + memcpy(key+Tiger::DIGESTSIZE,&ptr->features,2); +} + + +void __cdecl cpp_set_keyx(HANDLE context, BYTE *key) { + pCNTX ptr; pSIMDATA p; if(!cpp_get_simdata(context,&ptr,&p)) return; + SAFE_FREE(p->PubA); + SAFE_FREE(p->KeyA); + SAFE_FREE(p->KeyB); + SAFE_FREE(p->KeyX); + p->KeyX = (PBYTE) malloc(Tiger::DIGESTSIZE+2); + memcpy(p->KeyX,key,Tiger::DIGESTSIZE); + memcpy(&ptr->features,key+Tiger::DIGESTSIZE,2); +} + + +void __cdecl cpp_get_keyp(HANDLE context, BYTE *key) { + pCNTX ptr; pSIMDATA p; if(!cpp_get_simdata(context,&ptr,&p)) return; + memcpy(key,p->KeyP,Tiger::DIGESTSIZE); +} + + +int __cdecl cpp_size_keyp(void) { + return(Tiger::DIGESTSIZE); +} + + +void __cdecl cpp_set_keyp(HANDLE context, BYTE *key) { + pCNTX ptr; pSIMDATA p; if(!cpp_get_simdata(context,&ptr,&p)) return; + SAFE_FREE(p->KeyP); + p->KeyP = (PBYTE) malloc(Tiger::DIGESTSIZE); + memcpy(p->KeyP,key,Tiger::DIGESTSIZE); +} + + +int __cdecl cpp_keya(HANDLE context) { + pCNTX ptr; pSIMDATA p; if(!cpp_get_simdata(context,&ptr,&p)) return 0; + return p->KeyA!=NULL; +} + + +int __cdecl cpp_keyb(HANDLE context) { + pCNTX ptr; pSIMDATA p; if(!cpp_get_simdata(context,&ptr,&p)) return 0; + return p->KeyB!=NULL; +} + + +int __cdecl cpp_keyx(HANDLE context) { + pCNTX ptr; pSIMDATA p; if(!cpp_get_simdata(context,&ptr,&p)) return 0; + return p->KeyX!=NULL; +} + + +int __cdecl cpp_keyp(HANDLE context) { + pCNTX ptr; pSIMDATA p; if(!cpp_get_simdata(context,&ptr,&p)) return 0; + return p->KeyP!=NULL; +} + + +// EOF diff --git a/CryptoPP/cpp_pgpw.cpp b/CryptoPP/cpp_pgpw.cpp new file mode 100644 index 0000000..6d06ac0 --- /dev/null +++ b/CryptoPP/cpp_pgpw.cpp @@ -0,0 +1,324 @@ +#include "commonheaders.h" + + +HMODULE hpgpsdk; +UINT pgpVer; +HRSRC hRS_pgp; +PBYTE pRS_pgp; + + +int __cdecl _pgp_init(void); +int __cdecl _pgp_done(void); +int __cdecl _pgp_open_keyrings(LPSTR,LPSTR); +int __cdecl _pgp_close_keyrings(void); +int __cdecl _pgp_get_version(void); +LPSTR __cdecl _pgp_get_error(void); +int __cdecl _pgp_size_keyid(void); +PVOID __cdecl _pgp_select_keyid(HWND,LPSTR); +LPSTR __cdecl _pgp_encrypt_keydb(LPCSTR,PVOID); +LPSTR __cdecl _pgp_decrypt_keydb(LPCSTR); +//int __cdecl _pgp_check_key(LPCSTR); +LPSTR __cdecl _pgp_encrypt_key(LPCSTR,LPCSTR); +LPSTR __cdecl _pgp_decrypt_key(LPCSTR,LPCSTR); + +int (__cdecl *p_pgp_init)(void); +int (__cdecl *p_pgp_done)(void); +int (__cdecl *p_pgp_open_keyrings)(LPSTR,LPSTR); +int (__cdecl *p_pgp_close_keyrings)(void); +int (__cdecl *p_pgp_get_version)(void); +LPSTR (__cdecl *p_pgp_get_error)(void); +int (__cdecl *p_pgp_size_keyid)(void); +PVOID (__cdecl *p_pgp_select_keyid)(HWND,LPSTR); +LPSTR (__cdecl *p_pgp_encrypt_keydb)(LPCSTR,PVOID); +LPSTR (__cdecl *p_pgp_decrypt_keydb)(LPCSTR); +//int (__cdecl *p_pgp_check_key)(LPCSTR); +LPSTR (__cdecl *p_pgp_encrypt_key)(LPCSTR,LPCSTR); +LPSTR (__cdecl *p_pgp_decrypt_key)(LPCSTR,LPCSTR); + + +#define GPA(x) \ + { \ + *((PVOID*)&p##x) = (PVOID)GetProcAddress(mod, TEXT(#x)); \ + if (!p##x) { \ + return 0; \ + } \ + } + +int load_pgpsdk_dll(HMODULE mod) { + + GPA(_pgp_init); + GPA(_pgp_done); + GPA(_pgp_open_keyrings); + GPA(_pgp_close_keyrings); + GPA(_pgp_get_version); + GPA(_pgp_get_error); + GPA(_pgp_size_keyid); + GPA(_pgp_select_keyid); + GPA(_pgp_encrypt_keydb); + GPA(_pgp_decrypt_keydb); +// GPA(_pgp_check_key); + GPA(_pgp_encrypt_key); + GPA(_pgp_decrypt_key); + + return 1; +} + +#undef GPA + + +#define GPA(x) \ + { \ + *((PVOID*)&p##x) = (PVOID)MemGetProcAddress(mod, TEXT(#x)); \ + if (!p##x) { \ + return 0; \ + } \ + } + +int load_pgpsdk_mem(HMODULE mod) { + + GPA(_pgp_init); + GPA(_pgp_done); + GPA(_pgp_open_keyrings); + GPA(_pgp_close_keyrings); + GPA(_pgp_get_version); + GPA(_pgp_get_error); + GPA(_pgp_size_keyid); + GPA(_pgp_select_keyid); + GPA(_pgp_encrypt_keydb); + GPA(_pgp_decrypt_keydb); +// GPA(_pgp_check_key); + GPA(_pgp_encrypt_key); + GPA(_pgp_decrypt_key); + + return 1; +} + +#undef GPA + + +BOOL load_pgp_sdk(int type, int id) +{ + int r; char t[MAX_PATH]; + pgpVer = 0; + + if( isVista ){ + sprintf(t,"%s\\pgpsdkw.dll",TEMP); + ExtractFile(t,type,id); + hpgpsdk = LoadLibraryA(t); + } + else { + hRS_pgp = FindResource( g_hInst, MAKEINTRESOURCE(id), MAKEINTRESOURCE(type) ); + pRS_pgp = (PBYTE) LoadResource( g_hInst, hRS_pgp ); LockResource( pRS_pgp ); + hpgpsdk = MemLoadLibrary( pRS_pgp ); + } + if (hpgpsdk) { + if( isVista ) load_pgpsdk_dll(hpgpsdk); + else load_pgpsdk_mem(hpgpsdk); + r = p_pgp_init(); + if(r) { + pgpVer = p_pgp_get_version(); + return r; + } + if( isVista ){ + FreeLibrary(hpgpsdk); + } + else { + MemFreeLibrary(hpgpsdk); + UnlockResource( pRS_pgp ); + FreeResource( pRS_pgp ); + } + } + return 0; +} + + +int __cdecl pgp_init() +{ + int r; + + if( !hPGPPRIV ) { + // create context for private pgp keys + hPGPPRIV = (HANDLE) cpp_create_context(MODE_PGP|MODE_PRIV_KEY); + pCNTX tmp = (pCNTX) hPGPPRIV; + tmp->pdata = (PBYTE) malloc(sizeof(PGPDATA)); + memset(tmp->pdata,0,sizeof(PGPDATA)); + } + + if( r = load_pgp_sdk(666,6) ) return r; + if( r = load_pgp_sdk(666,8) ) return r; + + hpgpsdk = 0; + + return 0; +} + + +int __cdecl pgp_done() +{ + int r = 0; + pgpVer = 0; + if(hpgpsdk) { + r = p_pgp_done(); + if( isVista ){ + FreeLibrary(hpgpsdk); + } + else { + MemFreeLibrary(hpgpsdk); + UnlockResource( pRS_pgp ); + FreeResource( pRS_pgp ); + } + hpgpsdk = 0; + } + return r; +} + + +int __cdecl pgp_open_keyrings(LPSTR PubRingPath, LPSTR SecRingPath) +{ + return p_pgp_open_keyrings(PubRingPath,SecRingPath); +} + + +int __cdecl pgp_close_keyrings() +{ + return p_pgp_close_keyrings(); +} + + +int __cdecl pgp_get_version() +{ + return pgpVer; +} + + +LPSTR __cdecl pgp_get_error() +{ + return p_pgp_get_error(); +} + + +LPSTR __cdecl pgp_encrypt(pCNTX ptr, LPCSTR szPlainMsg) +{ + ptr->error = ERROR_NONE; + pPGPDATA p = (pPGPDATA) ptr->pdata; + SAFE_FREE(ptr->tmp); + + LPSTR szEncMsg; + if(p->pgpKey) + szEncMsg = p_pgp_encrypt_key(szPlainMsg,(LPCSTR)p->pgpKey); + else + szEncMsg = p_pgp_encrypt_keydb(szPlainMsg,p->pgpKeyID); + if(!szEncMsg) return 0; + + ptr->tmp = (LPSTR) strdup(szEncMsg); + LocalFree((LPVOID)szEncMsg); + + return ptr->tmp; +} + + +LPSTR __cdecl pgp_decrypt(pCNTX ptr, LPCSTR szEncMsg) +{ + ptr->error = ERROR_NONE; + SAFE_FREE(ptr->tmp); + + LPSTR szPlainMsg = p_pgp_decrypt_keydb(szEncMsg); + if(!szPlainMsg) { + ptr = get_context_on_id(hPGPPRIV); // find private pgp keys + if(ptr) { + pPGPDATA p = (pPGPDATA) ptr->pdata; + if(p->pgpKey) + szPlainMsg = p_pgp_decrypt_key(szEncMsg,(LPCSTR)p->pgpKey); + } + if(!szPlainMsg) return NULL; + } + + ptr->tmp = (LPSTR) strdup(szPlainMsg); + LocalFree((LPVOID)szPlainMsg); + + return ptr->tmp; +} + + +LPSTR __cdecl pgp_encode(HANDLE context, LPCSTR szPlainMsg) +{ + pCNTX ptr = get_context_on_id(context); if(!ptr) return NULL; + pPGPDATA p = (pPGPDATA) cpp_alloc_pdata(ptr); + if( !p->pgpKeyID && !p->pgpKey ) { ptr->error = ERROR_NO_PGP_KEY; return NULL; } + + // utf8 message: encrypt. + return pgp_encrypt(ptr, szPlainMsg); +} + + +LPSTR __cdecl pgp_decode(HANDLE context, LPCSTR szEncMsg) +{ + pCNTX ptr = get_context_on_id(context); + if(!ptr) return NULL; + + LPSTR szNewMsg = NULL; + LPSTR szOldMsg = pgp_decrypt(ptr, szEncMsg); + + if(szOldMsg) { + if( !is_7bit_string(szOldMsg) && !is_utf8_string(szOldMsg) ) { + int slen = strlen(szOldMsg)+1; + LPWSTR wszMsg = (LPWSTR) alloca(slen*sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, szOldMsg, -1, wszMsg, slen*sizeof(WCHAR)); + szNewMsg = _strdup(utf8encode(wszMsg)); + } + else { + szNewMsg = _strdup(szOldMsg); + } + } + SAFE_FREE(ptr->tmp); + ptr->tmp = szNewMsg; + return szNewMsg; +} + + +int __cdecl pgp_set_priv_key(LPCSTR LocalKey) +{ + return pgp_set_key(hPGPPRIV,LocalKey); +} + + +int __cdecl pgp_set_key(HANDLE context, LPCSTR RemoteKey) +{ + pCNTX ptr = get_context_on_id(context); if(!ptr) return 0; + pPGPDATA p = (pPGPDATA) cpp_alloc_pdata(ptr); + ptr->error = ERROR_NONE; + +// if(!p_pgp_check_key(RemoteKey)) return 0; + + SAFE_FREE(p->pgpKey); + p->pgpKey = (PBYTE) strdup(RemoteKey); + + return 1; +} + + +int __cdecl pgp_set_keyid(HANDLE context, PVOID RemoteKeyID) +{ + pCNTX ptr = get_context_on_id(context); if(!ptr) return 0; + pPGPDATA p = (pPGPDATA) cpp_alloc_pdata(ptr); + ptr->error = ERROR_NONE; + + SAFE_FREE(p->pgpKeyID); + p->pgpKeyID = (PBYTE) malloc(p_pgp_size_keyid()); + memcpy(p->pgpKeyID,RemoteKeyID,p_pgp_size_keyid()); + + return 1; +} + + +int __cdecl pgp_size_keyid() +{ + return p_pgp_size_keyid(); +} + + +PVOID __cdecl pgp_select_keyid(HWND hDlg,LPSTR szKeyID) +{ + return p_pgp_select_keyid(hDlg,szKeyID); +} + diff --git a/CryptoPP/cpp_rsam.cpp b/CryptoPP/cpp_rsam.cpp new file mode 100644 index 0000000..2cdd77b --- /dev/null +++ b/CryptoPP/cpp_rsam.cpp @@ -0,0 +1,1074 @@ +#include "commonheaders.h" + +/////////////////////////////////////////////////////////////////////////// + +#define RAND_SIZE (256/8) + +RSA_EXPORT exp = { + rsa_gen_keypair, + rsa_get_keypair, + rsa_get_keyhash, + rsa_set_keypair, + rsa_get_pubkey, + rsa_set_pubkey, + rsa_set_timeout, + rsa_get_state, + rsa_get_hash, + rsa_connect, + rsa_disconnect, + rsa_disabled, + rsa_recv, + rsa_send, + rsa_encrypt_file, + rsa_decrypt_file, + utf8encode, + utf8decode, + is_7bit_string, + is_utf8_string, + rsa_export_keypair, + rsa_import_keypair, + rsa_export_pubkey, + rsa_import_pubkey +}; + +pRSA_IMPORT imp; + +string null; +int timeout = 10; + +const string priv_beg = "-----BEGIN SECUREIM PRIVATE KEY BLOCK-----"; +const string priv_end = "-----END SECUREIM PRIVATE KEY BLOCK-----"; + +const string pub_beg = "-----BEGIN SECUREIM PUBLIC KEY BLOCK-----"; +const string pub_end = "-----END SECUREIM PUBLIC KEY BLOCK-----"; + +const string crlf = "\x0D\x0A"; + +/////////////////////////////////////////////////////////////////////////// + + +int __cdecl rsa_init(pRSA_EXPORT* e, pRSA_IMPORT i) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("rsa_init"); +#endif + *e = &exp; + imp = i; + if( !hRSA4096 ) { + // create context for private rsa keys + hRSA4096 = (HANDLE) cpp_create_context(MODE_RSA_4096|MODE_PRIV_KEY); + pCNTX tmp = (pCNTX) hRSA4096; + pRSAPRIV p = new RSAPRIV; + tmp->pdata = (PBYTE) p; + } + return 1; +} + + +int __cdecl rsa_done(void) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("rsa_done"); +#endif + return 1; +} + + +/////////////////////////////////////////////////////////////////////////// + + +pRSAPRIV rsa_gen_keys(HANDLE context) { + + if( context!=hRSA4096 ) return 0; + +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("rsa_gen_keys: %d", context); +#endif + pCNTX ptr = get_context_on_id(context); + pRSAPRIV r = (pRSAPRIV) ptr->pdata; + + string priv, pub; + GenerateRSAKey(4096, priv, pub); + + StringSource privsrc(priv, true, NULL); + RSAES_PKCS1v15_Decryptor Decryptor(privsrc); + + priv = tlv(1, IntegerToBinary(Decryptor.GetTrapdoorFunction().GetModulus() )) + + tlv(2, IntegerToBinary(Decryptor.GetTrapdoorFunction().GetPublicExponent() )) + + tlv(3, IntegerToBinary(Decryptor.GetTrapdoorFunction().GetPrivateExponent() )) + + tlv(4, IntegerToBinary(Decryptor.GetTrapdoorFunction().GetPrime1() )) + + tlv(5, IntegerToBinary(Decryptor.GetTrapdoorFunction().GetPrime2() )) + + tlv(6, IntegerToBinary(Decryptor.GetTrapdoorFunction().GetModPrime1PrivateExponent() )) + + tlv(7, IntegerToBinary(Decryptor.GetTrapdoorFunction().GetModPrime2PrivateExponent() )) + + tlv(8, IntegerToBinary(Decryptor.GetTrapdoorFunction().GetMultiplicativeInverseOfPrime2ModPrime1() )); + + init_priv(r,priv); + + return r; +} + + +pRSAPRIV rsa_get_priv(pCNTX ptr) { + pCNTX p = get_context_on_id(hRSA4096); + pRSAPRIV r = (pRSAPRIV) p->pdata; + return r; +} + + +int __cdecl rsa_gen_keypair(short mode) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("rsa_gen_keypair: %d", mode); +#endif + if( mode&MODE_RSA_4096 ) rsa_gen_keys(hRSA4096); // 4096 + + return 1; +} + + +int __cdecl rsa_get_keypair(short mode, PBYTE privKey, int* privKeyLen, PBYTE pubKey, int* pubKeyLen) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("rsa_get_keypair: %d", mode); +#endif + pCNTX ptr = get_context_on_id(hRSA4096); + pRSAPRIV r = (pRSAPRIV) ptr->pdata; + + *privKeyLen = r->priv_k.length(); if( privKey ) r->priv_k.copy((char*)privKey, *privKeyLen); + *pubKeyLen = r->pub_k.length(); if( pubKey ) r->pub_k.copy((char*)pubKey, *pubKeyLen); + + return 1; +} + + +int __cdecl rsa_get_keyhash(short mode, PBYTE privKey, int* privKeyLen, PBYTE pubKey, int* pubKeyLen) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("rsa_get_keyhash: %d", mode); +#endif + pCNTX ptr = get_context_on_id(hRSA4096); + pRSAPRIV r = (pRSAPRIV) ptr->pdata; + + if( privKey ) { *privKeyLen = r->priv_s.length(); r->priv_s.copy((char*)privKey, *privKeyLen); } + if( pubKey ) { *pubKeyLen = r->pub_s.length(); r->pub_s.copy((char*)pubKey, *pubKeyLen); } + + return 1; +} + + +int __cdecl rsa_set_keypair(short mode, PBYTE privKey, int privKeyLen) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("rsa_set_keypair: %s", privKey); +#endif + pCNTX ptr = get_context_on_id(hRSA4096); + pRSAPRIV r = (pRSAPRIV) ptr->pdata; + + if( privKey && privKeyLen ) { + string priv; + priv.assign((char*)privKey, privKeyLen); + + if( mode & MODE_RSA_BER ) { + // old BER format + StringStore s(priv); + r->priv.BERDecode(s); + + RSAES_PKCS1v15_Decryptor Decryptor(r->priv); + + priv = tlv(1, IntegerToBinary(Decryptor.GetTrapdoorFunction().GetModulus() )) + + tlv(2, IntegerToBinary(Decryptor.GetTrapdoorFunction().GetPublicExponent() )) + + tlv(3, IntegerToBinary(Decryptor.GetTrapdoorFunction().GetPrivateExponent() )) + + tlv(4, IntegerToBinary(Decryptor.GetTrapdoorFunction().GetPrime1() )) + + tlv(5, IntegerToBinary(Decryptor.GetTrapdoorFunction().GetPrime2() )) + + tlv(6, IntegerToBinary(Decryptor.GetTrapdoorFunction().GetModPrime1PrivateExponent() )) + + tlv(7, IntegerToBinary(Decryptor.GetTrapdoorFunction().GetModPrime2PrivateExponent() )) + + tlv(8, IntegerToBinary(Decryptor.GetTrapdoorFunction().GetMultiplicativeInverseOfPrime2ModPrime1() )); + + } + init_priv(r,priv); + } + + return 1; +} + + +int __cdecl rsa_get_pubkey(HANDLE context, PBYTE pubKey, int* pubKeyLen) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("rsa_get_pubkey: %s", pubKey); +#endif + pCNTX ptr = get_context_on_id(context); if(!ptr) return 0; + pRSADATA p = (pRSADATA) cpp_alloc_pdata(ptr); + + *pubKeyLen = p->pub_k.length(); if( pubKey ) p->pub_k.copy((char*)pubKey, *pubKeyLen); + + return 1; +} + + +int __cdecl rsa_set_pubkey(HANDLE context, PBYTE pubKey, int pubKeyLen) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("rsa_set_pubkey: %s", pubKey); +#endif + pCNTX ptr = get_context_on_id(context); if(!ptr) return 0; + pRSADATA p = (pRSADATA) cpp_alloc_pdata(ptr); + + if( pubKey && pubKeyLen ) { + string pub; + pub.assign((char*)pubKey, pubKeyLen); + init_pub(p,pub); + } + + return 1; +} + + +void __cdecl rsa_set_timeout(int t) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("rsa_set_timeout: %d", t); +#endif + timeout = t; +} + + +int __cdecl rsa_get_state(HANDLE context) { + + pCNTX ptr = get_context_on_id(context); if(!ptr) return 0; + pRSADATA p = (pRSADATA) cpp_alloc_pdata(ptr); + + return p->state; +} + + +int __cdecl rsa_get_hash(PBYTE pubKey, int pubKeyLen, PBYTE pubHash, int* pubHashLen) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("rsa_get_hash: %d", pubKeyLen); +#endif + string sig; + sig = hash(pubKey, pubKeyLen); + + *pubHashLen = sig.length(); + if( pubHash ) sig.copy((char*)pubHash, *pubHashLen); + + return 1; +} + + +int __cdecl rsa_connect(HANDLE context) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("rsa_connect: %08x", context); +#endif + pCNTX ptr = get_context_on_id(context); if(!ptr) return 0; + pRSADATA p = (pRSADATA) cpp_alloc_pdata(ptr); if(p->state) return p->state; + pRSAPRIV r = rsa_get_priv(ptr); + + if(ptr->mode&MODE_RSA_ONLY) { + inject_msg(context,0x0D,tlv(0,0)+tlv(1,r->pub_k)+tlv(2,p->pub_s)); + p->state = 0x0D; + } + else { + inject_msg(context,0x10,tlv(0,0)+tlv(1,r->pub_s)+tlv(2,p->pub_s)); + p->state = 2; + } + p->time = gettime()+timeout; + + return p->state; +} + + +int __cdecl rsa_disconnect(HANDLE context) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("rsa_disconnect: %08x", context); +#endif + pCNTX ptr = get_context_on_id(context); if(!ptr) return 0; + rsa_free( ptr ); // удалим трэд и очередь сообщений + + pRSADATA p = (pRSADATA) cpp_alloc_pdata(ptr); + if( !p->state ) return 1; + + PBYTE buffer=(PBYTE) alloca(RAND_SIZE); + GlobalRNG().GenerateBlock(buffer,RAND_SIZE); + inject_msg(context,0xF0,encode_msg(0,p,hash(buffer,RAND_SIZE))); + + p->state = 0; + imp->rsa_notify(context,-3); // соединение разорвано вручную + + return 1; +} + + +int __cdecl rsa_disabled(HANDLE context) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("rsa_disabled: %08x", context); +#endif + pCNTX ptr = get_context_on_id(context); if(!ptr) return 0; + rsa_free( ptr ); // удалим трэд и очередь сообщений + + pRSADATA p = (pRSADATA) cpp_alloc_pdata(ptr); + p->state = 0; + inject_msg(context,0xFF,null); +// imp->rsa_notify(-context,-8); // соединение разорвано по причине "disabled" + return 1; +} + + +LPSTR __cdecl rsa_recv(HANDLE context, LPCSTR msg) { + +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("rsa_recv: %s", msg); +#endif + pCNTX ptr = get_context_on_id(context); if(!ptr) return 0; + pRSADATA p = (pRSADATA) cpp_alloc_pdata(ptr); + pRSAPRIV r = rsa_get_priv(ptr); + + rtrim(msg); + + string buf = base64decode(msg); + if( !buf.length() ) return 0; + + string data; int type; + un_tlv(buf,type,data); + if( type==-1 ) return 0; + +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("rsa_recv: %02x %d", type, p->state); +#endif + if( type>0x10 && type<0xE0 ) // проверим тип сообщения (когда соединение еще не установлено) + if( p->state==0 || p->state!=(type>>4) ) { // неверное состояние + // шлем перерывание сессии + p->state=0; p->time=0; + rsa_free( ptr ); // удалим трэд и очередь сообщений + null_msg(context,0x00,-1); // сессия разорвана по ошибке, неверный тип сообщения + return 0; + } + + switch( type ) { + + case 0x00: // прерывание сессии по ошибке другой стороной + { + // если соединение установлено - ничего не делаем + if( p->state == 0 || p->state == 7 ) return 0; + // иначе сбрасываем текущее состояние + p->state=0; p->time=0; + imp->rsa_notify(context,-2); // сессия разорвана по ошибке другой стороной + } break; + + // это все будем обрабатывать в отдельном потоке, чтобы избежать таймаутов + case 0x10: // запрос на установку соединения + case 0x22: // получили удаленный паблик, отправляем уже криптоключ + case 0x23: // отправляем локальный паблик + case 0x24: // получили удаленный паблик, отправим локальный паблик + case 0x33: // получили удаленный паблик, отправляем криптоключ + case 0x34: + case 0x21: // получили криптоключ, отправляем криптотест + case 0x32: + case 0x40: + case 0x0D: // запрос паблика + case 0xD0: // ответ пабликом + { + if( !p->event ) { + p->event = CreateEvent(NULL,FALSE,FALSE,NULL); + unsigned int tID; + p->thread = (HANDLE) _beginthreadex(NULL, 0, sttConnectThread, (PVOID)context, 0, &tID); +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("rsa_recv: _beginthreadex(sttConnectThread)"); +#endif + } + EnterCriticalSection(&localQueueMutex); + p->queue->push(tlv(type,data)); + LeaveCriticalSection(&localQueueMutex); + SetEvent(p->event); // сказали обрабатывать :) + } break; + + case 0x50: // получили криптотест, отправляем свой криптотест + { + string msg = decode_msg(p,data); + if( !msg.length() ) { + p->state=0; p->time=0; + null_msg(context,0x00,-type); // сессия разорвана по ошибке + return 0; + } + PBYTE buffer=(PBYTE) alloca(RAND_SIZE); + GlobalRNG().GenerateBlock(buffer,RAND_SIZE); + inject_msg(context,0x60,encode_msg(0,p,hash(buffer,RAND_SIZE))); + p->state=7; p->time=0; + rsa_free_thread( p ); // удалим трэд и очередь сообщений + imp->rsa_notify(context,1); // заебися, криптосессия установлена + } break; + + case 0x60: // получили криптотест, сессия установлена + { + string msg = decode_msg(p,data); + if( !msg.length() ) { + p->state=0; p->time=0; + null_msg(context,0x00,-type); // сессия разорвана по ошибке + return 0; + } + p->state=7; p->time=0; + rsa_free_thread( p ); // удалим трэд и очередь сообщений + imp->rsa_notify(context,1); // заебися, криптосессия установлена + } break; + + case 0x70: // получили AES сообщение, декодируем + { + SAFE_FREE(ptr->tmp); + string msg = decode_msg(p,data); + if( msg.length() ) { + ptr->tmp = (LPSTR) strdup(msg.c_str()); + } + else { + imp->rsa_notify(context,-5); // ошибка декодирования AES сообщения + } + return ptr->tmp; + } break; + + case 0xE0: // получили RSA сообщение, декодируем + { + SAFE_FREE(ptr->tmp); + string msg = decode_rsa(p,r,data); + if( msg.length() ) { + ptr->tmp = (LPSTR) strdup(msg.c_str()); + } + else { + imp->rsa_notify(context,-6); // ошибка декодирования RSA сообщения + } + return ptr->tmp; + } break; + + case 0xF0: // разрыв соединения вручную + { + if( p->state != 7 ) return 0; + string msg = decode_msg(p,data); + if( !msg.length() ) return 0; + p->state=0; + rsa_free( ptr ); // удалим трэд и очередь сообщений + imp->rsa_notify(context,-4); // соединение разорвано вручную другой стороной + } break; + + case 0xFF: // разрыв соединения по причине "disabled" + { + p->state=0; + rsa_free( ptr ); // удалим трэд и очередь сообщений + imp->rsa_notify(context,-8); // соединение разорвано по причине "disabled" + } break; + + } + + if( p->state != 0 && p->state != 7 ) + p->time = gettime() + timeout; + + return 0; +} + +int __cdecl rsa_send(HANDLE context, LPCSTR msg) { + + pCNTX ptr = get_context_on_id(context); if(!ptr) return 0; + pRSADATA p = (pRSADATA) cpp_alloc_pdata(ptr); if(p->state!=0 && p->state!=7) return 0; + + if( p->state == 7 ) // сессия установлена, шифруем AES и отправляем + inject_msg(context,0x70,encode_msg(1,p,string(msg))); + else + if( p->state == 0 ) { // сессия установлена, отправляем RSA сообщение + if( !p->pub_k.length() ) return 0; + // есть паблик ключ - отправим сообщение + pRSAPRIV r = rsa_get_priv(ptr); + inject_msg(context,0xE0,encode_rsa(1,p,r,string(msg))); + } + + return 1; +} + + +void inject_msg(HANDLE context, int type, const string& msg) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("inject_msg(%02x): %s", type, msg.c_str()); +#endif + string txt=base64encode(tlv(type,msg)); + imp->rsa_inject(context,(LPCSTR)txt.c_str()); +} + + +string encode_msg(short z, pRSADATA p, string& msg) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("encode_msg: %s", msg.c_str()); +#endif + string zlib = (z) ? cpp_zlibc(msg) : msg; + string sig = hash(zlib); + + string ciphered; + try { + CBC_Mode::Encryption enc((PBYTE)p->aes_k.data(),p->aes_k.length(),(PBYTE)p->aes_v.data()); + StreamTransformationFilter cbcEncryptor(enc,new StringSink(ciphered)); + cbcEncryptor.Put((PBYTE)zlib.data(),zlib.length()); + cbcEncryptor.MessageEnd(); + } + catch (...) { + ; + } + return tlv(z,ciphered)+tlv(2,sig); +} + + +string decode_msg(pRSADATA p, string& msg) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("decode_msg: %s", msg.c_str()); +#endif + string ciphered,sig; int t1,t2; + un_tlv(msg,t1,ciphered); + un_tlv(msg,t2,sig); + + string unciphered,zlib; + try { + CBC_Mode::Decryption dec((PBYTE)p->aes_k.data(),p->aes_k.length(),(PBYTE)p->aes_v.data()); + StreamTransformationFilter cbcDecryptor(dec,new StringSink(zlib)); + cbcDecryptor.Put((PBYTE)ciphered.data(),ciphered.length()); + cbcDecryptor.MessageEnd(); + + if( sig == hash(zlib) ) { + unciphered = (t1==1) ? cpp_zlibd(zlib) : zlib; + } + } + catch (...) { + ; + } + return unciphered; +} + + +string encode_rsa(short z, pRSADATA p, pRSAPRIV r, string& msg) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("encode_rsa: %s", msg.c_str()); +#endif + string zlib = (z) ? cpp_zlibc(msg) : msg; + + string enc = RSAEncryptString(p->pub,zlib); + string sig = RSASignString(r->priv,zlib); + + return tlv(z,enc)+tlv(2,sig); +} + + +string decode_rsa(pRSADATA p, pRSAPRIV r, string& msg) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("decode_rsa: %s", msg.c_str()); +#endif + string ciphered,sig; int t1,t2; + un_tlv(msg,t1,ciphered); + un_tlv(msg,t2,sig); + + string unciphered,zlib; + zlib = RSADecryptString(r->priv,ciphered); + if( zlib.length() && RSAVerifyString(p->pub,zlib,sig) ) { + unciphered = (t1==1) ? cpp_zlibd(zlib) : zlib; + } + return unciphered; +} + + +string gen_aes_key_iv(short m, pRSADATA p, pRSAPRIV r) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("gen_aes_key_iv: %04x", m); +#endif + PBYTE buffer=(PBYTE) alloca(RAND_SIZE); + + GlobalRNG().GenerateBlock(buffer, RAND_SIZE); + p->aes_k = hash256(buffer,RAND_SIZE); + + GlobalRNG().GenerateBlock(buffer, RAND_SIZE); + p->aes_v = hash256(buffer,RAND_SIZE); + + string buf = tlv(10,p->aes_k)+tlv(11,p->aes_v); + + return encode_rsa(0,p,r,buf); +} + + +void init_priv(pRSAPRIV r, string& priv) { + + r->priv_k = priv; + r->priv_s = hash(priv); + + int t; + string tmp, n, e, d, p, q, dp, dq, u; + + while( priv.length() ) { + un_tlv(priv,t,tmp); + switch(t) { + case 1: n = tmp; break; + case 2: e = tmp; break; + case 3: d = tmp; break; + case 4: p = tmp; break; + case 5: q = tmp; break; + case 6: dp = tmp; break; + case 7: dq = tmp; break; + case 8: u = tmp; break; + } + } + + // if( !empty ); + + r->pub_k = tlv(1,n)+tlv(2,e); + r->pub_s = hash(r->pub_k); + + r->priv.Initialize(BinaryToInteger(n),BinaryToInteger(e), + BinaryToInteger(d),BinaryToInteger(p),BinaryToInteger(q), + BinaryToInteger(dp),BinaryToInteger(dq),BinaryToInteger(u)); +} + + +void init_pub(pRSADATA p, string& pub) { + + p->pub_k = pub; + p->pub_s = hash(pub); + + int t; + string tmp, n, e; + + while( pub.length() ) { + un_tlv(pub,t,tmp); + switch(t) { + case 1: n = tmp; break; + case 2: e = tmp; break; + } + } + + // if( !empty ); + + p->pub.Initialize(BinaryToInteger(n),BinaryToInteger(e)); +} + + +void null_msg(HANDLE context, int type, int status) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("null_msg: %02x", status); +#endif + inject_msg(context,type,null); + imp->rsa_notify(context,status); +} + + +void rsa_timeout(HANDLE context, pRSADATA p) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("rsa_timeout"); +#endif + p->state=0; p->time=0; +// null_msg(context,0x00,-7); + imp->rsa_notify(context,-7); // сессия разорвана по таймауту +} + + +int __cdecl rsa_encrypt_file(HANDLE context,LPCSTR file_in,LPCSTR file_out) { + + pCNTX ptr = get_context_on_id(context); if(!ptr) return 0; + pRSADATA p = (pRSADATA) cpp_alloc_pdata(ptr); if(p->state!=7) return 0; + + try { + CBC_Mode::Encryption enc((PBYTE)p->aes_k.data(),p->aes_k.length(),(PBYTE)p->aes_v.data()); + FileSource *f = new FileSource(file_in,true,new StreamTransformationFilter (enc,new FileSink(file_out))); + delete f; + } + catch (...) { + return 0; + } + return 1; +} + + +int __cdecl rsa_decrypt_file(HANDLE context,LPCSTR file_in,LPCSTR file_out) { + + pCNTX ptr = get_context_on_id(context); if(!ptr) return 0; + pRSADATA p = (pRSADATA) cpp_alloc_pdata(ptr); if(p->state!=7) return 0; + + try { + CBC_Mode::Decryption dec((PBYTE)p->aes_k.data(),p->aes_k.length(),(PBYTE)p->aes_v.data()); + FileSource *f = new FileSource(file_in,true,new StreamTransformationFilter (dec,new FileSink(file_out))); + delete f; + } + catch (...) { + return 0; + } + return 1; +} + + +int __cdecl rsa_recv_thread(HANDLE context, string& msg) { + +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("rsa_recv_thread: %s", msg.c_str()); +#endif + pCNTX ptr = get_context_on_id(context); if(!ptr) return 0; + pRSADATA p = (pRSADATA) cpp_alloc_pdata(ptr); + pRSAPRIV r = rsa_get_priv(ptr); + + string data; int type; + un_tlv(msg,type,data); + if( type==-1 ) return 0; + +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("rsa_recv_thread: %02x %d", type, p->state); +#endif + int t[4]; + + switch( type ) { + + case 0x10: + { + int features; string sha1,sha2; + un_tlv(un_tlv(un_tlv(data,t[0],features),t[1],sha1),t[2],sha2); + BOOL lr = (p->pub_s==sha1); BOOL ll = (r->pub_s==sha2); + switch( (lr<<4)|ll ){ + case 0x11: { // оба паблика совпали + inject_msg(context,0x21,gen_aes_key_iv(ptr->mode,p,r)); + p->state=5; + } break; + case 0x10: { // совпал удаленный паблик, нужен локальный + inject_msg(context,0x22,tlv(0,features)+tlv(1,r->pub_k)+tlv(2,r->pub_s)); + p->state=3; + } break; + case 0x01: { // совпал локальный паблик, нужен удаленный + inject_msg(context,0x23,tlv(0,features)); + p->state=3; + } break; + case 0x00: { // не совпали оба паблика + inject_msg(context,0x24,tlv(0,features)+tlv(1,r->pub_k)+tlv(2,r->pub_s)); + p->state=3; + } break; + } + } break; + + case 0x22: // получили удаленный паблик, отправляем уже криптоключ + { + int features; string pub; + un_tlv(un_tlv(data,t[0],features),t[1],pub); + string sig = hash(pub); + if( !imp->rsa_check_pub(context,(PBYTE)pub.data(),pub.length(),(PBYTE)sig.data(),sig.length()) ) { + p->state=0; p->time=0; + null_msg(context,0x00,-type); // сессия разорвана по ошибке + return 0; + } + init_pub(p,pub); + if( p->state==0 ) { // timeout +// rsa_connect(context); + return -1; + } + inject_msg(context,0x32,gen_aes_key_iv(ptr->mode,p,r)); + p->state=5; + } break; + + case 0x23: // отправляем локальный паблик + { + int features; + un_tlv(data,t[0],features); + inject_msg(context,0x33,tlv(1,r->pub_k)+tlv(2,r->pub_s)); + p->state=4; + } break; + + case 0x24: // получили удаленный паблик, отправим локальный паблик + { + int features; string pub; + un_tlv(un_tlv(data,t[0],features),t[1],pub); + string sig = hash(pub); + if( !imp->rsa_check_pub(context,(PBYTE)pub.data(),pub.length(),(PBYTE)sig.data(),sig.length()) ) { + p->state=0; p->time=0; + null_msg(context,0x00,-type); // сессия разорвана по ошибке + return 0; + } + init_pub(p,pub); + if( p->state==0 ) { // timeout +// rsa_connect(context); + return -1; + } + inject_msg(context,0x34,tlv(1,r->pub_k)+tlv(2,r->pub_s)); + p->state=4; + } break; + + case 0x33: // получили удаленный паблик, отправляем криптоключ + case 0x34: + { + string pub; + un_tlv(data,t[0],pub); + string sig = hash(pub); + if( !imp->rsa_check_pub(context,(PBYTE)pub.data(),pub.length(),(PBYTE)sig.data(),sig.length()) ) { + p->state=0; p->time=0; + null_msg(context,0x00,-type); // сессия разорвана по ошибке + return 0; + } + init_pub(p,pub); + if( p->state==0 ) { // timeout +// rsa_connect(context); + return -1; + } + inject_msg(context,0x40,gen_aes_key_iv(ptr->mode,p,r)); + p->state=5; + } break; + + case 0x21: // получили криптоключ, отправляем криптотест + case 0x32: + case 0x40: + { + string key = decode_rsa(p,r,data); + if( !key.length() ) { + p->state=0; p->time=0; + null_msg(context,0x00,-type); // сессия разорвана по ошибке + return 0; + } + un_tlv(key,t[0],p->aes_k); + un_tlv(key,t[1],p->aes_v); + PBYTE buffer=(PBYTE) alloca(RAND_SIZE); + GlobalRNG().GenerateBlock(buffer,RAND_SIZE); + inject_msg(context,0x50,encode_msg(0,p,hash(buffer,RAND_SIZE))); + p->state=6; + } break; + + case 0x0D: // запрос паблика + case 0xD0: // ответ пабликом + { + int features; string pub,sha; + un_tlv(un_tlv(un_tlv(data,t[0],features),t[1],pub),t[2],sha); + if( p->pub_k!=pub ) { // пришел новый паблик + string sig = hash(pub); + if( !imp->rsa_check_pub(context,(PBYTE)pub.data(),pub.length(),(PBYTE)sig.data(),sig.length()) ) { + p->state=0; p->time=0; + null_msg(context,0x00,-type); // сессия разорвана по ошибке + return 0; + } + init_pub(p,pub); + } + if( type == 0x0D ) { // нужно отправить мой паблик + inject_msg(context,0xD0,tlv(0,features)+tlv(1,r->pub_k)+tlv(2,p->pub_s)); + } + p->state=0; p->time=0; + } break; + + } + + if( p->state != 0 && p->state != 7 ) + p->time = gettime() + timeout; + + return 1; +} + + +void rsa_alloc( pCNTX ptr ) { + pRSADATA p = new RSADATA; + p->state = 0; + p->time = 0; + p->thread = p->event = NULL; + p->thread_exit = 0; + p->queue = new STRINGQUEUE; + ptr->pdata = (PBYTE) p; +} + + +void rsa_free( pCNTX ptr ) { + pRSADATA p = (pRSADATA) ptr->pdata; + if( p && p->event ) { + p->thread_exit = 2; // отпускаем поток в свободное плавание + SetEvent( p->event ); + rsa_alloc(ptr); + } +} + + +void rsa_free_thread( pRSADATA p ) { + if( p->event ) { + p->thread_exit = 1; + SetEvent( p->event ); + // ждем завершения потока + WaitForSingleObject(p->thread, INFINITE); + CloseHandle( p->thread ); + CloseHandle( p->event ); + p->thread = p->event = NULL; + p->thread_exit = 0; + } + p->time = 0; + clear_queue( p ); +} + + +void clear_queue( pRSADATA p ) { + EnterCriticalSection(&localQueueMutex); + while( p->queue && !p->queue->empty() ) { + p->queue->pop(); + } + LeaveCriticalSection(&localQueueMutex); +} + + +// establish RSA/AES thread +unsigned __stdcall sttConnectThread( LPVOID arg ) { + + HANDLE context = (HANDLE) arg; + + pCNTX ptr = get_context_on_id(context); if(!ptr) return 0; + pRSADATA p = (pRSADATA) cpp_alloc_pdata(ptr); + + while(1) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("sttConnectThread: WaitForSingleObject"); +#endif + WaitForSingleObject(p->event, INFINITE); // dwMsec rc==WAIT_TIMEOUT + if( p->thread_exit == 1 ) return 0; + if( p->thread_exit == 2 ) { + // мы в свободном плавании - освободим память и завершим трэд + CloseHandle( p->thread ); + CloseHandle( p->event ); + SAFE_DELETE(p->queue); + SAFE_DELETE(p); + return 0; + } + // дождались сообщения в очереди + while( !p->thread_exit && p->queue && !p->queue->empty() ) { + // обработаем сообщения из очереди + if( rsa_recv_thread(context, p->queue->front()) == -1 ) { + // очистить очередь + clear_queue(p); + break; + } + EnterCriticalSection(&localQueueMutex); + p->queue->pop(); + LeaveCriticalSection(&localQueueMutex); + } + } +} + + +int __cdecl rsa_export_keypair(short mode, LPSTR privKey, LPSTR pubKey, LPSTR passPhrase) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("rsa_export_keypair: %d", mode); +#endif + pCNTX ptr = get_context_on_id(hRSA4096); + pRSAPRIV r = (pRSAPRIV) ptr->pdata; + + if( pubKey ) { + string pub; + pub = tlv(3,r->pub_k) + tlv(4,r->pub_s); + pub = pub_beg + crlf + add_delim(base64encode(pub),crlf,65) + pub_end + crlf; + strcpy(pubKey, pub.c_str()); + } + + if( privKey && passPhrase ) { + string key = hash256(passPhrase); + string iv = hash256(key); + string priv = pad256(r->priv_k); + + string ciphered; + try { + CBC_Mode::Encryption enc((PBYTE)key.data(),key.length(),(PBYTE)iv.data()); + StreamTransformationFilter cbcEncryptor(enc,new StringSink(ciphered)); + cbcEncryptor.Put((PBYTE)priv.data(),priv.length()); + cbcEncryptor.MessageEnd(); + } + catch (...) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("rsa_export_keypair: error bad_passphrase"); +#endif + return 0; + } + + priv = tlv(1,ciphered) + tlv(2,hash(ciphered)); + priv = priv_beg + crlf + add_delim(base64encode(priv),crlf,65) + priv_end + crlf; + + strcpy(privKey, priv.c_str()); + } + + return 1; +} + + +int __cdecl rsa_import_keypair(short mode, LPSTR privKey, LPSTR passPhrase) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("rsa_import_keypair: %d", mode); +#endif + pCNTX ptr = get_context_on_id(hRSA4096); + pRSAPRIV r = (pRSAPRIV) ptr->pdata; + + if( !passPhrase ) return 0; + + string priv; + u_int found; + + priv.assign(privKey); + del_delim(priv,crlf); + + found = priv.find(priv_beg); + if( found != string::npos ) { + priv = priv.substr(found+priv_beg.length()); + found = priv.find(priv_end); + if( found != string::npos ) { + priv = base64decode(priv.substr(0,found)); + TLV k(priv); + if( k.exist(1) && k.exist(2) && hash(k.get(1)) == k.get(2) ) { + priv = k.get(1); + + string key = hash256(passPhrase); + string iv = hash256(key); + + string unciphered; + try { + CBC_Mode::Decryption dec((PBYTE)key.data(),key.length(),(PBYTE)iv.data()); + StreamTransformationFilter cbcDecryptor(dec,new StringSink(unciphered)); + cbcDecryptor.Put((PBYTE)priv.data(),priv.length()); + cbcDecryptor.MessageEnd(); + } + catch (...) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("rsa_import_keypair: error bad_passphrase"); +#endif + return 0; + } + + init_priv(r,unciphered); + return 1; + } + } + } + + return 0; +} + + +int __cdecl rsa_export_pubkey(HANDLE context, LPSTR pubKey) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("rsa_export_pubkey: %08x", context); +#endif + pCNTX ptr = get_context_on_id(context); if(!ptr) return 0; + pRSADATA p = (pRSADATA) cpp_alloc_pdata(ptr); + + if( !p->pub_k.length() || !pubKey ) return 0; + + string pub; + pub = tlv(3,p->pub_k) + tlv(4,p->pub_s); + pub = pub_beg + crlf + add_delim(base64encode(pub),crlf,65) + pub_end + crlf; + strcpy(pubKey, pub.c_str()); + + return 1; +} + + +int __cdecl rsa_import_pubkey(HANDLE context, LPSTR pubKey) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("rsa_import_pubkey: %08x", context); +#endif + pCNTX ptr = get_context_on_id(context); if(!ptr) return 0; + pRSADATA p = (pRSADATA) cpp_alloc_pdata(ptr); + + if( !pubKey ) return 0; + + string pub; + u_int found; + + pub.assign(pubKey); + del_delim(pub,crlf); + + found = pub.find(pub_beg); + if( found != string::npos ) { + pub = pub.substr(found+pub_beg.length()); + found = pub.find(pub_end); + if( found != string::npos ) { + pub = base64decode(pub.substr(0,found)); + TLV k(pub); + if( k.exist(3) && k.exist(4) && hash(k.get(3)) == k.get(4) ) { + init_pub(p,k.get(3)); + return 1; + } + } + } + return 0; +} + + +// EOF diff --git a/CryptoPP/cpp_rsam.h b/CryptoPP/cpp_rsam.h new file mode 100644 index 0000000..92c1143 --- /dev/null +++ b/CryptoPP/cpp_rsam.h @@ -0,0 +1,45 @@ +#ifndef __CPP_RSAM_H__ +#define __CPP_RSAM_H__ + +int __cdecl rsa_gen_keypair(short); +int __cdecl rsa_get_keypair(short,PBYTE,int*,PBYTE,int*); +int __cdecl rsa_get_keyhash(short,PBYTE,int*,PBYTE,int*); +int __cdecl rsa_set_keypair(short,PBYTE,int); +int __cdecl rsa_get_pubkey(HANDLE,PBYTE,int*); +int __cdecl rsa_set_pubkey(HANDLE,PBYTE,int); +void __cdecl rsa_set_timeout(int); +int __cdecl rsa_get_state(HANDLE); +int __cdecl rsa_get_hash(PBYTE,int,PBYTE,int*); +int __cdecl rsa_connect(HANDLE); +int __cdecl rsa_disconnect(HANDLE); +int __cdecl rsa_disabled(HANDLE); +LPSTR __cdecl rsa_recv(HANDLE,LPCSTR); +int __cdecl rsa_send(HANDLE,LPCSTR); +int __cdecl rsa_encrypt_file(HANDLE,LPCSTR,LPCSTR); +int __cdecl rsa_decrypt_file(HANDLE,LPCSTR,LPCSTR); +int __cdecl rsa_export_keypair(short,LPSTR,LPSTR,LPSTR); +int __cdecl rsa_import_keypair(short,LPSTR,LPSTR); +int __cdecl rsa_export_pubkey(HANDLE,LPSTR); +int __cdecl rsa_import_pubkey(HANDLE,LPSTR); + + +void inject_msg(HANDLE,int,const string&); +string encode_msg(short,pRSADATA,string&); +string decode_msg(pRSADATA,string&); +string encode_rsa(short,pRSADATA,pRSAPRIV,string&); +string decode_rsa(pRSADATA,pRSAPRIV,string&); +string gen_aes_key_iv(short,pRSADATA,pRSAPRIV); +void init_priv(pRSAPRIV,string&); +void init_pub(pRSADATA,string&); +void null_msg(HANDLE,int,int); + +void rsa_timeout(HANDLE,pRSADATA); +void rsa_alloc(pCNTX); +void rsa_free(pCNTX); +void rsa_free_thread(pRSADATA); +void clear_queue(pRSADATA); + + +unsigned __stdcall sttConnectThread(LPVOID); + +#endif diff --git a/CryptoPP/cpp_rsau.cpp b/CryptoPP/cpp_rsau.cpp new file mode 100644 index 0000000..6644e71 --- /dev/null +++ b/CryptoPP/cpp_rsau.cpp @@ -0,0 +1,258 @@ +#include "commonheaders.h" + +const string padding = "PADDING!PADDING!PADDING!PADDING!"; // 256 bit + + +string pad256(string& str) { + string out = str; + int pad = out.length() % 32; + if( pad ) { // ­ ¤® ўла®ў­пвм ­  256 ЎЁв + if( pad>3 ) { + out += tlv(0,padding.substr(0,32-3-pad)); + } + else { + if( pad==3 ) out += string("\0\0\0"); + else + if( pad==2 ) out += string("\0\0"); + else out += string("\0"); + } + } + return out; +} + + +string& add_delim(string& str, const string& del, int len) { + string val; + for( u_int i=0; i 3 ) { + t = 0; + b.copy((char*)&t,3); + u_int l = t>>8; + t &= 0xFF; + if( b.length() >= 3+l ) { + v = b.substr(3,l); + r = b.substr(3+l); + } + } + if( !v.length() ) { + t = -1; + } + b = r; + return b; +} + + +string& un_tlv(string& b, int& t, int& v) { + string s; + un_tlv(b,t,s); + v = 0; + s.copy((char*)&v,s.length()); + return b; +} + + +int str2int(string& s) { + int v = 0; + if( s.length()<=sizeof(int) ) + s.copy((char*)&v,s.length()); + return v; +} + + +string hash(string& b) +{ + return hash((PBYTE)b.data(),b.length()); +} + + +string hash(PBYTE b, int l) +{ + BYTE h[RSA_KEYSIZE]; + RSA_CalculateDigest(h, b, l); + string s; s.assign((char*)&h,RSA_KEYSIZE); + return s; +} + + +string hash128(string& b) +{ + return hash128((PBYTE)b.data(),b.length()); +} + + +string hash128(LPSTR b) +{ + return hash128((PBYTE)b,strlen(b)); +} + + +string hash128(PBYTE b, int l) +{ + BYTE h[RIPEMD128::DIGESTSIZE]; + RIPEMD128().CalculateDigest(h, b, l); + string s; s.assign((char*)&h,sizeof(h)); + return s; +} + + +string hash256(string& b) +{ + return hash256((PBYTE)b.data(),b.length()); +} + + +string hash256(LPSTR b) +{ + return hash256((PBYTE)b,strlen(b)); +} + + +string hash256(PBYTE b, int l) +{ +// BYTE h[SHA256::DIGESTSIZE]; +// SHA256().CalculateDigest(h, b, l); + BYTE h[RIPEMD256::DIGESTSIZE]; + RIPEMD256().CalculateDigest(h, b, l); + string s; s.assign((char*)&h,sizeof(h)); + return s; +} + + +Integer BinaryToInteger(const string& data) +{ + StringSource ss(data, true, NULL); + SecByteBlock result(ss.MaxRetrievable()); + ss.Get(result, result.size()); + return Integer(result, result.size()); +} + + +string IntegerToBinary(const Integer& value) +{ + SecByteBlock sbb(value.MinEncodedSize()); + value.Encode(sbb, sbb.size()); + string data; + StringSource(sbb, sbb.size(), true, new StringSink(data)); + return data; +} + +/* +RandomPool& GlobalRNG() +{ + static RandomPool randomPool; + return randomPool; +} +*/ + +AutoSeededRandomPool& GlobalRNG() +{ + static AutoSeededRandomPool randomPool; + return randomPool; +} + + +void GenerateRSAKey(unsigned int keyLength, string& privKey, string& pubKey) +{ + RSAES_PKCS1v15_Decryptor priv(GlobalRNG(), keyLength); + StringSink privFile(privKey); + priv.DEREncode(privFile); + privFile.MessageEnd(); + + RSAES_PKCS1v15_Encryptor pub(priv); + StringSink pubFile(pubKey); + pub.DEREncode(pubFile); + pubFile.MessageEnd(); +} + + +string RSAEncryptString(const RSA::PublicKey& pubkey, const string& plaintext) +{ + RSAES_PKCS1v15_Encryptor pub(pubkey); + + string result; + StringSource(plaintext, true, new PK_EncryptorFilter(GlobalRNG(), pub, new StringSink(result))); + return result; +} + + +string RSADecryptString(const RSA::PrivateKey& privkey, const string& ciphertext) +{ + RSAES_PKCS1v15_Decryptor priv(privkey); + + string result; + try { + StringSource(ciphertext, true, new PK_DecryptorFilter(GlobalRNG(), priv, new StringSink(result))); + } + catch (...) { + ; + } + return result; +} + + +string RSASignString(const RSA::PrivateKey& privkey, const string& plaintext) +{ + RSASSA_PKCS1v15_SHA_Signer priv(privkey); + + string result; + try { + StringSource(plaintext, true, new SignerFilter(GlobalRNG(), priv, new StringSink(result))); + } + catch (...) { + ; + } + return result; +} + + +BOOL RSAVerifyString(const RSA::PublicKey& pubkey, const string& plaintext, const string& sig) +{ + RSASSA_PKCS1v15_SHA_Verifier ver(pubkey); + + return ver.VerifyMessage((PBYTE)plaintext.data(), plaintext.length(), (PBYTE)sig.data(), sig.length()); +} + + +// EOF diff --git a/CryptoPP/cpp_rsau.h b/CryptoPP/cpp_rsau.h new file mode 100644 index 0000000..adb017c --- /dev/null +++ b/CryptoPP/cpp_rsau.h @@ -0,0 +1,101 @@ +#ifndef __CPP_RSAU_H__ +#define __CPP_RSAU_H__ + +class TLV { +private: + map data; + +public: + TLV(); + TLV(const string& b) { decode(b); }; + + string encode() { + map::const_iterator i; + string b; + for( i=data.begin(); i!=data.end(); ++i ) { + b += tlv(i->first,i->second); + } + return b; + }; + void decode(const string& b) { + u_char t; + string v; + string r = b; + while( r.length() ) { + t = un_tlv(r,v); + if( t==-1 ) { + break; + } + data[t] = v; + } + }; + + u_int count() { return data.size(); }; + bool exist(u_char t) { return (data.find(t) != data.end()); }; + string get(u_char t) { return data[t]; }; + void put(u_char t, string& v) { data[t]=v; }; + +private: + string tlv(u_int t, const string& v) { + string b; + t |= v.length()<<8; + b.assign((const char*)&t,3); + b += v; + return b; + }; + u_char un_tlv(string& b, string& v) { + string r; v = r; + u_int t = 0; + if( b.length() > 3 ) { + b.copy((char*)&t,3); + u_int l = t>>8; + t &= 0xFF; + if( b.length() >= 3+l ) { + v = b.substr(3,l); + r = b.substr(3+l); + } + } + if( !v.length() ) { + return -1; + } + b = r; + return t; + }; +}; + +string pad256(string&); + +string& add_delim(string&,const string&,int); +string& del_delim(string&,const string&); + +string tlv(int,const string&); +string tlv(int,const char*); +string tlv(int,int); +string& un_tlv(string&,int&,string&); +string& un_tlv(string&,int&,int&); + +int str2int(string&); + +string hash(string&); +string hash(PBYTE,int); + +string hash128(string&); +string hash128(LPSTR); +string hash128(PBYTE,int); + +string hash256(string&); +string hash256(LPSTR); +string hash256(PBYTE,int); + +Integer BinaryToInteger(const string&); +string IntegerToBinary(const Integer&); + +AutoSeededRandomPool& GlobalRNG(); + +void GenerateRSAKey(unsigned int,string&,string&); +string RSAEncryptString(const RSA::PublicKey&,const string&); +string RSADecryptString(const RSA::PrivateKey&,const string&); +string RSASignString(const RSA::PrivateKey&,const string&); +BOOL RSAVerifyString(const RSA::PublicKey&,const string&,const string&); + +#endif diff --git a/CryptoPP/cpp_svcs.cpp b/CryptoPP/cpp_svcs.cpp new file mode 100644 index 0000000..50a3ee1 --- /dev/null +++ b/CryptoPP/cpp_svcs.cpp @@ -0,0 +1,345 @@ +#include "commonheaders.h" + +const unsigned char IV[] = "SIMhell@MIRANDA!"; + + +// encrypt string using KeyX, return encoded string as ASCII or NULL +LPSTR __cdecl cpp_encrypt(pCNTX ptr, LPCSTR szPlainMsg) { + + ptr->error = ERROR_NONE; + pSIMDATA p = (pSIMDATA) ptr->pdata; + + BYTE dataflag = 0; + int clen,slen; + slen = strlen(szPlainMsg); + + LPSTR szMsg; + if(ptr->features & FEATURES_GZIP) { + szMsg = (LPSTR) cpp_gzip((BYTE*)szPlainMsg,slen,clen); + if(clen>=slen) { + free(szMsg); + szMsg = _strdup(szPlainMsg); + } + else { + slen = clen; + dataflag |= DATA_GZIP; + } + } + else + szMsg = _strdup(szPlainMsg); + + string ciphered; + + CBC_Mode::Encryption enc(p->KeyX,Tiger::DIGESTSIZE,IV); + StreamTransformationFilter cbcEncryptor(enc,new StringSink(ciphered)); + + cbcEncryptor.Put((PBYTE)szMsg, slen); + cbcEncryptor.MessageEnd(); + + free(szMsg); + + clen = (int) ciphered.length(); + if(ptr->features & FEATURES_CRC32) { + BYTE crc32[CRC32::DIGESTSIZE]; + memset(crc32,0,sizeof(crc32)); + CRC32().CalculateDigest(crc32, (BYTE*)ciphered.data(), clen); + ciphered.insert(0,(LPSTR)&crc32,CRC32::DIGESTSIZE); + ciphered.insert(0,(LPSTR)&clen,2); + } + if(ptr->features & FEATURES_GZIP) { + ciphered.insert(0,(LPSTR)&dataflag,1); + } + clen = (int) ciphered.length(); + + SAFE_FREE(ptr->tmp); + if(ptr->features & FEATURES_BASE64) { + ptr->tmp = base64encode(ciphered.data(),clen); + } + else { + ptr->tmp = base16encode(ciphered.data(),clen); + } + + return ptr->tmp; +} + + +// decrypt string using KeyX, return decoded string as ASCII or NULL +LPSTR __cdecl cpp_decrypt(pCNTX ptr, LPCSTR szEncMsg) { + + LPSTR ciphered = NULL; + + try { + ptr->error = ERROR_SEH; + pSIMDATA p = (pSIMDATA) ptr->pdata; + + int clen = strlen(szEncMsg); + + if(ptr->features & FEATURES_BASE64) + ciphered = base64decode(szEncMsg,&clen); + else + ciphered = base16decode(szEncMsg,&clen); + + LPSTR bciphered = ciphered; + + BYTE dataflag=0; + if(ptr->features & FEATURES_GZIP) { + dataflag = *ciphered; + bciphered++; clen--; // cut GZIP flag + } + if(ptr->features & FEATURES_CRC32) { + int len; + __asm { + mov esi,[bciphered]; + xor eax,eax; + mov ax,word ptr [esi]; + mov [len], eax; + } + bciphered+=2; clen-=2; // cut CRC32 length + + if(clen-CRC32::DIGESTSIZEerror = ERROR_BAD_LEN; + return NULL; + } + + BYTE crc32[CRC32::DIGESTSIZE]; + memset(crc32,0,sizeof(crc32)); + + CRC32().CalculateDigest(crc32, (PBYTE)(bciphered+CRC32::DIGESTSIZE), len); + + if(memcmp(crc32,bciphered,CRC32::DIGESTSIZE)) { // message is bad crc +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("cpp_decrypt: error bad_crc"); +#endif + free(ciphered); + ptr->error = ERROR_BAD_CRC; + return NULL; + } + bciphered+=CRC32::DIGESTSIZE; // cut CRC32 digest + clen=len; + } + + string unciphered; + + CBC_Mode::Decryption dec(p->KeyX,Tiger::DIGESTSIZE,IV); + StreamTransformationFilter cbcDecryptor(dec,new StringSink(unciphered)); + + cbcDecryptor.Put((PBYTE)bciphered,clen); + cbcDecryptor.MessageEnd(); + + free(ciphered); + SAFE_FREE(ptr->tmp); + + if(dataflag & DATA_GZIP) { + ptr->tmp = (LPSTR) cpp_gunzip((PBYTE)unciphered.data(),unciphered.length(),clen); + ptr->tmp[clen] = 0; + } + else { + ptr->tmp = (LPSTR) strdup(unciphered.c_str()); + } + + ptr->error = ERROR_NONE; + return ptr->tmp; + } + catch (...) { +#if defined(_DEBUG) || defined(NETLIB_LOG) + Sent_NetLog("cpp_decrypt: error seh"); +#endif + free(ciphered); + SAFE_FREE(ptr->tmp); + return NULL; + } +} + + +// encode message from ANSI into UTF8 if need +LPSTR __cdecl cpp_encodeA(HANDLE context, LPCSTR msg) { + + pCNTX ptr = get_context_on_id(context); + if(!ptr) return NULL; + cpp_alloc_pdata(ptr); pSIMDATA p = (pSIMDATA) ptr->pdata; + if(!p->KeyX) { ptr->error = ERROR_NO_KEYX; return NULL; } + + LPSTR szNewMsg = NULL; + LPSTR szOldMsg = (LPSTR) msg; + + if(ptr->features & FEATURES_UTF8) { + // ansi message: convert to unicode->utf-8 and encrypt. + int slen = strlen(szOldMsg)+1; + LPWSTR wstring = (LPWSTR) alloca(slen*sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, szOldMsg, -1, wstring, slen*sizeof(WCHAR)); + // encrypt + szNewMsg = cpp_encrypt(ptr, utf8encode(wstring)); + } + else { + // ansi message: encrypt. + szNewMsg = cpp_encrypt(ptr, szOldMsg); + } + + return szNewMsg; +} + + +// encode message from UTF8 +LPSTR __cdecl cpp_encodeU(HANDLE context, LPCSTR msg) { + + pCNTX ptr = get_context_on_id(context); + if(!ptr) return NULL; + cpp_alloc_pdata(ptr); pSIMDATA p = (pSIMDATA) ptr->pdata; + if(!p->KeyX) { ptr->error = ERROR_NO_KEYX; return NULL; } + + LPSTR szNewMsg = NULL; + LPSTR szOldMsg = (LPSTR) msg; + + if(ptr->features & FEATURES_UTF8) { + // utf8 message: encrypt. + szNewMsg = cpp_encrypt(ptr, szOldMsg); + } + else { + // utf8 message: convert to ansi and encrypt. + LPWSTR wstring = utf8decode(szOldMsg); + int wlen = wcslen(wstring)+1; + LPSTR astring = (LPSTR) alloca(wlen); + WideCharToMultiByte(CP_ACP, 0, (LPWSTR)szOldMsg, -1, astring, wlen, 0, 0); + szNewMsg = cpp_encrypt(ptr, astring); + } + + return szNewMsg; +} + + +// encode message from UNICODE into UTF8 if need +LPSTR __cdecl cpp_encodeW(HANDLE context, LPWSTR msg) { + + pCNTX ptr = get_context_on_id(context); + if(!ptr) return NULL; + cpp_alloc_pdata(ptr); pSIMDATA p = (pSIMDATA) ptr->pdata; + if(!p->KeyX) { ptr->error = ERROR_NO_KEYX; return NULL; } + + LPSTR szNewMsg = NULL; + LPSTR szOldMsg = (LPSTR) msg; + + if(ptr->features & FEATURES_UTF8) { + // unicode message: convert to utf-8 and encrypt. + szNewMsg = cpp_encrypt(ptr, utf8encode((LPWSTR)szOldMsg)); + } + else { + // unicode message: convert to ansi and encrypt. + int wlen = wcslen((LPWSTR)szOldMsg)+1; + LPSTR astring = (LPSTR) alloca(wlen); + WideCharToMultiByte(CP_ACP, 0, (LPWSTR)szOldMsg, -1, astring, wlen, 0, 0); + szNewMsg = cpp_encrypt(ptr, astring); + } + + return szNewMsg; +} + + +// decode message from UTF8 if need, return ANSIzUCS2z +LPSTR __cdecl cpp_decode(HANDLE context, LPCSTR szEncMsg) { + + pCNTX ptr = get_context_on_id(context); + if(!ptr) return NULL; + cpp_alloc_pdata(ptr); pSIMDATA p = (pSIMDATA) ptr->pdata; + if(!p->KeyX) { ptr->error = ERROR_NO_KEYX; return NULL; } + + LPSTR szNewMsg = NULL; + LPSTR szOldMsg = cpp_decrypt(ptr, szEncMsg); + + if(szOldMsg) { + if(ptr->features & FEATURES_UTF8) { + // utf8 message: convert to unicode -> ansii + LPWSTR wstring = utf8decode(szOldMsg); + int wlen = wcslen(wstring)+1; + szNewMsg = (LPSTR) malloc(wlen*(sizeof(WCHAR)+2)); // work.zy@gmail.com + WideCharToMultiByte(CP_ACP, 0, wstring, -1, szNewMsg, wlen, 0, 0); + memcpy(szNewMsg+strlen(szNewMsg)+1, wstring, wlen*sizeof(WCHAR)); // work.zy@gmail.com + } + else { + // ansi message: convert to unicode + int slen = strlen(szOldMsg)+1; + szNewMsg = (LPSTR) malloc(slen*(sizeof(WCHAR)+1)); + memcpy(szNewMsg,szOldMsg,slen); + WCHAR* wstring = (LPWSTR) alloca(slen*sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, szOldMsg, -1, wstring, slen*sizeof(WCHAR)); + memcpy(szNewMsg+slen,wstring,slen*sizeof(WCHAR)); + } + } + SAFE_FREE(ptr->tmp); + ptr->tmp = szNewMsg; + return szNewMsg; +} + + +// decode message return UTF8z +LPSTR __cdecl cpp_decodeU(HANDLE context, LPCSTR szEncMsg) { + + pCNTX ptr = get_context_on_id(context); + if(!ptr) return NULL; + cpp_alloc_pdata(ptr); pSIMDATA p = (pSIMDATA) ptr->pdata; + if(!p->KeyX) { ptr->error = ERROR_NO_KEYX; return NULL; } + + LPSTR szNewMsg = NULL; + LPSTR szOldMsg = cpp_decrypt(ptr, szEncMsg); + + if(szOldMsg) { + if(ptr->features & FEATURES_UTF8) { + // utf8 message: copy + szNewMsg = _strdup(szOldMsg); + } + else { + // ansi message: convert to utf8 + int slen = strlen(szOldMsg)+1; + LPWSTR wstring = (LPWSTR) alloca(slen*sizeof(WCHAR)); + MultiByteToWideChar(CP_ACP, 0, szOldMsg, -1, wstring, slen*sizeof(WCHAR)); + szNewMsg = _strdup(utf8encode(wstring)); + } + } + SAFE_FREE(ptr->tmp); + ptr->tmp = szNewMsg; + return szNewMsg; +} + + +int __cdecl cpp_encrypt_file(HANDLE context,LPCSTR file_in,LPCSTR file_out) { + + pCNTX ptr = get_context_on_id(context); + if(!ptr) return 0; + cpp_alloc_pdata(ptr); pSIMDATA p = (pSIMDATA) ptr->pdata; + if(!p->KeyX) return 0; + + try{ + CBC_Mode::Encryption enc(p->KeyX,Tiger::DIGESTSIZE,IV); + FileSource *f = new FileSource(file_in,true,new StreamTransformationFilter (enc,new FileSink(file_out))); + delete f; + } + catch (...) { + return 0; + } + return 1; +} + + +int __cdecl cpp_decrypt_file(HANDLE context,LPCSTR file_in,LPCSTR file_out) { + + pCNTX ptr = get_context_on_id(context); + if(!ptr) return 0; + cpp_alloc_pdata(ptr); pSIMDATA p = (pSIMDATA) ptr->pdata; + if(!p->KeyX) return 0; + + try{ + CBC_Mode::Decryption dec(p->KeyX,Tiger::DIGESTSIZE,IV); + FileSource *f = new FileSource(file_in,true,new StreamTransformationFilter (dec,new FileSink(file_out))); + delete f; + } + catch (...) { + return 0; + } + return 1; +} + + +// EOF diff --git a/CryptoPP/crypto/3desval.dat b/CryptoPP/crypto/3desval.dat new file mode 100644 index 0000000..d43e849 --- /dev/null +++ b/CryptoPP/crypto/3desval.dat @@ -0,0 +1,3 @@ +0123456789abcdeffedcba9876543210 0123456789abcde7 7f1d0a77826b8aff +0123456789abcdeffedcba987654321089abcdef01234567 0123456789abcde7 de0b7c06ae5e0ed5 +0123456789ABCDEF01010101010101011011121314151617 94DBE082549A14EF 9011121314151617 diff --git a/CryptoPP/crypto/3way.cpp b/CryptoPP/crypto/3way.cpp new file mode 100644 index 0000000..f1265ce --- /dev/null +++ b/CryptoPP/crypto/3way.cpp @@ -0,0 +1,139 @@ +// 3way.cpp - modifed by Wei Dai from Joan Daemen's 3way.c +// The original code and all modifications are in the public domain. + +#include "pch.h" +#include "3way.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +void ThreeWay_TestInstantiations() +{ + ThreeWay::Encryption x1; + ThreeWay::Decryption x2; +} + +static const word32 START_E = 0x0b0b; // round constant of first encryption round +static const word32 START_D = 0xb1b1; // round constant of first decryption round +static const word32 RC_MODULUS = 0x11011; + +static inline word32 reverseBits(word32 a) +{ + a = ((a & 0xAAAAAAAA) >> 1) | ((a & 0x55555555) << 1); + a = ((a & 0xCCCCCCCC) >> 2) | ((a & 0x33333333) << 2); + return ((a & 0xF0F0F0F0) >> 4) | ((a & 0x0F0F0F0F) << 4); +} + +#define mu(a0, a1, a2) \ +{ \ + a1 = reverseBits(a1); \ + word32 t = reverseBits(a0); \ + a0 = reverseBits(a2); \ + a2 = t; \ +} + +#define pi_gamma_pi(a0, a1, a2) \ +{ \ + word32 b0, b2; \ + b2 = rotlFixed(a2, 1U); \ + b0 = rotlFixed(a0, 22U); \ + a0 = rotlFixed(b0 ^ (a1|(~b2)), 1U); \ + a2 = rotlFixed(b2 ^ (b0|(~a1)), 22U);\ + a1 ^= (b2|(~b0)); \ +} + +// thanks to Paulo Barreto for this optimized theta() +#define theta(a0, a1, a2) \ +{ \ + word32 b0, b1, c; \ + c = a0 ^ a1 ^ a2; \ + c = rotlFixed(c, 16U) ^ rotlFixed(c, 8U); \ + b0 = (a0 << 24) ^ (a2 >> 8) ^ (a1 << 8) ^ (a0 >> 24); \ + b1 = (a1 << 24) ^ (a0 >> 8) ^ (a2 << 8) ^ (a1 >> 24); \ + a0 ^= c ^ b0; \ + a1 ^= c ^ b1; \ + a2 ^= c ^ (b0 >> 16) ^ (b1 << 16); \ +} + +#define rho(a0, a1, a2) \ +{ \ + theta(a0, a1, a2); \ + pi_gamma_pi(a0, a1, a2); \ +} + +void ThreeWay::Base::UncheckedSetKey(const byte *uk, unsigned int length, const NameValuePairs ¶ms) +{ + AssertValidKeyLength(length); + + m_rounds = GetRoundsAndThrowIfInvalid(params, this); + + for (unsigned int i=0; i<3; i++) + m_k[i] = (word32)uk[4*i+3] | ((word32)uk[4*i+2]<<8) | ((word32)uk[4*i+1]<<16) | ((word32)uk[4*i]<<24); + + if (!IsForwardTransformation()) + { + theta(m_k[0], m_k[1], m_k[2]); + mu(m_k[0], m_k[1], m_k[2]); + m_k[0] = ByteReverse(m_k[0]); + m_k[1] = ByteReverse(m_k[1]); + m_k[2] = ByteReverse(m_k[2]); + } +} + +void ThreeWay::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + typedef BlockGetAndPut Block; + + word32 a0, a1, a2; + Block::Get(inBlock)(a0)(a1)(a2); + + word32 rc = START_E; + + for(unsigned i=0; i Block; + + word32 a0, a1, a2; + Block::Get(inBlock)(a0)(a1)(a2); + + word32 rc = START_D; + + mu(a0, a1, a2); + for(unsigned i=0; i, public FixedKeyLength<12>, public VariableRounds<11> +{ + static const char *StaticAlgorithmName() {return "3-Way";} +}; + +/// 3-Way +class ThreeWay : public ThreeWay_Info, public BlockCipherDocumentation +{ + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + public: + void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms); + + protected: + unsigned int m_rounds; + FixedSizeSecBlock m_k; + }; + + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef ThreeWay::Encryption ThreeWayEncryption; +typedef ThreeWay::Decryption ThreeWayDecryption; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/3wayval.dat b/CryptoPP/crypto/3wayval.dat new file mode 100644 index 0000000..79e6ebd --- /dev/null +++ b/CryptoPP/crypto/3wayval.dat @@ -0,0 +1,5 @@ +000000000000000000000000 000000010000000100000001 4059c76e83ae9dc4ad21ecf7 +000000060000000500000004 000000030000000200000001 d2f05b5ed6144138cab920cd +def01234456789abbcdef012 234567899abcdef001234567 0aa55dbb9cdddb6d7cdb76b2 +d2f05b5ed6144138cab920cd 4059c76e83ae9dc4ad21ecf7 478ea8716b13f17c15b155ed + diff --git a/CryptoPP/crypto/Doxyfile b/CryptoPP/crypto/Doxyfile new file mode 100644 index 0000000..2b7398e --- /dev/null +++ b/CryptoPP/crypto/Doxyfile @@ -0,0 +1,1147 @@ +# Doxyfile 1.3.7 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = Crypto++ + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = doc + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 2 levels of 10 sub-directories under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of source +# files, where putting all generated files in the same directory would otherwise +# cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, +# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en +# (Japanese with English messages), Korean, Korean-en, Norwegian, Polish, Portuguese, +# Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# This tag can be used to specify the encoding used in the generated output. +# The encoding is not always determined by the language that is chosen, +# but also whether or not the output is meant for Windows or non-Windows users. +# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES +# forces the Windows encoding (this is the default for the Windows binary), +# whereas setting the tag to NO uses a Unix-style encoding (the default for +# all platforms other than Windows). + +USE_WINDOWS_ENCODING = YES + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is used +# as the annotated text. Otherwise, the brief description is used as-is. If left +# blank, the following values are used ("$name" is automatically replaced with the +# name of the entity): "The $name class" "The $name widget" "The $name file" +# "is" "provides" "specifies" "contains" "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited +# members of a class in the documentation of that class as if those members were +# ordinary class members. Constructors, destructors and assignment operators of +# the base classes will not be shown. + +INLINE_INHERITED_MEMB = YES + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explicit @brief command for a brief description. + +JAVADOC_AUTOBRIEF = YES + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = Yes + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources +# only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# users are advised to set this option to NO. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = NO + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = No + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = No + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = . + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp +# *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm + +FILE_PATTERNS = *.h \ + *.cpp + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = adhoc.cpp + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories +# that are symbolic links (a Unix filesystem feature) are excluded from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = . + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. + +INPUT_FILTER = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = NO + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 3 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = YES + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4 + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = YES + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_PREDEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = . + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. + +PREDEFINED = _WIN32 \ + _WINDOWS \ + WORD64_AVAILABLE \ + __FreeBSD__ \ + CRYPTOPP_DOXYGEN_PROCESSING + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse the +# parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base or +# super classes. Setting the tag to NO turns the diagrams off. Note that this +# option is superseded by the HAVE_DOT option below. This is only a fallback. It is +# recommended to install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found on the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes that +# lay further from the root node will be omitted. Note that setting this option to +# 1 or 2 may greatly reduce the computation time needed for large code bases. Also +# note that a graph may be further truncated if the graph's image dimensions are +# not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH and MAX_DOT_GRAPH_HEIGHT). +# If 0 is used for the depth value (the default), the graph is not depth-constrained. + +MAX_DOT_GRAPH_DEPTH = 0 + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/CryptoPP/crypto/GNUmakefile b/CryptoPP/crypto/GNUmakefile new file mode 100644 index 0000000..bd103a1 --- /dev/null +++ b/CryptoPP/crypto/GNUmakefile @@ -0,0 +1,158 @@ +CXXFLAGS = -DNDEBUG -g -O2 +# the following options reduce code size, but breaks link or makes link very slow on some systems +# CXXFLAGS += -ffunction-sections -fdata-sections +# LDFLAGS += -Wl,--gc-sections +ARFLAGS = -cr # ar needs the dash on OpenBSD +RANLIB = ranlib +CP = cp +MKDIR = mkdir +EGREP = egrep +UNAME = $(shell uname) +ISX86 = $(shell uname -m | $(EGREP) -c "i.86|x86|i86") +ISMINGW = $(shell uname | $(EGREP) -c "MINGW32") + +# Default prefix for make install +ifeq ($(PREFIX),) +PREFIX = /usr +endif + +ifeq ($(CXX),gcc) # for some reason CXX is gcc on cygwin 1.1.4 +CXX = g++ +endif + +ifeq ($(ISX86),1) + +GCC34_OR_LATER = $(shell $(CXX) --version 2>&1 | $(EGREP) -c "\(GCC\) (3.[4-9]|[4-9])") +GCC42_OR_LATER = $(shell $(CXX) --version 2>&1 | $(EGREP) -c "\(GCC\) (4.[2-9]|[5-9])") +INTEL_COMPILER = $(shell $(CXX) --version 2>&1 | $(EGREP) -c "\(ICC\)") +GAS210_OR_LATER = $(shell echo "" | $(AS) -v 2>&1 | $(EGREP) -c "GNU assembler version (2.[1-9][0-9]|[3-9])") + +ifneq ($(GCC34_OR_LATER) $(INTEL_COMPILER),0 0) +ifneq ($(GCC42_OR_LATER),0) +CXXFLAGS += -march=native -mtune=native +else +# -msse2 is in GCC 3.3, but it causes internal compiler error on salsa.cpp, +# so don't use it unless we're at GCC 3.4 or later +# actually, we're not using SSE2 intrinsics anymore, and -msse2 causes invalid instructions on non-SSE2 CPUs +# CXXFLAGS += -msse2 +endif +endif + +ifeq ($(GAS210_OR_LATER),0) # .intel_syntax wasn't supported until GNU assembler 2.10 +CXXFLAGS += -DCRYPTOPP_DISABLE_ASM +else +ifeq ($(UNAME),SunOS) +CXXFLAGS += -Wa,--divide # allow use of "/" operator +endif +endif + +endif + +ifeq ($(ISMINGW),1) +LDLIBS += -lws2_32 +endif + +ifeq ($(UNAME),) # for DJGPP, where uname doesn't exist +CXXFLAGS += -mbnu210 +else +CXXFLAGS += -pipe +endif + +ifeq ($(UNAME),Linux) +LDFLAGS += -pthread +endif + +ifeq ($(UNAME),Darwin) +AR = libtool +ARFLAGS = -static -o +CXX = c++ +IS_GCC2 = $(shell $(CXX) -v 2>&1 | $(EGREP) -c gcc-932) +ifeq ($(IS_GCC2),1) +CXXFLAGS += -fno-coalesce-templates -fno-coalesce-static-vtables +LDLIBS += -lstdc++ +LDFLAGS += -flat_namespace -undefined suppress -m +endif +endif + +ifeq ($(UNAME),SunOS) +LDLIBS += -lnsl -lsocket +ifeq ($(CXX),CC) # override flags for CC (Solaris native C++ compiler) +CXXFLAGS = -DNDEBUG -O -g -native +LDFLAGS = +ifeq ($(ISX86),1) +# SSE2 intrinsics should work in Sun Studio 12, but we're not using SSE2 intrinsics anymore +# CXXFLAGS += -xarch=sse2 -D__SSE2__ +endif +endif +endif + +SRCS = $(wildcard *.cpp) +ifeq ($(SRCS),) # workaround wildcard function bug in GNU Make 3.77 +SRCS = $(shell echo *.cpp) +endif + +OBJS = $(SRCS:.cpp=.o) +# test.o needs to be after bench.o for cygwin 1.1.4 (possible ld bug?) +TESTOBJS = bench.o bench2.o test.o validat1.o validat2.o validat3.o adhoc.o datatest.o regtest.o fipsalgt.o dlltest.o +LIBOBJS = $(filter-out $(TESTOBJS),$(OBJS)) + +DLLSRCS = algebra.cpp algparam.cpp asn.cpp basecode.cpp cbcmac.cpp channels.cpp cryptlib.cpp des.cpp dessp.cpp dh.cpp dll.cpp dsa.cpp ec2n.cpp eccrypto.cpp ecp.cpp eprecomp.cpp files.cpp filters.cpp fips140.cpp fipstest.cpp gf2n.cpp gfpcrypt.cpp hex.cpp hmac.cpp integer.cpp iterhash.cpp misc.cpp modes.cpp modexppc.cpp mqueue.cpp nbtheory.cpp oaep.cpp osrng.cpp pch.cpp pkcspad.cpp pubkey.cpp queue.cpp randpool.cpp rdtables.cpp rijndael.cpp rng.cpp rsa.cpp sha.cpp simple.cpp skipjack.cpp strciphr.cpp trdlocal.cpp +DLLOBJS = $(DLLSRCS:.cpp=.export.o) +LIBIMPORTOBJS = $(LIBOBJS:.o=.import.o) +TESTIMPORTOBJS = $(TESTOBJS:.o=.import.o) +DLLTESTOBJS = dlltest.dllonly.o + +all: cryptest.exe + +clean: + $(RM) cryptest.exe libcryptopp.a $(LIBOBJS) $(TESTOBJS) cryptopp.dll libcryptopp.dll.a libcryptopp.import.a cryptest.import.exe dlltest.exe $(DLLOBJS) $(LIBIMPORTOBJS) $(TESTIMPORTOBJS) $(DLLTESTOBJS) + +install: + $(MKDIR) -p $(PREFIX)/include/cryptopp $(PREFIX)/lib $(PREFIX)/bin + $(CP) *.h $(PREFIX)/include/cryptopp + $(CP) *.a $(PREFIX)/lib + $(CP) *.exe $(PREFIX)/bin + +libcryptopp.a: $(LIBOBJS) + $(AR) $(ARFLAGS) $@ $(LIBOBJS) + $(RANLIB) $@ + +cryptest.exe: libcryptopp.a $(TESTOBJS) + $(CXX) -o $@ $(CXXFLAGS) $(TESTOBJS) -L. -lcryptopp $(LDFLAGS) $(LDLIBS) + +nolib: $(OBJS) # makes it faster to test changes + $(CXX) -o ct $(CXXFLAGS) $(OBJS) $(LDFLAGS) $(LDLIBS) + +dll: cryptest.import.exe dlltest.exe + +cryptopp.dll: $(DLLOBJS) + $(CXX) -shared -o $@ $(CXXFLAGS) $(DLLOBJS) $(LDFLAGS) $(LDLIBS) -Wl,--out-implib=libcryptopp.dll.a + +libcryptopp.import.a: $(LIBIMPORTOBJS) + $(AR) $(ARFLAGS) $@ $(LIBIMPORTOBJS) + $(RANLIB) $@ + +cryptest.import.exe: cryptopp.dll libcryptopp.import.a $(TESTIMPORTOBJS) + $(CXX) -o $@ $(CXXFLAGS) $(TESTIMPORTOBJS) -L. -lcryptopp.dll -lcryptopp.import $(LDFLAGS) $(LDLIBS) + +dlltest.exe: cryptopp.dll $(DLLTESTOBJS) + $(CXX) -o $@ $(CXXFLAGS) $(DLLTESTOBJS) -L. -lcryptopp.dll $(LDFLAGS) $(LDLIBS) + +adhoc.cpp: adhoc.cpp.proto +ifeq ($(wildcard adhoc.cpp),) + cp adhoc.cpp.proto adhoc.cpp +else + touch adhoc.cpp +endif + +%.dllonly.o : %.cpp + $(CXX) $(CXXFLAGS) -DCRYPTOPP_DLL_ONLY -c $< -o $@ + +%.import.o : %.cpp + $(CXX) $(CXXFLAGS) -DCRYPTOPP_IMPORTS -c $< -o $@ + +%.export.o : %.cpp + $(CXX) $(CXXFLAGS) -DCRYPTOPP_EXPORTS -c $< -o $@ + +%.o : %.cpp + $(CXX) $(CXXFLAGS) -c $< diff --git a/CryptoPP/crypto/License.txt b/CryptoPP/crypto/License.txt new file mode 100644 index 0000000..8ec0a40 --- /dev/null +++ b/CryptoPP/crypto/License.txt @@ -0,0 +1,68 @@ +Compilation Copyright (c) 1995-2006 by Wei Dai. All rights reserved. +This copyright applies only to this software distribution package +as a compilation, and does not imply a copyright on any particular +file in the package. + +The following files are copyrighted by their respective original authors, +and their use is subject to additional licenses included in these files. + +mars.cpp - Copyright 1998 Brian Gladman. + +All other files in this compilation are placed in the public domain by +Wei Dai and other contributors. + +I would like to thank the following authors for placing their works into +the public domain: + +Joan Daemen - 3way.cpp +Leonard Janke - cast.cpp, seal.cpp +Steve Reid - cast.cpp +Phil Karn - des.cpp +Michael Paul Johnson - diamond.cpp +Andrew M. Kuchling - md2.cpp, md4.cpp +Colin Plumb - md5.cpp, md5mac.cpp +Seal Woods - rc6.cpp +Chris Morgan - rijndael.cpp +Paulo Baretto - rijndael.cpp, skipjack.cpp, square.cpp +Richard De Moliner - safer.cpp +Matthew Skala - twofish.cpp +Kevin Springle - camellia.cpp, shacal2.cpp, ttmac.cpp, whrlpool.cpp, ripemd.cpp + +Permission to use, copy, modify, and distribute this compilation for +any purpose, including commercial applications, is hereby granted +without fee, subject to the following restrictions: + +1. Any copy or modification of this compilation in any form, except +in object code form as part of an application software, must include +the above copyright notice and this license. + +2. Users of this software agree that any modification or extension +they provide to Wei Dai will be considered public domain and not +copyrighted unless it includes an explicit copyright notice. + +3. Wei Dai makes no warranty or representation that the operation of the +software in this compilation will be error-free, and Wei Dai is under no +obligation to provide any services, by way of maintenance, update, or +otherwise. THE SOFTWARE AND ANY DOCUMENTATION ARE PROVIDED "AS IS" +WITHOUT EXPRESS OR IMPLIED WARRANTY INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. IN NO EVENT WILL WEI DAI OR ANY OTHER CONTRIBUTOR BE LIABLE FOR +DIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +4. Users will not use Wei Dai or any other contributor's name in any +publicity or advertising, without prior written consent in each case. + +5. Export of this software from the United States may require a +specific license from the United States Government. It is the +responsibility of any person or organization contemplating export +to obtain such a license before exporting. + +6. Certain parts of this software may be protected by patents. It +is the users' responsibility to obtain the appropriate +licenses before using those parts. + +If this compilation is used in object code form in an application +software, acknowledgement of the author is not required but would be +appreciated. The contribution of any useful modifications or extensions +to Wei Dai is not required but would also be appreciated. diff --git a/CryptoPP/crypto/Readme.txt b/CryptoPP/crypto/Readme.txt new file mode 100644 index 0000000..d4d3acd --- /dev/null +++ b/CryptoPP/crypto/Readme.txt @@ -0,0 +1,414 @@ +Crypto++: a C++ Class Library of Cryptographic Schemes +Version 5.5.2 (9/24/2007) + +Crypto++ Library is a free C++ class library of cryptographic schemes. +Currently the library contains the following algorithms: + + algorithm type name + + high speed stream ciphers Panama, Salsa20, Sosemanuk + + AES and AES candidates AES (Rijndael), RC6, MARS, Twofish, Serpent, + CAST-256 + + IDEA, Triple-DES (DES-EDE2 and DES-EDE3), + other block ciphers Camellia, RC5, Blowfish, TEA, XTEA, + Skipjack, SHACAL-2 + + block cipher modes of operation ECB, CBC, CBC ciphertext stealing (CTS), + CFB, OFB, counter mode (CTR) + + message authentication codes VMAC, HMAC, CBC-MAC, DMAC, Two-Track-MAC + + SHA-1, SHA-2 (SHA-224, SHA-256, SHA-384, and + hash functions SHA-512), Tiger, WHIRLPOOL, RIPEMD-128, + RIPEMD-256, RIPEMD-160, RIPEMD-320 + + RSA, DSA, ElGamal, Nyberg-Rueppel (NR), + public-key cryptography Rabin, Rabin-Williams (RW), LUC, LUCELG, + DLIES (variants of DHAES), ESIGN + + padding schemes for public-key PKCS#1 v2.0, OAEP, PSS, PSSR, IEEE P1363 + systems EMSA2 and EMSA5 + + Diffie-Hellman (DH), Unified Diffie-Hellman + key agreement schemes (DH2), Menezes-Qu-Vanstone (MQV), LUCDIF, + XTR-DH + + elliptic curve cryptography ECDSA, ECNR, ECIES, ECDH, ECMQV + + insecure or obsolescent MD2, MD4, MD5, Panama Hash, DES, ARC4, SEAL +algorithms retained for backwards 3.0, WAKE, WAKE-OFB, DESX (DES-XEX3), RC2, + compatibility and historical SAFER, 3-WAY, GOST, SHARK, CAST-128, Square + value + +Other features include: + + * pseudo random number generators (PRNG): ANSI X9.17 appendix C, RandomPool + * password based key derivation functions: PBKDF1 and PBKDF2 from PKCS #5, + PBKDF from PKCS #12 appendix B + * Shamir's secret sharing scheme and Rabin's information dispersal algorithm + (IDA) + * fast multi-precision integer (bignum) and polynomial operations + * finite field arithmetics, including GF(p) and GF(2^n) + * prime number generation and verification + * useful non-cryptographic algorithms + + DEFLATE (RFC 1951) compression/decompression with gzip (RFC 1952) and + zlib (RFC 1950) format support + + hex, base-32, and base-64 coding/decoding + + 32-bit CRC and Adler32 checksum + * class wrappers for these operating system features (optional): + + high resolution timers on Windows, Unix, and Mac OS + + Berkeley and Windows style sockets + + Windows named pipes + + /dev/random, /dev/urandom, /dev/srandom + + Microsoft's CryptGenRandom on Windows + * A high level interface for most of the above, using a filter/pipeline + metaphor + * benchmarks and validation testing + * x86, x86-64 (x64), MMX, and SSE2 assembly code for the most commonly used + algorithms, with run-time CPU feature detection and code selection + * some versions are available in FIPS 140-2 validated form + +You are welcome to use it for any purpose without paying me, but see +License.txt for the fine print. + +The following compilers are supported for this release. Please visit +http://www.cryptopp.com the most up to date build instructions and porting notes. + + * MSVC 6.0 - 2008 + * GCC 3.3 - 4.2 + * Borland C++Builder 2006 - 2007 + * Intel C++ Compiler 9.1 - 10.0 + * Sun Studio 11 - 12 (CC 5.8 - 5.9) + +*** Important Usage Notes *** + +1. If a constructor for A takes a pointer to an object B (except primitive +types such as int and char), then A owns B and will delete B at A's +destruction. If a constructor for A takes a reference to an object B, +then the caller retains ownership of B and should not destroy it until +A no longer needs it. + +2. Crypto++ is thread safe at the class level. This means you can use +Crypto++ safely in a multithreaded application, but you must provide +synchronization when multiple threads access a common Crypto++ object. + +*** MSVC-Specific Information *** + +On Windows, Crypto++ can be compiled into 3 forms: a static library +including all algorithms, a DLL with only FIPS Approved algorithms, and +a static library with only algorithms not in the DLL. +(FIPS Approved means Approved according to the FIPS 140-2 standard.) +The DLL may be used by itself, or it may be used together with the second +form of the static library. MSVC project files are included to build +all three forms, and sample applications using each of the three forms +are also included. + +To compile Crypto++ with MSVC, open the "cryptest.dsw" (for MSVC 6 and MSVC .NET +2003) or "cryptest.sln" (for MSVC .NET 2005) workspace file and build one or +more of the following projects: + +cryptdll - This builds the DLL. Please note that if you wish to use Crypto++ + as a FIPS validated module, you must use a pre-built DLL that has undergone + the FIPS validation process instead of building your own. +dlltest - This builds a sample application that only uses the DLL. +cryptest Non-DLL-Import Configuration - This builds the full static library + along with a full test driver. +cryptest DLL-Import Configuration - This builds a static library containing + only algorithms not in the DLL, along with a full test driver that uses + both the DLL and the static library. + +To use the Crypto++ DLL in your application, #include "dll.h" before including +any other Crypto++ header files, and place the DLL in the same directory as +your .exe file. dll.h includes the line #pragma comment(lib, "cryptopp") +so you don't have to explicitly list the import library in your project +settings. To use a static library form of Crypto++, specify it as +an additional library to link with in your project settings. +In either case you should check the compiler options to +make sure that the library and your application are using the same C++ +run-time libraries and calling conventions. + +*** DLL Memory Management *** + +Because it's possible for the Crypto++ DLL to delete objects allocated +by the calling application, they must use the same C++ memory heap. Three +methods are provided to achieve this. +1. The calling application can tell Crypto++ what heap to use. This method + is required when the calling application uses a non-standard heap. +2. Crypto++ can tell the calling application what heap to use. This method + is required when the calling application uses a statically linked C++ Run + Time Library. (Method 1 does not work in this case because the Crypto++ DLL + is initialized before the calling application's heap is initialized.) +3. Crypto++ can automatically use the heap provided by the calling application's + dynamically linked C++ Run Time Library. The calling application must + make sure that the dynamically linked C++ Run Time Library is initialized + before Crypto++ is loaded. (At this time it is not clear if it is possible + to control the order in which DLLs are initialized on Windows 9x machines, + so it might be best to avoid using this method.) + +When Crypto++ attaches to a new process, it searches all modules loaded +into the process space for exported functions "GetNewAndDeleteForCryptoPP" +and "SetNewAndDeleteFromCryptoPP". If one of these functions is found, +Crypto++ uses methods 1 or 2, respectively, by calling the function. +Otherwise, method 3 is used. + +*** GCC-Specific Information *** + +A makefile is included for you to compile Crypto++ with GCC. Make sure +you are using GNU Make and GNU ld. The make process will produce two files, +libcryptopp.a and cryptest.exe. Run "cryptest.exe v" for the validation +suite. + +*** Documentation and Support *** + +Crypto++ is documented through inline comments in header files, which are +processed through Doxygen to produce an HTML reference manual. You can find +a link to the manual from http://www.cryptopp.com. Also at that site is +the Crypto++ FAQ, which you should browse through before attempting to +use this library, because it will likely answer many of questions that +may come up. + +If you run into any problems, please try the Crypto++ mailing list. +The subscription information and the list archive are available on +http://www.cryptopp.com. You can also email me directly by visiting +http://www.weidai.com, but you will probably get a faster response through +the mailing list. + +*** History *** + +1.0 - First public release. Withdrawn at the request of RSA DSI. + - included Blowfish, BBS, DES, DH, Diamond, DSA, ElGamal, IDEA, + MD5, RC4, RC5, RSA, SHA, WAKE, secret sharing, DEFLATE compression + - had a serious bug in the RSA key generation code. + +1.1 - Removed RSA, RC4, RC5 + - Disabled calls to RSAREF's non-public functions + - Minor bugs fixed + +2.0 - a completely new, faster multiprecision integer class + - added MD5-MAC, HAVAL, 3-WAY, TEA, SAFER, LUC, Rabin, BlumGoldwasser, + elliptic curve algorithms + - added the Lucas strong probable primality test + - ElGamal encryption and signature schemes modified to avoid weaknesses + - Diamond changed to Diamond2 because of key schedule weakness + - fixed bug in WAKE key setup + - SHS class renamed to SHA + - lots of miscellaneous optimizations + +2.1 - added Tiger, HMAC, GOST, RIPE-MD160, LUCELG, LUCDIF, XOR-MAC, + OAEP, PSSR, SHARK + - added precomputation to DH, ElGamal, DSA, and elliptic curve algorithms + - added back RC5 and a new RSA + - optimizations in elliptic curves over GF(p) + - changed Rabin to use OAEP and PSSR + - changed many classes to allow copy constructors to work correctly + - improved exception generation and handling + +2.2 - added SEAL, CAST-128, Square + - fixed bug in HAVAL (padding problem) + - fixed bug in triple-DES (decryption order was reversed) + - fixed bug in RC5 (couldn't handle key length not a multiple of 4) + - changed HMAC to conform to RFC-2104 (which is not compatible + with the original HMAC) + - changed secret sharing and information dispersal to use GF(2^32) + instead of GF(65521) + - removed zero knowledge prover/verifier for graph isomorphism + - removed several utility classes in favor of the C++ standard library + +2.3 - ported to EGCS + - fixed incomplete workaround of min/max conflict in MSVC + +3.0 - placed all names into the "CryptoPP" namespace + - added MD2, RC2, RC6, MARS, RW, DH2, MQV, ECDHC, CBC-CTS + - added abstract base classes PK_SimpleKeyAgreementDomain and + PK_AuthenticatedKeyAgreementDomain + - changed DH and LUCDIF to implement the PK_SimpleKeyAgreementDomain + interface and to perform domain parameter and key validation + - changed interfaces of PK_Signer and PK_Verifier to sign and verify + messages instead of message digests + - changed OAEP to conform to PKCS#1 v2.0 + - changed benchmark code to produce HTML tables as output + - changed PSSR to track IEEE P1363a + - renamed ElGamalSignature to NR and changed it to track IEEE P1363 + - renamed ECKEP to ECMQVC and changed it to track IEEE P1363 + - renamed several other classes for clarity + - removed support for calling RSAREF + - removed option to compile old SHA (SHA-0) + - removed option not to throw exceptions + +3.1 - added ARC4, Rijndael, Twofish, Serpent, CBC-MAC, DMAC + - added interface for querying supported key lengths of symmetric ciphers + and MACs + - added sample code for RSA signature and verification + - changed CBC-CTS to be compatible with RFC 2040 + - updated SEAL to version 3.0 of the cipher specification + - optimized multiprecision squaring and elliptic curves over GF(p) + - fixed bug in MARS key setup + - fixed bug with attaching objects to Deflator + +3.2 - added DES-XEX3, ECDSA, DefaultEncryptorWithMAC + - renamed DES-EDE to DES-EDE2 and TripleDES to DES-EDE3 + - optimized ARC4 + - generalized DSA to allow keys longer than 1024 bits + - fixed bugs in GF2N and ModularArithmetic that can cause calculation errors + - fixed crashing bug in Inflator when given invalid inputs + - fixed endian bug in Serpent + - fixed padding bug in Tiger + +4.0 - added Skipjack, CAST-256, Panama, SHA-2 (SHA-256, SHA-384, and SHA-512), + and XTR-DH + - added a faster variant of Rabin's Information Dispersal Algorithm (IDA) + - added class wrappers for these operating system features: + - high resolution timers on Windows, Unix, and MacOS + - Berkeley and Windows style sockets + - Windows named pipes + - /dev/random and /dev/urandom on Linux and FreeBSD + - Microsoft's CryptGenRandom on Windows + - added support for SEC 1 elliptic curve key format and compressed points + - added support for X.509 public key format (subjectPublicKeyInfo) for + RSA, DSA, and elliptic curve schemes + - added support for DER and OpenPGP signature format for DSA + - added support for ZLIB compressed data format (RFC 1950) + - changed elliptic curve encryption to use ECIES (as defined in SEC 1) + - changed MARS key schedule to reflect the latest specification + - changed BufferedTransformation interface to support multiple channels + and messages + - changed CAST and SHA-1 implementations to use public domain source code + - fixed bug in StringSource + - optmized multi-precision integer code for better performance + +4.1 - added more support for the recommended elliptic curve parameters in SEC 2 + - added Panama MAC, MARC4 + - added IV stealing feature to CTS mode + - added support for PKCS #8 private key format for RSA, DSA, and elliptic + curve schemes + - changed Deflate, MD5, Rijndael, and Twofish to use public domain code + - fixed a bug with flushing compressed streams + - fixed a bug with decompressing stored blocks + - fixed a bug with EC point decompression using non-trinomial basis + - fixed a bug in NetworkSource::GeneralPump() + - fixed a performance issue with EC over GF(p) decryption + - fixed syntax to allow GCC to compile without -fpermissive + - relaxed some restrictions in the license + +4.2 - added support for longer HMAC keys + - added MD4 (which is not secure so use for compatibility purposes only) + - added compatibility fixes/workarounds for STLport 4.5, GCC 3.0.2, + and MSVC 7.0 + - changed MD2 to use public domain code + - fixed a bug with decompressing multiple messages with the same object + - fixed a bug in CBC-MAC with MACing multiple messages with the same object + - fixed a bug in RC5 and RC6 with zero-length keys + - fixed a bug in Adler32 where incorrect checksum may be generated + +5.0 - added ESIGN, DLIES, WAKE-OFB, PBKDF1 and PBKDF2 from PKCS #5 + - added key validation for encryption and signature public/private keys + - renamed StreamCipher interface to SymmetricCipher, which is now implemented + by both stream ciphers and block cipher modes including ECB and CBC + - added keying interfaces to support resetting of keys and IVs without + having to destroy and recreate objects + - changed filter interface to support non-blocking input/output + - changed SocketSource and SocketSink to use overlapped I/O on Microsoft Windows + - grouped related classes inside structs to help templates, for example + AESEncryption and AESDecryption are now AES::Encryption and AES::Decryption + - where possible, typedefs have been added to improve backwards + compatibility when the CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY macro is defined + - changed Serpent, HAVAL and IDEA to use public domain code + - implemented SSE2 optimizations for Integer operations + - fixed a bug in HMAC::TruncatedFinal() + - fixed SKIPJACK byte ordering following NIST clarification dated 5/9/02 + +5.01 - added known answer test for X9.17 RNG in FIPS 140 power-up self test + - submitted to NIST/CSE, but not publicly released + +5.02 - changed EDC test to MAC integrity check using HMAC/SHA1 + - improved performance of integrity check + - added blinding to defend against RSA timing attack + +5.03 - created DLL version of Crypto++ for FIPS 140-2 validation + - fixed vulnerabilities in GetNextIV for CTR and OFB modes + +5.0.4 - Removed DES, SHA-256, SHA-384, SHA-512 from DLL + +5.1 - added PSS padding and changed PSSR to track IEEE P1363a draft standard + - added blinding for RSA and Rabin to defend against timing attacks + on decryption operations + - changed signing and decryption APIs to support the above + - changed WaitObjectContainer to allow waiting for more than 64 + objects at a time on Win32 platforms + - fixed a bug in CBC and ECB modes with processing non-aligned data + - fixed standard conformance bugs in DLIES (DHAES mode) and RW/EMSA2 + signature scheme (these fixes are not backwards compatible) + - fixed a number of compiler warnings, minor bugs, and portability problems + - removed Sapphire + +5.2 - merged in changes for 5.01 - 5.0.4 + - added support for using encoding parameters and key derivation parameters + with public key encryption (implemented by OAEP and DL/ECIES) + - added Camellia, SHACAL-2, Two-Track-MAC, Whirlpool, RIPEMD-320, + RIPEMD-128, RIPEMD-256, Base-32 coding, FIPS variant of CFB mode + - added ThreadUserTimer for timing thread CPU usage + - added option for password-based key derivation functions + to iterate until a mimimum elapsed thread CPU time is reached + - added option (on by default) for DEFLATE compression to detect + uncompressible files and process them more quickly + - improved compatibility and performance on 64-bit platforms, + including Alpha, IA-64, x86-64, PPC64, Sparc64, and MIPS64 + - fixed ONE_AND_ZEROS_PADDING to use 0x80 instead 0x01 as padding. + - fixed encoding/decoding of PKCS #8 privateKeyInfo to properly + handle optional attributes + +5.2.1 - fixed bug in the "dlltest" DLL testing program + - fixed compiling with STLport using VC .NET + - fixed compiling with -fPIC using GCC + - fixed compiling with -msse2 on systems without memalign() + - fixed inability to instantiate PanamaMAC + - fixed problems with inline documentation + +5.2.2 - added SHA-224 + - put SHA-256, SHA-384, SHA-512, RSASSA-PSS into DLL + +5.2.3 - fixed issues with FIPS algorithm test vectors + - put RSASSA-ISO into DLL + +5.3 - ported to MSVC 2005 with support for x86-64 + - added defense against AES timing attacks, and more AES test vectors + - changed StaticAlgorithmName() of Rijndael to "AES", CTR to "CTR" + +5.4 - added Salsa20 + - updated Whirlpool to version 3.0 + - ported to GCC 4.1, Sun C++ 5.8, and Borland C++Builder 2006 + +5.5 - added VMAC and Sosemanuk (with x86-64 and SSE2 assembly) + - improved speed of integer arithmetic, AES, SHA-512, Tiger, Salsa20, + Whirlpool, and PANAMA cipher using assembly (x86-64, MMX, SSE2) + - optimized Camellia and added defense against timing attacks + - updated benchmarks code to show cycles per byte and to time key/IV setup + - started using OpenMP for increased multi-core speed + - enabled GCC optimization flags by default in GNUmakefile + - added blinding and computational error checking for RW signing + - changed RandomPool, X917RNG, GetNextIV, DSA/NR/ECDSA/ECNR to reduce + the risk of reusing random numbers and IVs after virtual machine state + rollback + - changed default FIPS mode RNG from AutoSeededX917RNG to + AutoSeededX917RNG + - fixed PANAMA cipher interface to accept 256-bit key and 256-bit IV + - moved MD2, MD4, MD5, PanamaHash, ARC4, WAKE_CFB into the namespace "Weak" + - removed HAVAL, MD5-MAC, XMAC + +5.5.1 - fixed VMAC validation failure on 32-bit big-endian machines + +5.5.2 - ported x64 assembly language code for AES, Salsa20, Sosemanuk, and Panama + to MSVC 2005 (using MASM since MSVC doesn't support inline assembly on x64) + - fixed Salsa20 initialization crash on non-SSE2 machines + - fixed Whirlpool crash on Pentium 2 machines + - fixed possible branch prediction analysis (BPA) vulnerability in + MontgomeryReduce(), which may affect security of RSA, RW, LUC + - fixed link error with MSVC 2003 when using "debug DLL" form of runtime library + - fixed crash in SSE2_Add on P4 machines when compiled with + MSVC 6.0 SP5 with Processor Pack + - added support for newly released compilers: MSVC 2008, GCC 4.2, Sun CC 5.9, + Intel C++ Compiler 10.0, and Borland C++Builder 2007 + +Written by Wei Dai diff --git a/CryptoPP/crypto/adhoc.cpp b/CryptoPP/crypto/adhoc.cpp new file mode 100644 index 0000000..dc7f697 --- /dev/null +++ b/CryptoPP/crypto/adhoc.cpp @@ -0,0 +1,17 @@ +#include "filters.h" +#include "files.h" +#include "base64.h" +#include "hex.h" +#include + +USING_NAMESPACE(CryptoPP) +USING_NAMESPACE(std) + +extern int (*AdhocTest)(int argc, char *argv[]); + +int MyAdhocTest(int argc, char *argv[]) +{ + return 0; +} + +static int s_i = (AdhocTest = &MyAdhocTest, 0); diff --git a/CryptoPP/crypto/adhoc.cpp.copied b/CryptoPP/crypto/adhoc.cpp.copied new file mode 100644 index 0000000..56f3b36 --- /dev/null +++ b/CryptoPP/crypto/adhoc.cpp.copied @@ -0,0 +1 @@ + diff --git a/CryptoPP/crypto/adhoc.cpp.proto b/CryptoPP/crypto/adhoc.cpp.proto new file mode 100644 index 0000000..dc7f697 --- /dev/null +++ b/CryptoPP/crypto/adhoc.cpp.proto @@ -0,0 +1,17 @@ +#include "filters.h" +#include "files.h" +#include "base64.h" +#include "hex.h" +#include + +USING_NAMESPACE(CryptoPP) +USING_NAMESPACE(std) + +extern int (*AdhocTest)(int argc, char *argv[]); + +int MyAdhocTest(int argc, char *argv[]) +{ + return 0; +} + +static int s_i = (AdhocTest = &MyAdhocTest, 0); diff --git a/CryptoPP/crypto/adler32.cpp b/CryptoPP/crypto/adler32.cpp new file mode 100644 index 0000000..2270202 --- /dev/null +++ b/CryptoPP/crypto/adler32.cpp @@ -0,0 +1,77 @@ +// adler32.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "adler32.h" + +NAMESPACE_BEGIN(CryptoPP) + +void Adler32::Update(const byte *input, size_t length) +{ + const unsigned long BASE = 65521; + + unsigned long s1 = m_s1; + unsigned long s2 = m_s2; + + if (length % 8 != 0) + { + do + { + s1 += *input++; + s2 += s1; + length--; + } while (length % 8 != 0); + + if (s1 >= BASE) + s1 -= BASE; + s2 %= BASE; + } + + while (length > 0) + { + s1 += input[0]; s2 += s1; + s1 += input[1]; s2 += s1; + s1 += input[2]; s2 += s1; + s1 += input[3]; s2 += s1; + s1 += input[4]; s2 += s1; + s1 += input[5]; s2 += s1; + s1 += input[6]; s2 += s1; + s1 += input[7]; s2 += s1; + + length -= 8; + input += 8; + + if (s1 >= BASE) + s1 -= BASE; + if (length % 0x8000 == 0) + s2 %= BASE; + } + + assert(s1 < BASE); + assert(s2 < BASE); + + m_s1 = (word16)s1; + m_s2 = (word16)s2; +} + +void Adler32::TruncatedFinal(byte *hash, size_t size) +{ + ThrowIfInvalidTruncatedSize(size); + + switch (size) + { + default: + hash[3] = byte(m_s1); + case 3: + hash[2] = byte(m_s1 >> 8); + case 2: + hash[1] = byte(m_s2); + case 1: + hash[0] = byte(m_s2 >> 8); + case 0: + ; + } + + Reset(); +} + +NAMESPACE_END diff --git a/CryptoPP/crypto/adler32.h b/CryptoPP/crypto/adler32.h new file mode 100644 index 0000000..672b3ed --- /dev/null +++ b/CryptoPP/crypto/adler32.h @@ -0,0 +1,27 @@ +#ifndef CRYPTOPP_ADLER32_H +#define CRYPTOPP_ADLER32_H + +#include "cryptlib.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! ADLER-32 checksum calculations +class Adler32 : public HashTransformation +{ +public: + CRYPTOPP_CONSTANT(DIGESTSIZE = 4) + Adler32() {Reset();} + void Update(const byte *input, size_t length); + void TruncatedFinal(byte *hash, size_t size); + unsigned int DigestSize() const {return DIGESTSIZE;} + std::string AlgorithmName() const {return "Adler32";} + +private: + void Reset() {m_s1 = 1; m_s2 = 0;} + + word16 m_s1, m_s2; +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/aes.h b/CryptoPP/crypto/aes.h new file mode 100644 index 0000000..03b6bf1 --- /dev/null +++ b/CryptoPP/crypto/aes.h @@ -0,0 +1,16 @@ +#ifndef CRYPTOPP_AES_H +#define CRYPTOPP_AES_H + +#include "rijndael.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! AES winner, announced on 10/2/2000 +DOCUMENTED_TYPEDEF(Rijndael, AES); + +typedef RijndaelEncryption AESEncryption; +typedef RijndaelDecryption AESDecryption; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/algebra.cpp b/CryptoPP/crypto/algebra.cpp new file mode 100644 index 0000000..5d7e213 --- /dev/null +++ b/CryptoPP/crypto/algebra.cpp @@ -0,0 +1,340 @@ +// algebra.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_ALGEBRA_CPP // SunCC workaround: compiler could cause this file to be included twice +#define CRYPTOPP_ALGEBRA_CPP + +#include "algebra.h" +#include "integer.h" + +#include + +NAMESPACE_BEGIN(CryptoPP) + +template const T& AbstractGroup::Double(const Element &a) const +{ + return Add(a, a); +} + +template const T& AbstractGroup::Subtract(const Element &a, const Element &b) const +{ + // make copy of a in case Inverse() overwrites it + Element a1(a); + return Add(a1, Inverse(b)); +} + +template T& AbstractGroup::Accumulate(Element &a, const Element &b) const +{ + return a = Add(a, b); +} + +template T& AbstractGroup::Reduce(Element &a, const Element &b) const +{ + return a = Subtract(a, b); +} + +template const T& AbstractRing::Square(const Element &a) const +{ + return Multiply(a, a); +} + +template const T& AbstractRing::Divide(const Element &a, const Element &b) const +{ + // make copy of a in case MultiplicativeInverse() overwrites it + Element a1(a); + return Multiply(a1, MultiplicativeInverse(b)); +} + +template const T& AbstractEuclideanDomain::Mod(const Element &a, const Element &b) const +{ + Element q; + DivisionAlgorithm(result, q, a, b); + return result; +} + +template const T& AbstractEuclideanDomain::Gcd(const Element &a, const Element &b) const +{ + Element g[3]={b, a}; + unsigned int i0=0, i1=1, i2=2; + + while (!Equal(g[i1], this->Identity())) + { + g[i2] = Mod(g[i0], g[i1]); + unsigned int t = i0; i0 = i1; i1 = i2; i2 = t; + } + + return result = g[i0]; +} + +template const typename QuotientRing::Element& QuotientRing::MultiplicativeInverse(const Element &a) const +{ + Element g[3]={m_modulus, a}; + Element v[3]={m_domain.Identity(), m_domain.MultiplicativeIdentity()}; + Element y; + unsigned int i0=0, i1=1, i2=2; + + while (!Equal(g[i1], Identity())) + { + // y = g[i0] / g[i1]; + // g[i2] = g[i0] % g[i1]; + m_domain.DivisionAlgorithm(g[i2], y, g[i0], g[i1]); + // v[i2] = v[i0] - (v[i1] * y); + v[i2] = m_domain.Subtract(v[i0], m_domain.Multiply(v[i1], y)); + unsigned int t = i0; i0 = i1; i1 = i2; i2 = t; + } + + return m_domain.IsUnit(g[i0]) ? m_domain.Divide(v[i0], g[i0]) : m_domain.Identity(); +} + +template T AbstractGroup::ScalarMultiply(const Element &base, const Integer &exponent) const +{ + Element result; + SimultaneousMultiply(&result, base, &exponent, 1); + return result; +} + +template T AbstractGroup::CascadeScalarMultiply(const Element &x, const Integer &e1, const Element &y, const Integer &e2) const +{ + const unsigned expLen = STDMAX(e1.BitCount(), e2.BitCount()); + if (expLen==0) + return Identity(); + + const unsigned w = (expLen <= 46 ? 1 : (expLen <= 260 ? 2 : 3)); + const unsigned tableSize = 1< powerTable(tableSize << w); + + powerTable[1] = x; + powerTable[tableSize] = y; + if (w==1) + powerTable[3] = Add(x,y); + else + { + powerTable[2] = Double(x); + powerTable[2*tableSize] = Double(y); + + unsigned i, j; + + for (i=3; i=0; i--) + { + power1 = 2*power1 + e1.GetBit(i); + power2 = 2*power2 + e2.GetBit(i); + + if (i==0 || 2*power1 >= tableSize || 2*power2 >= tableSize) + { + unsigned squaresBefore = prevPosition-i; + unsigned squaresAfter = 0; + prevPosition = i; + while ((power1 || power2) && power1%2 == 0 && power2%2==0) + { + power1 /= 2; + power2 /= 2; + squaresBefore--; + squaresAfter++; + } + if (firstTime) + { + result = powerTable[(power2< Element GeneralCascadeMultiplication(const AbstractGroup &group, Iterator begin, Iterator end) +{ + if (end-begin == 1) + return group.ScalarMultiply(begin->base, begin->exponent); + else if (end-begin == 2) + return group.CascadeScalarMultiply(begin->base, begin->exponent, (begin+1)->base, (begin+1)->exponent); + else + { + Integer q, t; + Iterator last = end; + --last; + + std::make_heap(begin, end); + std::pop_heap(begin, end); + + while (!!begin->exponent) + { + // last->exponent is largest exponent, begin->exponent is next largest + t = last->exponent; + Integer::Divide(last->exponent, q, t, begin->exponent); + + if (q == Integer::One()) + group.Accumulate(begin->base, last->base); // avoid overhead of ScalarMultiply() + else + group.Accumulate(begin->base, group.ScalarMultiply(last->base, q)); + + std::push_heap(begin, end); + std::pop_heap(begin, end); + } + + return group.ScalarMultiply(last->base, last->exponent); + } +} + +struct WindowSlider +{ + WindowSlider(const Integer &expIn, bool fastNegate, unsigned int windowSizeIn=0) + : exp(expIn), windowModulus(Integer::One()), windowSize(windowSizeIn), windowBegin(0), fastNegate(fastNegate), firstTime(true), finished(false) + { + if (windowSize == 0) + { + unsigned int expLen = exp.BitCount(); + windowSize = expLen <= 17 ? 1 : (expLen <= 24 ? 2 : (expLen <= 70 ? 3 : (expLen <= 197 ? 4 : (expLen <= 539 ? 5 : (expLen <= 1434 ? 6 : 7))))); + } + windowModulus <<= windowSize; + } + + void FindNextWindow() + { + unsigned int expLen = exp.WordCount() * WORD_BITS; + unsigned int skipCount = firstTime ? 0 : windowSize; + firstTime = false; + while (!exp.GetBit(skipCount)) + { + if (skipCount >= expLen) + { + finished = true; + return; + } + skipCount++; + } + + exp >>= skipCount; + windowBegin += skipCount; + expWindow = word32(exp % (word(1) << windowSize)); + + if (fastNegate && exp.GetBit(windowSize)) + { + negateNext = true; + expWindow = (word32(1) << windowSize) - expWindow; + exp += windowModulus; + } + else + negateNext = false; + } + + Integer exp, windowModulus; + unsigned int windowSize, windowBegin; + word32 expWindow; + bool fastNegate, negateNext, firstTime, finished; +}; + +template +void AbstractGroup::SimultaneousMultiply(T *results, const T &base, const Integer *expBegin, unsigned int expCount) const +{ + std::vector > buckets(expCount); + std::vector exponents; + exponents.reserve(expCount); + unsigned int i; + + for (i=0; iNotNegative()); + exponents.push_back(WindowSlider(*expBegin++, InversionIsFast(), 0)); + exponents[i].FindNextWindow(); + buckets[i].resize(1<<(exponents[i].windowSize-1), Identity()); + } + + unsigned int expBitPosition = 0; + Element g = base; + bool notDone = true; + + while (notDone) + { + notDone = false; + for (i=0; i 1) + { + for (int j = (int)buckets[i].size()-2; j >= 1; j--) + { + Accumulate(buckets[i][j], buckets[i][j+1]); + Accumulate(r, buckets[i][j]); + } + Accumulate(buckets[i][0], buckets[i][1]); + r = Add(Double(r), buckets[i][0]); + } + } +} + +template T AbstractRing::Exponentiate(const Element &base, const Integer &exponent) const +{ + Element result; + SimultaneousExponentiate(&result, base, &exponent, 1); + return result; +} + +template T AbstractRing::CascadeExponentiate(const Element &x, const Integer &e1, const Element &y, const Integer &e2) const +{ + return MultiplicativeGroup().AbstractGroup::CascadeScalarMultiply(x, e1, y, e2); +} + +template Element GeneralCascadeExponentiation(const AbstractRing &ring, Iterator begin, Iterator end) +{ + return GeneralCascadeMultiplication(ring.MultiplicativeGroup(), begin, end); +} + +template +void AbstractRing::SimultaneousExponentiate(T *results, const T &base, const Integer *exponents, unsigned int expCount) const +{ + MultiplicativeGroup().AbstractGroup::SimultaneousMultiply(results, base, exponents, expCount); +} + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/algebra.h b/CryptoPP/crypto/algebra.h new file mode 100644 index 0000000..e7f3793 --- /dev/null +++ b/CryptoPP/crypto/algebra.h @@ -0,0 +1,285 @@ +#ifndef CRYPTOPP_ALGEBRA_H +#define CRYPTOPP_ALGEBRA_H + +#include "config.h" + +NAMESPACE_BEGIN(CryptoPP) + +class Integer; + +// "const Element&" returned by member functions are references +// to internal data members. Since each object may have only +// one such data member for holding results, the following code +// will produce incorrect results: +// abcd = group.Add(group.Add(a,b), group.Add(c,d)); +// But this should be fine: +// abcd = group.Add(a, group.Add(b, group.Add(c,d)); + +//! Abstract Group +template class CRYPTOPP_NO_VTABLE AbstractGroup +{ +public: + typedef T Element; + + virtual ~AbstractGroup() {} + + virtual bool Equal(const Element &a, const Element &b) const =0; + virtual const Element& Identity() const =0; + virtual const Element& Add(const Element &a, const Element &b) const =0; + virtual const Element& Inverse(const Element &a) const =0; + virtual bool InversionIsFast() const {return false;} + + virtual const Element& Double(const Element &a) const; + virtual const Element& Subtract(const Element &a, const Element &b) const; + virtual Element& Accumulate(Element &a, const Element &b) const; + virtual Element& Reduce(Element &a, const Element &b) const; + + virtual Element ScalarMultiply(const Element &a, const Integer &e) const; + virtual Element CascadeScalarMultiply(const Element &x, const Integer &e1, const Element &y, const Integer &e2) const; + + virtual void SimultaneousMultiply(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const; +}; + +//! Abstract Ring +template class CRYPTOPP_NO_VTABLE AbstractRing : public AbstractGroup +{ +public: + typedef T Element; + + AbstractRing() {m_mg.m_pRing = this;} + AbstractRing(const AbstractRing &source) {m_mg.m_pRing = this;} + AbstractRing& operator=(const AbstractRing &source) {return *this;} + + virtual bool IsUnit(const Element &a) const =0; + virtual const Element& MultiplicativeIdentity() const =0; + virtual const Element& Multiply(const Element &a, const Element &b) const =0; + virtual const Element& MultiplicativeInverse(const Element &a) const =0; + + virtual const Element& Square(const Element &a) const; + virtual const Element& Divide(const Element &a, const Element &b) const; + + virtual Element Exponentiate(const Element &a, const Integer &e) const; + virtual Element CascadeExponentiate(const Element &x, const Integer &e1, const Element &y, const Integer &e2) const; + + virtual void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const; + + virtual const AbstractGroup& MultiplicativeGroup() const + {return m_mg;} + +private: + class MultiplicativeGroupT : public AbstractGroup + { + public: + const AbstractRing& GetRing() const + {return *m_pRing;} + + bool Equal(const Element &a, const Element &b) const + {return GetRing().Equal(a, b);} + + const Element& Identity() const + {return GetRing().MultiplicativeIdentity();} + + const Element& Add(const Element &a, const Element &b) const + {return GetRing().Multiply(a, b);} + + Element& Accumulate(Element &a, const Element &b) const + {return a = GetRing().Multiply(a, b);} + + const Element& Inverse(const Element &a) const + {return GetRing().MultiplicativeInverse(a);} + + const Element& Subtract(const Element &a, const Element &b) const + {return GetRing().Divide(a, b);} + + Element& Reduce(Element &a, const Element &b) const + {return a = GetRing().Divide(a, b);} + + const Element& Double(const Element &a) const + {return GetRing().Square(a);} + + Element ScalarMultiply(const Element &a, const Integer &e) const + {return GetRing().Exponentiate(a, e);} + + Element CascadeScalarMultiply(const Element &x, const Integer &e1, const Element &y, const Integer &e2) const + {return GetRing().CascadeExponentiate(x, e1, y, e2);} + + void SimultaneousMultiply(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const + {GetRing().SimultaneousExponentiate(results, base, exponents, exponentsCount);} + + const AbstractRing *m_pRing; + }; + + MultiplicativeGroupT m_mg; +}; + +// ******************************************************** + +//! Base and Exponent +template +struct BaseAndExponent +{ +public: + BaseAndExponent() {} + BaseAndExponent(const T &base, const E &exponent) : base(base), exponent(exponent) {} + bool operator<(const BaseAndExponent &rhs) const {return exponent < rhs.exponent;} + T base; + E exponent; +}; + +// VC60 workaround: incomplete member template support +template + Element GeneralCascadeMultiplication(const AbstractGroup &group, Iterator begin, Iterator end); +template + Element GeneralCascadeExponentiation(const AbstractRing &ring, Iterator begin, Iterator end); + +// ******************************************************** + +//! Abstract Euclidean Domain +template class CRYPTOPP_NO_VTABLE AbstractEuclideanDomain : public AbstractRing +{ +public: + typedef T Element; + + virtual void DivisionAlgorithm(Element &r, Element &q, const Element &a, const Element &d) const =0; + + virtual const Element& Mod(const Element &a, const Element &b) const =0; + virtual const Element& Gcd(const Element &a, const Element &b) const; + +protected: + mutable Element result; +}; + +// ******************************************************** + +//! EuclideanDomainOf +template class EuclideanDomainOf : public AbstractEuclideanDomain +{ +public: + typedef T Element; + + EuclideanDomainOf() {} + + bool Equal(const Element &a, const Element &b) const + {return a==b;} + + const Element& Identity() const + {return Element::Zero();} + + const Element& Add(const Element &a, const Element &b) const + {return result = a+b;} + + Element& Accumulate(Element &a, const Element &b) const + {return a+=b;} + + const Element& Inverse(const Element &a) const + {return result = -a;} + + const Element& Subtract(const Element &a, const Element &b) const + {return result = a-b;} + + Element& Reduce(Element &a, const Element &b) const + {return a-=b;} + + const Element& Double(const Element &a) const + {return result = a.Doubled();} + + const Element& MultiplicativeIdentity() const + {return Element::One();} + + const Element& Multiply(const Element &a, const Element &b) const + {return result = a*b;} + + const Element& Square(const Element &a) const + {return result = a.Squared();} + + bool IsUnit(const Element &a) const + {return a.IsUnit();} + + const Element& MultiplicativeInverse(const Element &a) const + {return result = a.MultiplicativeInverse();} + + const Element& Divide(const Element &a, const Element &b) const + {return result = a/b;} + + const Element& Mod(const Element &a, const Element &b) const + {return result = a%b;} + + void DivisionAlgorithm(Element &r, Element &q, const Element &a, const Element &d) const + {Element::Divide(r, q, a, d);} + + bool operator==(const EuclideanDomainOf &rhs) const + {return true;} + +private: + mutable Element result; +}; + +//! Quotient Ring +template class QuotientRing : public AbstractRing +{ +public: + typedef T EuclideanDomain; + typedef typename T::Element Element; + + QuotientRing(const EuclideanDomain &domain, const Element &modulus) + : m_domain(domain), m_modulus(modulus) {} + + const EuclideanDomain & GetDomain() const + {return m_domain;} + + const Element& GetModulus() const + {return m_modulus;} + + bool Equal(const Element &a, const Element &b) const + {return m_domain.Equal(m_domain.Mod(m_domain.Subtract(a, b), m_modulus), m_domain.Identity());} + + const Element& Identity() const + {return m_domain.Identity();} + + const Element& Add(const Element &a, const Element &b) const + {return m_domain.Add(a, b);} + + Element& Accumulate(Element &a, const Element &b) const + {return m_domain.Accumulate(a, b);} + + const Element& Inverse(const Element &a) const + {return m_domain.Inverse(a);} + + const Element& Subtract(const Element &a, const Element &b) const + {return m_domain.Subtract(a, b);} + + Element& Reduce(Element &a, const Element &b) const + {return m_domain.Reduce(a, b);} + + const Element& Double(const Element &a) const + {return m_domain.Double(a);} + + bool IsUnit(const Element &a) const + {return m_domain.IsUnit(m_domain.Gcd(a, m_modulus));} + + const Element& MultiplicativeIdentity() const + {return m_domain.MultiplicativeIdentity();} + + const Element& Multiply(const Element &a, const Element &b) const + {return m_domain.Mod(m_domain.Multiply(a, b), m_modulus);} + + const Element& Square(const Element &a) const + {return m_domain.Mod(m_domain.Square(a), m_modulus);} + + const Element& MultiplicativeInverse(const Element &a) const; + + bool operator==(const QuotientRing &rhs) const + {return m_domain == rhs.m_domain && m_modulus == rhs.m_modulus;} + +protected: + EuclideanDomain m_domain; + Element m_modulus; +}; + +NAMESPACE_END + +#ifdef CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES +#include "algebra.cpp" +#endif + +#endif diff --git a/CryptoPP/crypto/algparam.cpp b/CryptoPP/crypto/algparam.cpp new file mode 100644 index 0000000..6e765c2 --- /dev/null +++ b/CryptoPP/crypto/algparam.cpp @@ -0,0 +1,42 @@ +// algparam.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "algparam.h" + +NAMESPACE_BEGIN(CryptoPP) + +PAssignIntToInteger g_pAssignIntToInteger = NULL; + +bool CombinedNameValuePairs::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const +{ + if (strcmp(name, "ValueNames") == 0) + return m_pairs1.GetVoidValue(name, valueType, pValue) && m_pairs2.GetVoidValue(name, valueType, pValue); + else + return m_pairs1.GetVoidValue(name, valueType, pValue) || m_pairs2.GetVoidValue(name, valueType, pValue); +} + +bool AlgorithmParametersBase::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const +{ + if (strcmp(name, "ValueNames") == 0) + { + ThrowIfTypeMismatch(name, typeid(std::string), valueType); + GetParent().GetVoidValue(name, valueType, pValue); + (*reinterpret_cast(pValue) += m_name) += ";"; + return true; + } + else if (strcmp(name, m_name) == 0) + { + AssignValue(name, valueType, pValue); + m_used = true; + return true; + } + else + return GetParent().GetVoidValue(name, valueType, pValue); +} + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/algparam.h b/CryptoPP/crypto/algparam.h new file mode 100644 index 0000000..27555d4 --- /dev/null +++ b/CryptoPP/crypto/algparam.h @@ -0,0 +1,360 @@ +#ifndef CRYPTOPP_ALGPARAM_H +#define CRYPTOPP_ALGPARAM_H + +#include "cryptlib.h" +#include "smartptr.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! used to pass byte array input as part of a NameValuePairs object +/*! the deepCopy option is used when the NameValuePairs object can't + keep a copy of the data available */ +class ConstByteArrayParameter +{ +public: + ConstByteArrayParameter(const char *data = NULL, bool deepCopy = false) + { + Assign((const byte *)data, data ? strlen(data) : 0, deepCopy); + } + ConstByteArrayParameter(const byte *data, size_t size, bool deepCopy = false) + { + Assign(data, size, deepCopy); + } + template ConstByteArrayParameter(const T &string, bool deepCopy = false) + { + CRYPTOPP_COMPILE_ASSERT(sizeof(CPP_TYPENAME T::value_type) == 1); + Assign((const byte *)string.data(), string.size(), deepCopy); + } + + void Assign(const byte *data, size_t size, bool deepCopy) + { + if (deepCopy) + m_block.Assign(data, size); + else + { + m_data = data; + m_size = size; + } + m_deepCopy = deepCopy; + } + + const byte *begin() const {return m_deepCopy ? m_block.begin() : m_data;} + const byte *end() const {return m_deepCopy ? m_block.end() : m_data + m_size;} + size_t size() const {return m_deepCopy ? m_block.size() : m_size;} + +private: + bool m_deepCopy; + const byte *m_data; + size_t m_size; + SecByteBlock m_block; +}; + +class ByteArrayParameter +{ +public: + ByteArrayParameter(byte *data = NULL, unsigned int size = 0) + : m_data(data), m_size(size) {} + ByteArrayParameter(SecByteBlock &block) + : m_data(block.begin()), m_size(block.size()) {} + + byte *begin() const {return m_data;} + byte *end() const {return m_data + m_size;} + size_t size() const {return m_size;} + +private: + byte *m_data; + size_t m_size; +}; + +class CRYPTOPP_DLL CombinedNameValuePairs : public NameValuePairs +{ +public: + CombinedNameValuePairs(const NameValuePairs &pairs1, const NameValuePairs &pairs2) + : m_pairs1(pairs1), m_pairs2(pairs2) {} + + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; + +private: + const NameValuePairs &m_pairs1, &m_pairs2; +}; + +template +class GetValueHelperClass +{ +public: + GetValueHelperClass(const T *pObject, const char *name, const std::type_info &valueType, void *pValue, const NameValuePairs *searchFirst) + : m_pObject(pObject), m_name(name), m_valueType(&valueType), m_pValue(pValue), m_found(false), m_getValueNames(false) + { + if (strcmp(m_name, "ValueNames") == 0) + { + m_found = m_getValueNames = true; + NameValuePairs::ThrowIfTypeMismatch(m_name, typeid(std::string), *m_valueType); + if (searchFirst) + searchFirst->GetVoidValue(m_name, valueType, pValue); + if (typeid(T) != typeid(BASE)) + pObject->BASE::GetVoidValue(m_name, valueType, pValue); + ((*reinterpret_cast(m_pValue) += "ThisPointer:") += typeid(T).name()) += ';'; + } + + if (!m_found && strncmp(m_name, "ThisPointer:", 12) == 0 && strcmp(m_name+12, typeid(T).name()) == 0) + { + NameValuePairs::ThrowIfTypeMismatch(m_name, typeid(T *), *m_valueType); + *reinterpret_cast(pValue) = pObject; + m_found = true; + return; + } + + if (!m_found && searchFirst) + m_found = searchFirst->GetVoidValue(m_name, valueType, pValue); + + if (!m_found && typeid(T) != typeid(BASE)) + m_found = pObject->BASE::GetVoidValue(m_name, valueType, pValue); + } + + operator bool() const {return m_found;} + + template + GetValueHelperClass & operator()(const char *name, const R & (T::*pm)() const) + { + if (m_getValueNames) + (*reinterpret_cast(m_pValue) += name) += ";"; + if (!m_found && strcmp(name, m_name) == 0) + { + NameValuePairs::ThrowIfTypeMismatch(name, typeid(R), *m_valueType); + *reinterpret_cast(m_pValue) = (m_pObject->*pm)(); + m_found = true; + } + return *this; + } + + GetValueHelperClass &Assignable() + { +#ifndef __INTEL_COMPILER // ICL 9.1 workaround: Intel compiler copies the vTable pointer for some reason + if (m_getValueNames) + ((*reinterpret_cast(m_pValue) += "ThisObject:") += typeid(T).name()) += ';'; + if (!m_found && strncmp(m_name, "ThisObject:", 11) == 0 && strcmp(m_name+11, typeid(T).name()) == 0) + { + NameValuePairs::ThrowIfTypeMismatch(m_name, typeid(T), *m_valueType); + *reinterpret_cast(m_pValue) = *m_pObject; + m_found = true; + } +#endif + return *this; + } + +private: + const T *m_pObject; + const char *m_name; + const std::type_info *m_valueType; + void *m_pValue; + bool m_found, m_getValueNames; +}; + +template +GetValueHelperClass GetValueHelper(const T *pObject, const char *name, const std::type_info &valueType, void *pValue, const NameValuePairs *searchFirst=NULL, BASE *dummy=NULL) +{ + return GetValueHelperClass(pObject, name, valueType, pValue, searchFirst); +} + +template +GetValueHelperClass GetValueHelper(const T *pObject, const char *name, const std::type_info &valueType, void *pValue, const NameValuePairs *searchFirst=NULL) +{ + return GetValueHelperClass(pObject, name, valueType, pValue, searchFirst); +} + +// ******************************************************** + +template +R Hack_DefaultValueFromConstReferenceType(const R &) +{ + return R(); +} + +template +bool Hack_GetValueIntoConstReference(const NameValuePairs &source, const char *name, const R &value) +{ + return source.GetValue(name, const_cast(value)); +} + +template +class AssignFromHelperClass +{ +public: + AssignFromHelperClass(T *pObject, const NameValuePairs &source) + : m_pObject(pObject), m_source(source), m_done(false) + { + if (source.GetThisObject(*pObject)) + m_done = true; + else if (typeid(BASE) != typeid(T)) + pObject->BASE::AssignFrom(source); + } + + template + AssignFromHelperClass & operator()(const char *name, void (T::*pm)(R)) // VC60 workaround: "const R &" here causes compiler error + { + if (!m_done) + { + R value = Hack_DefaultValueFromConstReferenceType(reinterpret_cast(*(int *)NULL)); + if (!Hack_GetValueIntoConstReference(m_source, name, value)) + throw InvalidArgument(std::string(typeid(T).name()) + ": Missing required parameter '" + name + "'"); + (m_pObject->*pm)(value); + } + return *this; + } + + template + AssignFromHelperClass & operator()(const char *name1, const char *name2, void (T::*pm)(R, S)) // VC60 workaround: "const R &" here causes compiler error + { + if (!m_done) + { + R value1 = Hack_DefaultValueFromConstReferenceType(reinterpret_cast(*(int *)NULL)); + if (!Hack_GetValueIntoConstReference(m_source, name1, value1)) + throw InvalidArgument(std::string(typeid(T).name()) + ": Missing required parameter '" + name1 + "'"); + S value2 = Hack_DefaultValueFromConstReferenceType(reinterpret_cast(*(int *)NULL)); + if (!Hack_GetValueIntoConstReference(m_source, name2, value2)) + throw InvalidArgument(std::string(typeid(T).name()) + ": Missing required parameter '" + name2 + "'"); + (m_pObject->*pm)(value1, value2); + } + return *this; + } + +private: + T *m_pObject; + const NameValuePairs &m_source; + bool m_done; +}; + +template +AssignFromHelperClass AssignFromHelper(T *pObject, const NameValuePairs &source, BASE *dummy=NULL) +{ + return AssignFromHelperClass(pObject, source); +} + +template +AssignFromHelperClass AssignFromHelper(T *pObject, const NameValuePairs &source) +{ + return AssignFromHelperClass(pObject, source); +} + +// ******************************************************** + +// to allow the linker to discard Integer code if not needed. +typedef bool (CRYPTOPP_API * PAssignIntToInteger)(const std::type_info &valueType, void *pInteger, const void *pInt); +CRYPTOPP_DLL extern PAssignIntToInteger g_pAssignIntToInteger; + +CRYPTOPP_DLL const std::type_info & CRYPTOPP_API IntegerTypeId(); + +class CRYPTOPP_DLL AlgorithmParametersBase : public NameValuePairs +{ +public: + class ParameterNotUsed : public Exception + { + public: + ParameterNotUsed(const char *name) : Exception(OTHER_ERROR, std::string("AlgorithmParametersBase: parameter \"") + name + "\" not used") {} + }; + + AlgorithmParametersBase(const char *name, bool throwIfNotUsed) + : m_name(name), m_throwIfNotUsed(throwIfNotUsed), m_used(false) {} + + ~AlgorithmParametersBase() + { +#ifdef CRYPTOPP_UNCAUGHT_EXCEPTION_AVAILABLE + if (!std::uncaught_exception()) +#else + try +#endif + { + if (m_throwIfNotUsed && !m_used) + throw ParameterNotUsed(m_name); + } +#ifndef CRYPTOPP_UNCAUGHT_EXCEPTION_AVAILABLE + catch(...) + { + } +#endif + } + + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; + +protected: + virtual void AssignValue(const char *name, const std::type_info &valueType, void *pValue) const =0; + virtual const NameValuePairs & GetParent() const =0; + + const char *m_name; + bool m_throwIfNotUsed; + mutable bool m_used; +}; + +template +class AlgorithmParametersBase2 : public AlgorithmParametersBase +{ +public: + AlgorithmParametersBase2(const char *name, const T &value, bool throwIfNotUsed) : AlgorithmParametersBase(name, throwIfNotUsed), m_value(value) {} + + void AssignValue(const char *name, const std::type_info &valueType, void *pValue) const + { + // special case for retrieving an Integer parameter when an int was passed in + if (!(g_pAssignIntToInteger != NULL && typeid(T) == typeid(int) && g_pAssignIntToInteger(valueType, pValue, &m_value))) + { + ThrowIfTypeMismatch(name, typeid(T), valueType); + *reinterpret_cast(pValue) = m_value; + } + } + +protected: + T m_value; +}; + +template +class AlgorithmParameters : public AlgorithmParametersBase2 +{ +public: + AlgorithmParameters(const PARENT &parent, const char *name, const T &value, bool throwIfNotUsed) + : AlgorithmParametersBase2(name, value, throwIfNotUsed), m_parent(parent) + {} + + AlgorithmParameters(const AlgorithmParameters ©) + : AlgorithmParametersBase2(copy), m_parent(copy.m_parent) + { + copy.m_used = true; + } + + template + AlgorithmParameters, R> operator()(const char *name, const R &value) const + { + return AlgorithmParameters, R>(*this, name, value, this->m_throwIfNotUsed); + } + + template + AlgorithmParameters, R> operator()(const char *name, const R &value, bool throwIfNotUsed) const + { + return AlgorithmParameters, R>(*this, name, value, throwIfNotUsed); + } + +private: + const NameValuePairs & GetParent() const {return m_parent;} + PARENT m_parent; +}; + +//! Create an object that implements NameValuePairs for passing parameters +/*! \param throwIfNotUsed if true, the object will throw an exception if the value is not accessed + \note throwIfNotUsed is ignored if using a compiler that does not support std::uncaught_exception(), + such as MSVC 7.0 and earlier. + \note A NameValuePairs object containing an arbitrary number of name value pairs may be constructed by + repeatedly using operator() on the object returned by MakeParameters, for example: + const NameValuePairs ¶meters = MakeParameters(name1, value1)(name2, value2)(name3, value3); +*/ +template +AlgorithmParameters MakeParameters(const char *name, const T &value, bool throwIfNotUsed = true) +{ + return AlgorithmParameters(g_nullNameValuePairs, name, value, throwIfNotUsed); +} + +#define CRYPTOPP_GET_FUNCTION_ENTRY(name) (Name::name(), &ThisClass::Get##name) +#define CRYPTOPP_SET_FUNCTION_ENTRY(name) (Name::name(), &ThisClass::Set##name) +#define CRYPTOPP_SET_FUNCTION_ENTRY2(name1, name2) (Name::name1(), Name::name2(), &ThisClass::Set##name1##And##name2) + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/arc4.cpp b/CryptoPP/crypto/arc4.cpp new file mode 100644 index 0000000..ff9d587 --- /dev/null +++ b/CryptoPP/crypto/arc4.cpp @@ -0,0 +1,120 @@ +// arc4.cpp - written and placed in the public domain by Wei Dai + +// The ARC4 algorithm was first revealed in an anonymous email to the +// cypherpunks mailing list. This file originally contained some +// code copied from this email. The code has since been rewritten in order +// to clarify the copyright status of this file. It should now be +// completely in the public domain. + +#include "pch.h" +#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 +#include "arc4.h" + +NAMESPACE_BEGIN(CryptoPP) +namespace Weak1 { + +void ARC4_TestInstantiations() +{ + ARC4 x; +} + +ARC4_Base::~ARC4_Base() +{ + m_x = m_y = 0; +} + +void ARC4_Base::UncheckedSetKey(const byte *key, unsigned int keyLen, const NameValuePairs ¶ms) +{ + AssertValidKeyLength(keyLen); + + m_x = 1; + m_y = 0; + + unsigned int i; + for (i=0; i<256; i++) + m_state[i] = i; + + unsigned int keyIndex = 0, stateIndex = 0; + for (i=0; i<256; i++) + { + unsigned int a = m_state[i]; + stateIndex += key[keyIndex] + a; + stateIndex &= 0xff; + m_state[i] = m_state[stateIndex]; + m_state[stateIndex] = a; + if (++keyIndex >= keyLen) + keyIndex = 0; + } + + int discardBytes = params.GetIntValueWithDefault("DiscardBytes", GetDefaultDiscardBytes()); + DiscardBytes(discardBytes); +} + +template +static inline unsigned int MakeByte(T &x, T &y, byte *s) +{ + unsigned int a = s[x]; + y = (y+a) & 0xff; + unsigned int b = s[y]; + s[x] = b; + s[y] = a; + x = (x+1) & 0xff; + return s[(a+b) & 0xff]; +} + +void ARC4_Base::GenerateBlock(byte *output, size_t size) +{ + while (size--) + *output++ = MakeByte(m_x, m_y, m_state); +} + +void ARC4_Base::ProcessData(byte *outString, const byte *inString, size_t length) +{ + if (length == 0) + return; + + byte *const s = m_state; + unsigned int x = m_x; + unsigned int y = m_y; + + if (inString == outString) + { + do + { + *outString++ ^= MakeByte(x, y, s); + } while (--length); + } + else + { + do + { + *outString++ = *inString++ ^ MakeByte(x, y, s); + } + while(--length); + } + + m_x = x; + m_y = y; +} + +void ARC4_Base::DiscardBytes(size_t length) +{ + if (length == 0) + return; + + byte *const s = m_state; + unsigned int x = m_x; + unsigned int y = m_y; + + do + { + MakeByte(x, y, s); + } + while(--length); + + m_x = x; + m_y = y; +} + +} +NAMESPACE_END diff --git a/CryptoPP/crypto/arc4.h b/CryptoPP/crypto/arc4.h new file mode 100644 index 0000000..7846d5a --- /dev/null +++ b/CryptoPP/crypto/arc4.h @@ -0,0 +1,71 @@ +#ifndef CRYPTOPP_ARC4_H +#define CRYPTOPP_ARC4_H + +#include "strciphr.h" + +NAMESPACE_BEGIN(CryptoPP) + +namespace Weak1 { + +//! _ +class CRYPTOPP_NO_VTABLE ARC4_Base : public VariableKeyLength<16, 1, 256>, public RandomNumberGenerator, public SymmetricCipher, public SymmetricCipherDocumentation +{ +public: + ~ARC4_Base(); + + static const char *StaticAlgorithmName() {return "ARC4";} + + void GenerateBlock(byte *output, size_t size); + void DiscardBytes(size_t n); + + void ProcessData(byte *outString, const byte *inString, size_t length); + + bool IsRandomAccess() const {return false;} + bool IsSelfInverting() const {return true;} + bool IsForwardTransformation() const {return true;} + + typedef SymmetricCipherFinal Encryption; + typedef SymmetricCipherFinal Decryption; + +protected: + void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms); + virtual unsigned int GetDefaultDiscardBytes() const {return 0;} + + FixedSizeSecBlock m_state; + byte m_x, m_y; +}; + +//! Alleged RC4 +DOCUMENTED_TYPEDEF(SymmetricCipherFinal, ARC4) + +//! _ +class CRYPTOPP_NO_VTABLE MARC4_Base : public ARC4_Base +{ +public: + static const char *StaticAlgorithmName() {return "MARC4";} + + typedef SymmetricCipherFinal Encryption; + typedef SymmetricCipherFinal Decryption; + +protected: + unsigned int GetDefaultDiscardBytes() const {return 256;} +}; + +//! Modified ARC4: it discards the first 256 bytes of keystream which may be weaker than the rest +DOCUMENTED_TYPEDEF(SymmetricCipherFinal, MARC4) + +} +#if CRYPTOPP_ENABLE_NAMESPACE_WEAK >= 1 +namespace Weak {using namespace Weak1;} // import Weak1 into CryptoPP::Weak +#else +using namespace Weak1; // import Weak1 into CryptoPP with warning +#ifdef __GNUC__ +#warning "You may be using a weak algorithm that has been retained for backwards compatibility. Please '#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1' before including this .h file and prepend the class name with 'Weak::' to remove this warning." +#else +#pragma message("You may be using a weak algorithm that has been retained for backwards compatibility. Please '#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1' before including this .h file and prepend the class name with 'Weak::' to remove this warning.") +#endif +#endif + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/argnames.h b/CryptoPP/crypto/argnames.h new file mode 100644 index 0000000..f888d42 --- /dev/null +++ b/CryptoPP/crypto/argnames.h @@ -0,0 +1,76 @@ +#ifndef CRYPTOPP_ARGNAMES_H +#define CRYPTOPP_ARGNAMES_H + +#include "cryptlib.h" + +NAMESPACE_BEGIN(CryptoPP) + +DOCUMENTED_NAMESPACE_BEGIN(Name) + +#define CRYPTOPP_DEFINE_NAME_STRING(name) inline const char *name() {return #name;} + +CRYPTOPP_DEFINE_NAME_STRING(ValueNames) //!< string, a list of value names with a semicolon (';') after each name +CRYPTOPP_DEFINE_NAME_STRING(Version) //!< int +CRYPTOPP_DEFINE_NAME_STRING(Seed) //!< ConstByteArrayParameter +CRYPTOPP_DEFINE_NAME_STRING(Key) //!< ConstByteArrayParameter +CRYPTOPP_DEFINE_NAME_STRING(IV) //!< const byte * +CRYPTOPP_DEFINE_NAME_STRING(StolenIV) //!< byte * +CRYPTOPP_DEFINE_NAME_STRING(Rounds) //!< int +CRYPTOPP_DEFINE_NAME_STRING(FeedbackSize) //!< int +CRYPTOPP_DEFINE_NAME_STRING(WordSize) //!< int, in bytes +CRYPTOPP_DEFINE_NAME_STRING(BlockSize) //!< int, in bytes +CRYPTOPP_DEFINE_NAME_STRING(EffectiveKeyLength) //!< int, in bits +CRYPTOPP_DEFINE_NAME_STRING(KeySize) //!< int, in bits +CRYPTOPP_DEFINE_NAME_STRING(ModulusSize) //!< int, in bits +CRYPTOPP_DEFINE_NAME_STRING(SubgroupOrderSize) //!< int, in bits +CRYPTOPP_DEFINE_NAME_STRING(PrivateExponentSize)//!< int, in bits +CRYPTOPP_DEFINE_NAME_STRING(Modulus) //!< Integer +CRYPTOPP_DEFINE_NAME_STRING(PublicExponent) //!< Integer +CRYPTOPP_DEFINE_NAME_STRING(PrivateExponent) //!< Integer +CRYPTOPP_DEFINE_NAME_STRING(PublicElement) //!< Integer +CRYPTOPP_DEFINE_NAME_STRING(SubgroupOrder) //!< Integer +CRYPTOPP_DEFINE_NAME_STRING(Cofactor) //!< Integer +CRYPTOPP_DEFINE_NAME_STRING(SubgroupGenerator) //!< Integer, ECP::Point, or EC2N::Point +CRYPTOPP_DEFINE_NAME_STRING(Curve) //!< ECP or EC2N +CRYPTOPP_DEFINE_NAME_STRING(GroupOID) //!< OID +CRYPTOPP_DEFINE_NAME_STRING(PointerToPrimeSelector) //!< const PrimeSelector * +CRYPTOPP_DEFINE_NAME_STRING(Prime1) //!< Integer +CRYPTOPP_DEFINE_NAME_STRING(Prime2) //!< Integer +CRYPTOPP_DEFINE_NAME_STRING(ModPrime1PrivateExponent) //!< Integer +CRYPTOPP_DEFINE_NAME_STRING(ModPrime2PrivateExponent) //!< Integer +CRYPTOPP_DEFINE_NAME_STRING(MultiplicativeInverseOfPrime2ModPrime1) //!< Integer +CRYPTOPP_DEFINE_NAME_STRING(QuadraticResidueModPrime1) //!< Integer +CRYPTOPP_DEFINE_NAME_STRING(QuadraticResidueModPrime2) //!< Integer +CRYPTOPP_DEFINE_NAME_STRING(PutMessage) //!< bool +CRYPTOPP_DEFINE_NAME_STRING(TruncatedDigestSize) //!< int +CRYPTOPP_DEFINE_NAME_STRING(HashVerificationFilterFlags) //!< word32 +CRYPTOPP_DEFINE_NAME_STRING(SignatureVerificationFilterFlags) //!< word32 +CRYPTOPP_DEFINE_NAME_STRING(InputBuffer) //!< ConstByteArrayParameter +CRYPTOPP_DEFINE_NAME_STRING(OutputBuffer) //!< ByteArrayParameter +CRYPTOPP_DEFINE_NAME_STRING(InputFileName) //!< const char * +CRYPTOPP_DEFINE_NAME_STRING(InputStreamPointer) //!< std::istream * +CRYPTOPP_DEFINE_NAME_STRING(InputBinaryMode) //!< bool +CRYPTOPP_DEFINE_NAME_STRING(OutputFileName) //!< const char * +CRYPTOPP_DEFINE_NAME_STRING(OutputStreamPointer) //!< std::ostream * +CRYPTOPP_DEFINE_NAME_STRING(OutputBinaryMode) //!< bool +CRYPTOPP_DEFINE_NAME_STRING(EncodingParameters) //!< ConstByteArrayParameter +CRYPTOPP_DEFINE_NAME_STRING(KeyDerivationParameters) //!< ConstByteArrayParameter +CRYPTOPP_DEFINE_NAME_STRING(Separator) //< ConstByteArrayParameter +CRYPTOPP_DEFINE_NAME_STRING(Terminator) //< ConstByteArrayParameter +CRYPTOPP_DEFINE_NAME_STRING(Uppercase) //< bool +CRYPTOPP_DEFINE_NAME_STRING(GroupSize) //< int +CRYPTOPP_DEFINE_NAME_STRING(Pad) //< bool +CRYPTOPP_DEFINE_NAME_STRING(PaddingByte) //< byte +CRYPTOPP_DEFINE_NAME_STRING(Log2Base) //< int +CRYPTOPP_DEFINE_NAME_STRING(EncodingLookupArray) //< const byte * +CRYPTOPP_DEFINE_NAME_STRING(DecodingLookupArray) //< const byte * +CRYPTOPP_DEFINE_NAME_STRING(InsertLineBreaks) //< bool +CRYPTOPP_DEFINE_NAME_STRING(MaxLineLength) //< int +CRYPTOPP_DEFINE_NAME_STRING(DigestSize) //!< int, in bytes +CRYPTOPP_DEFINE_NAME_STRING(L1KeyLength) //!< int, in bytes + +DOCUMENTED_NAMESPACE_END + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/asn.cpp b/CryptoPP/crypto/asn.cpp new file mode 100644 index 0000000..4174090 --- /dev/null +++ b/CryptoPP/crypto/asn.cpp @@ -0,0 +1,595 @@ +// asn.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "asn.h" + +#include +#include + +NAMESPACE_BEGIN(CryptoPP) +USING_NAMESPACE(std) + +/// DER Length +size_t DERLengthEncode(BufferedTransformation &bt, lword length) +{ + size_t i=0; + if (length <= 0x7f) + { + bt.Put(byte(length)); + i++; + } + else + { + bt.Put(byte(BytePrecision(length) | 0x80)); + i++; + for (int j=BytePrecision(length); j; --j) + { + bt.Put(byte(length >> (j-1)*8)); + i++; + } + } + return i; +} + +bool BERLengthDecode(BufferedTransformation &bt, lword &length, bool &definiteLength) +{ + byte b; + + if (!bt.Get(b)) + return false; + + if (!(b & 0x80)) + { + definiteLength = true; + length = b; + } + else + { + unsigned int lengthBytes = b & 0x7f; + + if (lengthBytes == 0) + { + definiteLength = false; + return true; + } + + definiteLength = true; + length = 0; + while (lengthBytes--) + { + if (length >> (8*(sizeof(length)-1))) + BERDecodeError(); // length about to overflow + + if (!bt.Get(b)) + return false; + + length = (length << 8) | b; + } + } + return true; +} + +bool BERLengthDecode(BufferedTransformation &bt, size_t &length) +{ + lword lw; + bool definiteLength; + if (!BERLengthDecode(bt, lw, definiteLength)) + BERDecodeError(); + if (!SafeConvert(lw, length)) + BERDecodeError(); + return definiteLength; +} + +void DEREncodeNull(BufferedTransformation &out) +{ + out.Put(TAG_NULL); + out.Put(0); +} + +void BERDecodeNull(BufferedTransformation &in) +{ + byte b; + if (!in.Get(b) || b != TAG_NULL) + BERDecodeError(); + size_t length; + if (!BERLengthDecode(in, length) || length != 0) + BERDecodeError(); +} + +/// ASN Strings +size_t DEREncodeOctetString(BufferedTransformation &bt, const byte *str, size_t strLen) +{ + bt.Put(OCTET_STRING); + size_t lengthBytes = DERLengthEncode(bt, strLen); + bt.Put(str, strLen); + return 1+lengthBytes+strLen; +} + +size_t DEREncodeOctetString(BufferedTransformation &bt, const SecByteBlock &str) +{ + return DEREncodeOctetString(bt, str.begin(), str.size()); +} + +size_t BERDecodeOctetString(BufferedTransformation &bt, SecByteBlock &str) +{ + byte b; + if (!bt.Get(b) || b != OCTET_STRING) + BERDecodeError(); + + size_t bc; + if (!BERLengthDecode(bt, bc)) + BERDecodeError(); + + str.resize(bc); + if (bc != bt.Get(str, bc)) + BERDecodeError(); + return bc; +} + +size_t BERDecodeOctetString(BufferedTransformation &bt, BufferedTransformation &str) +{ + byte b; + if (!bt.Get(b) || b != OCTET_STRING) + BERDecodeError(); + + size_t bc; + if (!BERLengthDecode(bt, bc)) + BERDecodeError(); + + bt.TransferTo(str, bc); + return bc; +} + +size_t DEREncodeTextString(BufferedTransformation &bt, const std::string &str, byte asnTag) +{ + bt.Put(asnTag); + size_t lengthBytes = DERLengthEncode(bt, str.size()); + bt.Put((const byte *)str.data(), str.size()); + return 1+lengthBytes+str.size(); +} + +size_t BERDecodeTextString(BufferedTransformation &bt, std::string &str, byte asnTag) +{ + byte b; + if (!bt.Get(b) || b != asnTag) + BERDecodeError(); + + size_t bc; + if (!BERLengthDecode(bt, bc)) + BERDecodeError(); + + SecByteBlock temp(bc); + if (bc != bt.Get(temp, bc)) + BERDecodeError(); + str.assign((char *)temp.begin(), bc); + return bc; +} + +/// ASN BitString +size_t DEREncodeBitString(BufferedTransformation &bt, const byte *str, size_t strLen, unsigned int unusedBits) +{ + bt.Put(BIT_STRING); + size_t lengthBytes = DERLengthEncode(bt, strLen+1); + bt.Put((byte)unusedBits); + bt.Put(str, strLen); + return 2+lengthBytes+strLen; +} + +size_t BERDecodeBitString(BufferedTransformation &bt, SecByteBlock &str, unsigned int &unusedBits) +{ + byte b; + if (!bt.Get(b) || b != BIT_STRING) + BERDecodeError(); + + size_t bc; + if (!BERLengthDecode(bt, bc)) + BERDecodeError(); + + byte unused; + if (!bt.Get(unused)) + BERDecodeError(); + unusedBits = unused; + str.resize(bc-1); + if ((bc-1) != bt.Get(str, bc-1)) + BERDecodeError(); + return bc-1; +} + +void DERReencode(BufferedTransformation &source, BufferedTransformation &dest) +{ + byte tag; + source.Peek(tag); + BERGeneralDecoder decoder(source, tag); + DERGeneralEncoder encoder(dest, tag); + if (decoder.IsDefiniteLength()) + decoder.TransferTo(encoder, decoder.RemainingLength()); + else + { + while (!decoder.EndReached()) + DERReencode(decoder, encoder); + } + decoder.MessageEnd(); + encoder.MessageEnd(); +} + +void OID::EncodeValue(BufferedTransformation &bt, word32 v) +{ + for (unsigned int i=RoundUpToMultipleOf(STDMAX(7U,BitPrecision(v)), 7U)-7; i != 0; i-=7) + bt.Put((byte)(0x80 | ((v >> i) & 0x7f))); + bt.Put((byte)(v & 0x7f)); +} + +size_t OID::DecodeValue(BufferedTransformation &bt, word32 &v) +{ + byte b; + size_t i=0; + v = 0; + while (true) + { + if (!bt.Get(b)) + BERDecodeError(); + i++; + v <<= 7; + v += b & 0x7f; + if (!(b & 0x80)) + return i; + } +} + +void OID::DEREncode(BufferedTransformation &bt) const +{ + assert(m_values.size() >= 2); + ByteQueue temp; + temp.Put(byte(m_values[0] * 40 + m_values[1])); + for (size_t i=2; i 0) + { + word32 v; + size_t valueLen = DecodeValue(bt, v); + if (valueLen > length) + BERDecodeError(); + m_values.push_back(v); + length -= valueLen; + } +} + +void OID::BERDecodeAndCheck(BufferedTransformation &bt) const +{ + OID oid(bt); + if (*this != oid) + BERDecodeError(); +} + +inline BufferedTransformation & EncodedObjectFilter::CurrentTarget() +{ + if (m_flags & PUT_OBJECTS) + return *AttachedTransformation(); + else + return TheBitBucket(); +} + +void EncodedObjectFilter::Put(const byte *inString, size_t length) +{ + if (m_nCurrentObject == m_nObjects) + { + AttachedTransformation()->Put(inString, length); + return; + } + + LazyPutter lazyPutter(m_queue, inString, length); + + while (m_queue.AnyRetrievable()) + { + switch (m_state) + { + case IDENTIFIER: + if (!m_queue.Get(m_id)) + return; + m_queue.TransferTo(CurrentTarget(), 1); + m_state = LENGTH; // fall through + case LENGTH: + { + byte b; + if (m_level > 0 && m_id == 0 && m_queue.Peek(b) && b == 0) + { + m_queue.TransferTo(CurrentTarget(), 1); + m_level--; + m_state = IDENTIFIER; + break; + } + ByteQueue::Walker walker(m_queue); + bool definiteLength; + if (!BERLengthDecode(walker, m_lengthRemaining, definiteLength)) + return; + m_queue.TransferTo(CurrentTarget(), walker.GetCurrentPosition()); + if (!((m_id & CONSTRUCTED) || definiteLength)) + BERDecodeError(); + if (!definiteLength) + { + if (!(m_id & CONSTRUCTED)) + BERDecodeError(); + m_level++; + m_state = IDENTIFIER; + break; + } + m_state = BODY; // fall through + } + case BODY: + m_lengthRemaining -= m_queue.TransferTo(CurrentTarget(), m_lengthRemaining); + + if (m_lengthRemaining == 0) + m_state = IDENTIFIER; + } + + if (m_state == IDENTIFIER && m_level == 0) + { + // just finished processing a level 0 object + ++m_nCurrentObject; + + if (m_flags & PUT_MESSANGE_END_AFTER_EACH_OBJECT) + AttachedTransformation()->MessageEnd(); + + if (m_nCurrentObject == m_nObjects) + { + if (m_flags & PUT_MESSANGE_END_AFTER_ALL_OBJECTS) + AttachedTransformation()->MessageEnd(); + + if (m_flags & PUT_MESSANGE_SERIES_END_AFTER_ALL_OBJECTS) + AttachedTransformation()->MessageSeriesEnd(); + + m_queue.TransferAllTo(*AttachedTransformation()); + return; + } + } + } +} + +BERGeneralDecoder::BERGeneralDecoder(BufferedTransformation &inQueue, byte asnTag) + : m_inQueue(inQueue), m_finished(false) +{ + Init(asnTag); +} + +BERGeneralDecoder::BERGeneralDecoder(BERGeneralDecoder &inQueue, byte asnTag) + : m_inQueue(inQueue), m_finished(false) +{ + Init(asnTag); +} + +void BERGeneralDecoder::Init(byte asnTag) +{ + byte b; + if (!m_inQueue.Get(b) || b != asnTag) + BERDecodeError(); + + if (!BERLengthDecode(m_inQueue, m_length, m_definiteLength)) + BERDecodeError(); + + if (!m_definiteLength && !(asnTag & CONSTRUCTED)) + BERDecodeError(); // cannot be primitive and have indefinite length +} + +BERGeneralDecoder::~BERGeneralDecoder() +{ + try // avoid throwing in constructor + { + if (!m_finished) + MessageEnd(); + } + catch (...) + { + } +} + +bool BERGeneralDecoder::EndReached() const +{ + if (m_definiteLength) + return m_length == 0; + else + { // check end-of-content octets + word16 i; + return (m_inQueue.PeekWord16(i)==2 && i==0); + } +} + +byte BERGeneralDecoder::PeekByte() const +{ + byte b; + if (!Peek(b)) + BERDecodeError(); + return b; +} + +void BERGeneralDecoder::CheckByte(byte check) +{ + byte b; + if (!Get(b) || b != check) + BERDecodeError(); +} + +void BERGeneralDecoder::MessageEnd() +{ + m_finished = true; + if (m_definiteLength) + { + if (m_length != 0) + BERDecodeError(); + } + else + { // remove end-of-content octets + word16 i; + if (m_inQueue.GetWord16(i) != 2 || i != 0) + BERDecodeError(); + } +} + +size_t BERGeneralDecoder::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking) +{ + if (m_definiteLength && transferBytes > m_length) + transferBytes = m_length; + size_t blockedBytes = m_inQueue.TransferTo2(target, transferBytes, channel, blocking); + ReduceLength(transferBytes); + return blockedBytes; +} + +size_t BERGeneralDecoder::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end, const std::string &channel, bool blocking) const +{ + if (m_definiteLength) + end = STDMIN(m_length, end); + return m_inQueue.CopyRangeTo2(target, begin, end, channel, blocking); +} + +lword BERGeneralDecoder::ReduceLength(lword delta) +{ + if (m_definiteLength) + { + if (m_length < delta) + BERDecodeError(); + m_length -= delta; + } + return delta; +} + +DERGeneralEncoder::DERGeneralEncoder(BufferedTransformation &outQueue, byte asnTag) + : m_outQueue(outQueue), m_finished(false), m_asnTag(asnTag) +{ +} + +DERGeneralEncoder::DERGeneralEncoder(DERGeneralEncoder &outQueue, byte asnTag) + : m_outQueue(outQueue), m_finished(false), m_asnTag(asnTag) +{ +} + +DERGeneralEncoder::~DERGeneralEncoder() +{ + try // avoid throwing in constructor + { + if (!m_finished) + MessageEnd(); + } + catch (...) + { + } +} + +void DERGeneralEncoder::MessageEnd() +{ + m_finished = true; + lword length = CurrentSize(); + m_outQueue.Put(m_asnTag); + DERLengthEncode(m_outQueue, length); + TransferTo(m_outQueue); +} + +// ************************************************************* + +void X509PublicKey::BERDecode(BufferedTransformation &bt) +{ + BERSequenceDecoder subjectPublicKeyInfo(bt); + BERSequenceDecoder algorithm(subjectPublicKeyInfo); + GetAlgorithmID().BERDecodeAndCheck(algorithm); + bool parametersPresent = algorithm.EndReached() ? false : BERDecodeAlgorithmParameters(algorithm); + algorithm.MessageEnd(); + + BERGeneralDecoder subjectPublicKey(subjectPublicKeyInfo, BIT_STRING); + subjectPublicKey.CheckByte(0); // unused bits + BERDecodePublicKey(subjectPublicKey, parametersPresent, (size_t)subjectPublicKey.RemainingLength()); + subjectPublicKey.MessageEnd(); + subjectPublicKeyInfo.MessageEnd(); +} + +void X509PublicKey::DEREncode(BufferedTransformation &bt) const +{ + DERSequenceEncoder subjectPublicKeyInfo(bt); + + DERSequenceEncoder algorithm(subjectPublicKeyInfo); + GetAlgorithmID().DEREncode(algorithm); + DEREncodeAlgorithmParameters(algorithm); + algorithm.MessageEnd(); + + DERGeneralEncoder subjectPublicKey(subjectPublicKeyInfo, BIT_STRING); + subjectPublicKey.Put(0); // unused bits + DEREncodePublicKey(subjectPublicKey); + subjectPublicKey.MessageEnd(); + + subjectPublicKeyInfo.MessageEnd(); +} + +void PKCS8PrivateKey::BERDecode(BufferedTransformation &bt) +{ + BERSequenceDecoder privateKeyInfo(bt); + word32 version; + BERDecodeUnsigned(privateKeyInfo, version, INTEGER, 0, 0); // check version + + BERSequenceDecoder algorithm(privateKeyInfo); + GetAlgorithmID().BERDecodeAndCheck(algorithm); + bool parametersPresent = algorithm.EndReached() ? false : BERDecodeAlgorithmParameters(algorithm); + algorithm.MessageEnd(); + + BERGeneralDecoder octetString(privateKeyInfo, OCTET_STRING); + BERDecodePrivateKey(octetString, parametersPresent, (size_t)privateKeyInfo.RemainingLength()); + octetString.MessageEnd(); + + if (!privateKeyInfo.EndReached()) + BERDecodeOptionalAttributes(privateKeyInfo); + privateKeyInfo.MessageEnd(); +} + +void PKCS8PrivateKey::DEREncode(BufferedTransformation &bt) const +{ + DERSequenceEncoder privateKeyInfo(bt); + DEREncodeUnsigned(privateKeyInfo, 0); // version + + DERSequenceEncoder algorithm(privateKeyInfo); + GetAlgorithmID().DEREncode(algorithm); + DEREncodeAlgorithmParameters(algorithm); + algorithm.MessageEnd(); + + DERGeneralEncoder octetString(privateKeyInfo, OCTET_STRING); + DEREncodePrivateKey(octetString); + octetString.MessageEnd(); + + DEREncodeOptionalAttributes(privateKeyInfo); + privateKeyInfo.MessageEnd(); +} + +void PKCS8PrivateKey::BERDecodeOptionalAttributes(BufferedTransformation &bt) +{ + DERReencode(bt, m_optionalAttributes); +} + +void PKCS8PrivateKey::DEREncodeOptionalAttributes(BufferedTransformation &bt) const +{ + m_optionalAttributes.CopyTo(bt); +} + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/asn.h b/CryptoPP/crypto/asn.h new file mode 100644 index 0000000..d74af5a --- /dev/null +++ b/CryptoPP/crypto/asn.h @@ -0,0 +1,369 @@ +#ifndef CRYPTOPP_ASN_H +#define CRYPTOPP_ASN_H + +#include "filters.h" +#include "queue.h" +#include + +NAMESPACE_BEGIN(CryptoPP) + +// these tags and flags are not complete +enum ASNTag +{ + BOOLEAN = 0x01, + INTEGER = 0x02, + BIT_STRING = 0x03, + OCTET_STRING = 0x04, + TAG_NULL = 0x05, + OBJECT_IDENTIFIER = 0x06, + OBJECT_DESCRIPTOR = 0x07, + EXTERNAL = 0x08, + REAL = 0x09, + ENUMERATED = 0x0a, + UTF8_STRING = 0x0c, + SEQUENCE = 0x10, + SET = 0x11, + NUMERIC_STRING = 0x12, + PRINTABLE_STRING = 0x13, + T61_STRING = 0x14, + VIDEOTEXT_STRING = 0x15, + IA5_STRING = 0x16, + UTC_TIME = 0x17, + GENERALIZED_TIME = 0x18, + GRAPHIC_STRING = 0x19, + VISIBLE_STRING = 0x1a, + GENERAL_STRING = 0x1b +}; + +enum ASNIdFlag +{ + UNIVERSAL = 0x00, +// DATA = 0x01, +// HEADER = 0x02, + CONSTRUCTED = 0x20, + APPLICATION = 0x40, + CONTEXT_SPECIFIC = 0x80, + PRIVATE = 0xc0 +}; + +inline void BERDecodeError() {throw BERDecodeErr();} + +class CRYPTOPP_DLL UnknownOID : public BERDecodeErr +{ +public: + UnknownOID() : BERDecodeErr("BER decode error: unknown object identifier") {} + UnknownOID(const char *err) : BERDecodeErr(err) {} +}; + +// unsigned int DERLengthEncode(unsigned int length, byte *output=0); +CRYPTOPP_DLL size_t CRYPTOPP_API DERLengthEncode(BufferedTransformation &out, lword length); +// returns false if indefinite length +CRYPTOPP_DLL bool CRYPTOPP_API BERLengthDecode(BufferedTransformation &in, size_t &length); + +CRYPTOPP_DLL void CRYPTOPP_API DEREncodeNull(BufferedTransformation &out); +CRYPTOPP_DLL void CRYPTOPP_API BERDecodeNull(BufferedTransformation &in); + +CRYPTOPP_DLL size_t CRYPTOPP_API DEREncodeOctetString(BufferedTransformation &out, const byte *str, size_t strLen); +CRYPTOPP_DLL size_t CRYPTOPP_API DEREncodeOctetString(BufferedTransformation &out, const SecByteBlock &str); +CRYPTOPP_DLL size_t CRYPTOPP_API BERDecodeOctetString(BufferedTransformation &in, SecByteBlock &str); +CRYPTOPP_DLL size_t CRYPTOPP_API BERDecodeOctetString(BufferedTransformation &in, BufferedTransformation &str); + +// for UTF8_STRING, PRINTABLE_STRING, and IA5_STRING +CRYPTOPP_DLL size_t CRYPTOPP_API DEREncodeTextString(BufferedTransformation &out, const std::string &str, byte asnTag); +CRYPTOPP_DLL size_t CRYPTOPP_API BERDecodeTextString(BufferedTransformation &in, std::string &str, byte asnTag); + +CRYPTOPP_DLL size_t CRYPTOPP_API DEREncodeBitString(BufferedTransformation &out, const byte *str, size_t strLen, unsigned int unusedBits=0); +CRYPTOPP_DLL size_t CRYPTOPP_API BERDecodeBitString(BufferedTransformation &in, SecByteBlock &str, unsigned int &unusedBits); + +// BER decode from source and DER reencode into dest +CRYPTOPP_DLL void CRYPTOPP_API DERReencode(BufferedTransformation &source, BufferedTransformation &dest); + +//! Object Identifier +class CRYPTOPP_DLL OID +{ +public: + OID() {} + OID(word32 v) : m_values(1, v) {} + OID(BufferedTransformation &bt) {BERDecode(bt);} + + inline OID & operator+=(word32 rhs) {m_values.push_back(rhs); return *this;} + + void DEREncode(BufferedTransformation &bt) const; + void BERDecode(BufferedTransformation &bt); + + // throw BERDecodeErr() if decoded value doesn't equal this OID + void BERDecodeAndCheck(BufferedTransformation &bt) const; + + std::vector m_values; + +private: + static void EncodeValue(BufferedTransformation &bt, word32 v); + static size_t DecodeValue(BufferedTransformation &bt, word32 &v); +}; + +class EncodedObjectFilter : public Filter +{ +public: + enum Flag {PUT_OBJECTS=1, PUT_MESSANGE_END_AFTER_EACH_OBJECT=2, PUT_MESSANGE_END_AFTER_ALL_OBJECTS=4, PUT_MESSANGE_SERIES_END_AFTER_ALL_OBJECTS=8}; + EncodedObjectFilter(BufferedTransformation *attachment = NULL, unsigned int nObjects = 1, word32 flags = 0); + + void Put(const byte *inString, size_t length); + + unsigned int GetNumberOfCompletedObjects() const {return m_nCurrentObject;} + unsigned long GetPositionOfObject(unsigned int i) const {return m_positions[i];} + +private: + BufferedTransformation & CurrentTarget(); + + word32 m_flags; + unsigned int m_nObjects, m_nCurrentObject, m_level; + std::vector m_positions; + ByteQueue m_queue; + enum State {IDENTIFIER, LENGTH, BODY, TAIL, ALL_DONE} m_state; + byte m_id; + lword m_lengthRemaining; +}; + +//! BER General Decoder +class CRYPTOPP_DLL BERGeneralDecoder : public Store +{ +public: + explicit BERGeneralDecoder(BufferedTransformation &inQueue, byte asnTag); + explicit BERGeneralDecoder(BERGeneralDecoder &inQueue, byte asnTag); + ~BERGeneralDecoder(); + + bool IsDefiniteLength() const {return m_definiteLength;} + lword RemainingLength() const {assert(m_definiteLength); return m_length;} + bool EndReached() const; + byte PeekByte() const; + void CheckByte(byte b); + + size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=NULL_CHANNEL, bool blocking=true); + size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=NULL_CHANNEL, bool blocking=true) const; + + // call this to denote end of sequence + void MessageEnd(); + +protected: + BufferedTransformation &m_inQueue; + bool m_finished, m_definiteLength; + lword m_length; + +private: + void Init(byte asnTag); + void StoreInitialize(const NameValuePairs ¶meters) {assert(false);} + lword ReduceLength(lword delta); +}; + +//! DER General Encoder +class CRYPTOPP_DLL DERGeneralEncoder : public ByteQueue +{ +public: + explicit DERGeneralEncoder(BufferedTransformation &outQueue, byte asnTag = SEQUENCE | CONSTRUCTED); + explicit DERGeneralEncoder(DERGeneralEncoder &outQueue, byte asnTag = SEQUENCE | CONSTRUCTED); + ~DERGeneralEncoder(); + + // call this to denote end of sequence + void MessageEnd(); + +private: + BufferedTransformation &m_outQueue; + bool m_finished; + + byte m_asnTag; +}; + +//! BER Sequence Decoder +class CRYPTOPP_DLL BERSequenceDecoder : public BERGeneralDecoder +{ +public: + explicit BERSequenceDecoder(BufferedTransformation &inQueue, byte asnTag = SEQUENCE | CONSTRUCTED) + : BERGeneralDecoder(inQueue, asnTag) {} + explicit BERSequenceDecoder(BERSequenceDecoder &inQueue, byte asnTag = SEQUENCE | CONSTRUCTED) + : BERGeneralDecoder(inQueue, asnTag) {} +}; + +//! DER Sequence Encoder +class CRYPTOPP_DLL DERSequenceEncoder : public DERGeneralEncoder +{ +public: + explicit DERSequenceEncoder(BufferedTransformation &outQueue, byte asnTag = SEQUENCE | CONSTRUCTED) + : DERGeneralEncoder(outQueue, asnTag) {} + explicit DERSequenceEncoder(DERSequenceEncoder &outQueue, byte asnTag = SEQUENCE | CONSTRUCTED) + : DERGeneralEncoder(outQueue, asnTag) {} +}; + +//! BER Set Decoder +class CRYPTOPP_DLL BERSetDecoder : public BERGeneralDecoder +{ +public: + explicit BERSetDecoder(BufferedTransformation &inQueue, byte asnTag = SET | CONSTRUCTED) + : BERGeneralDecoder(inQueue, asnTag) {} + explicit BERSetDecoder(BERSetDecoder &inQueue, byte asnTag = SET | CONSTRUCTED) + : BERGeneralDecoder(inQueue, asnTag) {} +}; + +//! DER Set Encoder +class CRYPTOPP_DLL DERSetEncoder : public DERGeneralEncoder +{ +public: + explicit DERSetEncoder(BufferedTransformation &outQueue, byte asnTag = SET | CONSTRUCTED) + : DERGeneralEncoder(outQueue, asnTag) {} + explicit DERSetEncoder(DERSetEncoder &outQueue, byte asnTag = SET | CONSTRUCTED) + : DERGeneralEncoder(outQueue, asnTag) {} +}; + +template +class ASNOptional : public member_ptr +{ +public: + void BERDecode(BERSequenceDecoder &seqDecoder, byte tag, byte mask = ~CONSTRUCTED) + { + byte b; + if (seqDecoder.Peek(b) && (b & mask) == tag) + reset(new T(seqDecoder)); + } + void DEREncode(BufferedTransformation &out) + { + if (this->get() != NULL) + this->get()->DEREncode(out); + } +}; + +//! _ +template +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE ASN1CryptoMaterial : public ASN1Object, public BASE +{ +public: + void Save(BufferedTransformation &bt) const + {BEREncode(bt);} + void Load(BufferedTransformation &bt) + {BERDecode(bt);} +}; + +//! encodes/decodes subjectPublicKeyInfo +class CRYPTOPP_DLL X509PublicKey : public ASN1CryptoMaterial +{ +public: + void BERDecode(BufferedTransformation &bt); + void DEREncode(BufferedTransformation &bt) const; + + virtual OID GetAlgorithmID() const =0; + virtual bool BERDecodeAlgorithmParameters(BufferedTransformation &bt) + {BERDecodeNull(bt); return false;} + virtual bool DEREncodeAlgorithmParameters(BufferedTransformation &bt) const + {DEREncodeNull(bt); return false;} // see RFC 2459, section 7.3.1 + + //! decode subjectPublicKey part of subjectPublicKeyInfo, without the BIT STRING header + virtual void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size) =0; + //! encode subjectPublicKey part of subjectPublicKeyInfo, without the BIT STRING header + virtual void DEREncodePublicKey(BufferedTransformation &bt) const =0; +}; + +//! encodes/decodes privateKeyInfo +class CRYPTOPP_DLL PKCS8PrivateKey : public ASN1CryptoMaterial +{ +public: + void BERDecode(BufferedTransformation &bt); + void DEREncode(BufferedTransformation &bt) const; + + virtual OID GetAlgorithmID() const =0; + virtual bool BERDecodeAlgorithmParameters(BufferedTransformation &bt) + {BERDecodeNull(bt); return false;} + virtual bool DEREncodeAlgorithmParameters(BufferedTransformation &bt) const + {DEREncodeNull(bt); return false;} // see RFC 2459, section 7.3.1 + + //! decode privateKey part of privateKeyInfo, without the OCTET STRING header + virtual void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size) =0; + //! encode privateKey part of privateKeyInfo, without the OCTET STRING header + virtual void DEREncodePrivateKey(BufferedTransformation &bt) const =0; + + //! decode optional attributes including context-specific tag + /*! /note default implementation stores attributes to be output in DEREncodeOptionalAttributes */ + virtual void BERDecodeOptionalAttributes(BufferedTransformation &bt); + //! encode optional attributes including context-specific tag + virtual void DEREncodeOptionalAttributes(BufferedTransformation &bt) const; + +protected: + ByteQueue m_optionalAttributes; +}; + +// ******************************************************** + +//! DER Encode Unsigned +/*! for INTEGER, BOOLEAN, and ENUM */ +template +size_t DEREncodeUnsigned(BufferedTransformation &out, T w, byte asnTag = INTEGER) +{ + byte buf[sizeof(w)+1]; + unsigned int bc; + if (asnTag == BOOLEAN) + { + buf[sizeof(w)] = w ? 0xff : 0; + bc = 1; + } + else + { + buf[0] = 0; + for (unsigned int i=0; i> (sizeof(w)-1-i)*8); + bc = sizeof(w); + while (bc > 1 && buf[sizeof(w)+1-bc] == 0) + --bc; + if (buf[sizeof(w)+1-bc] & 0x80) + ++bc; + } + out.Put(asnTag); + size_t lengthBytes = DERLengthEncode(out, bc); + out.Put(buf+sizeof(w)+1-bc, bc); + return 1+lengthBytes+bc; +} + +//! BER Decode Unsigned +// VC60 workaround: std::numeric_limits::max conflicts with MFC max macro +// CW41 workaround: std::numeric_limits::max causes a template error +template +void BERDecodeUnsigned(BufferedTransformation &in, T &w, byte asnTag = INTEGER, + T minValue = 0, T maxValue = 0xffffffff) +{ + byte b; + if (!in.Get(b) || b != asnTag) + BERDecodeError(); + + size_t bc; + BERLengthDecode(in, bc); + + SecByteBlock buf(bc); + + if (bc != in.Get(buf, bc)) + BERDecodeError(); + + const byte *ptr = buf; + while (bc > sizeof(w) && *ptr == 0) + { + bc--; + ptr++; + } + if (bc > sizeof(w)) + BERDecodeError(); + + w = 0; + for (unsigned int i=0; i maxValue) + BERDecodeError(); +} + +inline bool operator==(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs) + {return lhs.m_values == rhs.m_values;} +inline bool operator!=(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs) + {return lhs.m_values != rhs.m_values;} +inline bool operator<(const ::CryptoPP::OID &lhs, const ::CryptoPP::OID &rhs) + {return std::lexicographical_compare(lhs.m_values.begin(), lhs.m_values.end(), rhs.m_values.begin(), rhs.m_values.end());} +inline ::CryptoPP::OID operator+(const ::CryptoPP::OID &lhs, unsigned long rhs) + {return ::CryptoPP::OID(lhs)+=rhs;} + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/base32.cpp b/CryptoPP/crypto/base32.cpp new file mode 100644 index 0000000..5eee3aa --- /dev/null +++ b/CryptoPP/crypto/base32.cpp @@ -0,0 +1,39 @@ +// base32.cpp - written and placed in the public domain by Frank Palazzolo, based on hex.cpp by Wei Dai + +#include "pch.h" +#include "base32.h" + +NAMESPACE_BEGIN(CryptoPP) + +static const byte s_vecUpper[] = "ABCDEFGHIJKMNPQRSTUVWXYZ23456789"; +static const byte s_vecLower[] = "abcdefghijkmnpqrstuvwxyz23456789"; + +void Base32Encoder::IsolatedInitialize(const NameValuePairs ¶meters) +{ + bool uppercase = parameters.GetValueWithDefault(Name::Uppercase(), true); + m_filter->Initialize(CombinedNameValuePairs( + parameters, + MakeParameters(Name::EncodingLookupArray(), uppercase ? &s_vecUpper[0] : &s_vecLower[0], false)(Name::Log2Base(), 5, true))); +} + +void Base32Decoder::IsolatedInitialize(const NameValuePairs ¶meters) +{ + BaseN_Decoder::Initialize(CombinedNameValuePairs( + parameters, + MakeParameters(Name::DecodingLookupArray(), GetDefaultDecodingLookupArray(), false)(Name::Log2Base(), 5, true))); +} + +const int *Base32Decoder::GetDefaultDecodingLookupArray() +{ + static bool s_initialized = false; + static int s_array[256]; + + if (!s_initialized) + { + InitializeDecodingLookupArray(s_array, s_vecUpper, 32, true); + s_initialized = true; + } + return s_array; +} + +NAMESPACE_END diff --git a/CryptoPP/crypto/base32.h b/CryptoPP/crypto/base32.h new file mode 100644 index 0000000..6b7937a --- /dev/null +++ b/CryptoPP/crypto/base32.h @@ -0,0 +1,38 @@ +#ifndef CRYPTOPP_BASE32_H +#define CRYPTOPP_BASE32_H + +#include "basecode.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! Converts given data to base 32, the default code is based on draft-ietf-idn-dude-02.txt +/*! To specify alternative code, call Initialize() with EncodingLookupArray parameter. */ +class Base32Encoder : public SimpleProxyFilter +{ +public: + Base32Encoder(BufferedTransformation *attachment = NULL, bool uppercase = true, int outputGroupSize = 0, const std::string &separator = ":", const std::string &terminator = "") + : SimpleProxyFilter(new BaseN_Encoder(new Grouper), attachment) + { + IsolatedInitialize(MakeParameters(Name::Uppercase(), uppercase)(Name::GroupSize(), outputGroupSize)(Name::Separator(), ConstByteArrayParameter(separator))); + } + + void IsolatedInitialize(const NameValuePairs ¶meters); +}; + +//! Decode base 32 data back to bytes, the default code is based on draft-ietf-idn-dude-02.txt +/*! To specify alternative code, call Initialize() with DecodingLookupArray parameter. */ +class Base32Decoder : public BaseN_Decoder +{ +public: + Base32Decoder(BufferedTransformation *attachment = NULL) + : BaseN_Decoder(GetDefaultDecodingLookupArray(), 5, attachment) {} + + void IsolatedInitialize(const NameValuePairs ¶meters); + +private: + static const int * CRYPTOPP_API GetDefaultDecodingLookupArray(); +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/base64.cpp b/CryptoPP/crypto/base64.cpp new file mode 100644 index 0000000..1e23349 --- /dev/null +++ b/CryptoPP/crypto/base64.cpp @@ -0,0 +1,42 @@ +// base64.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "base64.h" + +NAMESPACE_BEGIN(CryptoPP) + +static const byte s_vec[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +static const byte s_padding = '='; + +void Base64Encoder::IsolatedInitialize(const NameValuePairs ¶meters) +{ + bool insertLineBreaks = parameters.GetValueWithDefault(Name::InsertLineBreaks(), true); + int maxLineLength = parameters.GetIntValueWithDefault(Name::MaxLineLength(), 72); + + const char *lineBreak = insertLineBreaks ? "\n" : ""; + + m_filter->Initialize(CombinedNameValuePairs( + parameters, + MakeParameters(Name::EncodingLookupArray(), &s_vec[0], false) + (Name::PaddingByte(), s_padding) + (Name::GroupSize(), insertLineBreaks ? maxLineLength : 0) + (Name::Separator(), ConstByteArrayParameter(lineBreak)) + (Name::Terminator(), ConstByteArrayParameter(lineBreak)) + (Name::Log2Base(), 6, true))); +} + +const int *Base64Decoder::GetDecodingLookupArray() +{ + static bool s_initialized = false; + static int s_array[256]; + + if (!s_initialized) + { + InitializeDecodingLookupArray(s_array, s_vec, 64, false); + s_initialized = true; + } + return s_array; +} + +NAMESPACE_END diff --git a/CryptoPP/crypto/base64.h b/CryptoPP/crypto/base64.h new file mode 100644 index 0000000..c405eca --- /dev/null +++ b/CryptoPP/crypto/base64.h @@ -0,0 +1,36 @@ +#ifndef CRYPTOPP_BASE64_H +#define CRYPTOPP_BASE64_H + +#include "basecode.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! Base64 Encoder Class +class Base64Encoder : public SimpleProxyFilter +{ +public: + Base64Encoder(BufferedTransformation *attachment = NULL, bool insertLineBreaks = true, int maxLineLength = 72) + : SimpleProxyFilter(new BaseN_Encoder(new Grouper), attachment) + { + IsolatedInitialize(MakeParameters(Name::InsertLineBreaks(), insertLineBreaks)(Name::MaxLineLength(), maxLineLength)); + } + + void IsolatedInitialize(const NameValuePairs ¶meters); +}; + +//! Base64 Decoder Class +class Base64Decoder : public BaseN_Decoder +{ +public: + Base64Decoder(BufferedTransformation *attachment = NULL) + : BaseN_Decoder(GetDecodingLookupArray(), 6, attachment) {} + + void IsolatedInitialize(const NameValuePairs ¶meters) {} + +private: + static const int * CRYPTOPP_API GetDecodingLookupArray(); +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/basecode.cpp b/CryptoPP/crypto/basecode.cpp new file mode 100644 index 0000000..ab94f81 --- /dev/null +++ b/CryptoPP/crypto/basecode.cpp @@ -0,0 +1,238 @@ +// basecode.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "basecode.h" +#include "fltrimpl.h" +#include + +NAMESPACE_BEGIN(CryptoPP) + +void BaseN_Encoder::IsolatedInitialize(const NameValuePairs ¶meters) +{ + parameters.GetRequiredParameter("BaseN_Encoder", Name::EncodingLookupArray(), m_alphabet); + + parameters.GetRequiredIntParameter("BaseN_Encoder", Name::Log2Base(), m_bitsPerChar); + if (m_bitsPerChar <= 0 || m_bitsPerChar >= 8) + throw InvalidArgument("BaseN_Encoder: Log2Base must be between 1 and 7 inclusive"); + + byte padding; + bool pad; + if (parameters.GetValue(Name::PaddingByte(), padding)) + pad = parameters.GetValueWithDefault(Name::Pad(), true); + else + pad = false; + m_padding = pad ? padding : -1; + + m_bytePos = m_bitPos = 0; + + int i = 8; + while (i%m_bitsPerChar != 0) + i += 8; + m_outputBlockSize = i/m_bitsPerChar; + + m_outBuf.New(m_outputBlockSize); +} + +size_t BaseN_Encoder::Put2(const byte *begin, size_t length, int messageEnd, bool blocking) +{ + FILTER_BEGIN; + while (m_inputPosition < length) + { + if (m_bytePos == 0) + memset(m_outBuf, 0, m_outputBlockSize); + + { + unsigned int b = begin[m_inputPosition++], bitsLeftInSource = 8; + while (true) + { + assert(m_bitPos < m_bitsPerChar); + unsigned int bitsLeftInTarget = m_bitsPerChar-m_bitPos; + m_outBuf[m_bytePos] |= b >> (8-bitsLeftInTarget); + if (bitsLeftInSource >= bitsLeftInTarget) + { + m_bitPos = 0; + ++m_bytePos; + bitsLeftInSource -= bitsLeftInTarget; + if (bitsLeftInSource == 0) + break; + b <<= bitsLeftInTarget; + b &= 0xff; + } + else + { + m_bitPos += bitsLeftInSource; + break; + } + } + } + + assert(m_bytePos <= m_outputBlockSize); + if (m_bytePos == m_outputBlockSize) + { + int i; + for (i=0; i 0) + ++m_bytePos; + + int i; + for (i=0; i 0) + { + memset(m_outBuf+m_bytePos, m_padding, m_outputBlockSize-m_bytePos); + m_bytePos = m_outputBlockSize; + } + FILTER_OUTPUT(2, m_outBuf, m_bytePos, messageEnd); + m_bytePos = m_bitPos = 0; + } + FILTER_END_NO_MESSAGE_END; +} + +void BaseN_Decoder::IsolatedInitialize(const NameValuePairs ¶meters) +{ + parameters.GetRequiredParameter("BaseN_Decoder", Name::DecodingLookupArray(), m_lookup); + + parameters.GetRequiredIntParameter("BaseN_Decoder", Name::Log2Base(), m_bitsPerChar); + if (m_bitsPerChar <= 0 || m_bitsPerChar >= 8) + throw InvalidArgument("BaseN_Decoder: Log2Base must be between 1 and 7 inclusive"); + + m_bytePos = m_bitPos = 0; + + int i = m_bitsPerChar; + while (i%8 != 0) + i += m_bitsPerChar; + m_outputBlockSize = i/8; + + m_outBuf.New(m_outputBlockSize); +} + +size_t BaseN_Decoder::Put2(const byte *begin, size_t length, int messageEnd, bool blocking) +{ + FILTER_BEGIN; + while (m_inputPosition < length) + { + unsigned int value; + value = m_lookup[begin[m_inputPosition++]]; + if (value >= 256) + continue; + + if (m_bytePos == 0 && m_bitPos == 0) + memset(m_outBuf, 0, m_outputBlockSize); + + { + int newBitPos = m_bitPos + m_bitsPerChar; + if (newBitPos <= 8) + m_outBuf[m_bytePos] |= value << (8-newBitPos); + else + { + m_outBuf[m_bytePos] |= value >> (newBitPos-8); + m_outBuf[m_bytePos+1] |= value << (16-newBitPos); + } + + m_bitPos = newBitPos; + while (m_bitPos >= 8) + { + m_bitPos -= 8; + ++m_bytePos; + } + } + + if (m_bytePos == m_outputBlockSize) + { + FILTER_OUTPUT(1, m_outBuf, m_outputBlockSize, 0); + m_bytePos = m_bitPos = 0; + } + } + if (messageEnd) + { + FILTER_OUTPUT(2, m_outBuf, m_bytePos, messageEnd); + m_bytePos = m_bitPos = 0; + } + FILTER_END_NO_MESSAGE_END; +} + +void BaseN_Decoder::InitializeDecodingLookupArray(int *lookup, const byte *alphabet, unsigned int base, bool caseInsensitive) +{ + std::fill(lookup, lookup+256, -1); + + for (unsigned int i=0; i +{ +public: + BaseN_Encoder(BufferedTransformation *attachment=NULL) + {Detach(attachment);} + + BaseN_Encoder(const byte *alphabet, int log2base, BufferedTransformation *attachment=NULL, int padding=-1) + { + Detach(attachment); + IsolatedInitialize(MakeParameters(Name::EncodingLookupArray(), alphabet) + (Name::Log2Base(), log2base) + (Name::Pad(), padding != -1) + (Name::PaddingByte(), byte(padding))); + } + + void IsolatedInitialize(const NameValuePairs ¶meters); + size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking); + +private: + const byte *m_alphabet; + int m_padding, m_bitsPerChar, m_outputBlockSize; + int m_bytePos, m_bitPos; + SecByteBlock m_outBuf; +}; + +//! base n decoder, where n is a power of 2 +class CRYPTOPP_DLL BaseN_Decoder : public Unflushable +{ +public: + BaseN_Decoder(BufferedTransformation *attachment=NULL) + {Detach(attachment);} + + BaseN_Decoder(const int *lookup, int log2base, BufferedTransformation *attachment=NULL) + { + Detach(attachment); + IsolatedInitialize(MakeParameters(Name::DecodingLookupArray(), lookup)(Name::Log2Base(), log2base)); + } + + void IsolatedInitialize(const NameValuePairs ¶meters); + size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking); + + static void CRYPTOPP_API InitializeDecodingLookupArray(int *lookup, const byte *alphabet, unsigned int base, bool caseInsensitive); + +private: + const int *m_lookup; + int m_padding, m_bitsPerChar, m_outputBlockSize; + int m_bytePos, m_bitPos; + SecByteBlock m_outBuf; +}; + +//! filter that breaks input stream into groups of fixed size +class CRYPTOPP_DLL Grouper : public Bufferless +{ +public: + Grouper(BufferedTransformation *attachment=NULL) + {Detach(attachment);} + + Grouper(int groupSize, const std::string &separator, const std::string &terminator, BufferedTransformation *attachment=NULL) + { + Detach(attachment); + IsolatedInitialize(MakeParameters(Name::GroupSize(), groupSize) + (Name::Separator(), ConstByteArrayParameter(separator)) + (Name::Terminator(), ConstByteArrayParameter(terminator))); + } + + void IsolatedInitialize(const NameValuePairs ¶meters); + size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking); + +private: + SecByteBlock m_separator, m_terminator; + size_t m_groupSize, m_counter; +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/bench.cpp b/CryptoPP/crypto/bench.cpp new file mode 100644 index 0000000..bbaa1e5 --- /dev/null +++ b/CryptoPP/crypto/bench.cpp @@ -0,0 +1,344 @@ +// bench.cpp - written and placed in the public domain by Wei Dai + +#define _CRT_SECURE_NO_DEPRECATE + +#include "bench.h" +#include "crc.h" +#include "adler32.h" +#include "idea.h" +#include "des.h" +#include "rc5.h" +#include "blowfish.h" +#include "wake.h" +#include "cast.h" +#include "seal.h" +#include "rc6.h" +#include "mars.h" +#include "twofish.h" +#include "serpent.h" +#include "skipjack.h" +#include "cbcmac.h" +#include "dmac.h" +#include "aes.h" +#include "blumshub.h" +#include "rng.h" +#include "files.h" +#include "hex.h" +#include "modes.h" +#include "factory.h" + +#include +#include +#include +#include + +USING_NAMESPACE(CryptoPP) +USING_NAMESPACE(std) + +#ifdef CLOCKS_PER_SEC +const double CLOCK_TICKS_PER_SECOND = (double)CLOCKS_PER_SEC; +#elif defined(CLK_TCK) +const double CLOCK_TICKS_PER_SECOND = (double)CLK_TCK; +#else +const double CLOCK_TICKS_PER_SECOND = 1000000.0; +#endif + +double logtotal = 0, g_allocatedTime, g_hertz; +unsigned int logcount = 0; + +static const byte *const key=(byte *)"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + +void OutputResultBytes(const char *name, double length, double timeTaken) +{ + double mbs = length / timeTaken / (1024*1024); + cout << "\n" << name; +// cout << "" << setprecision(3) << length / (1024*1024); + cout << setiosflags(ios::fixed); +// cout << "" << setprecision(3) << timeTaken; + cout << "" << setprecision(0) << setiosflags(ios::fixed) << mbs; + if (g_hertz) + cout << "" << setprecision(1) << setiosflags(ios::fixed) << timeTaken * g_hertz / length; + cout << resetiosflags(ios::fixed); + logtotal += log(mbs); + logcount++; +} + +void OutputResultKeying(double iterations, double timeTaken) +{ + cout << "" << setprecision(3) << setiosflags(ios::fixed) << (1000*1000*timeTaken/iterations); + if (g_hertz) + cout << "" << setprecision(0) << setiosflags(ios::fixed) << timeTaken * g_hertz / iterations; +} + +void OutputResultOperations(const char *name, const char *operation, bool pc, unsigned long iterations, double timeTaken) +{ + cout << "\n" << name << " " << operation << (pc ? " with precomputation" : ""); +// cout << "" << iterations; +// cout << setiosflags(ios::fixed); +// cout << "" << setprecision(3) << timeTaken; + cout << "" << setprecision(2) << setiosflags(ios::fixed) << (1000*timeTaken/iterations); + if (g_hertz) + cout << "" << setprecision(2) << setiosflags(ios::fixed) << timeTaken * g_hertz / iterations / 1000000; + cout << resetiosflags(ios::fixed); + + logtotal += log(iterations/timeTaken); + logcount++; +} + +void BenchMark(const char *name, BlockTransformation &cipher, double timeTotal) +{ + const int BUF_SIZE = RoundUpToMultipleOf(2048U, cipher.OptimalNumberOfParallelBlocks() * cipher.BlockSize()); + AlignedSecByteBlock buf(BUF_SIZE); + const int nBlocks = BUF_SIZE / cipher.BlockSize(); + clock_t start = clock(); + + unsigned long i=0, blocks=1; + double timeTaken; + do + { + blocks *= 2; + for (; i +void BenchMarkKeyed(const char *name, double timeTotal, const NameValuePairs ¶ms = g_nullNameValuePairs, T *x=NULL) +{ + T c; + c.SetKey(key, c.DefaultKeyLength(), CombinedNameValuePairs(params, MakeParameters(Name::IV(), key, false))); + BenchMark(name, c, timeTotal); + BenchMarkKeying(c, c.DefaultKeyLength(), CombinedNameValuePairs(params, MakeParameters(Name::IV(), key, false))); +} + +//VC60 workaround: compiler bug triggered without the extra dummy parameters +template +void BenchMarkKeyedVariable(const char *name, double timeTotal, unsigned int keyLength, const NameValuePairs ¶ms = g_nullNameValuePairs, T *x=NULL) +{ + T c; + c.SetKey(key, keyLength, CombinedNameValuePairs(params, MakeParameters(Name::IV(), key, false))); + BenchMark(name, c, timeTotal); + BenchMarkKeying(c, keyLength, CombinedNameValuePairs(params, MakeParameters(Name::IV(), key, false))); +} + +//VC60 workaround: compiler bug triggered without the extra dummy parameters +template +void BenchMarkKeyless(const char *name, double timeTotal, T *x=NULL) +{ + T c; + BenchMark(name, c, timeTotal); +} + +//VC60 workaround: compiler bug triggered without the extra dummy parameters +template +void BenchMarkByName(const char *factoryName, size_t keyLength = 0, const char *displayName=NULL, const NameValuePairs ¶ms = g_nullNameValuePairs, T *x=NULL) +{ + std::string name = factoryName; + if (displayName) + name = displayName; + else if (keyLength) + name += " (" + IntToString(keyLength * 8) + "-bit key)"; + + std::auto_ptr obj(ObjectFactoryRegistry::Registry().CreateObject(factoryName)); + if (!keyLength) + keyLength = obj->DefaultKeyLength(); + obj->SetKey(key, keyLength, CombinedNameValuePairs(params, MakeParameters(Name::IV(), key, false))); + BenchMark(name.c_str(), *obj, g_allocatedTime); + BenchMarkKeying(*obj, keyLength, CombinedNameValuePairs(params, MakeParameters(Name::IV(), key, false))); +} + +template +void BenchMarkByNameKeyLess(const char *factoryName, const char *displayName=NULL, const NameValuePairs ¶ms = g_nullNameValuePairs, T *x=NULL) +{ + std::string name = factoryName; + if (displayName) + name = displayName; + + std::auto_ptr obj(ObjectFactoryRegistry::Registry().CreateObject(factoryName)); + BenchMark(name.c_str(), *obj, g_allocatedTime); +} + +void BenchmarkAll(double t, double hertz) +{ +#if 1 + logtotal = 0; + logcount = 0; + g_allocatedTime = t; + g_hertz = hertz; + + const char *cpb, *cpk; + if (g_hertz) + { + cpb = "Cycles Per Byte"; + cpk = "Cycles to
Setup Key and IV"; + cout << "CPU frequency of the test platform is " << g_hertz << " Hz.\n"; + } + else + { + cpb = cpk = ""; + cout << "CPU frequency of the test platform was not provided.\n"; + } + + cout << "" << endl; + cout << ""; + BenchMarkByName("VMAC(AES)-64"); + BenchMarkByName("VMAC(AES)-128"); + BenchMarkByName("HMAC(SHA-1)"); + BenchMarkByName("Two-Track-MAC"); + BenchMarkKeyed >("CBC-MAC/AES", t); + BenchMarkKeyed >("DMAC/AES", t); + + cout << "\n"; + BenchMarkKeyless("CRC-32", t); + BenchMarkKeyless("Adler-32", t); + BenchMarkByNameKeyLess("MD5"); + BenchMarkByNameKeyLess("SHA-1"); + BenchMarkByNameKeyLess("SHA-256"); +#ifdef WORD64_AVAILABLE + BenchMarkByNameKeyLess("SHA-512"); + BenchMarkByNameKeyLess("Tiger"); + BenchMarkByNameKeyLess("Whirlpool"); +#endif + BenchMarkByNameKeyLess("RIPEMD-160"); + BenchMarkByNameKeyLess("RIPEMD-320"); + BenchMarkByNameKeyLess("RIPEMD-128"); + BenchMarkByNameKeyLess("RIPEMD-256"); + + cout << "\n"; + BenchMarkByName("Panama-LE"); + BenchMarkByName("Panama-BE"); + BenchMarkByName("Salsa20"); + BenchMarkByName("Salsa20", 0, "Salsa20/12", MakeParameters(Name::Rounds(), 12)); + BenchMarkByName("Salsa20", 0, "Salsa20/8", MakeParameters(Name::Rounds(), 8)); + BenchMarkByName("Sosemanuk"); + BenchMarkByName("MARC4"); + BenchMarkKeyed::Encryption>("SEAL-3.0-BE", t); + BenchMarkKeyed::Encryption>("SEAL-3.0-LE", t); + BenchMarkKeyed::Encryption>("WAKE-OFB-BE", t); + BenchMarkKeyed::Encryption>("WAKE-OFB-LE", t); + + cout << "\n"; + BenchMarkByName("AES/ECB", 16); + BenchMarkByName("AES/ECB", 24); + BenchMarkByName("AES/ECB", 32); + BenchMarkByName("AES/CTR", 16); + BenchMarkByName("AES/OFB", 16); + BenchMarkByName("AES/CFB", 16); + BenchMarkByName("AES/CBC", 16); + BenchMarkByName("Camellia/ECB", 16); + BenchMarkByName("Camellia/ECB", 32); + BenchMarkKeyed("Twofish", t); + BenchMarkKeyed("Serpent", t); + BenchMarkKeyed("CAST-256", t); + BenchMarkKeyed("RC6", t); + BenchMarkKeyed("MARS", t); + BenchMarkByName("SHACAL-2/ECB", 16); + BenchMarkByName("SHACAL-2/ECB", 64); + BenchMarkKeyed("DES", t); + BenchMarkKeyed("DES-XEX3", t); + BenchMarkKeyed("DES-EDE3", t); + BenchMarkKeyed("IDEA", t); + BenchMarkKeyed("RC5 (r=16)", t); + BenchMarkKeyed("Blowfish", t); + BenchMarkByName("TEA/ECB"); + BenchMarkByName("XTEA/ECB"); + BenchMarkKeyed("CAST-128", t); + BenchMarkKeyed("SKIPJACK", t); + cout << "
AlgorithmMiB/Second" << cpb << "Microseconds to
Setup Key and IV" << cpk << endl; + + cout << "\n
" << endl; + + BenchmarkAll2(t, hertz); + + cout << "Throughput Geometric Average: " << setiosflags(ios::fixed) << exp(logtotal/logcount) << endl; + + time_t endTime = time(NULL); + cout << "\nTest ended at " << asctime(localtime(&endTime)); +#endif +} diff --git a/CryptoPP/crypto/bench.h b/CryptoPP/crypto/bench.h new file mode 100644 index 0000000..c5da2cf --- /dev/null +++ b/CryptoPP/crypto/bench.h @@ -0,0 +1,11 @@ +#ifndef CRYPTOPP_BENCH_H +#define CRYPTOPP_BENCH_H + +#include "cryptlib.h" + +extern const double CLOCK_TICKS_PER_SECOND; + +void BenchmarkAll(double t, double hertz); +void BenchmarkAll2(double t, double hertz); + +#endif diff --git a/CryptoPP/crypto/bench2.cpp b/CryptoPP/crypto/bench2.cpp new file mode 100644 index 0000000..144c1b1 --- /dev/null +++ b/CryptoPP/crypto/bench2.cpp @@ -0,0 +1,327 @@ +// bench2.cpp - written and placed in the public domain by Wei Dai + +#include "bench.h" +#include "rng.h" +#include "files.h" +#include "hex.h" + +#include "rsa.h" +#include "nr.h" +#include "dsa.h" +#include "luc.h" +#include "rw.h" +#include "eccrypto.h" +#include "ecp.h" +#include "ec2n.h" +#include "asn.h" +#include "dh.h" +#include "mqv.h" +#include "xtrcrypt.h" +#include "esign.h" +#include "pssr.h" +#include "oids.h" +#include "randpool.h" + +#include +#include +#include +#include + +USING_NAMESPACE(CryptoPP) +USING_NAMESPACE(std) + +void OutputResultOperations(const char *name, const char *operation, bool pc, unsigned long iterations, double timeTaken); + +void BenchMarkEncryption(const char *name, PK_Encryptor &key, double timeTotal, bool pc=false) +{ + unsigned int len = 16; + LC_RNG rng((word32)time(NULL)); + SecByteBlock plaintext(len), ciphertext(key.CiphertextLength(len)); + rng.GenerateBlock(plaintext, len); + + clock_t start = clock(); + unsigned int i; + double timeTaken; + for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i++) + key.Encrypt(rng, plaintext, len, ciphertext); + + OutputResultOperations(name, "Encryption", pc, i, timeTaken); + + if (!pc && key.GetMaterial().SupportsPrecomputation()) + { + key.AccessMaterial().Precompute(16); + BenchMarkEncryption(name, key, timeTotal, true); + } +} + +void BenchMarkDecryption(const char *name, PK_Decryptor &priv, PK_Encryptor &pub, double timeTotal) +{ + unsigned int len = 16; + LC_RNG rng((word32)time(NULL)); + SecByteBlock ciphertext(pub.CiphertextLength(len)); + SecByteBlock plaintext(pub.MaxPlaintextLength(ciphertext.size())); + rng.GenerateBlock(plaintext, len); + pub.Encrypt(rng, plaintext, len, ciphertext); + + clock_t start = clock(); + unsigned int i; + double timeTaken; + for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i++) + priv.Decrypt(rng, ciphertext, ciphertext.size(), plaintext); + + OutputResultOperations(name, "Decryption", false, i, timeTaken); +} + +void BenchMarkSigning(const char *name, PK_Signer &key, double timeTotal, bool pc=false) +{ + unsigned int len = 16; + LC_RNG rng((word32)time(NULL)); + AlignedSecByteBlock message(len), signature(key.SignatureLength()); + rng.GenerateBlock(message, len); + + clock_t start = clock(); + unsigned int i; + double timeTaken; + for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i++) + key.SignMessage(rng, message, len, signature); + + OutputResultOperations(name, "Signature", pc, i, timeTaken); + + if (!pc && key.GetMaterial().SupportsPrecomputation()) + { + key.AccessMaterial().Precompute(16); + BenchMarkSigning(name, key, timeTotal, true); + } +} + +void BenchMarkVerification(const char *name, const PK_Signer &priv, PK_Verifier &pub, double timeTotal, bool pc=false) +{ + unsigned int len = 16; + LC_RNG rng((word32)time(NULL)); + AlignedSecByteBlock message(len), signature(pub.SignatureLength()); + rng.GenerateBlock(message, len); + priv.SignMessage(rng, message, len, signature); + + clock_t start = clock(); + unsigned int i; + double timeTaken; + for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i++) + pub.VerifyMessage(message, len, signature, signature.size()); + + OutputResultOperations(name, "Verification", pc, i, timeTaken); + + if (!pc && pub.GetMaterial().SupportsPrecomputation()) + { + pub.AccessMaterial().Precompute(16); + BenchMarkVerification(name, priv, pub, timeTotal, true); + } +} + +void BenchMarkKeyGen(const char *name, SimpleKeyAgreementDomain &d, double timeTotal, bool pc=false) +{ + LC_RNG rng((word32)time(NULL)); + SecByteBlock priv(d.PrivateKeyLength()), pub(d.PublicKeyLength()); + + clock_t start = clock(); + unsigned int i; + double timeTaken; + for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i++) + d.GenerateKeyPair(rng, priv, pub); + + OutputResultOperations(name, "Key-Pair Generation", pc, i, timeTaken); + + if (!pc && d.GetMaterial().SupportsPrecomputation()) + { + d.AccessMaterial().Precompute(16); + BenchMarkKeyGen(name, d, timeTotal, true); + } +} + +void BenchMarkKeyGen(const char *name, AuthenticatedKeyAgreementDomain &d, double timeTotal, bool pc=false) +{ + LC_RNG rng((word32)time(NULL)); + SecByteBlock priv(d.EphemeralPrivateKeyLength()), pub(d.EphemeralPublicKeyLength()); + + clock_t start = clock(); + unsigned int i; + double timeTaken; + for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i++) + d.GenerateEphemeralKeyPair(rng, priv, pub); + + OutputResultOperations(name, "Key-Pair Generation", pc, i, timeTaken); + + if (!pc && d.GetMaterial().SupportsPrecomputation()) + { + d.AccessMaterial().Precompute(16); + BenchMarkKeyGen(name, d, timeTotal, true); + } +} + +void BenchMarkAgreement(const char *name, SimpleKeyAgreementDomain &d, double timeTotal, bool pc=false) +{ + LC_RNG rng((word32)time(NULL)); + SecByteBlock priv1(d.PrivateKeyLength()), priv2(d.PrivateKeyLength()); + SecByteBlock pub1(d.PublicKeyLength()), pub2(d.PublicKeyLength()); + d.GenerateKeyPair(rng, priv1, pub1); + d.GenerateKeyPair(rng, priv2, pub2); + SecByteBlock val(d.AgreedValueLength()); + + clock_t start = clock(); + unsigned int i; + double timeTaken; + for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i+=2) + { + d.Agree(val, priv1, pub2); + d.Agree(val, priv2, pub1); + } + + OutputResultOperations(name, "Key Agreement", pc, i, timeTaken); +} + +void BenchMarkAgreement(const char *name, AuthenticatedKeyAgreementDomain &d, double timeTotal, bool pc=false) +{ + LC_RNG rng((word32)time(NULL)); + SecByteBlock spriv1(d.StaticPrivateKeyLength()), spriv2(d.StaticPrivateKeyLength()); + SecByteBlock epriv1(d.EphemeralPrivateKeyLength()), epriv2(d.EphemeralPrivateKeyLength()); + SecByteBlock spub1(d.StaticPublicKeyLength()), spub2(d.StaticPublicKeyLength()); + SecByteBlock epub1(d.EphemeralPublicKeyLength()), epub2(d.EphemeralPublicKeyLength()); + d.GenerateStaticKeyPair(rng, spriv1, spub1); + d.GenerateStaticKeyPair(rng, spriv2, spub2); + d.GenerateEphemeralKeyPair(rng, epriv1, epub1); + d.GenerateEphemeralKeyPair(rng, epriv2, epub2); + SecByteBlock val(d.AgreedValueLength()); + + clock_t start = clock(); + unsigned int i; + double timeTaken; + for (timeTaken=(double)0, i=0; timeTaken < timeTotal; timeTaken = double(clock() - start) / CLOCK_TICKS_PER_SECOND, i+=2) + { + d.Agree(val, spriv1, epriv1, spub2, epub2); + d.Agree(val, spriv2, epriv2, spub1, epub1); + } + + OutputResultOperations(name, "Key Agreement", pc, i, timeTaken); +} + +//VC60 workaround: compiler bug triggered without the extra dummy parameters +template +void BenchMarkCrypto(const char *filename, const char *name, double timeTotal, SCHEME *x=NULL) +{ + FileSource f(filename, true, new HexDecoder()); + typename SCHEME::Decryptor priv(f); + typename SCHEME::Encryptor pub(priv); + BenchMarkEncryption(name, pub, timeTotal); + BenchMarkDecryption(name, priv, pub, timeTotal); +} + +//VC60 workaround: compiler bug triggered without the extra dummy parameters +template +void BenchMarkSignature(const char *filename, const char *name, double timeTotal, SCHEME *x=NULL) +{ + FileSource f(filename, true, new HexDecoder()); + typename SCHEME::Signer priv(f); + typename SCHEME::Verifier pub(priv); + BenchMarkSigning(name, priv, timeTotal); + BenchMarkVerification(name, priv, pub, timeTotal); +} + +//VC60 workaround: compiler bug triggered without the extra dummy parameters +template +void BenchMarkKeyAgreement(const char *filename, const char *name, double timeTotal, D *x=NULL) +{ + FileSource f(filename, true, new HexDecoder()); + D d(f); + BenchMarkKeyGen(name, d, timeTotal); + BenchMarkAgreement(name, d, timeTotal); +} + +extern double g_hertz; + +void BenchmarkAll2(double t, double hertz) +{ + g_hertz = hertz; + + cout << "" << endl; + cout << ""; + BenchMarkCrypto > >("rsa1024.dat", "RSA 1024", t); + BenchMarkCrypto > >("luc1024.dat", "LUC 1024", t); + BenchMarkCrypto >("dlie1024.dat", "DLIES 1024", t); + BenchMarkCrypto >("lucc512.dat", "LUCELG 512", t); + + cout << "\n"; + BenchMarkCrypto > >("rsa2048.dat", "RSA 2048", t); + BenchMarkCrypto > >("luc2048.dat", "LUC 2048", t); + BenchMarkCrypto >("dlie2048.dat", "DLIES 2048", t); + BenchMarkCrypto >("lucc1024.dat", "LUCELG 1024", t); + + cout << "\n"; + BenchMarkSignature >("rsa1024.dat", "RSA 1024", t); + BenchMarkSignature >("rw1024.dat", "RW 1024", t); + BenchMarkSignature >("luc1024.dat", "LUC 1024", t); + BenchMarkSignature >("nr1024.dat", "NR 1024", t); + BenchMarkSignature("dsa1024.dat", "DSA 1024", t); + BenchMarkSignature >("lucs512.dat", "LUC-HMP 512", t); + BenchMarkSignature >("esig1023.dat", "ESIGN 1023", t); + BenchMarkSignature >("esig1536.dat", "ESIGN 1536", t); + + cout << "\n"; + BenchMarkSignature >("rsa2048.dat", "RSA 2048", t); + BenchMarkSignature >("rw2048.dat", "RW 2048", t); + BenchMarkSignature >("luc2048.dat", "LUC 2048", t); + BenchMarkSignature >("nr2048.dat", "NR 2048", t); + BenchMarkSignature >("lucs1024.dat", "LUC-HMP 1024", t); + BenchMarkSignature >("esig2046.dat", "ESIGN 2046", t); + + cout << "\n"; + BenchMarkKeyAgreement("xtrdh171.dat", "XTR-DH 171", t); + BenchMarkKeyAgreement("xtrdh342.dat", "XTR-DH 342", t); + BenchMarkKeyAgreement("dh1024.dat", "DH 1024", t); + BenchMarkKeyAgreement("dh2048.dat", "DH 2048", t); + BenchMarkKeyAgreement("lucd512.dat", "LUCDIF 512", t); + BenchMarkKeyAgreement("lucd1024.dat", "LUCDIF 1024", t); + BenchMarkKeyAgreement("mqv1024.dat", "MQV 1024", t); + BenchMarkKeyAgreement("mqv2048.dat", "MQV 2048", t); + + cout << "\n"; + { + RandomPool rng; // not seeded + ECIES::Decryptor cpriv(rng, ASN1::secp256k1()); + ECIES::Encryptor cpub(cpriv); + ECDSA::Signer spriv(cpriv); + ECDSA::Verifier spub(spriv); + ECDH::Domain ecdhc(ASN1::secp256k1()); + ECMQV::Domain ecmqvc(ASN1::secp256k1()); + + BenchMarkEncryption("ECIES over GF(p) 256", cpub, t); + BenchMarkDecryption("ECIES over GF(p) 256", cpriv, cpub, t); + BenchMarkSigning("ECNR over GF(p) 256", spriv, t); + BenchMarkVerification("ECNR over GF(p) 256", spriv, spub, t); + BenchMarkKeyGen("ECDHC over GF(p) 256", ecdhc, t); + BenchMarkAgreement("ECDHC over GF(p) 256", ecdhc, t); + BenchMarkKeyGen("ECMQVC over GF(p) 256", ecmqvc, t); + BenchMarkAgreement("ECMQVC over GF(p) 256", ecmqvc, t); + } + + cout << "" << endl; + { + RandomPool rng; // not seeded + ECIES::Decryptor cpriv(rng, ASN1::sect233r1()); + ECIES::Encryptor cpub(cpriv); + ECDSA::Signer spriv(cpriv); + ECDSA::Verifier spub(spriv); + ECDH::Domain ecdhc(ASN1::sect233r1()); + ECMQV::Domain ecmqvc(ASN1::sect233r1()); + + BenchMarkEncryption("ECIES over GF(2^n) 233", cpub, t); + BenchMarkDecryption("ECIES over GF(2^n) 233", cpriv, cpub, t); + BenchMarkSigning("ECNR over GF(2^n) 233", spriv, t); + BenchMarkVerification("ECNR over GF(2^n) 233", spriv, spub, t); + BenchMarkKeyGen("ECDHC over GF(2^n) 233", ecdhc, t); + BenchMarkAgreement("ECDHC over GF(2^n) 233", ecdhc, t); + BenchMarkKeyGen("ECMQVC over GF(2^n) 233", ecmqvc, t); + BenchMarkAgreement("ECMQVC over GF(2^n) 233", ecmqvc, t); + } + cout << "
OperationMilliseconds/Operation" << (g_hertz ? "Megacycles/Operation" : "") << endl; + + cout << "\n
" << endl; +} diff --git a/CryptoPP/crypto/bfinit.cpp b/CryptoPP/crypto/bfinit.cpp new file mode 100644 index 0000000..06db209 --- /dev/null +++ b/CryptoPP/crypto/bfinit.cpp @@ -0,0 +1,277 @@ +#include "pch.h" +#include "blowfish.h" + +NAMESPACE_BEGIN(CryptoPP) + +const word32 Blowfish::Base::p_init[Blowfish::ROUNDS+2] = +{ + 608135816U, 2242054355U, 320440878U, 57701188U, + 2752067618U, 698298832U, 137296536U, 3964562569U, + 1160258022U, 953160567U, 3193202383U, 887688300U, + 3232508343U, 3380367581U, 1065670069U, 3041331479U, + 2450970073U, 2306472731U +} ; + +const word32 Blowfish::Base::s_init[4*256] = { + 3509652390U, 2564797868U, 805139163U, 3491422135U, + 3101798381U, 1780907670U, 3128725573U, 4046225305U, + 614570311U, 3012652279U, 134345442U, 2240740374U, + 1667834072U, 1901547113U, 2757295779U, 4103290238U, + 227898511U, 1921955416U, 1904987480U, 2182433518U, + 2069144605U, 3260701109U, 2620446009U, 720527379U, + 3318853667U, 677414384U, 3393288472U, 3101374703U, + 2390351024U, 1614419982U, 1822297739U, 2954791486U, + 3608508353U, 3174124327U, 2024746970U, 1432378464U, + 3864339955U, 2857741204U, 1464375394U, 1676153920U, + 1439316330U, 715854006U, 3033291828U, 289532110U, + 2706671279U, 2087905683U, 3018724369U, 1668267050U, + 732546397U, 1947742710U, 3462151702U, 2609353502U, + 2950085171U, 1814351708U, 2050118529U, 680887927U, + 999245976U, 1800124847U, 3300911131U, 1713906067U, + 1641548236U, 4213287313U, 1216130144U, 1575780402U, + 4018429277U, 3917837745U, 3693486850U, 3949271944U, + 596196993U, 3549867205U, 258830323U, 2213823033U, + 772490370U, 2760122372U, 1774776394U, 2652871518U, + 566650946U, 4142492826U, 1728879713U, 2882767088U, + 1783734482U, 3629395816U, 2517608232U, 2874225571U, + 1861159788U, 326777828U, 3124490320U, 2130389656U, + 2716951837U, 967770486U, 1724537150U, 2185432712U, + 2364442137U, 1164943284U, 2105845187U, 998989502U, + 3765401048U, 2244026483U, 1075463327U, 1455516326U, + 1322494562U, 910128902U, 469688178U, 1117454909U, + 936433444U, 3490320968U, 3675253459U, 1240580251U, + 122909385U, 2157517691U, 634681816U, 4142456567U, + 3825094682U, 3061402683U, 2540495037U, 79693498U, + 3249098678U, 1084186820U, 1583128258U, 426386531U, + 1761308591U, 1047286709U, 322548459U, 995290223U, + 1845252383U, 2603652396U, 3431023940U, 2942221577U, + 3202600964U, 3727903485U, 1712269319U, 422464435U, + 3234572375U, 1170764815U, 3523960633U, 3117677531U, + 1434042557U, 442511882U, 3600875718U, 1076654713U, + 1738483198U, 4213154764U, 2393238008U, 3677496056U, + 1014306527U, 4251020053U, 793779912U, 2902807211U, + 842905082U, 4246964064U, 1395751752U, 1040244610U, + 2656851899U, 3396308128U, 445077038U, 3742853595U, + 3577915638U, 679411651U, 2892444358U, 2354009459U, + 1767581616U, 3150600392U, 3791627101U, 3102740896U, + 284835224U, 4246832056U, 1258075500U, 768725851U, + 2589189241U, 3069724005U, 3532540348U, 1274779536U, + 3789419226U, 2764799539U, 1660621633U, 3471099624U, + 4011903706U, 913787905U, 3497959166U, 737222580U, + 2514213453U, 2928710040U, 3937242737U, 1804850592U, + 3499020752U, 2949064160U, 2386320175U, 2390070455U, + 2415321851U, 4061277028U, 2290661394U, 2416832540U, + 1336762016U, 1754252060U, 3520065937U, 3014181293U, + 791618072U, 3188594551U, 3933548030U, 2332172193U, + 3852520463U, 3043980520U, 413987798U, 3465142937U, + 3030929376U, 4245938359U, 2093235073U, 3534596313U, + 375366246U, 2157278981U, 2479649556U, 555357303U, + 3870105701U, 2008414854U, 3344188149U, 4221384143U, + 3956125452U, 2067696032U, 3594591187U, 2921233993U, + 2428461U, 544322398U, 577241275U, 1471733935U, + 610547355U, 4027169054U, 1432588573U, 1507829418U, + 2025931657U, 3646575487U, 545086370U, 48609733U, + 2200306550U, 1653985193U, 298326376U, 1316178497U, + 3007786442U, 2064951626U, 458293330U, 2589141269U, + 3591329599U, 3164325604U, 727753846U, 2179363840U, + 146436021U, 1461446943U, 4069977195U, 705550613U, + 3059967265U, 3887724982U, 4281599278U, 3313849956U, + 1404054877U, 2845806497U, 146425753U, 1854211946U, + + 1266315497U, 3048417604U, 3681880366U, 3289982499U, + 2909710000U, 1235738493U, 2632868024U, 2414719590U, + 3970600049U, 1771706367U, 1449415276U, 3266420449U, + 422970021U, 1963543593U, 2690192192U, 3826793022U, + 1062508698U, 1531092325U, 1804592342U, 2583117782U, + 2714934279U, 4024971509U, 1294809318U, 4028980673U, + 1289560198U, 2221992742U, 1669523910U, 35572830U, + 157838143U, 1052438473U, 1016535060U, 1802137761U, + 1753167236U, 1386275462U, 3080475397U, 2857371447U, + 1040679964U, 2145300060U, 2390574316U, 1461121720U, + 2956646967U, 4031777805U, 4028374788U, 33600511U, + 2920084762U, 1018524850U, 629373528U, 3691585981U, + 3515945977U, 2091462646U, 2486323059U, 586499841U, + 988145025U, 935516892U, 3367335476U, 2599673255U, + 2839830854U, 265290510U, 3972581182U, 2759138881U, + 3795373465U, 1005194799U, 847297441U, 406762289U, + 1314163512U, 1332590856U, 1866599683U, 4127851711U, + 750260880U, 613907577U, 1450815602U, 3165620655U, + 3734664991U, 3650291728U, 3012275730U, 3704569646U, + 1427272223U, 778793252U, 1343938022U, 2676280711U, + 2052605720U, 1946737175U, 3164576444U, 3914038668U, + 3967478842U, 3682934266U, 1661551462U, 3294938066U, + 4011595847U, 840292616U, 3712170807U, 616741398U, + 312560963U, 711312465U, 1351876610U, 322626781U, + 1910503582U, 271666773U, 2175563734U, 1594956187U, + 70604529U, 3617834859U, 1007753275U, 1495573769U, + 4069517037U, 2549218298U, 2663038764U, 504708206U, + 2263041392U, 3941167025U, 2249088522U, 1514023603U, + 1998579484U, 1312622330U, 694541497U, 2582060303U, + 2151582166U, 1382467621U, 776784248U, 2618340202U, + 3323268794U, 2497899128U, 2784771155U, 503983604U, + 4076293799U, 907881277U, 423175695U, 432175456U, + 1378068232U, 4145222326U, 3954048622U, 3938656102U, + 3820766613U, 2793130115U, 2977904593U, 26017576U, + 3274890735U, 3194772133U, 1700274565U, 1756076034U, + 4006520079U, 3677328699U, 720338349U, 1533947780U, + 354530856U, 688349552U, 3973924725U, 1637815568U, + 332179504U, 3949051286U, 53804574U, 2852348879U, + 3044236432U, 1282449977U, 3583942155U, 3416972820U, + 4006381244U, 1617046695U, 2628476075U, 3002303598U, + 1686838959U, 431878346U, 2686675385U, 1700445008U, + 1080580658U, 1009431731U, 832498133U, 3223435511U, + 2605976345U, 2271191193U, 2516031870U, 1648197032U, + 4164389018U, 2548247927U, 300782431U, 375919233U, + 238389289U, 3353747414U, 2531188641U, 2019080857U, + 1475708069U, 455242339U, 2609103871U, 448939670U, + 3451063019U, 1395535956U, 2413381860U, 1841049896U, + 1491858159U, 885456874U, 4264095073U, 4001119347U, + 1565136089U, 3898914787U, 1108368660U, 540939232U, + 1173283510U, 2745871338U, 3681308437U, 4207628240U, + 3343053890U, 4016749493U, 1699691293U, 1103962373U, + 3625875870U, 2256883143U, 3830138730U, 1031889488U, + 3479347698U, 1535977030U, 4236805024U, 3251091107U, + 2132092099U, 1774941330U, 1199868427U, 1452454533U, + 157007616U, 2904115357U, 342012276U, 595725824U, + 1480756522U, 206960106U, 497939518U, 591360097U, + 863170706U, 2375253569U, 3596610801U, 1814182875U, + 2094937945U, 3421402208U, 1082520231U, 3463918190U, + 2785509508U, 435703966U, 3908032597U, 1641649973U, + 2842273706U, 3305899714U, 1510255612U, 2148256476U, + 2655287854U, 3276092548U, 4258621189U, 236887753U, + 3681803219U, 274041037U, 1734335097U, 3815195456U, + 3317970021U, 1899903192U, 1026095262U, 4050517792U, + 356393447U, 2410691914U, 3873677099U, 3682840055U, + + 3913112168U, 2491498743U, 4132185628U, 2489919796U, + 1091903735U, 1979897079U, 3170134830U, 3567386728U, + 3557303409U, 857797738U, 1136121015U, 1342202287U, + 507115054U, 2535736646U, 337727348U, 3213592640U, + 1301675037U, 2528481711U, 1895095763U, 1721773893U, + 3216771564U, 62756741U, 2142006736U, 835421444U, + 2531993523U, 1442658625U, 3659876326U, 2882144922U, + 676362277U, 1392781812U, 170690266U, 3921047035U, + 1759253602U, 3611846912U, 1745797284U, 664899054U, + 1329594018U, 3901205900U, 3045908486U, 2062866102U, + 2865634940U, 3543621612U, 3464012697U, 1080764994U, + 553557557U, 3656615353U, 3996768171U, 991055499U, + 499776247U, 1265440854U, 648242737U, 3940784050U, + 980351604U, 3713745714U, 1749149687U, 3396870395U, + 4211799374U, 3640570775U, 1161844396U, 3125318951U, + 1431517754U, 545492359U, 4268468663U, 3499529547U, + 1437099964U, 2702547544U, 3433638243U, 2581715763U, + 2787789398U, 1060185593U, 1593081372U, 2418618748U, + 4260947970U, 69676912U, 2159744348U, 86519011U, + 2512459080U, 3838209314U, 1220612927U, 3339683548U, + 133810670U, 1090789135U, 1078426020U, 1569222167U, + 845107691U, 3583754449U, 4072456591U, 1091646820U, + 628848692U, 1613405280U, 3757631651U, 526609435U, + 236106946U, 48312990U, 2942717905U, 3402727701U, + 1797494240U, 859738849U, 992217954U, 4005476642U, + 2243076622U, 3870952857U, 3732016268U, 765654824U, + 3490871365U, 2511836413U, 1685915746U, 3888969200U, + 1414112111U, 2273134842U, 3281911079U, 4080962846U, + 172450625U, 2569994100U, 980381355U, 4109958455U, + 2819808352U, 2716589560U, 2568741196U, 3681446669U, + 3329971472U, 1835478071U, 660984891U, 3704678404U, + 4045999559U, 3422617507U, 3040415634U, 1762651403U, + 1719377915U, 3470491036U, 2693910283U, 3642056355U, + 3138596744U, 1364962596U, 2073328063U, 1983633131U, + 926494387U, 3423689081U, 2150032023U, 4096667949U, + 1749200295U, 3328846651U, 309677260U, 2016342300U, + 1779581495U, 3079819751U, 111262694U, 1274766160U, + 443224088U, 298511866U, 1025883608U, 3806446537U, + 1145181785U, 168956806U, 3641502830U, 3584813610U, + 1689216846U, 3666258015U, 3200248200U, 1692713982U, + 2646376535U, 4042768518U, 1618508792U, 1610833997U, + 3523052358U, 4130873264U, 2001055236U, 3610705100U, + 2202168115U, 4028541809U, 2961195399U, 1006657119U, + 2006996926U, 3186142756U, 1430667929U, 3210227297U, + 1314452623U, 4074634658U, 4101304120U, 2273951170U, + 1399257539U, 3367210612U, 3027628629U, 1190975929U, + 2062231137U, 2333990788U, 2221543033U, 2438960610U, + 1181637006U, 548689776U, 2362791313U, 3372408396U, + 3104550113U, 3145860560U, 296247880U, 1970579870U, + 3078560182U, 3769228297U, 1714227617U, 3291629107U, + 3898220290U, 166772364U, 1251581989U, 493813264U, + 448347421U, 195405023U, 2709975567U, 677966185U, + 3703036547U, 1463355134U, 2715995803U, 1338867538U, + 1343315457U, 2802222074U, 2684532164U, 233230375U, + 2599980071U, 2000651841U, 3277868038U, 1638401717U, + 4028070440U, 3237316320U, 6314154U, 819756386U, + 300326615U, 590932579U, 1405279636U, 3267499572U, + 3150704214U, 2428286686U, 3959192993U, 3461946742U, + 1862657033U, 1266418056U, 963775037U, 2089974820U, + 2263052895U, 1917689273U, 448879540U, 3550394620U, + 3981727096U, 150775221U, 3627908307U, 1303187396U, + 508620638U, 2975983352U, 2726630617U, 1817252668U, + 1876281319U, 1457606340U, 908771278U, 3720792119U, + 3617206836U, 2455994898U, 1729034894U, 1080033504U, + + 976866871U, 3556439503U, 2881648439U, 1522871579U, + 1555064734U, 1336096578U, 3548522304U, 2579274686U, + 3574697629U, 3205460757U, 3593280638U, 3338716283U, + 3079412587U, 564236357U, 2993598910U, 1781952180U, + 1464380207U, 3163844217U, 3332601554U, 1699332808U, + 1393555694U, 1183702653U, 3581086237U, 1288719814U, + 691649499U, 2847557200U, 2895455976U, 3193889540U, + 2717570544U, 1781354906U, 1676643554U, 2592534050U, + 3230253752U, 1126444790U, 2770207658U, 2633158820U, + 2210423226U, 2615765581U, 2414155088U, 3127139286U, + 673620729U, 2805611233U, 1269405062U, 4015350505U, + 3341807571U, 4149409754U, 1057255273U, 2012875353U, + 2162469141U, 2276492801U, 2601117357U, 993977747U, + 3918593370U, 2654263191U, 753973209U, 36408145U, + 2530585658U, 25011837U, 3520020182U, 2088578344U, + 530523599U, 2918365339U, 1524020338U, 1518925132U, + 3760827505U, 3759777254U, 1202760957U, 3985898139U, + 3906192525U, 674977740U, 4174734889U, 2031300136U, + 2019492241U, 3983892565U, 4153806404U, 3822280332U, + 352677332U, 2297720250U, 60907813U, 90501309U, + 3286998549U, 1016092578U, 2535922412U, 2839152426U, + 457141659U, 509813237U, 4120667899U, 652014361U, + 1966332200U, 2975202805U, 55981186U, 2327461051U, + 676427537U, 3255491064U, 2882294119U, 3433927263U, + 1307055953U, 942726286U, 933058658U, 2468411793U, + 3933900994U, 4215176142U, 1361170020U, 2001714738U, + 2830558078U, 3274259782U, 1222529897U, 1679025792U, + 2729314320U, 3714953764U, 1770335741U, 151462246U, + 3013232138U, 1682292957U, 1483529935U, 471910574U, + 1539241949U, 458788160U, 3436315007U, 1807016891U, + 3718408830U, 978976581U, 1043663428U, 3165965781U, + 1927990952U, 4200891579U, 2372276910U, 3208408903U, + 3533431907U, 1412390302U, 2931980059U, 4132332400U, + 1947078029U, 3881505623U, 4168226417U, 2941484381U, + 1077988104U, 1320477388U, 886195818U, 18198404U, + 3786409000U, 2509781533U, 112762804U, 3463356488U, + 1866414978U, 891333506U, 18488651U, 661792760U, + 1628790961U, 3885187036U, 3141171499U, 876946877U, + 2693282273U, 1372485963U, 791857591U, 2686433993U, + 3759982718U, 3167212022U, 3472953795U, 2716379847U, + 445679433U, 3561995674U, 3504004811U, 3574258232U, + 54117162U, 3331405415U, 2381918588U, 3769707343U, + 4154350007U, 1140177722U, 4074052095U, 668550556U, + 3214352940U, 367459370U, 261225585U, 2610173221U, + 4209349473U, 3468074219U, 3265815641U, 314222801U, + 3066103646U, 3808782860U, 282218597U, 3406013506U, + 3773591054U, 379116347U, 1285071038U, 846784868U, + 2669647154U, 3771962079U, 3550491691U, 2305946142U, + 453669953U, 1268987020U, 3317592352U, 3279303384U, + 3744833421U, 2610507566U, 3859509063U, 266596637U, + 3847019092U, 517658769U, 3462560207U, 3443424879U, + 370717030U, 4247526661U, 2224018117U, 4143653529U, + 4112773975U, 2788324899U, 2477274417U, 1456262402U, + 2901442914U, 1517677493U, 1846949527U, 2295493580U, + 3734397586U, 2176403920U, 1280348187U, 1908823572U, + 3871786941U, 846861322U, 1172426758U, 3287448474U, + 3383383037U, 1655181056U, 3139813346U, 901632758U, + 1897031941U, 2986607138U, 3066810236U, 3447102507U, + 1393639104U, 373351379U, 950779232U, 625454576U, + 3124240540U, 4148612726U, 2007998917U, 544563296U, + 2244738638U, 2330496472U, 2058025392U, 1291430526U, + 424198748U, 50039436U, 29584100U, 3605783033U, + 2429876329U, 2791104160U, 1057563949U, 3255363231U, + 3075367218U, 3463963227U, 1469046755U, 985887462U +}; + +NAMESPACE_END diff --git a/CryptoPP/crypto/blowfish.cpp b/CryptoPP/crypto/blowfish.cpp new file mode 100644 index 0000000..7fe9a56 --- /dev/null +++ b/CryptoPP/crypto/blowfish.cpp @@ -0,0 +1,99 @@ +// blowfish.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "blowfish.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +void Blowfish::Base::UncheckedSetKey(const byte *key_string, unsigned int keylength, const NameValuePairs &) +{ + AssertValidKeyLength(keylength); + + unsigned i, j=0, k; + word32 data, dspace[2] = {0, 0}; + + memcpy(pbox, p_init, sizeof(p_init)); + memcpy(sbox, s_init, sizeof(s_init)); + + // Xor key string into encryption key vector + for (i=0 ; i Block; + + word32 left, right; + Block::Get(inBlock)(left)(right); + + const word32 *const s=sbox; + const word32 *p=pbox; + + left ^= p[0]; + + for (unsigned i=0; i, public VariableKeyLength<16, 1, 56>, public FixedRounds<16> +{ + static const char *StaticAlgorithmName() {return "Blowfish";} +}; + +//! Blowfish +class Blowfish : public Blowfish_Info, public BlockCipherDocumentation +{ + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + void UncheckedSetKey(const byte *key_string, unsigned int keylength, const NameValuePairs ¶ms); + + private: + void crypt_block(const word32 in[2], word32 out[2]) const; + + static const word32 p_init[ROUNDS+2]; + static const word32 s_init[4*256]; + + FixedSizeSecBlock pbox; + FixedSizeSecBlock sbox; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef Blowfish::Encryption BlowfishEncryption; +typedef Blowfish::Decryption BlowfishDecryption; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/blumshub.cpp b/CryptoPP/crypto/blumshub.cpp new file mode 100644 index 0000000..6ab2209 --- /dev/null +++ b/CryptoPP/crypto/blumshub.cpp @@ -0,0 +1,63 @@ +// blumshub.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "blumshub.h" + +NAMESPACE_BEGIN(CryptoPP) + +PublicBlumBlumShub::PublicBlumBlumShub(const Integer &n, const Integer &seed) + : modn(n), + maxBits(BitPrecision(n.BitCount())-1) +{ + current = modn.Square(modn.Square(seed)); + bitsLeft = maxBits; +} + +unsigned int PublicBlumBlumShub::GenerateBit() +{ + if (bitsLeft==0) + { + current = modn.Square(current); + bitsLeft = maxBits; + } + + return current.GetBit(--bitsLeft); +} + +byte PublicBlumBlumShub::GenerateByte() +{ + byte b=0; + for (int i=0; i<8; i++) + b = (b << 1) | PublicBlumBlumShub::GenerateBit(); + return b; +} + +void PublicBlumBlumShub::GenerateBlock(byte *output, size_t size) +{ + while (size--) + *output++ = PublicBlumBlumShub::GenerateByte(); +} + +void PublicBlumBlumShub::ProcessData(byte *outString, const byte *inString, size_t length) +{ + while (length--) + *outString++ = *inString++ ^ PublicBlumBlumShub::GenerateByte(); +} + +BlumBlumShub::BlumBlumShub(const Integer &p, const Integer &q, const Integer &seed) + : PublicBlumBlumShub(p*q, seed), + p(p), q(q), + x0(modn.Square(seed)) +{ +} + +void BlumBlumShub::Seek(lword index) +{ + Integer i(Integer::POSITIVE, index); + i *= 8; + Integer e = a_exp_b_mod_c (2, i / maxBits + 1, (p-1)*(q-1)); + current = modn.Exponentiate(x0, e); + bitsLeft = maxBits - i % maxBits; +} + +NAMESPACE_END diff --git a/CryptoPP/crypto/blumshub.h b/CryptoPP/crypto/blumshub.h new file mode 100644 index 0000000..538c152 --- /dev/null +++ b/CryptoPP/crypto/blumshub.h @@ -0,0 +1,53 @@ +#ifndef CRYPTOPP_BLUMSHUB_H +#define CRYPTOPP_BLUMSHUB_H + +#include "modarith.h" + +NAMESPACE_BEGIN(CryptoPP) + +class BlumGoldwasserPublicKey; +class BlumGoldwasserPrivateKey; + +//! BlumBlumShub without factorization of the modulus +class PublicBlumBlumShub : public RandomNumberGenerator, + public StreamTransformation +{ +public: + PublicBlumBlumShub(const Integer &n, const Integer &seed); + + unsigned int GenerateBit(); + byte GenerateByte(); + void GenerateBlock(byte *output, size_t size); + void ProcessData(byte *outString, const byte *inString, size_t length); + + bool IsSelfInverting() const {return true;} + bool IsForwardTransformation() const {return true;} + +protected: + ModularArithmetic modn; + word maxBits, bitsLeft; + Integer current; + + friend class BlumGoldwasserPublicKey; + friend class BlumGoldwasserPrivateKey; +}; + +//! BlumBlumShub with factorization of the modulus +class BlumBlumShub : public PublicBlumBlumShub +{ +public: + // Make sure p and q are both primes congruent to 3 mod 4 and at least 512 bits long, + // seed is the secret key and should be about as big as p*q + BlumBlumShub(const Integer &p, const Integer &q, const Integer &seed); + + bool IsRandomAccess() const {return true;} + void Seek(lword index); + +protected: + const Integer p, q; + const Integer x0; +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/camellia.cpp b/CryptoPP/crypto/camellia.cpp new file mode 100644 index 0000000..b9f1db8 --- /dev/null +++ b/CryptoPP/crypto/camellia.cpp @@ -0,0 +1,537 @@ +// camellia.cpp - by Kevin Springle, 2003 +// This code is hereby placed in the public domain. + +/* +Optimisations and defense against timing attacks added in Jan 2007 by Wei Dai. + +The first 2 rounds and the last round seem especially vulnerable to timing +attacks. The protection is similar to what was implemented for Rijndael. +See comments at top of rijndael.cpp for more details. +*/ + +#include "pch.h" + +#include "camellia.h" +#include "misc.h" +#include "cpu.h" + +NAMESPACE_BEGIN(CryptoPP) + +// round implementation that uses a small table for protection against timing attacks +#define SLOW_ROUND(lh, ll, rh, rl, kh, kl) { \ + word32 zr = ll ^ kl; \ + word32 zl = lh ^ kh; \ + zr= rotlFixed(s1[GETBYTE(zr, 3)], 1) | \ + (rotrFixed(s1[GETBYTE(zr, 2)], 1) << 24) | \ + (s1[rotlFixed(CRYPTOPP_GET_BYTE_AS_BYTE(zr, 1),1)] << 16) | \ + (s1[GETBYTE(zr, 0)] << 8); \ + zl= (s1[GETBYTE(zl, 3)] << 24) | \ + (rotlFixed(s1[GETBYTE(zl, 2)], 1) << 16) | \ + (rotrFixed(s1[GETBYTE(zl, 1)], 1) << 8) | \ + s1[rotlFixed(CRYPTOPP_GET_BYTE_AS_BYTE(zl, 0), 1)]; \ + zl ^= zr; \ + zr = zl ^ rotlFixed(zr, 8); \ + zl = zr ^ rotrFixed(zl, 8); \ + rh ^= rotlFixed(zr, 16); \ + rh ^= zl; \ + rl ^= rotlFixed(zl, 8); \ + } + +// normal round - same output as above but using larger tables for faster speed +#define ROUND(lh, ll, rh, rl, kh, kl) { \ + word32 th = lh ^ kh; \ + word32 tl = ll ^ kl; \ + word32 d = SP[0][GETBYTE(tl,0)] ^ SP[1][GETBYTE(tl,3)] ^ SP[2][GETBYTE(tl,2)] ^ SP[3][GETBYTE(tl,1)]; \ + word32 u = SP[0][GETBYTE(th,3)] ^ SP[1][GETBYTE(th,2)] ^ SP[2][GETBYTE(th,1)] ^ SP[3][GETBYTE(th,0)]; \ + d ^= u; \ + rh ^= d; \ + rl ^= d; \ + rl ^= rotrFixed(u, 8);} + +#define DOUBLE_ROUND(lh, ll, rh, rl, k0, k1, k2, k3) \ + ROUND(lh, ll, rh, rl, k0, k1) \ + ROUND(rh, rl, lh, ll, k2, k3) + +#ifdef IS_LITTLE_ENDIAN +#define EFI(i) (1-(i)) +#else +#define EFI(i) (i) +#endif + +void Camellia::Base::UncheckedSetKey(const byte *key, unsigned int keylen, const NameValuePairs &) +{ + m_rounds = (keylen >= 24) ? 4 : 3; + unsigned int kslen = (8 * m_rounds + 2); + m_key.New(kslen*2); + word32 *ks32 = m_key.data(); + int m=0, a=0; + if (!IsForwardTransformation()) + m = -1, a = kslen-1; + + word32 kl0, kl1, kl2, kl3; + GetBlock getBlock(key); + getBlock(kl0)(kl1)(kl2)(kl3); + word32 k0=kl0, k1=kl1, k2=kl2, k3=kl3; + +#define CALC_ADDR2(base, i, j) ((byte *)(base)+8*(i)+4*(j)+((-16*(i))&m)) +#define CALC_ADDR(base, i) CALC_ADDR2(base, i, 0) + +#if !defined(WORD64_AVAILABLE) + ks32 += 2*a; +#define PREPARE_KS_ROUNDS +#define KS_ROUND_0(i) \ + *(word32*)CALC_ADDR2(ks32, i+EFI(0), EFI(0)) = k0; \ + *(word32*)CALC_ADDR2(ks32, i+EFI(0), EFI(1)) = k1; \ + *(word32*)CALC_ADDR2(ks32, i+EFI(1), EFI(0)) = k2; \ + *(word32*)CALC_ADDR2(ks32, i+EFI(1), EFI(1)) = k3 +#define KS_ROUND(i, r, which) \ + if (which & (1<<((7-r/32)%4/2))) *(word32*)CALC_ADDR2(ks32, i+EFI((7-r/32)%4/2), EFI((7-r/32)%2)) = (k3 << (r%32)) | (k0 >> (32-r%32)); \ + if (which & (1<<((6-r/32)%4/2))) *(word32*)CALC_ADDR2(ks32, i+EFI((6-r/32)%4/2), EFI((6-r/32)%2)) = (k2 << (r%32)) | (k3 >> (32-r%32)); \ + if (which & (1<<((5-r/32)%4/2))) *(word32*)CALC_ADDR2(ks32, i+EFI((5-r/32)%4/2), EFI((5-r/32)%2)) = (k1 << (r%32)) | (k2 >> (32-r%32)); \ + if (which & (1<<((4-r/32)%4/2))) *(word32*)CALC_ADDR2(ks32, i+EFI((4-r/32)%4/2), EFI((4-r/32)%2)) = (k0 << (r%32)) | (k1 >> (32-r%32)) +#elif 1 + word64 kwl, kwr; + ks32 += 2*a; +#define PREPARE_KS_ROUNDS \ + kwl = (word64(k0) << 32) | k1; \ + kwr = (word64(k2) << 32) | k3 +#define KS_ROUND_0(i) \ + *(word64*)CALC_ADDR(ks32, i+EFI(0)) = kwl; \ + *(word64*)CALC_ADDR(ks32, i+EFI(1)) = kwr +#define KS_ROUND(i, r, which) \ + if (which & (1<> (64 - (r%64))); \ + if (which & (1<64))) *(word64*)CALC_ADDR(ks32, i+EFI(r>64)) = (kwl << (r%64)) | (kwr >> (64 - (r%64))) +#else + // SSE2 version is 30% faster on Intel Core 2. Doesn't seem worth the hassle of maintenance, but left here + // #if'd out in case someone needs it. + __m128i kw, kw2; + __m128i *ks128 = (__m128i *)ks32+a/2; + ks32 += 2*a; +#define PREPARE_KS_ROUNDS \ + kw = _mm_set_epi32(k0, k1, k2, k3); \ + if (m) kw2 = kw, kw = _mm_shuffle_epi32(kw, _MM_SHUFFLE(1, 0, 3, 2)); \ + else kw2 = _mm_shuffle_epi32(kw, _MM_SHUFFLE(1, 0, 3, 2)) +#define KS_ROUND_0(i) \ + _mm_store_si128((__m128i *)CALC_ADDR(ks128, i), kw) +#define KS_ROUND(i, r, which) { \ + __m128i temp; \ + if (r<64 && (which!=1 || m)) temp = _mm_or_si128(_mm_slli_epi64(kw, r%64), _mm_srli_epi64(kw2, 64-r%64)); \ + else temp = _mm_or_si128(_mm_slli_epi64(kw2, r%64), _mm_srli_epi64(kw, 64-r%64)); \ + if (which & 2) _mm_store_si128((__m128i *)CALC_ADDR(ks128, i), temp); \ + else _mm_storel_epi64((__m128i*)CALC_ADDR(ks32, i+EFI(0)), temp); \ + } +#endif + + if (keylen == 16) + { + // KL + PREPARE_KS_ROUNDS; + KS_ROUND_0(0); + KS_ROUND(4, 15, 3); + KS_ROUND(10, 45, 3); + KS_ROUND(12, 60, 2); + KS_ROUND(16, 77, 3); + KS_ROUND(18, 94, 3); + KS_ROUND(22, 111, 3); + + // KA + k0=kl0, k1=kl1, k2=kl2, k3=kl3; + DOUBLE_ROUND(k0, k1, k2, k3, 0xA09E667Ful, 0x3BCC908Bul, 0xB67AE858ul, 0x4CAA73B2ul); + k0^=kl0, k1^=kl1, k2^=kl2, k3^=kl3; + DOUBLE_ROUND(k0, k1, k2, k3, 0xC6EF372Ful, 0xE94F82BEul, 0x54FF53A5ul, 0xF1D36F1Cul); + + PREPARE_KS_ROUNDS; + KS_ROUND_0(2); + KS_ROUND(6, 15, 3); + KS_ROUND(8, 30, 3); + KS_ROUND(12, 45, 1); + KS_ROUND(14, 60, 3); + KS_ROUND(20, 94, 3); + KS_ROUND(24, 47, 3); + } + else + { + // KL + PREPARE_KS_ROUNDS; + KS_ROUND_0(0); + KS_ROUND(12, 45, 3); + KS_ROUND(16, 60, 3); + KS_ROUND(22, 77, 3); + KS_ROUND(30, 111, 3); + + // KR + word32 kr0, kr1, kr2, kr3; + GetBlock(key+16)(kr0)(kr1); + if (keylen == 24) + kr2 = ~kr0, kr3 = ~kr1; + else + GetBlock(key+24)(kr2)(kr3); + k0=kr0, k1=kr1, k2=kr2, k3=kr3; + + PREPARE_KS_ROUNDS; + KS_ROUND(4, 15, 3); + KS_ROUND(8, 30, 3); + KS_ROUND(18, 60, 3); + KS_ROUND(26, 94, 3); + + // KA + k0^=kl0, k1^=kl1, k2^=kl2, k3^=kl3; + DOUBLE_ROUND(k0, k1, k2, k3, 0xA09E667Ful, 0x3BCC908Bul, 0xB67AE858ul, 0x4CAA73B2ul); + k0^=kl0, k1^=kl1, k2^=kl2, k3^=kl3; + DOUBLE_ROUND(k0, k1, k2, k3, 0xC6EF372Ful, 0xE94F82BEul, 0x54FF53A5ul, 0xF1D36F1Cul); + + PREPARE_KS_ROUNDS; + KS_ROUND(6, 15, 3); + KS_ROUND(14, 45, 3); + KS_ROUND(24, 77, 3); + KS_ROUND(28, 94, 3); + + // KB + k0^=kr0, k1^=kr1, k2^=kr2, k3^=kr3; + DOUBLE_ROUND(k0, k1, k2, k3, 0x10E527FAul, 0xDE682D1Dul, 0xB05688C2ul, 0xB3E6C1FDul); + + PREPARE_KS_ROUNDS; + KS_ROUND_0(2); + KS_ROUND(10, 30, 3); + KS_ROUND(20, 60, 3); + KS_ROUND(32, 47, 3); + } +} + +void Camellia::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ +#define KS(i, j) ks[i*4 + EFI(j/2)*2 + EFI(j%2)] + +#define FL(klh, kll, krh, krl) \ + ll ^= rotlFixed(lh & klh, 1); \ + lh ^= (ll | kll); \ + rh ^= (rl | krl); \ + rl ^= rotlFixed(rh & krh, 1); + + word32 lh, ll, rh, rl; + typedef BlockGetAndPut Block; + Block::Get(inBlock)(lh)(ll)(rh)(rl); + const word32 *ks = m_key.data(); + lh ^= KS(0,0); + ll ^= KS(0,1); + rh ^= KS(0,2); + rl ^= KS(0,3); + + // timing attack countermeasure. see comments at top for more details + const int cacheLineSize = GetCacheLineSize(); + unsigned int i; + word32 u = 0; + for (i=0; i<256; i+=cacheLineSize) + u &= *(const word32 *)(s1+i); + u &= *(const word32 *)(s1+252); + lh |= u; ll |= u; + + SLOW_ROUND(lh, ll, rh, rl, KS(1,0), KS(1,1)) + SLOW_ROUND(rh, rl, lh, ll, KS(1,2), KS(1,3)) + for (i = m_rounds-1; i > 0; --i) + { + DOUBLE_ROUND(lh, ll, rh, rl, KS(2,0), KS(2,1), KS(2,2), KS(2,3)) + DOUBLE_ROUND(lh, ll, rh, rl, KS(3,0), KS(3,1), KS(3,2), KS(3,3)) + FL(KS(4,0), KS(4,1), KS(4,2), KS(4,3)); + DOUBLE_ROUND(lh, ll, rh, rl, KS(5,0), KS(5,1), KS(5,2), KS(5,3)) + ks += 16; + } + DOUBLE_ROUND(lh, ll, rh, rl, KS(2,0), KS(2,1), KS(2,2), KS(2,3)) + ROUND(lh, ll, rh, rl, KS(3,0), KS(3,1)) + SLOW_ROUND(rh, rl, lh, ll, KS(3,2), KS(3,3)) + lh ^= KS(4,0); + ll ^= KS(4,1); + rh ^= KS(4,2); + rl ^= KS(4,3); + Block::Put(xorBlock, outBlock)(rh)(rl)(lh)(ll); +} + +// The Camellia s-boxes + +const byte Camellia::Base::s1[256] = +{ + 112,130,44,236,179,39,192,229,228,133,87,53,234,12,174,65, + 35,239,107,147,69,25,165,33,237,14,79,78,29,101,146,189, + 134,184,175,143,124,235,31,206,62,48,220,95,94,197,11,26, + 166,225,57,202,213,71,93,61,217,1,90,214,81,86,108,77, + 139,13,154,102,251,204,176,45,116,18,43,32,240,177,132,153, + 223,76,203,194,52,126,118,5,109,183,169,49,209,23,4,215, + 20,88,58,97,222,27,17,28,50,15,156,22,83,24,242,34, + 254,68,207,178,195,181,122,145,36,8,232,168,96,252,105,80, + 170,208,160,125,161,137,98,151,84,91,30,149,224,255,100,210, + 16,196,0,72,163,247,117,219,138,3,230,218,9,63,221,148, + 135,92,131,2,205,74,144,51,115,103,246,243,157,127,191,226, + 82,155,216,38,200,55,198,59,129,150,111,75,19,190,99,46, + 233,121,167,140,159,110,188,142,41,245,249,182,47,253,180,89, + 120,152,6,106,231,70,113,186,212,37,171,66,136,162,141,250, + 114,7,185,85,248,238,172,10,54,73,42,104,60,56,241,164, + 64,40,211,123,187,201,67,193,21,227,173,244,119,199,128,158 +}; + +const word32 Camellia::Base::SP[4][256] = { + { + 0x70707000, 0x82828200, 0x2c2c2c00, 0xececec00, + 0xb3b3b300, 0x27272700, 0xc0c0c000, 0xe5e5e500, + 0xe4e4e400, 0x85858500, 0x57575700, 0x35353500, + 0xeaeaea00, 0x0c0c0c00, 0xaeaeae00, 0x41414100, + 0x23232300, 0xefefef00, 0x6b6b6b00, 0x93939300, + 0x45454500, 0x19191900, 0xa5a5a500, 0x21212100, + 0xededed00, 0x0e0e0e00, 0x4f4f4f00, 0x4e4e4e00, + 0x1d1d1d00, 0x65656500, 0x92929200, 0xbdbdbd00, + 0x86868600, 0xb8b8b800, 0xafafaf00, 0x8f8f8f00, + 0x7c7c7c00, 0xebebeb00, 0x1f1f1f00, 0xcecece00, + 0x3e3e3e00, 0x30303000, 0xdcdcdc00, 0x5f5f5f00, + 0x5e5e5e00, 0xc5c5c500, 0x0b0b0b00, 0x1a1a1a00, + 0xa6a6a600, 0xe1e1e100, 0x39393900, 0xcacaca00, + 0xd5d5d500, 0x47474700, 0x5d5d5d00, 0x3d3d3d00, + 0xd9d9d900, 0x01010100, 0x5a5a5a00, 0xd6d6d600, + 0x51515100, 0x56565600, 0x6c6c6c00, 0x4d4d4d00, + 0x8b8b8b00, 0x0d0d0d00, 0x9a9a9a00, 0x66666600, + 0xfbfbfb00, 0xcccccc00, 0xb0b0b000, 0x2d2d2d00, + 0x74747400, 0x12121200, 0x2b2b2b00, 0x20202000, + 0xf0f0f000, 0xb1b1b100, 0x84848400, 0x99999900, + 0xdfdfdf00, 0x4c4c4c00, 0xcbcbcb00, 0xc2c2c200, + 0x34343400, 0x7e7e7e00, 0x76767600, 0x05050500, + 0x6d6d6d00, 0xb7b7b700, 0xa9a9a900, 0x31313100, + 0xd1d1d100, 0x17171700, 0x04040400, 0xd7d7d700, + 0x14141400, 0x58585800, 0x3a3a3a00, 0x61616100, + 0xdedede00, 0x1b1b1b00, 0x11111100, 0x1c1c1c00, + 0x32323200, 0x0f0f0f00, 0x9c9c9c00, 0x16161600, + 0x53535300, 0x18181800, 0xf2f2f200, 0x22222200, + 0xfefefe00, 0x44444400, 0xcfcfcf00, 0xb2b2b200, + 0xc3c3c300, 0xb5b5b500, 0x7a7a7a00, 0x91919100, + 0x24242400, 0x08080800, 0xe8e8e800, 0xa8a8a800, + 0x60606000, 0xfcfcfc00, 0x69696900, 0x50505000, + 0xaaaaaa00, 0xd0d0d000, 0xa0a0a000, 0x7d7d7d00, + 0xa1a1a100, 0x89898900, 0x62626200, 0x97979700, + 0x54545400, 0x5b5b5b00, 0x1e1e1e00, 0x95959500, + 0xe0e0e000, 0xffffff00, 0x64646400, 0xd2d2d200, + 0x10101000, 0xc4c4c400, 0x00000000, 0x48484800, + 0xa3a3a300, 0xf7f7f700, 0x75757500, 0xdbdbdb00, + 0x8a8a8a00, 0x03030300, 0xe6e6e600, 0xdadada00, + 0x09090900, 0x3f3f3f00, 0xdddddd00, 0x94949400, + 0x87878700, 0x5c5c5c00, 0x83838300, 0x02020200, + 0xcdcdcd00, 0x4a4a4a00, 0x90909000, 0x33333300, + 0x73737300, 0x67676700, 0xf6f6f600, 0xf3f3f300, + 0x9d9d9d00, 0x7f7f7f00, 0xbfbfbf00, 0xe2e2e200, + 0x52525200, 0x9b9b9b00, 0xd8d8d800, 0x26262600, + 0xc8c8c800, 0x37373700, 0xc6c6c600, 0x3b3b3b00, + 0x81818100, 0x96969600, 0x6f6f6f00, 0x4b4b4b00, + 0x13131300, 0xbebebe00, 0x63636300, 0x2e2e2e00, + 0xe9e9e900, 0x79797900, 0xa7a7a700, 0x8c8c8c00, + 0x9f9f9f00, 0x6e6e6e00, 0xbcbcbc00, 0x8e8e8e00, + 0x29292900, 0xf5f5f500, 0xf9f9f900, 0xb6b6b600, + 0x2f2f2f00, 0xfdfdfd00, 0xb4b4b400, 0x59595900, + 0x78787800, 0x98989800, 0x06060600, 0x6a6a6a00, + 0xe7e7e700, 0x46464600, 0x71717100, 0xbababa00, + 0xd4d4d400, 0x25252500, 0xababab00, 0x42424200, + 0x88888800, 0xa2a2a200, 0x8d8d8d00, 0xfafafa00, + 0x72727200, 0x07070700, 0xb9b9b900, 0x55555500, + 0xf8f8f800, 0xeeeeee00, 0xacacac00, 0x0a0a0a00, + 0x36363600, 0x49494900, 0x2a2a2a00, 0x68686800, + 0x3c3c3c00, 0x38383800, 0xf1f1f100, 0xa4a4a400, + 0x40404000, 0x28282800, 0xd3d3d300, 0x7b7b7b00, + 0xbbbbbb00, 0xc9c9c900, 0x43434300, 0xc1c1c100, + 0x15151500, 0xe3e3e300, 0xadadad00, 0xf4f4f400, + 0x77777700, 0xc7c7c700, 0x80808000, 0x9e9e9e00 + }, + { + 0x00e0e0e0, 0x00050505, 0x00585858, 0x00d9d9d9, + 0x00676767, 0x004e4e4e, 0x00818181, 0x00cbcbcb, + 0x00c9c9c9, 0x000b0b0b, 0x00aeaeae, 0x006a6a6a, + 0x00d5d5d5, 0x00181818, 0x005d5d5d, 0x00828282, + 0x00464646, 0x00dfdfdf, 0x00d6d6d6, 0x00272727, + 0x008a8a8a, 0x00323232, 0x004b4b4b, 0x00424242, + 0x00dbdbdb, 0x001c1c1c, 0x009e9e9e, 0x009c9c9c, + 0x003a3a3a, 0x00cacaca, 0x00252525, 0x007b7b7b, + 0x000d0d0d, 0x00717171, 0x005f5f5f, 0x001f1f1f, + 0x00f8f8f8, 0x00d7d7d7, 0x003e3e3e, 0x009d9d9d, + 0x007c7c7c, 0x00606060, 0x00b9b9b9, 0x00bebebe, + 0x00bcbcbc, 0x008b8b8b, 0x00161616, 0x00343434, + 0x004d4d4d, 0x00c3c3c3, 0x00727272, 0x00959595, + 0x00ababab, 0x008e8e8e, 0x00bababa, 0x007a7a7a, + 0x00b3b3b3, 0x00020202, 0x00b4b4b4, 0x00adadad, + 0x00a2a2a2, 0x00acacac, 0x00d8d8d8, 0x009a9a9a, + 0x00171717, 0x001a1a1a, 0x00353535, 0x00cccccc, + 0x00f7f7f7, 0x00999999, 0x00616161, 0x005a5a5a, + 0x00e8e8e8, 0x00242424, 0x00565656, 0x00404040, + 0x00e1e1e1, 0x00636363, 0x00090909, 0x00333333, + 0x00bfbfbf, 0x00989898, 0x00979797, 0x00858585, + 0x00686868, 0x00fcfcfc, 0x00ececec, 0x000a0a0a, + 0x00dadada, 0x006f6f6f, 0x00535353, 0x00626262, + 0x00a3a3a3, 0x002e2e2e, 0x00080808, 0x00afafaf, + 0x00282828, 0x00b0b0b0, 0x00747474, 0x00c2c2c2, + 0x00bdbdbd, 0x00363636, 0x00222222, 0x00383838, + 0x00646464, 0x001e1e1e, 0x00393939, 0x002c2c2c, + 0x00a6a6a6, 0x00303030, 0x00e5e5e5, 0x00444444, + 0x00fdfdfd, 0x00888888, 0x009f9f9f, 0x00656565, + 0x00878787, 0x006b6b6b, 0x00f4f4f4, 0x00232323, + 0x00484848, 0x00101010, 0x00d1d1d1, 0x00515151, + 0x00c0c0c0, 0x00f9f9f9, 0x00d2d2d2, 0x00a0a0a0, + 0x00555555, 0x00a1a1a1, 0x00414141, 0x00fafafa, + 0x00434343, 0x00131313, 0x00c4c4c4, 0x002f2f2f, + 0x00a8a8a8, 0x00b6b6b6, 0x003c3c3c, 0x002b2b2b, + 0x00c1c1c1, 0x00ffffff, 0x00c8c8c8, 0x00a5a5a5, + 0x00202020, 0x00898989, 0x00000000, 0x00909090, + 0x00474747, 0x00efefef, 0x00eaeaea, 0x00b7b7b7, + 0x00151515, 0x00060606, 0x00cdcdcd, 0x00b5b5b5, + 0x00121212, 0x007e7e7e, 0x00bbbbbb, 0x00292929, + 0x000f0f0f, 0x00b8b8b8, 0x00070707, 0x00040404, + 0x009b9b9b, 0x00949494, 0x00212121, 0x00666666, + 0x00e6e6e6, 0x00cecece, 0x00ededed, 0x00e7e7e7, + 0x003b3b3b, 0x00fefefe, 0x007f7f7f, 0x00c5c5c5, + 0x00a4a4a4, 0x00373737, 0x00b1b1b1, 0x004c4c4c, + 0x00919191, 0x006e6e6e, 0x008d8d8d, 0x00767676, + 0x00030303, 0x002d2d2d, 0x00dedede, 0x00969696, + 0x00262626, 0x007d7d7d, 0x00c6c6c6, 0x005c5c5c, + 0x00d3d3d3, 0x00f2f2f2, 0x004f4f4f, 0x00191919, + 0x003f3f3f, 0x00dcdcdc, 0x00797979, 0x001d1d1d, + 0x00525252, 0x00ebebeb, 0x00f3f3f3, 0x006d6d6d, + 0x005e5e5e, 0x00fbfbfb, 0x00696969, 0x00b2b2b2, + 0x00f0f0f0, 0x00313131, 0x000c0c0c, 0x00d4d4d4, + 0x00cfcfcf, 0x008c8c8c, 0x00e2e2e2, 0x00757575, + 0x00a9a9a9, 0x004a4a4a, 0x00575757, 0x00848484, + 0x00111111, 0x00454545, 0x001b1b1b, 0x00f5f5f5, + 0x00e4e4e4, 0x000e0e0e, 0x00737373, 0x00aaaaaa, + 0x00f1f1f1, 0x00dddddd, 0x00595959, 0x00141414, + 0x006c6c6c, 0x00929292, 0x00545454, 0x00d0d0d0, + 0x00787878, 0x00707070, 0x00e3e3e3, 0x00494949, + 0x00808080, 0x00505050, 0x00a7a7a7, 0x00f6f6f6, + 0x00777777, 0x00939393, 0x00868686, 0x00838383, + 0x002a2a2a, 0x00c7c7c7, 0x005b5b5b, 0x00e9e9e9, + 0x00eeeeee, 0x008f8f8f, 0x00010101, 0x003d3d3d + }, + { + 0x38003838, 0x41004141, 0x16001616, 0x76007676, + 0xd900d9d9, 0x93009393, 0x60006060, 0xf200f2f2, + 0x72007272, 0xc200c2c2, 0xab00abab, 0x9a009a9a, + 0x75007575, 0x06000606, 0x57005757, 0xa000a0a0, + 0x91009191, 0xf700f7f7, 0xb500b5b5, 0xc900c9c9, + 0xa200a2a2, 0x8c008c8c, 0xd200d2d2, 0x90009090, + 0xf600f6f6, 0x07000707, 0xa700a7a7, 0x27002727, + 0x8e008e8e, 0xb200b2b2, 0x49004949, 0xde00dede, + 0x43004343, 0x5c005c5c, 0xd700d7d7, 0xc700c7c7, + 0x3e003e3e, 0xf500f5f5, 0x8f008f8f, 0x67006767, + 0x1f001f1f, 0x18001818, 0x6e006e6e, 0xaf00afaf, + 0x2f002f2f, 0xe200e2e2, 0x85008585, 0x0d000d0d, + 0x53005353, 0xf000f0f0, 0x9c009c9c, 0x65006565, + 0xea00eaea, 0xa300a3a3, 0xae00aeae, 0x9e009e9e, + 0xec00ecec, 0x80008080, 0x2d002d2d, 0x6b006b6b, + 0xa800a8a8, 0x2b002b2b, 0x36003636, 0xa600a6a6, + 0xc500c5c5, 0x86008686, 0x4d004d4d, 0x33003333, + 0xfd00fdfd, 0x66006666, 0x58005858, 0x96009696, + 0x3a003a3a, 0x09000909, 0x95009595, 0x10001010, + 0x78007878, 0xd800d8d8, 0x42004242, 0xcc00cccc, + 0xef00efef, 0x26002626, 0xe500e5e5, 0x61006161, + 0x1a001a1a, 0x3f003f3f, 0x3b003b3b, 0x82008282, + 0xb600b6b6, 0xdb00dbdb, 0xd400d4d4, 0x98009898, + 0xe800e8e8, 0x8b008b8b, 0x02000202, 0xeb00ebeb, + 0x0a000a0a, 0x2c002c2c, 0x1d001d1d, 0xb000b0b0, + 0x6f006f6f, 0x8d008d8d, 0x88008888, 0x0e000e0e, + 0x19001919, 0x87008787, 0x4e004e4e, 0x0b000b0b, + 0xa900a9a9, 0x0c000c0c, 0x79007979, 0x11001111, + 0x7f007f7f, 0x22002222, 0xe700e7e7, 0x59005959, + 0xe100e1e1, 0xda00dada, 0x3d003d3d, 0xc800c8c8, + 0x12001212, 0x04000404, 0x74007474, 0x54005454, + 0x30003030, 0x7e007e7e, 0xb400b4b4, 0x28002828, + 0x55005555, 0x68006868, 0x50005050, 0xbe00bebe, + 0xd000d0d0, 0xc400c4c4, 0x31003131, 0xcb00cbcb, + 0x2a002a2a, 0xad00adad, 0x0f000f0f, 0xca00caca, + 0x70007070, 0xff00ffff, 0x32003232, 0x69006969, + 0x08000808, 0x62006262, 0x00000000, 0x24002424, + 0xd100d1d1, 0xfb00fbfb, 0xba00baba, 0xed00eded, + 0x45004545, 0x81008181, 0x73007373, 0x6d006d6d, + 0x84008484, 0x9f009f9f, 0xee00eeee, 0x4a004a4a, + 0xc300c3c3, 0x2e002e2e, 0xc100c1c1, 0x01000101, + 0xe600e6e6, 0x25002525, 0x48004848, 0x99009999, + 0xb900b9b9, 0xb300b3b3, 0x7b007b7b, 0xf900f9f9, + 0xce00cece, 0xbf00bfbf, 0xdf00dfdf, 0x71007171, + 0x29002929, 0xcd00cdcd, 0x6c006c6c, 0x13001313, + 0x64006464, 0x9b009b9b, 0x63006363, 0x9d009d9d, + 0xc000c0c0, 0x4b004b4b, 0xb700b7b7, 0xa500a5a5, + 0x89008989, 0x5f005f5f, 0xb100b1b1, 0x17001717, + 0xf400f4f4, 0xbc00bcbc, 0xd300d3d3, 0x46004646, + 0xcf00cfcf, 0x37003737, 0x5e005e5e, 0x47004747, + 0x94009494, 0xfa00fafa, 0xfc00fcfc, 0x5b005b5b, + 0x97009797, 0xfe00fefe, 0x5a005a5a, 0xac00acac, + 0x3c003c3c, 0x4c004c4c, 0x03000303, 0x35003535, + 0xf300f3f3, 0x23002323, 0xb800b8b8, 0x5d005d5d, + 0x6a006a6a, 0x92009292, 0xd500d5d5, 0x21002121, + 0x44004444, 0x51005151, 0xc600c6c6, 0x7d007d7d, + 0x39003939, 0x83008383, 0xdc00dcdc, 0xaa00aaaa, + 0x7c007c7c, 0x77007777, 0x56005656, 0x05000505, + 0x1b001b1b, 0xa400a4a4, 0x15001515, 0x34003434, + 0x1e001e1e, 0x1c001c1c, 0xf800f8f8, 0x52005252, + 0x20002020, 0x14001414, 0xe900e9e9, 0xbd00bdbd, + 0xdd00dddd, 0xe400e4e4, 0xa100a1a1, 0xe000e0e0, + 0x8a008a8a, 0xf100f1f1, 0xd600d6d6, 0x7a007a7a, + 0xbb00bbbb, 0xe300e3e3, 0x40004040, 0x4f004f4f + }, + { + 0x70700070, 0x2c2c002c, 0xb3b300b3, 0xc0c000c0, + 0xe4e400e4, 0x57570057, 0xeaea00ea, 0xaeae00ae, + 0x23230023, 0x6b6b006b, 0x45450045, 0xa5a500a5, + 0xeded00ed, 0x4f4f004f, 0x1d1d001d, 0x92920092, + 0x86860086, 0xafaf00af, 0x7c7c007c, 0x1f1f001f, + 0x3e3e003e, 0xdcdc00dc, 0x5e5e005e, 0x0b0b000b, + 0xa6a600a6, 0x39390039, 0xd5d500d5, 0x5d5d005d, + 0xd9d900d9, 0x5a5a005a, 0x51510051, 0x6c6c006c, + 0x8b8b008b, 0x9a9a009a, 0xfbfb00fb, 0xb0b000b0, + 0x74740074, 0x2b2b002b, 0xf0f000f0, 0x84840084, + 0xdfdf00df, 0xcbcb00cb, 0x34340034, 0x76760076, + 0x6d6d006d, 0xa9a900a9, 0xd1d100d1, 0x04040004, + 0x14140014, 0x3a3a003a, 0xdede00de, 0x11110011, + 0x32320032, 0x9c9c009c, 0x53530053, 0xf2f200f2, + 0xfefe00fe, 0xcfcf00cf, 0xc3c300c3, 0x7a7a007a, + 0x24240024, 0xe8e800e8, 0x60600060, 0x69690069, + 0xaaaa00aa, 0xa0a000a0, 0xa1a100a1, 0x62620062, + 0x54540054, 0x1e1e001e, 0xe0e000e0, 0x64640064, + 0x10100010, 0x00000000, 0xa3a300a3, 0x75750075, + 0x8a8a008a, 0xe6e600e6, 0x09090009, 0xdddd00dd, + 0x87870087, 0x83830083, 0xcdcd00cd, 0x90900090, + 0x73730073, 0xf6f600f6, 0x9d9d009d, 0xbfbf00bf, + 0x52520052, 0xd8d800d8, 0xc8c800c8, 0xc6c600c6, + 0x81810081, 0x6f6f006f, 0x13130013, 0x63630063, + 0xe9e900e9, 0xa7a700a7, 0x9f9f009f, 0xbcbc00bc, + 0x29290029, 0xf9f900f9, 0x2f2f002f, 0xb4b400b4, + 0x78780078, 0x06060006, 0xe7e700e7, 0x71710071, + 0xd4d400d4, 0xabab00ab, 0x88880088, 0x8d8d008d, + 0x72720072, 0xb9b900b9, 0xf8f800f8, 0xacac00ac, + 0x36360036, 0x2a2a002a, 0x3c3c003c, 0xf1f100f1, + 0x40400040, 0xd3d300d3, 0xbbbb00bb, 0x43430043, + 0x15150015, 0xadad00ad, 0x77770077, 0x80800080, + 0x82820082, 0xecec00ec, 0x27270027, 0xe5e500e5, + 0x85850085, 0x35350035, 0x0c0c000c, 0x41410041, + 0xefef00ef, 0x93930093, 0x19190019, 0x21210021, + 0x0e0e000e, 0x4e4e004e, 0x65650065, 0xbdbd00bd, + 0xb8b800b8, 0x8f8f008f, 0xebeb00eb, 0xcece00ce, + 0x30300030, 0x5f5f005f, 0xc5c500c5, 0x1a1a001a, + 0xe1e100e1, 0xcaca00ca, 0x47470047, 0x3d3d003d, + 0x01010001, 0xd6d600d6, 0x56560056, 0x4d4d004d, + 0x0d0d000d, 0x66660066, 0xcccc00cc, 0x2d2d002d, + 0x12120012, 0x20200020, 0xb1b100b1, 0x99990099, + 0x4c4c004c, 0xc2c200c2, 0x7e7e007e, 0x05050005, + 0xb7b700b7, 0x31310031, 0x17170017, 0xd7d700d7, + 0x58580058, 0x61610061, 0x1b1b001b, 0x1c1c001c, + 0x0f0f000f, 0x16160016, 0x18180018, 0x22220022, + 0x44440044, 0xb2b200b2, 0xb5b500b5, 0x91910091, + 0x08080008, 0xa8a800a8, 0xfcfc00fc, 0x50500050, + 0xd0d000d0, 0x7d7d007d, 0x89890089, 0x97970097, + 0x5b5b005b, 0x95950095, 0xffff00ff, 0xd2d200d2, + 0xc4c400c4, 0x48480048, 0xf7f700f7, 0xdbdb00db, + 0x03030003, 0xdada00da, 0x3f3f003f, 0x94940094, + 0x5c5c005c, 0x02020002, 0x4a4a004a, 0x33330033, + 0x67670067, 0xf3f300f3, 0x7f7f007f, 0xe2e200e2, + 0x9b9b009b, 0x26260026, 0x37370037, 0x3b3b003b, + 0x96960096, 0x4b4b004b, 0xbebe00be, 0x2e2e002e, + 0x79790079, 0x8c8c008c, 0x6e6e006e, 0x8e8e008e, + 0xf5f500f5, 0xb6b600b6, 0xfdfd00fd, 0x59590059, + 0x98980098, 0x6a6a006a, 0x46460046, 0xbaba00ba, + 0x25250025, 0x42420042, 0xa2a200a2, 0xfafa00fa, + 0x07070007, 0x55550055, 0xeeee00ee, 0x0a0a000a, + 0x49490049, 0x68680068, 0x38380038, 0xa4a400a4, + 0x28280028, 0x7b7b007b, 0xc9c900c9, 0xc1c100c1, + 0xe3e300e3, 0xf4f400f4, 0xc7c700c7, 0x9e9e009e + }}; + +NAMESPACE_END diff --git a/CryptoPP/crypto/camellia.dat b/CryptoPP/crypto/camellia.dat new file mode 100644 index 0000000..833ffc0 --- /dev/null +++ b/CryptoPP/crypto/camellia.dat @@ -0,0 +1,45 @@ +0123456789ABCDEFFEDCBA9876543210 0123456789ABCDEFFEDCBA9876543210 67673138549669730857065648EABE43 +80000000000000000000000000000000 00000000000000000000000000000000 6C227F749319A3AA7DA235A9BBA05A2C +00000000000000000000000000000001 00000000000000000000000000000000 41E0E6DC2DDEC65D8B8120E60977B82D +00000000000000000000000000000000 80000000000000000000000000000000 07923A39EB0A817D1C4D87BDB82D1F1C +00000000000000000000000000000000 00000000000000000000000000000001 F5574ACC3148DFCB9015200631024DF9 +00000000000000000000000000000000 00000000000000000000000000000000 3D028025B156327C17F762C1F2CBCA71 +01010101010101010101010101010101 01010101010101010101010101010101 637084CB1120D6F25DB618893040AA27 +02020202020202020202020202020202 02020202020202020202020202020202 612834AAC9EF906BAEAA076E1C75179D +04040404040404040404040404040404 04040404040404040404040404040404 B24FAF8A579E4EFE986571FB2F68B5B4 +08080808080808080808080808080808 08080808080808080808080808080808 3E5CAFBB70545AABB1109293A1C44C14 +10101010101010101010101010101010 10101010101010101010101010101010 E1FA5FD3F40B766BBE3DF469AF41B420 +20202020202020202020202020202020 20202020202020202020202020202020 7E724027BB2F591C63254D936FCC4B43 +40404040404040404040404040404040 40404040404040404040404040404040 538ADCBE104A3483B3C2A3D8CE72FBD6 +80808080808080808080808080808080 80808080808080808080808080808080 AA7627F70F6B54C217C3EF232D362459 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 25DD9EB9DD67FBC6E8431F56F4FBE651 +0123456789ABCDEFFEDCBA98765432100011223344556677 0123456789ABCDEFFEDCBA9876543210 B4993401B3E996F84EE5CEE7D79B09B9 +800000000000000000000000000000000000000000000000 00000000000000000000000000000000 1B6220D365C2176C1D41A5826520FCA1 +000000000000000000000000000000000000000000000001 00000000000000000000000000000000 E37577F71E0E643C4D3F55219ABA1394 +000000000000000000000000000000000000000000000000 80000000000000000000000000000000 3EB6CC5618EFC98455B5992050D474E7 +000000000000000000000000000000000000000000000000 00000000000000000000000000000001 BA9AE89FDDCE4B51131E17C4D65CE587 +000000000000000000000000000000000000000000000000 00000000000000000000000000000000 56E1E129CA5C02C7F9AC6AFDEF86ADC3 +010101010101010101010101010101010101010101010101 01010101010101010101010101010101 8F764397C10BE84BA876CEEFA4225BFF +020202020202020202020202020202020202020202020202 02020202020202020202020202020202 60B00674BFD444D07B5A19851E6151CD +040404040404040404040404040404040404040404040404 04040404040404040404040404040404 81B26FF4F6B4377CC555873504B3A38B +080808080808080808080808080808080808080808080808 08080808080808080808080808080808 A2AA1C6693DC2B70D75C9B39B9B214D0 +101010101010101010101010101010101010101010101010 10101010101010101010101010101010 A907BFDAEEF8C81D05855235E8D3BE08 +202020202020202020202020202020202020202020202020 20202020202020202020202020202020 87F8EA30332036F17CEAC0097CE33BC1 +404040404040404040404040404040404040404040404040 40404040404040404040404040404040 A2C32EA499E41A248565253BACC11E3B +808080808080808080808080808080808080808080808080 80808080808080808080808080808080 F602BA7F515B082983B8F7A27F92408F +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 3F8D5676F51CE23DC3BDB627F8B3883E +0123456789ABCDEFFEDCBA987654321000112233445566778899AABBCCDDEEFF 0123456789ABCDEFFEDCBA9876543210 9ACC237DFF16D76C20EF7C919E3A7509 +8000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000 2136FABDA091DFB5171B94B8EFBB5D08 +0000000000000000000000000000000000000000000000000000000000000001 00000000000000000000000000000000 AFCD38B195E0A736304E89B9AE3019D3 +0000000000000000000000000000000000000000000000000000000000000000 80000000000000000000000000000000 B0C6B88AEA518AB09E847248E91B1B9D +0000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000001 9CDB269B5D293BC5DB9C55B057D9B591 +0000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000 396154111ADEFC500CF6E5C99038BC17 +0101010101010101010101010101010101010101010101010101010101010101 01010101010101010101010101010101 438D0C2E7E86869B56EBA23B66086A01 +0202020202020202020202020202020202020202020202020202020202020202 02020202020202020202020202020202 D4F553BFA794F55EF3B7A578629F6DEA +0404040404040404040404040404040404040404040404040404040404040404 04040404040404040404040404040404 5E858730ABC9823A93CA4CAB67F0B423 +0808080808080808080808080808080808080808080808080808080808080808 08080808080808080808080808080808 F9A9C1540AE1B314DBEDF9A49054DC9D +1010101010101010101010101010101010101010101010101010101010101010 10101010101010101010101010101010 6693FC130669F194F81E8D175194DDA2 +2020202020202020202020202020202020202020202020202020202020202020 20202020202020202020202020202020 F3E1FDA6B9C8314799F4654C29F1C690 +4040404040404040404040404040404040404040404040404040404040404040 40404040404040404040404040404040 4A30476F1141FBF303ED63FCD3CB0536 +8080808080808080808080808080808080808080808080808080808080808080 80808080808080808080808080808080 0C765AA494E048FC8BB23139F2124CB6 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 4F05F28CA23EEAE205B67B1C95CD5280 diff --git a/CryptoPP/crypto/camellia.h b/CryptoPP/crypto/camellia.h new file mode 100644 index 0000000..0426e45 --- /dev/null +++ b/CryptoPP/crypto/camellia.h @@ -0,0 +1,48 @@ +#ifndef CRYPTOPP_CAMELLIA_H +#define CRYPTOPP_CAMELLIA_H + +#include "config.h" + +/** \file +*/ + +#include "seckey.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! _ +struct Camellia_Info : public FixedBlockSize<16>, public VariableKeyLength<16, 16, 32, 8> +{ + static const char *StaticAlgorithmName() {return "Camellia";} +}; + +/// Camellia +class Camellia : public Camellia_Info, public BlockCipherDocumentation +{ + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + public: + void UncheckedSetKey(const byte *key, unsigned int keylen, const NameValuePairs ¶ms); + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + unsigned int BlockAlignment() const {return 8;} + + protected: + static const byte s1[256]; + static const word32 SP[4][256]; + + unsigned int m_rounds; + SecBlock m_key; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef Camellia::Encryption CamelliaEncryption; +typedef Camellia::Decryption CamelliaDecryption; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/cast.cpp b/CryptoPP/crypto/cast.cpp new file mode 100644 index 0000000..c6787ea --- /dev/null +++ b/CryptoPP/crypto/cast.cpp @@ -0,0 +1,296 @@ +// cast.cpp - written and placed in the public domain by Wei Dai and Leonard Janke +// based on Steve Reid's public domain cast.c + +#include "pch.h" +#include "cast.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +/* Macros to access 8-bit bytes out of a 32-bit word */ +#define U8a(x) GETBYTE(x,3) +#define U8b(x) GETBYTE(x,2) +#define U8c(x) GETBYTE(x,1) +#define U8d(x) GETBYTE(x,0) + +/* CAST uses three different round functions */ +#define f1(l, r, km, kr) \ + t = rotlVariable(km + r, kr); \ + l ^= ((S[0][U8a(t)] ^ S[1][U8b(t)]) - \ + S[2][U8c(t)]) + S[3][U8d(t)]; +#define f2(l, r, km, kr) \ + t = rotlVariable(km ^ r, kr); \ + l ^= ((S[0][U8a(t)] - S[1][U8b(t)]) + \ + S[2][U8c(t)]) ^ S[3][U8d(t)]; +#define f3(l, r, km, kr) \ + t = rotlVariable(km - r, kr); \ + l ^= ((S[0][U8a(t)] + S[1][U8b(t)]) ^ \ + S[2][U8c(t)]) - S[3][U8d(t)]; + +#define F1(l, r, i, j) f1(l, r, K[i], K[i+j]) +#define F2(l, r, i, j) f2(l, r, K[i], K[i+j]) +#define F3(l, r, i, j) f3(l, r, K[i], K[i+j]) + +typedef BlockGetAndPut Block; + +void CAST128::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word32 t, l, r; + + /* Get inblock into l,r */ + Block::Get(inBlock)(l)(r); + /* Do the work */ + F1(l, r, 0, 16); + F2(r, l, 1, 16); + F3(l, r, 2, 16); + F1(r, l, 3, 16); + F2(l, r, 4, 16); + F3(r, l, 5, 16); + F1(l, r, 6, 16); + F2(r, l, 7, 16); + F3(l, r, 8, 16); + F1(r, l, 9, 16); + F2(l, r, 10, 16); + F3(r, l, 11, 16); + /* Only do full 16 rounds if key length > 80 bits */ + if (!reduced) { + F1(l, r, 12, 16); + F2(r, l, 13, 16); + F3(l, r, 14, 16); + F1(r, l, 15, 16); + } + /* Put l,r into outblock */ + Block::Put(xorBlock, outBlock)(r)(l); +} + +void CAST128::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word32 t, l, r; + + /* Get inblock into l,r */ + Block::Get(inBlock)(r)(l); + /* Only do full 16 rounds if key length > 80 bits */ + if (!reduced) { + F1(r, l, 15, 16); + F3(l, r, 14, 16); + F2(r, l, 13, 16); + F1(l, r, 12, 16); + } + F3(r, l, 11, 16); + F2(l, r, 10, 16); + F1(r, l, 9, 16); + F3(l, r, 8, 16); + F2(r, l, 7, 16); + F1(l, r, 6, 16); + F3(r, l, 5, 16); + F2(l, r, 4, 16); + F1(r, l, 3, 16); + F3(l, r, 2, 16); + F2(r, l, 1, 16); + F1(l, r, 0, 16); + /* Put l,r into outblock */ + Block::Put(xorBlock, outBlock)(l)(r); + /* Wipe clean */ + t = l = r = 0; +} + +void CAST128::Base::UncheckedSetKey(const byte *userKey, unsigned int keylength, const NameValuePairs &) +{ + AssertValidKeyLength(keylength); + + reduced = (keylength <= 10); + + word32 X[4], Z[4]; + GetUserKey(BIG_ENDIAN_ORDER, X, 4, userKey, keylength); + +#define x(i) GETBYTE(X[i/4], 3-i%4) +#define z(i) GETBYTE(Z[i/4], 3-i%4) + + unsigned int i; + for (i=0; i<=16; i+=16) + { + // this part is copied directly from RFC 2144 (with some search and replace) by Wei Dai + Z[0] = X[0] ^ S[4][x(0xD)] ^ S[5][x(0xF)] ^ S[6][x(0xC)] ^ S[7][x(0xE)] ^ S[6][x(0x8)]; + Z[1] = X[2] ^ S[4][z(0x0)] ^ S[5][z(0x2)] ^ S[6][z(0x1)] ^ S[7][z(0x3)] ^ S[7][x(0xA)]; + Z[2] = X[3] ^ S[4][z(0x7)] ^ S[5][z(0x6)] ^ S[6][z(0x5)] ^ S[7][z(0x4)] ^ S[4][x(0x9)]; + Z[3] = X[1] ^ S[4][z(0xA)] ^ S[5][z(0x9)] ^ S[6][z(0xB)] ^ S[7][z(0x8)] ^ S[5][x(0xB)]; + K[i+0] = S[4][z(0x8)] ^ S[5][z(0x9)] ^ S[6][z(0x7)] ^ S[7][z(0x6)] ^ S[4][z(0x2)]; + K[i+1] = S[4][z(0xA)] ^ S[5][z(0xB)] ^ S[6][z(0x5)] ^ S[7][z(0x4)] ^ S[5][z(0x6)]; + K[i+2] = S[4][z(0xC)] ^ S[5][z(0xD)] ^ S[6][z(0x3)] ^ S[7][z(0x2)] ^ S[6][z(0x9)]; + K[i+3] = S[4][z(0xE)] ^ S[5][z(0xF)] ^ S[6][z(0x1)] ^ S[7][z(0x0)] ^ S[7][z(0xC)]; + X[0] = Z[2] ^ S[4][z(0x5)] ^ S[5][z(0x7)] ^ S[6][z(0x4)] ^ S[7][z(0x6)] ^ S[6][z(0x0)]; + X[1] = Z[0] ^ S[4][x(0x0)] ^ S[5][x(0x2)] ^ S[6][x(0x1)] ^ S[7][x(0x3)] ^ S[7][z(0x2)]; + X[2] = Z[1] ^ S[4][x(0x7)] ^ S[5][x(0x6)] ^ S[6][x(0x5)] ^ S[7][x(0x4)] ^ S[4][z(0x1)]; + X[3] = Z[3] ^ S[4][x(0xA)] ^ S[5][x(0x9)] ^ S[6][x(0xB)] ^ S[7][x(0x8)] ^ S[5][z(0x3)]; + K[i+4] = S[4][x(0x3)] ^ S[5][x(0x2)] ^ S[6][x(0xC)] ^ S[7][x(0xD)] ^ S[4][x(0x8)]; + K[i+5] = S[4][x(0x1)] ^ S[5][x(0x0)] ^ S[6][x(0xE)] ^ S[7][x(0xF)] ^ S[5][x(0xD)]; + K[i+6] = S[4][x(0x7)] ^ S[5][x(0x6)] ^ S[6][x(0x8)] ^ S[7][x(0x9)] ^ S[6][x(0x3)]; + K[i+7] = S[4][x(0x5)] ^ S[5][x(0x4)] ^ S[6][x(0xA)] ^ S[7][x(0xB)] ^ S[7][x(0x7)]; + Z[0] = X[0] ^ S[4][x(0xD)] ^ S[5][x(0xF)] ^ S[6][x(0xC)] ^ S[7][x(0xE)] ^ S[6][x(0x8)]; + Z[1] = X[2] ^ S[4][z(0x0)] ^ S[5][z(0x2)] ^ S[6][z(0x1)] ^ S[7][z(0x3)] ^ S[7][x(0xA)]; + Z[2] = X[3] ^ S[4][z(0x7)] ^ S[5][z(0x6)] ^ S[6][z(0x5)] ^ S[7][z(0x4)] ^ S[4][x(0x9)]; + Z[3] = X[1] ^ S[4][z(0xA)] ^ S[5][z(0x9)] ^ S[6][z(0xB)] ^ S[7][z(0x8)] ^ S[5][x(0xB)]; + K[i+8] = S[4][z(0x3)] ^ S[5][z(0x2)] ^ S[6][z(0xC)] ^ S[7][z(0xD)] ^ S[4][z(0x9)]; + K[i+9] = S[4][z(0x1)] ^ S[5][z(0x0)] ^ S[6][z(0xE)] ^ S[7][z(0xF)] ^ S[5][z(0xC)]; + K[i+10] = S[4][z(0x7)] ^ S[5][z(0x6)] ^ S[6][z(0x8)] ^ S[7][z(0x9)] ^ S[6][z(0x2)]; + K[i+11] = S[4][z(0x5)] ^ S[5][z(0x4)] ^ S[6][z(0xA)] ^ S[7][z(0xB)] ^ S[7][z(0x6)]; + X[0] = Z[2] ^ S[4][z(0x5)] ^ S[5][z(0x7)] ^ S[6][z(0x4)] ^ S[7][z(0x6)] ^ S[6][z(0x0)]; + X[1] = Z[0] ^ S[4][x(0x0)] ^ S[5][x(0x2)] ^ S[6][x(0x1)] ^ S[7][x(0x3)] ^ S[7][z(0x2)]; + X[2] = Z[1] ^ S[4][x(0x7)] ^ S[5][x(0x6)] ^ S[6][x(0x5)] ^ S[7][x(0x4)] ^ S[4][z(0x1)]; + X[3] = Z[3] ^ S[4][x(0xA)] ^ S[5][x(0x9)] ^ S[6][x(0xB)] ^ S[7][x(0x8)] ^ S[5][z(0x3)]; + K[i+12] = S[4][x(0x8)] ^ S[5][x(0x9)] ^ S[6][x(0x7)] ^ S[7][x(0x6)] ^ S[4][x(0x3)]; + K[i+13] = S[4][x(0xA)] ^ S[5][x(0xB)] ^ S[6][x(0x5)] ^ S[7][x(0x4)] ^ S[5][x(0x7)]; + K[i+14] = S[4][x(0xC)] ^ S[5][x(0xD)] ^ S[6][x(0x3)] ^ S[7][x(0x2)] ^ S[6][x(0x8)]; + K[i+15] = S[4][x(0xE)] ^ S[5][x(0xF)] ^ S[6][x(0x1)] ^ S[7][x(0x0)] ^ S[7][x(0xD)]; + } + + for (i=16; i<32; i++) + K[i] &= 0x1f; +} + +// The following CAST-256 implementation was contributed by Leonard Janke + +const word32 CAST256::Base::t_m[8][24]={ +{ 0x5a827999, 0xd151d6a1, 0x482133a9, 0xbef090b1, 0x35bfedb9, 0xac8f4ac1, + 0x235ea7c9, 0x9a2e04d1, 0x10fd61d9, 0x87ccbee1, 0xfe9c1be9, 0x756b78f1, + 0xec3ad5f9, 0x630a3301, 0xd9d99009, 0x50a8ed11, 0xc7784a19, 0x3e47a721, + 0xb5170429, 0x2be66131, 0xa2b5be39, 0x19851b41, 0x90547849, 0x0723d551}, +{ 0xc95c653a, 0x402bc242, 0xb6fb1f4a, 0x2dca7c52, 0xa499d95a, 0x1b693662, + 0x9238936a, 0x0907f072, 0x7fd74d7a, 0xf6a6aa82, 0x6d76078a, 0xe4456492, + 0x5b14c19a, 0xd1e41ea2, 0x48b37baa, 0xbf82d8b2, 0x365235ba, 0xad2192c2, + 0x23f0efca, 0x9ac04cd2, 0x118fa9da, 0x885f06e2, 0xff2e63ea, 0x75fdc0f2}, +{ 0x383650db, 0xaf05ade3, 0x25d50aeb, 0x9ca467f3, 0x1373c4fb, 0x8a432203, + 0x01127f0b, 0x77e1dc13, 0xeeb1391b, 0x65809623, 0xdc4ff32b, 0x531f5033, + 0xc9eead3b, 0x40be0a43, 0xb78d674b, 0x2e5cc453, 0xa52c215b, 0x1bfb7e63, + 0x92cadb6b, 0x099a3873, 0x8069957b, 0xf738f283, 0x6e084f8b, 0xe4d7ac93}, +{ 0xa7103c7c, 0x1ddf9984, 0x94aef68c, 0x0b7e5394, 0x824db09c, 0xf91d0da4, + 0x6fec6aac, 0xe6bbc7b4, 0x5d8b24bc, 0xd45a81c4, 0x4b29decc, 0xc1f93bd4, + 0x38c898dc, 0xaf97f5e4, 0x266752ec, 0x9d36aff4, 0x14060cfc, 0x8ad56a04, + 0x01a4c70c, 0x78742414, 0xef43811c, 0x6612de24, 0xdce23b2c, 0x53b19834}, +{ 0x15ea281d, 0x8cb98525, 0x0388e22d, 0x7a583f35, 0xf1279c3d, 0x67f6f945, + 0xdec6564d, 0x5595b355, 0xcc65105d, 0x43346d65, 0xba03ca6d, 0x30d32775, + 0xa7a2847d, 0x1e71e185, 0x95413e8d, 0x0c109b95, 0x82dff89d, 0xf9af55a5, + 0x707eb2ad, 0xe74e0fb5, 0x5e1d6cbd, 0xd4ecc9c5, 0x4bbc26cd, 0xc28b83d5}, +{ 0x84c413be, 0xfb9370c6, 0x7262cdce, 0xe9322ad6, 0x600187de, 0xd6d0e4e6, + 0x4da041ee, 0xc46f9ef6, 0x3b3efbfe, 0xb20e5906, 0x28ddb60e, 0x9fad1316, + 0x167c701e, 0x8d4bcd26, 0x041b2a2e, 0x7aea8736, 0xf1b9e43e, 0x68894146, + 0xdf589e4e, 0x5627fb56, 0xccf7585e, 0x43c6b566, 0xba96126e, 0x31656f76}, +{ 0xf39dff5f, 0x6a6d5c67, 0xe13cb96f, 0x580c1677, 0xcedb737f, 0x45aad087, + 0xbc7a2d8f, 0x33498a97, 0xaa18e79f, 0x20e844a7, 0x97b7a1af, 0x0e86feb7, + 0x85565bbf, 0xfc25b8c7, 0x72f515cf, 0xe9c472d7, 0x6093cfdf, 0xd7632ce7, + 0x4e3289ef, 0xc501e6f7, 0x3bd143ff, 0xb2a0a107, 0x296ffe0f, 0xa03f5b17}, +{ 0x6277eb00, 0xd9474808, 0x5016a510, 0xc6e60218, 0x3db55f20, 0xb484bc28, + 0x2b541930, 0xa2237638, 0x18f2d340, 0x8fc23048, 0x06918d50, 0x7d60ea58, + 0xf4304760, 0x6affa468, 0xe1cf0170, 0x589e5e78, 0xcf6dbb80, 0x463d1888, + 0xbd0c7590, 0x33dbd298, 0xaaab2fa0, 0x217a8ca8, 0x9849e9b0, 0x0f1946b8} +}; + +const unsigned int CAST256::Base::t_r[8][24]={ + {19, 27, 3, 11, 19, 27, 3, 11, 19, 27, 3, 11, 19, 27, 3, 11, 19, 27, 3, 11, 19, 27, 3, 11}, + {4, 12, 20, 28, 4, 12, 20, 28, 4, 12, 20, 28, 4, 12, 20, 28, 4, 12, 20, 28, 4, 12, 20, 28}, + {21, 29, 5, 13, 21, 29, 5, 13, 21, 29, 5, 13, 21, 29, 5, 13, 21, 29, 5, 13, 21, 29, 5, 13}, + {6, 14, 22, 30, 6, 14, 22, 30, 6, 14, 22, 30, 6, 14, 22, 30, 6, 14, 22, 30, 6, 14, 22, 30}, + {23, 31, 7, 15, 23, 31, 7, 15, 23, 31, 7, 15, 23, 31, 7, 15, 23, 31, 7, 15, 23, 31, 7, 15}, + {8, 16, 24, 0, 8, 16, 24, 0, 8, 16, 24, 0, 8, 16, 24, 0, 8, 16, 24, 0, 8, 16, 24, 0}, + {25, 1, 9, 17, 25, 1, 9, 17, 25, 1, 9, 17, 25, 1, 9, 17, 25, 1, 9, 17, 25, 1, 9, 17}, + {10, 18, 26, 2, 10, 18, 26, 2, 10, 18, 26, 2, 10, 18, 26, 2, 10, 18, 26, 2, 10, 18, 26, 2} +}; + +#define Q(i) \ + F1(block[2],block[3],8*i+4,-4); \ + F2(block[1],block[2],8*i+5,-4); \ + F3(block[0],block[1],8*i+6,-4); \ + F1(block[3],block[0],8*i+7,-4); + +#define QBar(i) \ + F1(block[3],block[0],8*i+7,-4); \ + F3(block[0],block[1],8*i+6,-4); \ + F2(block[1],block[2],8*i+5,-4); \ + F1(block[2],block[3],8*i+4,-4); + +/* CAST256's encrypt/decrypt functions are identical except for the order that +the keys are used */ + +void CAST256::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word32 t, block[4]; + Block::Get(inBlock)(block[0])(block[1])(block[2])(block[3]); + + // Perform 6 forward quad rounds + Q(0); + Q(1); + Q(2); + Q(3); + Q(4); + Q(5); + + // Perform 6 reverse quad rounds + QBar(6); + QBar(7); + QBar(8); + QBar(9); + QBar(10); + QBar(11); + + Block::Put(xorBlock, outBlock)(block[0])(block[1])(block[2])(block[3]); +} + +/* Set up a CAST-256 key */ + +void CAST256::Base::Omega(int i, word32 kappa[8]) +{ + word32 t; + + f1(kappa[6],kappa[7],t_m[0][i],t_r[0][i]); + f2(kappa[5],kappa[6],t_m[1][i],t_r[1][i]); + f3(kappa[4],kappa[5],t_m[2][i],t_r[2][i]); + f1(kappa[3],kappa[4],t_m[3][i],t_r[3][i]); + f2(kappa[2],kappa[3],t_m[4][i],t_r[4][i]); + f3(kappa[1],kappa[2],t_m[5][i],t_r[5][i]); + f1(kappa[0],kappa[1],t_m[6][i],t_r[6][i]); + f2(kappa[7],kappa[0],t_m[7][i],t_r[7][i]); +} + +void CAST256::Base::UncheckedSetKey(const byte *userKey, unsigned int keylength, const NameValuePairs &) +{ + AssertValidKeyLength(keylength); + + word32 kappa[8]; + GetUserKey(BIG_ENDIAN_ORDER, kappa, 8, userKey, keylength); + + for(int i=0; i<12; ++i) + { + Omega(2*i,kappa); + Omega(2*i+1,kappa); + + K[8*i]=kappa[0] & 31; + K[8*i+1]=kappa[2] & 31; + K[8*i+2]=kappa[4] & 31; + K[8*i+3]=kappa[6] & 31; + K[8*i+4]=kappa[7]; + K[8*i+5]=kappa[5]; + K[8*i+6]=kappa[3]; + K[8*i+7]=kappa[1]; + } + + if (!IsForwardTransformation()) + { + for(int j=0; j<6; ++j) + { + for(int i=0; i<4; ++i) + { + int i1=8*j+i; + int i2=8*(11-j)+i; + + assert(i1, public VariableKeyLength<16, 5, 16> +{ + static const char *StaticAlgorithmName() {return "CAST-128";} +}; + +/// CAST-128 +class CAST128 : public CAST128_Info, public BlockCipherDocumentation +{ + class CRYPTOPP_NO_VTABLE Base : public CAST, public BlockCipherImpl + { + public: + void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); + + protected: + bool reduced; + FixedSizeSecBlock K; + }; + + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +//! algorithm info +struct CAST256_Info : public FixedBlockSize<16>, public VariableKeyLength<16, 16, 32> +{ + static const char *StaticAlgorithmName() {return "CAST-256";} +}; + +//! CAST-256 +class CAST256 : public CAST256_Info, public BlockCipherDocumentation +{ + class CRYPTOPP_NO_VTABLE Base : public CAST, public BlockCipherImpl + { + public: + void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + + protected: + static const word32 t_m[8][24]; + static const unsigned int t_r[8][24]; + + static void Omega(int i, word32 kappa[8]); + + FixedSizeSecBlock K; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef CAST128::Encryption CAST128Encryption; +typedef CAST128::Decryption CAST128Decryption; + +typedef CAST256::Encryption CAST256Encryption; +typedef CAST256::Decryption CAST256Decryption; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/cast128v.dat b/CryptoPP/crypto/cast128v.dat new file mode 100644 index 0000000..b46518c --- /dev/null +++ b/CryptoPP/crypto/cast128v.dat @@ -0,0 +1,11 @@ +01 23 45 67 12 34 56 78 23 45 67 89 34 56 78 9A +01 23 45 67 89 AB CD EF +23 8B 4F E5 84 7E 44 B2 + +01 23 45 67 12 34 56 78 23 45 +01 23 45 67 89 AB CD EF +EB 6A 71 1A 2C 02 27 1B + +01 23 45 67 12 +01 23 45 67 89 AB CD EF +7A C8 16 D1 6E 9B 30 2E diff --git a/CryptoPP/crypto/cast256v.dat b/CryptoPP/crypto/cast256v.dat new file mode 100644 index 0000000..40264eb --- /dev/null +++ b/CryptoPP/crypto/cast256v.dat @@ -0,0 +1,11 @@ +2342bb9efa38542c0af75647f29f615d +00000000000000000000000000000000 +c842a08972b43d20836c91d1b7530f6b + +2342bb9efa38542cbed0ac83940ac298bac77a7717942863 +00000000000000000000000000000000 +1b386c0210dcadcbdd0e41aa08a7a7e8 + +2342bb9efa38542cbed0ac83940ac2988d7c47ce264908461cc1b5137ae6b604 +00000000000000000000000000000000 +4f6a2038286897b9c9870136553317fa diff --git a/CryptoPP/crypto/casts.cpp b/CryptoPP/crypto/casts.cpp new file mode 100644 index 0000000..d823d72 --- /dev/null +++ b/CryptoPP/crypto/casts.cpp @@ -0,0 +1,545 @@ +#include "pch.h" +#include "cast.h" + +NAMESPACE_BEGIN(CryptoPP) + +// CAST S-boxes + +const word32 CAST::S[8][256] = { +{ + 0x30FB40D4UL, 0x9FA0FF0BUL, 0x6BECCD2FUL, 0x3F258C7AUL, + 0x1E213F2FUL, 0x9C004DD3UL, 0x6003E540UL, 0xCF9FC949UL, + 0xBFD4AF27UL, 0x88BBBDB5UL, 0xE2034090UL, 0x98D09675UL, + 0x6E63A0E0UL, 0x15C361D2UL, 0xC2E7661DUL, 0x22D4FF8EUL, + 0x28683B6FUL, 0xC07FD059UL, 0xFF2379C8UL, 0x775F50E2UL, + 0x43C340D3UL, 0xDF2F8656UL, 0x887CA41AUL, 0xA2D2BD2DUL, + 0xA1C9E0D6UL, 0x346C4819UL, 0x61B76D87UL, 0x22540F2FUL, + 0x2ABE32E1UL, 0xAA54166BUL, 0x22568E3AUL, 0xA2D341D0UL, + 0x66DB40C8UL, 0xA784392FUL, 0x004DFF2FUL, 0x2DB9D2DEUL, + 0x97943FACUL, 0x4A97C1D8UL, 0x527644B7UL, 0xB5F437A7UL, + 0xB82CBAEFUL, 0xD751D159UL, 0x6FF7F0EDUL, 0x5A097A1FUL, + 0x827B68D0UL, 0x90ECF52EUL, 0x22B0C054UL, 0xBC8E5935UL, + 0x4B6D2F7FUL, 0x50BB64A2UL, 0xD2664910UL, 0xBEE5812DUL, + 0xB7332290UL, 0xE93B159FUL, 0xB48EE411UL, 0x4BFF345DUL, + 0xFD45C240UL, 0xAD31973FUL, 0xC4F6D02EUL, 0x55FC8165UL, + 0xD5B1CAADUL, 0xA1AC2DAEUL, 0xA2D4B76DUL, 0xC19B0C50UL, + 0x882240F2UL, 0x0C6E4F38UL, 0xA4E4BFD7UL, 0x4F5BA272UL, + 0x564C1D2FUL, 0xC59C5319UL, 0xB949E354UL, 0xB04669FEUL, + 0xB1B6AB8AUL, 0xC71358DDUL, 0x6385C545UL, 0x110F935DUL, + 0x57538AD5UL, 0x6A390493UL, 0xE63D37E0UL, 0x2A54F6B3UL, + 0x3A787D5FUL, 0x6276A0B5UL, 0x19A6FCDFUL, 0x7A42206AUL, + 0x29F9D4D5UL, 0xF61B1891UL, 0xBB72275EUL, 0xAA508167UL, + 0x38901091UL, 0xC6B505EBUL, 0x84C7CB8CUL, 0x2AD75A0FUL, + 0x874A1427UL, 0xA2D1936BUL, 0x2AD286AFUL, 0xAA56D291UL, + 0xD7894360UL, 0x425C750DUL, 0x93B39E26UL, 0x187184C9UL, + 0x6C00B32DUL, 0x73E2BB14UL, 0xA0BEBC3CUL, 0x54623779UL, + 0x64459EABUL, 0x3F328B82UL, 0x7718CF82UL, 0x59A2CEA6UL, + 0x04EE002EUL, 0x89FE78E6UL, 0x3FAB0950UL, 0x325FF6C2UL, + 0x81383F05UL, 0x6963C5C8UL, 0x76CB5AD6UL, 0xD49974C9UL, + 0xCA180DCFUL, 0x380782D5UL, 0xC7FA5CF6UL, 0x8AC31511UL, + 0x35E79E13UL, 0x47DA91D0UL, 0xF40F9086UL, 0xA7E2419EUL, + 0x31366241UL, 0x051EF495UL, 0xAA573B04UL, 0x4A805D8DUL, + 0x548300D0UL, 0x00322A3CUL, 0xBF64CDDFUL, 0xBA57A68EUL, + 0x75C6372BUL, 0x50AFD341UL, 0xA7C13275UL, 0x915A0BF5UL, + 0x6B54BFABUL, 0x2B0B1426UL, 0xAB4CC9D7UL, 0x449CCD82UL, + 0xF7FBF265UL, 0xAB85C5F3UL, 0x1B55DB94UL, 0xAAD4E324UL, + 0xCFA4BD3FUL, 0x2DEAA3E2UL, 0x9E204D02UL, 0xC8BD25ACUL, + 0xEADF55B3UL, 0xD5BD9E98UL, 0xE31231B2UL, 0x2AD5AD6CUL, + 0x954329DEUL, 0xADBE4528UL, 0xD8710F69UL, 0xAA51C90FUL, + 0xAA786BF6UL, 0x22513F1EUL, 0xAA51A79BUL, 0x2AD344CCUL, + 0x7B5A41F0UL, 0xD37CFBADUL, 0x1B069505UL, 0x41ECE491UL, + 0xB4C332E6UL, 0x032268D4UL, 0xC9600ACCUL, 0xCE387E6DUL, + 0xBF6BB16CUL, 0x6A70FB78UL, 0x0D03D9C9UL, 0xD4DF39DEUL, + 0xE01063DAUL, 0x4736F464UL, 0x5AD328D8UL, 0xB347CC96UL, + 0x75BB0FC3UL, 0x98511BFBUL, 0x4FFBCC35UL, 0xB58BCF6AUL, + 0xE11F0ABCUL, 0xBFC5FE4AUL, 0xA70AEC10UL, 0xAC39570AUL, + 0x3F04442FUL, 0x6188B153UL, 0xE0397A2EUL, 0x5727CB79UL, + 0x9CEB418FUL, 0x1CACD68DUL, 0x2AD37C96UL, 0x0175CB9DUL, + 0xC69DFF09UL, 0xC75B65F0UL, 0xD9DB40D8UL, 0xEC0E7779UL, + 0x4744EAD4UL, 0xB11C3274UL, 0xDD24CB9EUL, 0x7E1C54BDUL, + 0xF01144F9UL, 0xD2240EB1UL, 0x9675B3FDUL, 0xA3AC3755UL, + 0xD47C27AFUL, 0x51C85F4DUL, 0x56907596UL, 0xA5BB15E6UL, + 0x580304F0UL, 0xCA042CF1UL, 0x011A37EAUL, 0x8DBFAADBUL, + 0x35BA3E4AUL, 0x3526FFA0UL, 0xC37B4D09UL, 0xBC306ED9UL, + 0x98A52666UL, 0x5648F725UL, 0xFF5E569DUL, 0x0CED63D0UL, + 0x7C63B2CFUL, 0x700B45E1UL, 0xD5EA50F1UL, 0x85A92872UL, + 0xAF1FBDA7UL, 0xD4234870UL, 0xA7870BF3UL, 0x2D3B4D79UL, + 0x42E04198UL, 0x0CD0EDE7UL, 0x26470DB8UL, 0xF881814CUL, + 0x474D6AD7UL, 0x7C0C5E5CUL, 0xD1231959UL, 0x381B7298UL, + 0xF5D2F4DBUL, 0xAB838653UL, 0x6E2F1E23UL, 0x83719C9EUL, + 0xBD91E046UL, 0x9A56456EUL, 0xDC39200CUL, 0x20C8C571UL, + 0x962BDA1CUL, 0xE1E696FFUL, 0xB141AB08UL, 0x7CCA89B9UL, + 0x1A69E783UL, 0x02CC4843UL, 0xA2F7C579UL, 0x429EF47DUL, + 0x427B169CUL, 0x5AC9F049UL, 0xDD8F0F00UL, 0x5C8165BFUL +}, + +{ + 0x1F201094UL, 0xEF0BA75BUL, 0x69E3CF7EUL, 0x393F4380UL, + 0xFE61CF7AUL, 0xEEC5207AUL, 0x55889C94UL, 0x72FC0651UL, + 0xADA7EF79UL, 0x4E1D7235UL, 0xD55A63CEUL, 0xDE0436BAUL, + 0x99C430EFUL, 0x5F0C0794UL, 0x18DCDB7DUL, 0xA1D6EFF3UL, + 0xA0B52F7BUL, 0x59E83605UL, 0xEE15B094UL, 0xE9FFD909UL, + 0xDC440086UL, 0xEF944459UL, 0xBA83CCB3UL, 0xE0C3CDFBUL, + 0xD1DA4181UL, 0x3B092AB1UL, 0xF997F1C1UL, 0xA5E6CF7BUL, + 0x01420DDBUL, 0xE4E7EF5BUL, 0x25A1FF41UL, 0xE180F806UL, + 0x1FC41080UL, 0x179BEE7AUL, 0xD37AC6A9UL, 0xFE5830A4UL, + 0x98DE8B7FUL, 0x77E83F4EUL, 0x79929269UL, 0x24FA9F7BUL, + 0xE113C85BUL, 0xACC40083UL, 0xD7503525UL, 0xF7EA615FUL, + 0x62143154UL, 0x0D554B63UL, 0x5D681121UL, 0xC866C359UL, + 0x3D63CF73UL, 0xCEE234C0UL, 0xD4D87E87UL, 0x5C672B21UL, + 0x071F6181UL, 0x39F7627FUL, 0x361E3084UL, 0xE4EB573BUL, + 0x602F64A4UL, 0xD63ACD9CUL, 0x1BBC4635UL, 0x9E81032DUL, + 0x2701F50CUL, 0x99847AB4UL, 0xA0E3DF79UL, 0xBA6CF38CUL, + 0x10843094UL, 0x2537A95EUL, 0xF46F6FFEUL, 0xA1FF3B1FUL, + 0x208CFB6AUL, 0x8F458C74UL, 0xD9E0A227UL, 0x4EC73A34UL, + 0xFC884F69UL, 0x3E4DE8DFUL, 0xEF0E0088UL, 0x3559648DUL, + 0x8A45388CUL, 0x1D804366UL, 0x721D9BFDUL, 0xA58684BBUL, + 0xE8256333UL, 0x844E8212UL, 0x128D8098UL, 0xFED33FB4UL, + 0xCE280AE1UL, 0x27E19BA5UL, 0xD5A6C252UL, 0xE49754BDUL, + 0xC5D655DDUL, 0xEB667064UL, 0x77840B4DUL, 0xA1B6A801UL, + 0x84DB26A9UL, 0xE0B56714UL, 0x21F043B7UL, 0xE5D05860UL, + 0x54F03084UL, 0x066FF472UL, 0xA31AA153UL, 0xDADC4755UL, + 0xB5625DBFUL, 0x68561BE6UL, 0x83CA6B94UL, 0x2D6ED23BUL, + 0xECCF01DBUL, 0xA6D3D0BAUL, 0xB6803D5CUL, 0xAF77A709UL, + 0x33B4A34CUL, 0x397BC8D6UL, 0x5EE22B95UL, 0x5F0E5304UL, + 0x81ED6F61UL, 0x20E74364UL, 0xB45E1378UL, 0xDE18639BUL, + 0x881CA122UL, 0xB96726D1UL, 0x8049A7E8UL, 0x22B7DA7BUL, + 0x5E552D25UL, 0x5272D237UL, 0x79D2951CUL, 0xC60D894CUL, + 0x488CB402UL, 0x1BA4FE5BUL, 0xA4B09F6BUL, 0x1CA815CFUL, + 0xA20C3005UL, 0x8871DF63UL, 0xB9DE2FCBUL, 0x0CC6C9E9UL, + 0x0BEEFF53UL, 0xE3214517UL, 0xB4542835UL, 0x9F63293CUL, + 0xEE41E729UL, 0x6E1D2D7CUL, 0x50045286UL, 0x1E6685F3UL, + 0xF33401C6UL, 0x30A22C95UL, 0x31A70850UL, 0x60930F13UL, + 0x73F98417UL, 0xA1269859UL, 0xEC645C44UL, 0x52C877A9UL, + 0xCDFF33A6UL, 0xA02B1741UL, 0x7CBAD9A2UL, 0x2180036FUL, + 0x50D99C08UL, 0xCB3F4861UL, 0xC26BD765UL, 0x64A3F6ABUL, + 0x80342676UL, 0x25A75E7BUL, 0xE4E6D1FCUL, 0x20C710E6UL, + 0xCDF0B680UL, 0x17844D3BUL, 0x31EEF84DUL, 0x7E0824E4UL, + 0x2CCB49EBUL, 0x846A3BAEUL, 0x8FF77888UL, 0xEE5D60F6UL, + 0x7AF75673UL, 0x2FDD5CDBUL, 0xA11631C1UL, 0x30F66F43UL, + 0xB3FAEC54UL, 0x157FD7FAUL, 0xEF8579CCUL, 0xD152DE58UL, + 0xDB2FFD5EUL, 0x8F32CE19UL, 0x306AF97AUL, 0x02F03EF8UL, + 0x99319AD5UL, 0xC242FA0FUL, 0xA7E3EBB0UL, 0xC68E4906UL, + 0xB8DA230CUL, 0x80823028UL, 0xDCDEF3C8UL, 0xD35FB171UL, + 0x088A1BC8UL, 0xBEC0C560UL, 0x61A3C9E8UL, 0xBCA8F54DUL, + 0xC72FEFFAUL, 0x22822E99UL, 0x82C570B4UL, 0xD8D94E89UL, + 0x8B1C34BCUL, 0x301E16E6UL, 0x273BE979UL, 0xB0FFEAA6UL, + 0x61D9B8C6UL, 0x00B24869UL, 0xB7FFCE3FUL, 0x08DC283BUL, + 0x43DAF65AUL, 0xF7E19798UL, 0x7619B72FUL, 0x8F1C9BA4UL, + 0xDC8637A0UL, 0x16A7D3B1UL, 0x9FC393B7UL, 0xA7136EEBUL, + 0xC6BCC63EUL, 0x1A513742UL, 0xEF6828BCUL, 0x520365D6UL, + 0x2D6A77ABUL, 0x3527ED4BUL, 0x821FD216UL, 0x095C6E2EUL, + 0xDB92F2FBUL, 0x5EEA29CBUL, 0x145892F5UL, 0x91584F7FUL, + 0x5483697BUL, 0x2667A8CCUL, 0x85196048UL, 0x8C4BACEAUL, + 0x833860D4UL, 0x0D23E0F9UL, 0x6C387E8AUL, 0x0AE6D249UL, + 0xB284600CUL, 0xD835731DUL, 0xDCB1C647UL, 0xAC4C56EAUL, + 0x3EBD81B3UL, 0x230EABB0UL, 0x6438BC87UL, 0xF0B5B1FAUL, + 0x8F5EA2B3UL, 0xFC184642UL, 0x0A036B7AUL, 0x4FB089BDUL, + 0x649DA589UL, 0xA345415EUL, 0x5C038323UL, 0x3E5D3BB9UL, + 0x43D79572UL, 0x7E6DD07CUL, 0x06DFDF1EUL, 0x6C6CC4EFUL, + 0x7160A539UL, 0x73BFBE70UL, 0x83877605UL, 0x4523ECF1UL +}, + +{ + 0x8DEFC240UL, 0x25FA5D9FUL, 0xEB903DBFUL, 0xE810C907UL, + 0x47607FFFUL, 0x369FE44BUL, 0x8C1FC644UL, 0xAECECA90UL, + 0xBEB1F9BFUL, 0xEEFBCAEAUL, 0xE8CF1950UL, 0x51DF07AEUL, + 0x920E8806UL, 0xF0AD0548UL, 0xE13C8D83UL, 0x927010D5UL, + 0x11107D9FUL, 0x07647DB9UL, 0xB2E3E4D4UL, 0x3D4F285EUL, + 0xB9AFA820UL, 0xFADE82E0UL, 0xA067268BUL, 0x8272792EUL, + 0x553FB2C0UL, 0x489AE22BUL, 0xD4EF9794UL, 0x125E3FBCUL, + 0x21FFFCEEUL, 0x825B1BFDUL, 0x9255C5EDUL, 0x1257A240UL, + 0x4E1A8302UL, 0xBAE07FFFUL, 0x528246E7UL, 0x8E57140EUL, + 0x3373F7BFUL, 0x8C9F8188UL, 0xA6FC4EE8UL, 0xC982B5A5UL, + 0xA8C01DB7UL, 0x579FC264UL, 0x67094F31UL, 0xF2BD3F5FUL, + 0x40FFF7C1UL, 0x1FB78DFCUL, 0x8E6BD2C1UL, 0x437BE59BUL, + 0x99B03DBFUL, 0xB5DBC64BUL, 0x638DC0E6UL, 0x55819D99UL, + 0xA197C81CUL, 0x4A012D6EUL, 0xC5884A28UL, 0xCCC36F71UL, + 0xB843C213UL, 0x6C0743F1UL, 0x8309893CUL, 0x0FEDDD5FUL, + 0x2F7FE850UL, 0xD7C07F7EUL, 0x02507FBFUL, 0x5AFB9A04UL, + 0xA747D2D0UL, 0x1651192EUL, 0xAF70BF3EUL, 0x58C31380UL, + 0x5F98302EUL, 0x727CC3C4UL, 0x0A0FB402UL, 0x0F7FEF82UL, + 0x8C96FDADUL, 0x5D2C2AAEUL, 0x8EE99A49UL, 0x50DA88B8UL, + 0x8427F4A0UL, 0x1EAC5790UL, 0x796FB449UL, 0x8252DC15UL, + 0xEFBD7D9BUL, 0xA672597DUL, 0xADA840D8UL, 0x45F54504UL, + 0xFA5D7403UL, 0xE83EC305UL, 0x4F91751AUL, 0x925669C2UL, + 0x23EFE941UL, 0xA903F12EUL, 0x60270DF2UL, 0x0276E4B6UL, + 0x94FD6574UL, 0x927985B2UL, 0x8276DBCBUL, 0x02778176UL, + 0xF8AF918DUL, 0x4E48F79EUL, 0x8F616DDFUL, 0xE29D840EUL, + 0x842F7D83UL, 0x340CE5C8UL, 0x96BBB682UL, 0x93B4B148UL, + 0xEF303CABUL, 0x984FAF28UL, 0x779FAF9BUL, 0x92DC560DUL, + 0x224D1E20UL, 0x8437AA88UL, 0x7D29DC96UL, 0x2756D3DCUL, + 0x8B907CEEUL, 0xB51FD240UL, 0xE7C07CE3UL, 0xE566B4A1UL, + 0xC3E9615EUL, 0x3CF8209DUL, 0x6094D1E3UL, 0xCD9CA341UL, + 0x5C76460EUL, 0x00EA983BUL, 0xD4D67881UL, 0xFD47572CUL, + 0xF76CEDD9UL, 0xBDA8229CUL, 0x127DADAAUL, 0x438A074EUL, + 0x1F97C090UL, 0x081BDB8AUL, 0x93A07EBEUL, 0xB938CA15UL, + 0x97B03CFFUL, 0x3DC2C0F8UL, 0x8D1AB2ECUL, 0x64380E51UL, + 0x68CC7BFBUL, 0xD90F2788UL, 0x12490181UL, 0x5DE5FFD4UL, + 0xDD7EF86AUL, 0x76A2E214UL, 0xB9A40368UL, 0x925D958FUL, + 0x4B39FFFAUL, 0xBA39AEE9UL, 0xA4FFD30BUL, 0xFAF7933BUL, + 0x6D498623UL, 0x193CBCFAUL, 0x27627545UL, 0x825CF47AUL, + 0x61BD8BA0UL, 0xD11E42D1UL, 0xCEAD04F4UL, 0x127EA392UL, + 0x10428DB7UL, 0x8272A972UL, 0x9270C4A8UL, 0x127DE50BUL, + 0x285BA1C8UL, 0x3C62F44FUL, 0x35C0EAA5UL, 0xE805D231UL, + 0x428929FBUL, 0xB4FCDF82UL, 0x4FB66A53UL, 0x0E7DC15BUL, + 0x1F081FABUL, 0x108618AEUL, 0xFCFD086DUL, 0xF9FF2889UL, + 0x694BCC11UL, 0x236A5CAEUL, 0x12DECA4DUL, 0x2C3F8CC5UL, + 0xD2D02DFEUL, 0xF8EF5896UL, 0xE4CF52DAUL, 0x95155B67UL, + 0x494A488CUL, 0xB9B6A80CUL, 0x5C8F82BCUL, 0x89D36B45UL, + 0x3A609437UL, 0xEC00C9A9UL, 0x44715253UL, 0x0A874B49UL, + 0xD773BC40UL, 0x7C34671CUL, 0x02717EF6UL, 0x4FEB5536UL, + 0xA2D02FFFUL, 0xD2BF60C4UL, 0xD43F03C0UL, 0x50B4EF6DUL, + 0x07478CD1UL, 0x006E1888UL, 0xA2E53F55UL, 0xB9E6D4BCUL, + 0xA2048016UL, 0x97573833UL, 0xD7207D67UL, 0xDE0F8F3DUL, + 0x72F87B33UL, 0xABCC4F33UL, 0x7688C55DUL, 0x7B00A6B0UL, + 0x947B0001UL, 0x570075D2UL, 0xF9BB88F8UL, 0x8942019EUL, + 0x4264A5FFUL, 0x856302E0UL, 0x72DBD92BUL, 0xEE971B69UL, + 0x6EA22FDEUL, 0x5F08AE2BUL, 0xAF7A616DUL, 0xE5C98767UL, + 0xCF1FEBD2UL, 0x61EFC8C2UL, 0xF1AC2571UL, 0xCC8239C2UL, + 0x67214CB8UL, 0xB1E583D1UL, 0xB7DC3E62UL, 0x7F10BDCEUL, + 0xF90A5C38UL, 0x0FF0443DUL, 0x606E6DC6UL, 0x60543A49UL, + 0x5727C148UL, 0x2BE98A1DUL, 0x8AB41738UL, 0x20E1BE24UL, + 0xAF96DA0FUL, 0x68458425UL, 0x99833BE5UL, 0x600D457DUL, + 0x282F9350UL, 0x8334B362UL, 0xD91D1120UL, 0x2B6D8DA0UL, + 0x642B1E31UL, 0x9C305A00UL, 0x52BCE688UL, 0x1B03588AUL, + 0xF7BAEFD5UL, 0x4142ED9CUL, 0xA4315C11UL, 0x83323EC5UL, + 0xDFEF4636UL, 0xA133C501UL, 0xE9D3531CUL, 0xEE353783UL +}, + +{ + 0x9DB30420UL, 0x1FB6E9DEUL, 0xA7BE7BEFUL, 0xD273A298UL, + 0x4A4F7BDBUL, 0x64AD8C57UL, 0x85510443UL, 0xFA020ED1UL, + 0x7E287AFFUL, 0xE60FB663UL, 0x095F35A1UL, 0x79EBF120UL, + 0xFD059D43UL, 0x6497B7B1UL, 0xF3641F63UL, 0x241E4ADFUL, + 0x28147F5FUL, 0x4FA2B8CDUL, 0xC9430040UL, 0x0CC32220UL, + 0xFDD30B30UL, 0xC0A5374FUL, 0x1D2D00D9UL, 0x24147B15UL, + 0xEE4D111AUL, 0x0FCA5167UL, 0x71FF904CUL, 0x2D195FFEUL, + 0x1A05645FUL, 0x0C13FEFEUL, 0x081B08CAUL, 0x05170121UL, + 0x80530100UL, 0xE83E5EFEUL, 0xAC9AF4F8UL, 0x7FE72701UL, + 0xD2B8EE5FUL, 0x06DF4261UL, 0xBB9E9B8AUL, 0x7293EA25UL, + 0xCE84FFDFUL, 0xF5718801UL, 0x3DD64B04UL, 0xA26F263BUL, + 0x7ED48400UL, 0x547EEBE6UL, 0x446D4CA0UL, 0x6CF3D6F5UL, + 0x2649ABDFUL, 0xAEA0C7F5UL, 0x36338CC1UL, 0x503F7E93UL, + 0xD3772061UL, 0x11B638E1UL, 0x72500E03UL, 0xF80EB2BBUL, + 0xABE0502EUL, 0xEC8D77DEUL, 0x57971E81UL, 0xE14F6746UL, + 0xC9335400UL, 0x6920318FUL, 0x081DBB99UL, 0xFFC304A5UL, + 0x4D351805UL, 0x7F3D5CE3UL, 0xA6C866C6UL, 0x5D5BCCA9UL, + 0xDAEC6FEAUL, 0x9F926F91UL, 0x9F46222FUL, 0x3991467DUL, + 0xA5BF6D8EUL, 0x1143C44FUL, 0x43958302UL, 0xD0214EEBUL, + 0x022083B8UL, 0x3FB6180CUL, 0x18F8931EUL, 0x281658E6UL, + 0x26486E3EUL, 0x8BD78A70UL, 0x7477E4C1UL, 0xB506E07CUL, + 0xF32D0A25UL, 0x79098B02UL, 0xE4EABB81UL, 0x28123B23UL, + 0x69DEAD38UL, 0x1574CA16UL, 0xDF871B62UL, 0x211C40B7UL, + 0xA51A9EF9UL, 0x0014377BUL, 0x041E8AC8UL, 0x09114003UL, + 0xBD59E4D2UL, 0xE3D156D5UL, 0x4FE876D5UL, 0x2F91A340UL, + 0x557BE8DEUL, 0x00EAE4A7UL, 0x0CE5C2ECUL, 0x4DB4BBA6UL, + 0xE756BDFFUL, 0xDD3369ACUL, 0xEC17B035UL, 0x06572327UL, + 0x99AFC8B0UL, 0x56C8C391UL, 0x6B65811CUL, 0x5E146119UL, + 0x6E85CB75UL, 0xBE07C002UL, 0xC2325577UL, 0x893FF4ECUL, + 0x5BBFC92DUL, 0xD0EC3B25UL, 0xB7801AB7UL, 0x8D6D3B24UL, + 0x20C763EFUL, 0xC366A5FCUL, 0x9C382880UL, 0x0ACE3205UL, + 0xAAC9548AUL, 0xECA1D7C7UL, 0x041AFA32UL, 0x1D16625AUL, + 0x6701902CUL, 0x9B757A54UL, 0x31D477F7UL, 0x9126B031UL, + 0x36CC6FDBUL, 0xC70B8B46UL, 0xD9E66A48UL, 0x56E55A79UL, + 0x026A4CEBUL, 0x52437EFFUL, 0x2F8F76B4UL, 0x0DF980A5UL, + 0x8674CDE3UL, 0xEDDA04EBUL, 0x17A9BE04UL, 0x2C18F4DFUL, + 0xB7747F9DUL, 0xAB2AF7B4UL, 0xEFC34D20UL, 0x2E096B7CUL, + 0x1741A254UL, 0xE5B6A035UL, 0x213D42F6UL, 0x2C1C7C26UL, + 0x61C2F50FUL, 0x6552DAF9UL, 0xD2C231F8UL, 0x25130F69UL, + 0xD8167FA2UL, 0x0418F2C8UL, 0x001A96A6UL, 0x0D1526ABUL, + 0x63315C21UL, 0x5E0A72ECUL, 0x49BAFEFDUL, 0x187908D9UL, + 0x8D0DBD86UL, 0x311170A7UL, 0x3E9B640CUL, 0xCC3E10D7UL, + 0xD5CAD3B6UL, 0x0CAEC388UL, 0xF73001E1UL, 0x6C728AFFUL, + 0x71EAE2A1UL, 0x1F9AF36EUL, 0xCFCBD12FUL, 0xC1DE8417UL, + 0xAC07BE6BUL, 0xCB44A1D8UL, 0x8B9B0F56UL, 0x013988C3UL, + 0xB1C52FCAUL, 0xB4BE31CDUL, 0xD8782806UL, 0x12A3A4E2UL, + 0x6F7DE532UL, 0x58FD7EB6UL, 0xD01EE900UL, 0x24ADFFC2UL, + 0xF4990FC5UL, 0x9711AAC5UL, 0x001D7B95UL, 0x82E5E7D2UL, + 0x109873F6UL, 0x00613096UL, 0xC32D9521UL, 0xADA121FFUL, + 0x29908415UL, 0x7FBB977FUL, 0xAF9EB3DBUL, 0x29C9ED2AUL, + 0x5CE2A465UL, 0xA730F32CUL, 0xD0AA3FE8UL, 0x8A5CC091UL, + 0xD49E2CE7UL, 0x0CE454A9UL, 0xD60ACD86UL, 0x015F1919UL, + 0x77079103UL, 0xDEA03AF6UL, 0x78A8565EUL, 0xDEE356DFUL, + 0x21F05CBEUL, 0x8B75E387UL, 0xB3C50651UL, 0xB8A5C3EFUL, + 0xD8EEB6D2UL, 0xE523BE77UL, 0xC2154529UL, 0x2F69EFDFUL, + 0xAFE67AFBUL, 0xF470C4B2UL, 0xF3E0EB5BUL, 0xD6CC9876UL, + 0x39E4460CUL, 0x1FDA8538UL, 0x1987832FUL, 0xCA007367UL, + 0xA99144F8UL, 0x296B299EUL, 0x492FC295UL, 0x9266BEABUL, + 0xB5676E69UL, 0x9BD3DDDAUL, 0xDF7E052FUL, 0xDB25701CUL, + 0x1B5E51EEUL, 0xF65324E6UL, 0x6AFCE36CUL, 0x0316CC04UL, + 0x8644213EUL, 0xB7DC59D0UL, 0x7965291FUL, 0xCCD6FD43UL, + 0x41823979UL, 0x932BCDF6UL, 0xB657C34DUL, 0x4EDFD282UL, + 0x7AE5290CUL, 0x3CB9536BUL, 0x851E20FEUL, 0x9833557EUL, + 0x13ECF0B0UL, 0xD3FFB372UL, 0x3F85C5C1UL, 0x0AEF7ED2UL +}, + +{ + 0x7EC90C04UL, 0x2C6E74B9UL, 0x9B0E66DFUL, 0xA6337911UL, + 0xB86A7FFFUL, 0x1DD358F5UL, 0x44DD9D44UL, 0x1731167FUL, + 0x08FBF1FAUL, 0xE7F511CCUL, 0xD2051B00UL, 0x735ABA00UL, + 0x2AB722D8UL, 0x386381CBUL, 0xACF6243AUL, 0x69BEFD7AUL, + 0xE6A2E77FUL, 0xF0C720CDUL, 0xC4494816UL, 0xCCF5C180UL, + 0x38851640UL, 0x15B0A848UL, 0xE68B18CBUL, 0x4CAADEFFUL, + 0x5F480A01UL, 0x0412B2AAUL, 0x259814FCUL, 0x41D0EFE2UL, + 0x4E40B48DUL, 0x248EB6FBUL, 0x8DBA1CFEUL, 0x41A99B02UL, + 0x1A550A04UL, 0xBA8F65CBUL, 0x7251F4E7UL, 0x95A51725UL, + 0xC106ECD7UL, 0x97A5980AUL, 0xC539B9AAUL, 0x4D79FE6AUL, + 0xF2F3F763UL, 0x68AF8040UL, 0xED0C9E56UL, 0x11B4958BUL, + 0xE1EB5A88UL, 0x8709E6B0UL, 0xD7E07156UL, 0x4E29FEA7UL, + 0x6366E52DUL, 0x02D1C000UL, 0xC4AC8E05UL, 0x9377F571UL, + 0x0C05372AUL, 0x578535F2UL, 0x2261BE02UL, 0xD642A0C9UL, + 0xDF13A280UL, 0x74B55BD2UL, 0x682199C0UL, 0xD421E5ECUL, + 0x53FB3CE8UL, 0xC8ADEDB3UL, 0x28A87FC9UL, 0x3D959981UL, + 0x5C1FF900UL, 0xFE38D399UL, 0x0C4EFF0BUL, 0x062407EAUL, + 0xAA2F4FB1UL, 0x4FB96976UL, 0x90C79505UL, 0xB0A8A774UL, + 0xEF55A1FFUL, 0xE59CA2C2UL, 0xA6B62D27UL, 0xE66A4263UL, + 0xDF65001FUL, 0x0EC50966UL, 0xDFDD55BCUL, 0x29DE0655UL, + 0x911E739AUL, 0x17AF8975UL, 0x32C7911CUL, 0x89F89468UL, + 0x0D01E980UL, 0x524755F4UL, 0x03B63CC9UL, 0x0CC844B2UL, + 0xBCF3F0AAUL, 0x87AC36E9UL, 0xE53A7426UL, 0x01B3D82BUL, + 0x1A9E7449UL, 0x64EE2D7EUL, 0xCDDBB1DAUL, 0x01C94910UL, + 0xB868BF80UL, 0x0D26F3FDUL, 0x9342EDE7UL, 0x04A5C284UL, + 0x636737B6UL, 0x50F5B616UL, 0xF24766E3UL, 0x8ECA36C1UL, + 0x136E05DBUL, 0xFEF18391UL, 0xFB887A37UL, 0xD6E7F7D4UL, + 0xC7FB7DC9UL, 0x3063FCDFUL, 0xB6F589DEUL, 0xEC2941DAUL, + 0x26E46695UL, 0xB7566419UL, 0xF654EFC5UL, 0xD08D58B7UL, + 0x48925401UL, 0xC1BACB7FUL, 0xE5FF550FUL, 0xB6083049UL, + 0x5BB5D0E8UL, 0x87D72E5AUL, 0xAB6A6EE1UL, 0x223A66CEUL, + 0xC62BF3CDUL, 0x9E0885F9UL, 0x68CB3E47UL, 0x086C010FUL, + 0xA21DE820UL, 0xD18B69DEUL, 0xF3F65777UL, 0xFA02C3F6UL, + 0x407EDAC3UL, 0xCBB3D550UL, 0x1793084DUL, 0xB0D70EBAUL, + 0x0AB378D5UL, 0xD951FB0CUL, 0xDED7DA56UL, 0x4124BBE4UL, + 0x94CA0B56UL, 0x0F5755D1UL, 0xE0E1E56EUL, 0x6184B5BEUL, + 0x580A249FUL, 0x94F74BC0UL, 0xE327888EUL, 0x9F7B5561UL, + 0xC3DC0280UL, 0x05687715UL, 0x646C6BD7UL, 0x44904DB3UL, + 0x66B4F0A3UL, 0xC0F1648AUL, 0x697ED5AFUL, 0x49E92FF6UL, + 0x309E374FUL, 0x2CB6356AUL, 0x85808573UL, 0x4991F840UL, + 0x76F0AE02UL, 0x083BE84DUL, 0x28421C9AUL, 0x44489406UL, + 0x736E4CB8UL, 0xC1092910UL, 0x8BC95FC6UL, 0x7D869CF4UL, + 0x134F616FUL, 0x2E77118DUL, 0xB31B2BE1UL, 0xAA90B472UL, + 0x3CA5D717UL, 0x7D161BBAUL, 0x9CAD9010UL, 0xAF462BA2UL, + 0x9FE459D2UL, 0x45D34559UL, 0xD9F2DA13UL, 0xDBC65487UL, + 0xF3E4F94EUL, 0x176D486FUL, 0x097C13EAUL, 0x631DA5C7UL, + 0x445F7382UL, 0x175683F4UL, 0xCDC66A97UL, 0x70BE0288UL, + 0xB3CDCF72UL, 0x6E5DD2F3UL, 0x20936079UL, 0x459B80A5UL, + 0xBE60E2DBUL, 0xA9C23101UL, 0xEBA5315CUL, 0x224E42F2UL, + 0x1C5C1572UL, 0xF6721B2CUL, 0x1AD2FFF3UL, 0x8C25404EUL, + 0x324ED72FUL, 0x4067B7FDUL, 0x0523138EUL, 0x5CA3BC78UL, + 0xDC0FD66EUL, 0x75922283UL, 0x784D6B17UL, 0x58EBB16EUL, + 0x44094F85UL, 0x3F481D87UL, 0xFCFEAE7BUL, 0x77B5FF76UL, + 0x8C2302BFUL, 0xAAF47556UL, 0x5F46B02AUL, 0x2B092801UL, + 0x3D38F5F7UL, 0x0CA81F36UL, 0x52AF4A8AUL, 0x66D5E7C0UL, + 0xDF3B0874UL, 0x95055110UL, 0x1B5AD7A8UL, 0xF61ED5ADUL, + 0x6CF6E479UL, 0x20758184UL, 0xD0CEFA65UL, 0x88F7BE58UL, + 0x4A046826UL, 0x0FF6F8F3UL, 0xA09C7F70UL, 0x5346ABA0UL, + 0x5CE96C28UL, 0xE176EDA3UL, 0x6BAC307FUL, 0x376829D2UL, + 0x85360FA9UL, 0x17E3FE2AUL, 0x24B79767UL, 0xF5A96B20UL, + 0xD6CD2595UL, 0x68FF1EBFUL, 0x7555442CUL, 0xF19F06BEUL, + 0xF9E0659AUL, 0xEEB9491DUL, 0x34010718UL, 0xBB30CAB8UL, + 0xE822FE15UL, 0x88570983UL, 0x750E6249UL, 0xDA627E55UL, + 0x5E76FFA8UL, 0xB1534546UL, 0x6D47DE08UL, 0xEFE9E7D4UL +}, + +{ + 0xF6FA8F9DUL, 0x2CAC6CE1UL, 0x4CA34867UL, 0xE2337F7CUL, + 0x95DB08E7UL, 0x016843B4UL, 0xECED5CBCUL, 0x325553ACUL, + 0xBF9F0960UL, 0xDFA1E2EDUL, 0x83F0579DUL, 0x63ED86B9UL, + 0x1AB6A6B8UL, 0xDE5EBE39UL, 0xF38FF732UL, 0x8989B138UL, + 0x33F14961UL, 0xC01937BDUL, 0xF506C6DAUL, 0xE4625E7EUL, + 0xA308EA99UL, 0x4E23E33CUL, 0x79CBD7CCUL, 0x48A14367UL, + 0xA3149619UL, 0xFEC94BD5UL, 0xA114174AUL, 0xEAA01866UL, + 0xA084DB2DUL, 0x09A8486FUL, 0xA888614AUL, 0x2900AF98UL, + 0x01665991UL, 0xE1992863UL, 0xC8F30C60UL, 0x2E78EF3CUL, + 0xD0D51932UL, 0xCF0FEC14UL, 0xF7CA07D2UL, 0xD0A82072UL, + 0xFD41197EUL, 0x9305A6B0UL, 0xE86BE3DAUL, 0x74BED3CDUL, + 0x372DA53CUL, 0x4C7F4448UL, 0xDAB5D440UL, 0x6DBA0EC3UL, + 0x083919A7UL, 0x9FBAEED9UL, 0x49DBCFB0UL, 0x4E670C53UL, + 0x5C3D9C01UL, 0x64BDB941UL, 0x2C0E636AUL, 0xBA7DD9CDUL, + 0xEA6F7388UL, 0xE70BC762UL, 0x35F29ADBUL, 0x5C4CDD8DUL, + 0xF0D48D8CUL, 0xB88153E2UL, 0x08A19866UL, 0x1AE2EAC8UL, + 0x284CAF89UL, 0xAA928223UL, 0x9334BE53UL, 0x3B3A21BFUL, + 0x16434BE3UL, 0x9AEA3906UL, 0xEFE8C36EUL, 0xF890CDD9UL, + 0x80226DAEUL, 0xC340A4A3UL, 0xDF7E9C09UL, 0xA694A807UL, + 0x5B7C5ECCUL, 0x221DB3A6UL, 0x9A69A02FUL, 0x68818A54UL, + 0xCEB2296FUL, 0x53C0843AUL, 0xFE893655UL, 0x25BFE68AUL, + 0xB4628ABCUL, 0xCF222EBFUL, 0x25AC6F48UL, 0xA9A99387UL, + 0x53BDDB65UL, 0xE76FFBE7UL, 0xE967FD78UL, 0x0BA93563UL, + 0x8E342BC1UL, 0xE8A11BE9UL, 0x4980740DUL, 0xC8087DFCUL, + 0x8DE4BF99UL, 0xA11101A0UL, 0x7FD37975UL, 0xDA5A26C0UL, + 0xE81F994FUL, 0x9528CD89UL, 0xFD339FEDUL, 0xB87834BFUL, + 0x5F04456DUL, 0x22258698UL, 0xC9C4C83BUL, 0x2DC156BEUL, + 0x4F628DAAUL, 0x57F55EC5UL, 0xE2220ABEUL, 0xD2916EBFUL, + 0x4EC75B95UL, 0x24F2C3C0UL, 0x42D15D99UL, 0xCD0D7FA0UL, + 0x7B6E27FFUL, 0xA8DC8AF0UL, 0x7345C106UL, 0xF41E232FUL, + 0x35162386UL, 0xE6EA8926UL, 0x3333B094UL, 0x157EC6F2UL, + 0x372B74AFUL, 0x692573E4UL, 0xE9A9D848UL, 0xF3160289UL, + 0x3A62EF1DUL, 0xA787E238UL, 0xF3A5F676UL, 0x74364853UL, + 0x20951063UL, 0x4576698DUL, 0xB6FAD407UL, 0x592AF950UL, + 0x36F73523UL, 0x4CFB6E87UL, 0x7DA4CEC0UL, 0x6C152DAAUL, + 0xCB0396A8UL, 0xC50DFE5DUL, 0xFCD707ABUL, 0x0921C42FUL, + 0x89DFF0BBUL, 0x5FE2BE78UL, 0x448F4F33UL, 0x754613C9UL, + 0x2B05D08DUL, 0x48B9D585UL, 0xDC049441UL, 0xC8098F9BUL, + 0x7DEDE786UL, 0xC39A3373UL, 0x42410005UL, 0x6A091751UL, + 0x0EF3C8A6UL, 0x890072D6UL, 0x28207682UL, 0xA9A9F7BEUL, + 0xBF32679DUL, 0xD45B5B75UL, 0xB353FD00UL, 0xCBB0E358UL, + 0x830F220AUL, 0x1F8FB214UL, 0xD372CF08UL, 0xCC3C4A13UL, + 0x8CF63166UL, 0x061C87BEUL, 0x88C98F88UL, 0x6062E397UL, + 0x47CF8E7AUL, 0xB6C85283UL, 0x3CC2ACFBUL, 0x3FC06976UL, + 0x4E8F0252UL, 0x64D8314DUL, 0xDA3870E3UL, 0x1E665459UL, + 0xC10908F0UL, 0x513021A5UL, 0x6C5B68B7UL, 0x822F8AA0UL, + 0x3007CD3EUL, 0x74719EEFUL, 0xDC872681UL, 0x073340D4UL, + 0x7E432FD9UL, 0x0C5EC241UL, 0x8809286CUL, 0xF592D891UL, + 0x08A930F6UL, 0x957EF305UL, 0xB7FBFFBDUL, 0xC266E96FUL, + 0x6FE4AC98UL, 0xB173ECC0UL, 0xBC60B42AUL, 0x953498DAUL, + 0xFBA1AE12UL, 0x2D4BD736UL, 0x0F25FAABUL, 0xA4F3FCEBUL, + 0xE2969123UL, 0x257F0C3DUL, 0x9348AF49UL, 0x361400BCUL, + 0xE8816F4AUL, 0x3814F200UL, 0xA3F94043UL, 0x9C7A54C2UL, + 0xBC704F57UL, 0xDA41E7F9UL, 0xC25AD33AUL, 0x54F4A084UL, + 0xB17F5505UL, 0x59357CBEUL, 0xEDBD15C8UL, 0x7F97C5ABUL, + 0xBA5AC7B5UL, 0xB6F6DEAFUL, 0x3A479C3AUL, 0x5302DA25UL, + 0x653D7E6AUL, 0x54268D49UL, 0x51A477EAUL, 0x5017D55BUL, + 0xD7D25D88UL, 0x44136C76UL, 0x0404A8C8UL, 0xB8E5A121UL, + 0xB81A928AUL, 0x60ED5869UL, 0x97C55B96UL, 0xEAEC991BUL, + 0x29935913UL, 0x01FDB7F1UL, 0x088E8DFAUL, 0x9AB6F6F5UL, + 0x3B4CBF9FUL, 0x4A5DE3ABUL, 0xE6051D35UL, 0xA0E1D855UL, + 0xD36B4CF1UL, 0xF544EDEBUL, 0xB0E93524UL, 0xBEBB8FBDUL, + 0xA2D762CFUL, 0x49C92F54UL, 0x38B5F331UL, 0x7128A454UL, + 0x48392905UL, 0xA65B1DB8UL, 0x851C97BDUL, 0xD675CF2FUL +}, + +{ + 0x85E04019UL, 0x332BF567UL, 0x662DBFFFUL, 0xCFC65693UL, + 0x2A8D7F6FUL, 0xAB9BC912UL, 0xDE6008A1UL, 0x2028DA1FUL, + 0x0227BCE7UL, 0x4D642916UL, 0x18FAC300UL, 0x50F18B82UL, + 0x2CB2CB11UL, 0xB232E75CUL, 0x4B3695F2UL, 0xB28707DEUL, + 0xA05FBCF6UL, 0xCD4181E9UL, 0xE150210CUL, 0xE24EF1BDUL, + 0xB168C381UL, 0xFDE4E789UL, 0x5C79B0D8UL, 0x1E8BFD43UL, + 0x4D495001UL, 0x38BE4341UL, 0x913CEE1DUL, 0x92A79C3FUL, + 0x089766BEUL, 0xBAEEADF4UL, 0x1286BECFUL, 0xB6EACB19UL, + 0x2660C200UL, 0x7565BDE4UL, 0x64241F7AUL, 0x8248DCA9UL, + 0xC3B3AD66UL, 0x28136086UL, 0x0BD8DFA8UL, 0x356D1CF2UL, + 0x107789BEUL, 0xB3B2E9CEUL, 0x0502AA8FUL, 0x0BC0351EUL, + 0x166BF52AUL, 0xEB12FF82UL, 0xE3486911UL, 0xD34D7516UL, + 0x4E7B3AFFUL, 0x5F43671BUL, 0x9CF6E037UL, 0x4981AC83UL, + 0x334266CEUL, 0x8C9341B7UL, 0xD0D854C0UL, 0xCB3A6C88UL, + 0x47BC2829UL, 0x4725BA37UL, 0xA66AD22BUL, 0x7AD61F1EUL, + 0x0C5CBAFAUL, 0x4437F107UL, 0xB6E79962UL, 0x42D2D816UL, + 0x0A961288UL, 0xE1A5C06EUL, 0x13749E67UL, 0x72FC081AUL, + 0xB1D139F7UL, 0xF9583745UL, 0xCF19DF58UL, 0xBEC3F756UL, + 0xC06EBA30UL, 0x07211B24UL, 0x45C28829UL, 0xC95E317FUL, + 0xBC8EC511UL, 0x38BC46E9UL, 0xC6E6FA14UL, 0xBAE8584AUL, + 0xAD4EBC46UL, 0x468F508BUL, 0x7829435FUL, 0xF124183BUL, + 0x821DBA9FUL, 0xAFF60FF4UL, 0xEA2C4E6DUL, 0x16E39264UL, + 0x92544A8BUL, 0x009B4FC3UL, 0xABA68CEDUL, 0x9AC96F78UL, + 0x06A5B79AUL, 0xB2856E6EUL, 0x1AEC3CA9UL, 0xBE838688UL, + 0x0E0804E9UL, 0x55F1BE56UL, 0xE7E5363BUL, 0xB3A1F25DUL, + 0xF7DEBB85UL, 0x61FE033CUL, 0x16746233UL, 0x3C034C28UL, + 0xDA6D0C74UL, 0x79AAC56CUL, 0x3CE4E1ADUL, 0x51F0C802UL, + 0x98F8F35AUL, 0x1626A49FUL, 0xEED82B29UL, 0x1D382FE3UL, + 0x0C4FB99AUL, 0xBB325778UL, 0x3EC6D97BUL, 0x6E77A6A9UL, + 0xCB658B5CUL, 0xD45230C7UL, 0x2BD1408BUL, 0x60C03EB7UL, + 0xB9068D78UL, 0xA33754F4UL, 0xF430C87DUL, 0xC8A71302UL, + 0xB96D8C32UL, 0xEBD4E7BEUL, 0xBE8B9D2DUL, 0x7979FB06UL, + 0xE7225308UL, 0x8B75CF77UL, 0x11EF8DA4UL, 0xE083C858UL, + 0x8D6B786FUL, 0x5A6317A6UL, 0xFA5CF7A0UL, 0x5DDA0033UL, + 0xF28EBFB0UL, 0xF5B9C310UL, 0xA0EAC280UL, 0x08B9767AUL, + 0xA3D9D2B0UL, 0x79D34217UL, 0x021A718DUL, 0x9AC6336AUL, + 0x2711FD60UL, 0x438050E3UL, 0x069908A8UL, 0x3D7FEDC4UL, + 0x826D2BEFUL, 0x4EEB8476UL, 0x488DCF25UL, 0x36C9D566UL, + 0x28E74E41UL, 0xC2610ACAUL, 0x3D49A9CFUL, 0xBAE3B9DFUL, + 0xB65F8DE6UL, 0x92AEAF64UL, 0x3AC7D5E6UL, 0x9EA80509UL, + 0xF22B017DUL, 0xA4173F70UL, 0xDD1E16C3UL, 0x15E0D7F9UL, + 0x50B1B887UL, 0x2B9F4FD5UL, 0x625ABA82UL, 0x6A017962UL, + 0x2EC01B9CUL, 0x15488AA9UL, 0xD716E740UL, 0x40055A2CUL, + 0x93D29A22UL, 0xE32DBF9AUL, 0x058745B9UL, 0x3453DC1EUL, + 0xD699296EUL, 0x496CFF6FUL, 0x1C9F4986UL, 0xDFE2ED07UL, + 0xB87242D1UL, 0x19DE7EAEUL, 0x053E561AUL, 0x15AD6F8CUL, + 0x66626C1CUL, 0x7154C24CUL, 0xEA082B2AUL, 0x93EB2939UL, + 0x17DCB0F0UL, 0x58D4F2AEUL, 0x9EA294FBUL, 0x52CF564CUL, + 0x9883FE66UL, 0x2EC40581UL, 0x763953C3UL, 0x01D6692EUL, + 0xD3A0C108UL, 0xA1E7160EUL, 0xE4F2DFA6UL, 0x693ED285UL, + 0x74904698UL, 0x4C2B0EDDUL, 0x4F757656UL, 0x5D393378UL, + 0xA132234FUL, 0x3D321C5DUL, 0xC3F5E194UL, 0x4B269301UL, + 0xC79F022FUL, 0x3C997E7EUL, 0x5E4F9504UL, 0x3FFAFBBDUL, + 0x76F7AD0EUL, 0x296693F4UL, 0x3D1FCE6FUL, 0xC61E45BEUL, + 0xD3B5AB34UL, 0xF72BF9B7UL, 0x1B0434C0UL, 0x4E72B567UL, + 0x5592A33DUL, 0xB5229301UL, 0xCFD2A87FUL, 0x60AEB767UL, + 0x1814386BUL, 0x30BCC33DUL, 0x38A0C07DUL, 0xFD1606F2UL, + 0xC363519BUL, 0x589DD390UL, 0x5479F8E6UL, 0x1CB8D647UL, + 0x97FD61A9UL, 0xEA7759F4UL, 0x2D57539DUL, 0x569A58CFUL, + 0xE84E63ADUL, 0x462E1B78UL, 0x6580F87EUL, 0xF3817914UL, + 0x91DA55F4UL, 0x40A230F3UL, 0xD1988F35UL, 0xB6E318D2UL, + 0x3FFA50BCUL, 0x3D40F021UL, 0xC3C0BDAEUL, 0x4958C24CUL, + 0x518F36B2UL, 0x84B1D370UL, 0x0FEDCE83UL, 0x878DDADAUL, + 0xF2A279C7UL, 0x94E01BE8UL, 0x90716F4BUL, 0x954B8AA3UL +}, + +{ + 0xE216300DUL, 0xBBDDFFFCUL, 0xA7EBDABDUL, 0x35648095UL, + 0x7789F8B7UL, 0xE6C1121BUL, 0x0E241600UL, 0x052CE8B5UL, + 0x11A9CFB0UL, 0xE5952F11UL, 0xECE7990AUL, 0x9386D174UL, + 0x2A42931CUL, 0x76E38111UL, 0xB12DEF3AUL, 0x37DDDDFCUL, + 0xDE9ADEB1UL, 0x0A0CC32CUL, 0xBE197029UL, 0x84A00940UL, + 0xBB243A0FUL, 0xB4D137CFUL, 0xB44E79F0UL, 0x049EEDFDUL, + 0x0B15A15DUL, 0x480D3168UL, 0x8BBBDE5AUL, 0x669DED42UL, + 0xC7ECE831UL, 0x3F8F95E7UL, 0x72DF191BUL, 0x7580330DUL, + 0x94074251UL, 0x5C7DCDFAUL, 0xABBE6D63UL, 0xAA402164UL, + 0xB301D40AUL, 0x02E7D1CAUL, 0x53571DAEUL, 0x7A3182A2UL, + 0x12A8DDECUL, 0xFDAA335DUL, 0x176F43E8UL, 0x71FB46D4UL, + 0x38129022UL, 0xCE949AD4UL, 0xB84769ADUL, 0x965BD862UL, + 0x82F3D055UL, 0x66FB9767UL, 0x15B80B4EUL, 0x1D5B47A0UL, + 0x4CFDE06FUL, 0xC28EC4B8UL, 0x57E8726EUL, 0x647A78FCUL, + 0x99865D44UL, 0x608BD593UL, 0x6C200E03UL, 0x39DC5FF6UL, + 0x5D0B00A3UL, 0xAE63AFF2UL, 0x7E8BD632UL, 0x70108C0CUL, + 0xBBD35049UL, 0x2998DF04UL, 0x980CF42AUL, 0x9B6DF491UL, + 0x9E7EDD53UL, 0x06918548UL, 0x58CB7E07UL, 0x3B74EF2EUL, + 0x522FFFB1UL, 0xD24708CCUL, 0x1C7E27CDUL, 0xA4EB215BUL, + 0x3CF1D2E2UL, 0x19B47A38UL, 0x424F7618UL, 0x35856039UL, + 0x9D17DEE7UL, 0x27EB35E6UL, 0xC9AFF67BUL, 0x36BAF5B8UL, + 0x09C467CDUL, 0xC18910B1UL, 0xE11DBF7BUL, 0x06CD1AF8UL, + 0x7170C608UL, 0x2D5E3354UL, 0xD4DE495AUL, 0x64C6D006UL, + 0xBCC0C62CUL, 0x3DD00DB3UL, 0x708F8F34UL, 0x77D51B42UL, + 0x264F620FUL, 0x24B8D2BFUL, 0x15C1B79EUL, 0x46A52564UL, + 0xF8D7E54EUL, 0x3E378160UL, 0x7895CDA5UL, 0x859C15A5UL, + 0xE6459788UL, 0xC37BC75FUL, 0xDB07BA0CUL, 0x0676A3ABUL, + 0x7F229B1EUL, 0x31842E7BUL, 0x24259FD7UL, 0xF8BEF472UL, + 0x835FFCB8UL, 0x6DF4C1F2UL, 0x96F5B195UL, 0xFD0AF0FCUL, + 0xB0FE134CUL, 0xE2506D3DUL, 0x4F9B12EAUL, 0xF215F225UL, + 0xA223736FUL, 0x9FB4C428UL, 0x25D04979UL, 0x34C713F8UL, + 0xC4618187UL, 0xEA7A6E98UL, 0x7CD16EFCUL, 0x1436876CUL, + 0xF1544107UL, 0xBEDEEE14UL, 0x56E9AF27UL, 0xA04AA441UL, + 0x3CF7C899UL, 0x92ECBAE6UL, 0xDD67016DUL, 0x151682EBUL, + 0xA842EEDFUL, 0xFDBA60B4UL, 0xF1907B75UL, 0x20E3030FUL, + 0x24D8C29EUL, 0xE139673BUL, 0xEFA63FB8UL, 0x71873054UL, + 0xB6F2CF3BUL, 0x9F326442UL, 0xCB15A4CCUL, 0xB01A4504UL, + 0xF1E47D8DUL, 0x844A1BE5UL, 0xBAE7DFDCUL, 0x42CBDA70UL, + 0xCD7DAE0AUL, 0x57E85B7AUL, 0xD53F5AF6UL, 0x20CF4D8CUL, + 0xCEA4D428UL, 0x79D130A4UL, 0x3486EBFBUL, 0x33D3CDDCUL, + 0x77853B53UL, 0x37EFFCB5UL, 0xC5068778UL, 0xE580B3E6UL, + 0x4E68B8F4UL, 0xC5C8B37EUL, 0x0D809EA2UL, 0x398FEB7CUL, + 0x132A4F94UL, 0x43B7950EUL, 0x2FEE7D1CUL, 0x223613BDUL, + 0xDD06CAA2UL, 0x37DF932BUL, 0xC4248289UL, 0xACF3EBC3UL, + 0x5715F6B7UL, 0xEF3478DDUL, 0xF267616FUL, 0xC148CBE4UL, + 0x9052815EUL, 0x5E410FABUL, 0xB48A2465UL, 0x2EDA7FA4UL, + 0xE87B40E4UL, 0xE98EA084UL, 0x5889E9E1UL, 0xEFD390FCUL, + 0xDD07D35BUL, 0xDB485694UL, 0x38D7E5B2UL, 0x57720101UL, + 0x730EDEBCUL, 0x5B643113UL, 0x94917E4FUL, 0x503C2FBAUL, + 0x646F1282UL, 0x7523D24AUL, 0xE0779695UL, 0xF9C17A8FUL, + 0x7A5B2121UL, 0xD187B896UL, 0x29263A4DUL, 0xBA510CDFUL, + 0x81F47C9FUL, 0xAD1163EDUL, 0xEA7B5965UL, 0x1A00726EUL, + 0x11403092UL, 0x00DA6D77UL, 0x4A0CDD61UL, 0xAD1F4603UL, + 0x605BDFB0UL, 0x9EEDC364UL, 0x22EBE6A8UL, 0xCEE7D28AUL, + 0xA0E736A0UL, 0x5564A6B9UL, 0x10853209UL, 0xC7EB8F37UL, + 0x2DE705CAUL, 0x8951570FUL, 0xDF09822BUL, 0xBD691A6CUL, + 0xAA12E4F2UL, 0x87451C0FUL, 0xE0F6A27AUL, 0x3ADA4819UL, + 0x4CF1764FUL, 0x0D771C2BUL, 0x67CDB156UL, 0x350D8384UL, + 0x5938FA0FUL, 0x42399EF3UL, 0x36997B07UL, 0x0E84093DUL, + 0x4AA93E61UL, 0x8360D87BUL, 0x1FA98B0CUL, 0x1149382CUL, + 0xE97625A5UL, 0x0614D1B7UL, 0x0E25244BUL, 0x0C768347UL, + 0x589E8D82UL, 0x0D2059D1UL, 0xA466BB1EUL, 0xF8DA0A82UL, + 0x04F19130UL, 0xBA6E4EC0UL, 0x99265164UL, 0x1EE7230DUL, + 0x50B2AD80UL, 0xEAEE6801UL, 0x8DB2A283UL, 0xEA8BF59EUL +}}; + +NAMESPACE_END diff --git a/CryptoPP/crypto/cbcmac.cpp b/CryptoPP/crypto/cbcmac.cpp new file mode 100644 index 0000000..322a4c3 --- /dev/null +++ b/CryptoPP/crypto/cbcmac.cpp @@ -0,0 +1,63 @@ +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "cbcmac.h" + +NAMESPACE_BEGIN(CryptoPP) + +void CBC_MAC_Base::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms) +{ + AccessCipher().SetKey(key, length, params); + m_reg.CleanNew(AccessCipher().BlockSize()); + m_counter = 0; +} + +void CBC_MAC_Base::Update(const byte *input, size_t length) +{ + unsigned int blockSize = AccessCipher().BlockSize(); + + while (m_counter && length) + { + m_reg[m_counter++] ^= *input++; + if (m_counter == blockSize) + ProcessBuf(); + length--; + } + + while (length >= blockSize) + { + xorbuf(m_reg, input, blockSize); + ProcessBuf(); + input += blockSize; + length -= blockSize; + } + + while (length--) + { + m_reg[m_counter++] ^= *input++; + if (m_counter == blockSize) + ProcessBuf(); + } +} + +void CBC_MAC_Base::TruncatedFinal(byte *mac, size_t size) +{ + ThrowIfInvalidTruncatedSize(size); + + if (m_counter) + ProcessBuf(); + + memcpy(mac, m_reg, size); + memset(m_reg, 0, AccessCipher().BlockSize()); +} + +void CBC_MAC_Base::ProcessBuf() +{ + AccessCipher().ProcessBlock(m_reg); + m_counter = 0; +} + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/cbcmac.h b/CryptoPP/crypto/cbcmac.h new file mode 100644 index 0000000..9e944c6 --- /dev/null +++ b/CryptoPP/crypto/cbcmac.h @@ -0,0 +1,51 @@ +#ifndef CRYPTOPP_CBCMAC_H +#define CRYPTOPP_CBCMAC_H + +#include "seckey.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! _ +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CBC_MAC_Base : public MessageAuthenticationCode +{ +public: + CBC_MAC_Base() {} + + void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms); + void Update(const byte *input, size_t length); + void TruncatedFinal(byte *mac, size_t size); + unsigned int DigestSize() const {return const_cast(this)->AccessCipher().BlockSize();} + +protected: + virtual BlockCipher & AccessCipher() =0; + +private: + void ProcessBuf(); + SecByteBlock m_reg; + unsigned int m_counter; +}; + +//! CBC-MAC +/*! Compatible with FIPS 113. T should be a class derived from BlockCipherDocumentation. + Secure only for fixed length messages. For variable length + messages use DMAC. +*/ +template +class CBC_MAC : public MessageAuthenticationCodeImpl >, public SameKeyLengthAs +{ +public: + CBC_MAC() {} + CBC_MAC(const byte *key, size_t length=SameKeyLengthAs::DEFAULT_KEYLENGTH) + {this->SetKey(key, length);} + + static std::string StaticAlgorithmName() {return std::string("CBC-MAC(") + T::StaticAlgorithmName() + ")";} + +private: + BlockCipher & AccessCipher() {return m_cipher;} + typename T::Encryption m_cipher; +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/channels.cpp b/CryptoPP/crypto/channels.cpp new file mode 100644 index 0000000..e0c5c4f --- /dev/null +++ b/CryptoPP/crypto/channels.cpp @@ -0,0 +1,309 @@ +// channels.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "channels.h" + +NAMESPACE_BEGIN(CryptoPP) +USING_NAMESPACE(std) + +#if 0 +void MessageSwitch::AddDefaultRoute(BufferedTransformation &destination, const std::string &channel) +{ + m_defaultRoutes.push_back(Route(&destination, channel)); +} + +void MessageSwitch::AddRoute(unsigned int begin, unsigned int end, BufferedTransformation &destination, const std::string &channel) +{ + RangeRoute route(begin, end, Route(&destination, channel)); + RouteList::iterator it = upper_bound(m_routes.begin(), m_routes.end(), route); + m_routes.insert(it, route); +} + +/* +class MessageRouteIterator +{ +public: + typedef MessageSwitch::RouteList::const_iterator RouteIterator; + typedef MessageSwitch::DefaultRouteList::const_iterator DefaultIterator; + + bool m_useDefault; + RouteIterator m_itRouteCurrent, m_itRouteEnd; + DefaultIterator m_itDefaultCurrent, m_itDefaultEnd; + + MessageRouteIterator(MessageSwitch &ms, const std::string &channel) + : m_channel(channel) + { + pair range = cs.m_routeMap.equal_range(channel); + if (range.first == range.second) + { + m_useDefault = true; + m_itListCurrent = cs.m_defaultRoutes.begin(); + m_itListEnd = cs.m_defaultRoutes.end(); + } + else + { + m_useDefault = false; + m_itMapCurrent = range.first; + m_itMapEnd = range.second; + } + } + + bool End() const + { + return m_useDefault ? m_itListCurrent == m_itListEnd : m_itMapCurrent == m_itMapEnd; + } + + void Next() + { + if (m_useDefault) + ++m_itListCurrent; + else + ++m_itMapCurrent; + } + + BufferedTransformation & Destination() + { + return m_useDefault ? *m_itListCurrent->first : *m_itMapCurrent->second.first; + } + + const std::string & Message() + { + if (m_useDefault) + return m_itListCurrent->second.get() ? *m_itListCurrent->second.get() : m_channel; + else + return m_itMapCurrent->second.second; + } +}; + +void MessageSwitch::Put(byte inByte); +void MessageSwitch::Put(const byte *inString, unsigned int length); + +void MessageSwitch::Flush(bool completeFlush, int propagation=-1); +void MessageSwitch::MessageEnd(int propagation=-1); +void MessageSwitch::PutMessageEnd(const byte *inString, unsigned int length, int propagation=-1); +void MessageSwitch::MessageSeriesEnd(int propagation=-1); +*/ +#endif + + +// +// ChannelRouteIterator +////////////////////////// + +void ChannelRouteIterator::Reset(const std::string &channel) +{ + m_channel = channel; + pair range = m_cs.m_routeMap.equal_range(channel); + if (range.first == range.second) + { + m_useDefault = true; + m_itListCurrent = m_cs.m_defaultRoutes.begin(); + m_itListEnd = m_cs.m_defaultRoutes.end(); + } + else + { + m_useDefault = false; + m_itMapCurrent = range.first; + m_itMapEnd = range.second; + } +} + +bool ChannelRouteIterator::End() const +{ + return m_useDefault ? m_itListCurrent == m_itListEnd : m_itMapCurrent == m_itMapEnd; +} + +void ChannelRouteIterator::Next() +{ + if (m_useDefault) + ++m_itListCurrent; + else + ++m_itMapCurrent; +} + +BufferedTransformation & ChannelRouteIterator::Destination() +{ + return m_useDefault ? *m_itListCurrent->first : *m_itMapCurrent->second.first; +} + +const std::string & ChannelRouteIterator::Channel() +{ + if (m_useDefault) + return m_itListCurrent->second.get() ? *m_itListCurrent->second.get() : m_channel; + else + return m_itMapCurrent->second.second; +} + + +// +// ChannelSwitch +/////////////////// + +size_t ChannelSwitch::ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking) +{ + if (m_blocked) + { + m_blocked = false; + goto WasBlocked; + } + + m_it.Reset(channel); + + while (!m_it.End()) + { +WasBlocked: + if (m_it.Destination().ChannelPut2(m_it.Channel(), begin, length, messageEnd, blocking)) + { + m_blocked = true; + return 1; + } + + m_it.Next(); + } + + return 0; +} + +void ChannelSwitch::IsolatedInitialize(const NameValuePairs ¶meters/* =g_nullNameValuePairs */) +{ + m_routeMap.clear(); + m_defaultRoutes.clear(); + m_blocked = false; +} + +bool ChannelSwitch::ChannelFlush(const std::string &channel, bool completeFlush, int propagation, bool blocking) +{ + if (m_blocked) + { + m_blocked = false; + goto WasBlocked; + } + + m_it.Reset(channel); + + while (!m_it.End()) + { + WasBlocked: + if (m_it.Destination().ChannelFlush(m_it.Channel(), completeFlush, propagation, blocking)) + { + m_blocked = true; + return true; + } + + m_it.Next(); + } + + return false; +} + +bool ChannelSwitch::ChannelMessageSeriesEnd(const std::string &channel, int propagation, bool blocking) +{ + if (m_blocked) + { + m_blocked = false; + goto WasBlocked; + } + + m_it.Reset(channel); + + while (!m_it.End()) + { + WasBlocked: + if (m_it.Destination().ChannelMessageSeriesEnd(m_it.Channel(), propagation)) + { + m_blocked = true; + return true; + } + + m_it.Next(); + } + + return false; +} + +byte * ChannelSwitch::ChannelCreatePutSpace(const std::string &channel, size_t &size) +{ + m_it.Reset(channel); + if (!m_it.End()) + { + BufferedTransformation &target = m_it.Destination(); + const std::string &channel = m_it.Channel(); + m_it.Next(); + if (m_it.End()) // there is only one target channel + return target.ChannelCreatePutSpace(channel, size); + } + size = 0; + return NULL; +} + +size_t ChannelSwitch::ChannelPutModifiable2(const std::string &channel, byte *inString, size_t length, int messageEnd, bool blocking) +{ + ChannelRouteIterator it(*this); + it.Reset(channel); + + if (!it.End()) + { + BufferedTransformation &target = it.Destination(); + const std::string &targetChannel = it.Channel(); + it.Next(); + if (it.End()) // there is only one target channel + return target.ChannelPutModifiable2(targetChannel, inString, length, messageEnd, blocking); + } + + return ChannelPut2(channel, inString, length, messageEnd, blocking); +} + +void ChannelSwitch::AddDefaultRoute(BufferedTransformation &destination) +{ + m_defaultRoutes.push_back(DefaultRoute(&destination, value_ptr(NULL))); +} + +void ChannelSwitch::RemoveDefaultRoute(BufferedTransformation &destination) +{ + for (DefaultRouteList::iterator it = m_defaultRoutes.begin(); it != m_defaultRoutes.end(); ++it) + if (it->first == &destination && !it->second.get()) + { + m_defaultRoutes.erase(it); + break; + } +} + +void ChannelSwitch::AddDefaultRoute(BufferedTransformation &destination, const std::string &outChannel) +{ + m_defaultRoutes.push_back(DefaultRoute(&destination, outChannel)); +} + +void ChannelSwitch::RemoveDefaultRoute(BufferedTransformation &destination, const std::string &outChannel) +{ + for (DefaultRouteList::iterator it = m_defaultRoutes.begin(); it != m_defaultRoutes.end(); ++it) + if (it->first == &destination && (it->second.get() && *it->second == outChannel)) + { + m_defaultRoutes.erase(it); + break; + } +} + +void ChannelSwitch::AddRoute(const std::string &inChannel, BufferedTransformation &destination, const std::string &outChannel) +{ + m_routeMap.insert(RouteMap::value_type(inChannel, Route(&destination, outChannel))); +} + +void ChannelSwitch::RemoveRoute(const std::string &inChannel, BufferedTransformation &destination, const std::string &outChannel) +{ + typedef ChannelSwitch::RouteMap::iterator MapIterator; + pair range = m_routeMap.equal_range(inChannel); + + for (MapIterator it = range.first; it != range.second; ++it) + if (it->second.first == &destination && it->second.second == outChannel) + { + m_routeMap.erase(it); + break; + } +} + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/channels.h b/CryptoPP/crypto/channels.h new file mode 100644 index 0000000..499a246 --- /dev/null +++ b/CryptoPP/crypto/channels.h @@ -0,0 +1,123 @@ +#ifndef CRYPTOPP_CHANNELS_H +#define CRYPTOPP_CHANNELS_H + +#include "simple.h" +#include "smartptr.h" +#include +#include + +NAMESPACE_BEGIN(CryptoPP) + +#if 0 +//! Route input on default channel to different and/or multiple channels based on message sequence number +class MessageSwitch : public Sink +{ +public: + void AddDefaultRoute(BufferedTransformation &destination, const std::string &channel); + void AddRoute(unsigned int begin, unsigned int end, BufferedTransformation &destination, const std::string &channel); + + void Put(byte inByte); + void Put(const byte *inString, unsigned int length); + + void Flush(bool completeFlush, int propagation=-1); + void MessageEnd(int propagation=-1); + void PutMessageEnd(const byte *inString, unsigned int length, int propagation=-1); + void MessageSeriesEnd(int propagation=-1); + +private: + typedef std::pair Route; + struct RangeRoute + { + RangeRoute(unsigned int begin, unsigned int end, const Route &route) + : begin(begin), end(end), route(route) {} + bool operator<(const RangeRoute &rhs) const {return begin < rhs.begin;} + unsigned int begin, end; + Route route; + }; + + typedef std::list RouteList; + typedef std::list DefaultRouteList; + + RouteList m_routes; + DefaultRouteList m_defaultRoutes; + unsigned int m_nCurrentMessage; +}; +#endif + +class ChannelSwitchTypedefs +{ +public: + typedef std::pair Route; + typedef std::multimap RouteMap; + + typedef std::pair > DefaultRoute; + typedef std::list DefaultRouteList; + + // SunCC workaround: can't use const_iterator here + typedef RouteMap::iterator MapIterator; + typedef DefaultRouteList::iterator ListIterator; +}; + +class ChannelSwitch; + +class ChannelRouteIterator : public ChannelSwitchTypedefs +{ +public: + ChannelSwitch& m_cs; + std::string m_channel; + bool m_useDefault; + MapIterator m_itMapCurrent, m_itMapEnd; + ListIterator m_itListCurrent, m_itListEnd; + + ChannelRouteIterator(ChannelSwitch &cs) : m_cs(cs) {} + void Reset(const std::string &channel); + bool End() const; + void Next(); + BufferedTransformation & Destination(); + const std::string & Channel(); +}; + +//! Route input to different and/or multiple channels based on channel ID +class CRYPTOPP_DLL ChannelSwitch : public Multichannel, public ChannelSwitchTypedefs +{ +public: + ChannelSwitch() : m_it(*this), m_blocked(false) {} + ChannelSwitch(BufferedTransformation &destination) : m_it(*this), m_blocked(false) + { + AddDefaultRoute(destination); + } + ChannelSwitch(BufferedTransformation &destination, const std::string &outChannel) : m_it(*this), m_blocked(false) + { + AddDefaultRoute(destination, outChannel); + } + + void IsolatedInitialize(const NameValuePairs ¶meters=g_nullNameValuePairs); + + size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking); + size_t ChannelPutModifiable2(const std::string &channel, byte *begin, size_t length, int messageEnd, bool blocking); + + bool ChannelFlush(const std::string &channel, bool completeFlush, int propagation=-1, bool blocking=true); + bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true); + + byte * ChannelCreatePutSpace(const std::string &channel, size_t &size); + + void AddDefaultRoute(BufferedTransformation &destination); + void RemoveDefaultRoute(BufferedTransformation &destination); + void AddDefaultRoute(BufferedTransformation &destination, const std::string &outChannel); + void RemoveDefaultRoute(BufferedTransformation &destination, const std::string &outChannel); + void AddRoute(const std::string &inChannel, BufferedTransformation &destination, const std::string &outChannel); + void RemoveRoute(const std::string &inChannel, BufferedTransformation &destination, const std::string &outChannel); + +private: + RouteMap m_routeMap; + DefaultRouteList m_defaultRoutes; + + ChannelRouteIterator m_it; + bool m_blocked; + + friend class ChannelRouteIterator; +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/config.h b/CryptoPP/crypto/config.h new file mode 100644 index 0000000..cc088e3 --- /dev/null +++ b/CryptoPP/crypto/config.h @@ -0,0 +1,454 @@ +#ifndef CRYPTOPP_CONFIG_H +#define CRYPTOPP_CONFIG_H + +// ***************** Important Settings ******************** + +// define this if running on a big-endian CPU +#if !defined(IS_LITTLE_ENDIAN) && (defined(__BIG_ENDIAN__) || defined(__sparc) || defined(__sparc__) || defined(__hppa__) || defined(__mips__) || (defined(__MWERKS__) && !defined(__INTEL__))) +# define IS_BIG_ENDIAN +#endif + +// define this if running on a little-endian CPU +// big endian will be assumed if IS_LITTLE_ENDIAN is not defined +#ifndef IS_BIG_ENDIAN +# define IS_LITTLE_ENDIAN +#endif + +// define this if you want to disable all OS-dependent features, +// such as sockets and OS-provided random number generators +// #define NO_OS_DEPENDENCE + +// Define this to use features provided by Microsoft's CryptoAPI. +// Currently the only feature used is random number generation. +// This macro will be ignored if NO_OS_DEPENDENCE is defined. +#define USE_MS_CRYPTOAPI + +// Define this to 1 to enforce the requirement in FIPS 186-2 Change Notice 1 that only 1024 bit moduli be used +#ifndef DSA_1024_BIT_MODULUS_ONLY +# define DSA_1024_BIT_MODULUS_ONLY 1 +#endif + +// ***************** Less Important Settings *************** + +// define this to retain (as much as possible) old deprecated function and class names +// #define CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY + +#define GZIP_OS_CODE 0 + +// Try this if your CPU has 256K internal cache or a slow multiply instruction +// and you want a (possibly) faster IDEA implementation using log tables +// #define IDEA_LARGECACHE + +// Define this if, for the linear congruential RNG, you want to use +// the original constants as specified in S.K. Park and K.W. Miller's +// CACM paper. +// #define LCRNG_ORIGINAL_NUMBERS + +// choose which style of sockets to wrap (mostly useful for cygwin which has both) +#define PREFER_BERKELEY_STYLE_SOCKETS +// #define PREFER_WINDOWS_STYLE_SOCKETS + +// set the name of Rijndael cipher, was "Rijndael" before version 5.3 +#define CRYPTOPP_RIJNDAEL_NAME "AES" + +// ***************** Important Settings Again ******************** +// But the defaults should be ok. + +// namespace support is now required +#ifdef NO_NAMESPACE +# error namespace support is now required +#endif + +// Define this to workaround a Microsoft CryptoAPI bug where +// each call to CryptAcquireContext causes a 100 KB memory leak. +// Defining this will cause Crypto++ to make only one call to CryptAcquireContext. +#define WORKAROUND_MS_BUG_Q258000 + +#ifdef CRYPTOPP_DOXYGEN_PROCESSING +// Avoid putting "CryptoPP::" in front of everything in Doxygen output +# define CryptoPP +# define NAMESPACE_BEGIN(x) +# define NAMESPACE_END +// Get Doxygen to generate better documentation for these typedefs +# define DOCUMENTED_TYPEDEF(x, y) class y : public x {}; +#else +# define NAMESPACE_BEGIN(x) namespace x { +# define NAMESPACE_END } +# define DOCUMENTED_TYPEDEF(x, y) typedef x y; +#endif +#define ANONYMOUS_NAMESPACE_BEGIN namespace { +#define USING_NAMESPACE(x) using namespace x; +#define DOCUMENTED_NAMESPACE_BEGIN(x) namespace x { +#define DOCUMENTED_NAMESPACE_END } + +// What is the type of the third parameter to bind? +// For Unix, the new standard is ::socklen_t (typically unsigned int), and the old standard is int. +// Unfortunately there is no way to tell whether or not socklen_t is defined. +// To work around this, TYPE_OF_SOCKLEN_T is a macro so that you can change it from the makefile. +#ifndef TYPE_OF_SOCKLEN_T +# if defined(_WIN32) || defined(__CYGWIN__) +# define TYPE_OF_SOCKLEN_T int +# else +# define TYPE_OF_SOCKLEN_T ::socklen_t +# endif +#endif + +#if defined(__CYGWIN__) && defined(PREFER_WINDOWS_STYLE_SOCKETS) +# define __USE_W32_SOCKETS +#endif + +typedef unsigned char byte; // put in global namespace to avoid ambiguity with other byte typedefs + +NAMESPACE_BEGIN(CryptoPP) + +typedef unsigned short word16; +typedef unsigned int word32; + +#if defined(__GNUC__) || defined(__MWERKS__) || defined(__SUNPRO_CC) + #define WORD64_AVAILABLE + typedef unsigned long long word64; + #define W64LIT(x) x##LL +#elif defined(_MSC_VER) || defined(__BORLANDC__) + #define WORD64_AVAILABLE + typedef unsigned __int64 word64; + #define W64LIT(x) x##ui64 +#endif + +// define large word type, used for file offsets and such +#ifdef WORD64_AVAILABLE + typedef word64 lword; + const lword LWORD_MAX = W64LIT(0xffffffffffffffff); +#else + typedef word32 lword; + const lword LWORD_MAX = 0xffffffffUL; +#endif + +// define hword, word, and dword. these are used for multiprecision integer arithmetic +// Intel compiler won't have _umul128 until version 10.0. See http://softwarecommunity.intel.com/isn/Community/en-US/forums/thread/30231625.aspx +#if (defined(_MSC_VER) && (!defined(__INTEL_COMPILER) || __INTEL_COMPILER >= 1000) && (defined(_M_X64) || defined(_M_IA64))) || (defined(__DECCXX) && defined(__alpha__)) || (defined(__INTEL_COMPILER) && defined(__x86_64__)) + typedef word32 hword; + typedef word64 word; +#else + #define CRYPTOPP_NATIVE_DWORD_AVAILABLE + #if defined(__alpha__) || defined(__ia64__) || defined(_ARCH_PPC64) || defined(__x86_64__) || defined(__mips64) || defined(__sparc64__) + #if defined(__GNUC__) && !defined(__INTEL_COMPILER) + typedef word32 hword; + typedef word64 word; + typedef __uint128_t dword; + typedef __uint128_t word128; + #define CRYPTOPP_WORD128_AVAILABLE + #else + // if we're here, it means we're on a 64-bit CPU but we don't have a way to obtain 128-bit multiplication results + typedef word16 hword; + typedef word32 word; + typedef word64 dword; + #endif + #elif defined(WORD64_AVAILABLE) + #define CRYPTOPP_SLOW_WORD64 // use alternative code that avoids word64 + typedef word16 hword; + typedef word32 word; + typedef word64 dword; + #else + typedef byte hword; + typedef word16 word; + typedef word32 dword; + #endif +#endif + +const unsigned int WORD_SIZE = sizeof(word); +const unsigned int WORD_BITS = WORD_SIZE * 8; + +NAMESPACE_END + +#ifndef CRYPTOPP_L1_CACHE_LINE_SIZE + // This should be a lower bound on the L1 cache line size. It's used for defense against timing attacks. + #if defined(_M_X64) || defined(__x86_64__) + #define CRYPTOPP_L1_CACHE_LINE_SIZE 64 + #else + // L1 cache line size is 32 on Pentium III and earlier + #define CRYPTOPP_L1_CACHE_LINE_SIZE 32 + #endif +#endif + +#if defined(_MSC_VER) + #if _MSC_VER == 1200 + #include + #endif + #if _MSC_VER > 1200 || defined(_mm_free) + #define CRYPTOPP_MSVC6PP_OR_LATER // VC 6 processor pack or later + #else + #define CRYPTOPP_MSVC6_NO_PP // VC 6 without processor pack + #endif +#endif + +#ifdef __GNUC__ + #define CRYPTOPP_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) +#endif + +#ifndef CRYPTOPP_ALIGN_DATA + #if defined(CRYPTOPP_MSVC6PP_OR_LATER) + #define CRYPTOPP_ALIGN_DATA(x) __declspec(align(x)) + #elif defined(__GNUC__) || __SUNPRO_CC > 0x580 + #define CRYPTOPP_ALIGN_DATA(x) __attribute__((aligned(x))) + #else + #define CRYPTOPP_ALIGN_DATA(x) + #endif +#endif + +#ifndef CRYPTOPP_SECTION_ALIGN16 + #if defined(__GNUC__) && !defined(__APPLE__) + // the alignment attribute doesn't seem to work without this section attribute when -fdata-sections is turned on + #define CRYPTOPP_SECTION_ALIGN16 __attribute__((section ("CryptoPP_Align16"))) + #else + #define CRYPTOPP_SECTION_ALIGN16 + #endif +#endif + +#if defined(_MSC_VER) || defined(__fastcall) + #define CRYPTOPP_FASTCALL __fastcall +#else + #define CRYPTOPP_FASTCALL +#endif + +// VC60 workaround: it doesn't allow typename in some places +#if defined(_MSC_VER) && (_MSC_VER < 1300) +#define CPP_TYPENAME +#else +#define CPP_TYPENAME typename +#endif + +// VC60 workaround: can't cast unsigned __int64 to float or double +#if defined(_MSC_VER) && !defined(CRYPTOPP_MSVC6PP_OR_LATER) +#define CRYPTOPP_VC6_INT64 (__int64) +#else +#define CRYPTOPP_VC6_INT64 +#endif + +#ifdef _MSC_VER +#define CRYPTOPP_NO_VTABLE __declspec(novtable) +#else +#define CRYPTOPP_NO_VTABLE +#endif + +#ifdef _MSC_VER + // 4231: nonstandard extension used : 'extern' before template explicit instantiation + // 4250: dominance + // 4251: member needs to have dll-interface + // 4275: base needs to have dll-interface + // 4660: explicitly instantiating a class that's already implicitly instantiated + // 4661: no suitable definition provided for explicit template instantiation request + // 4786: identifer was truncated in debug information + // 4355: 'this' : used in base member initializer list + // 4910: '__declspec(dllexport)' and 'extern' are incompatible on an explicit instantiation +# pragma warning(disable: 4231 4250 4251 4275 4660 4661 4786 4355 4910) +#endif + +#ifdef __BORLANDC__ +// 8037: non-const function called for const object. needed to work around BCB2006 bug +# pragma warn -8037 +#endif + +#if (defined(_MSC_VER) && _MSC_VER <= 1300) || defined(__MWERKS__) || defined(_STLPORT_VERSION) +#define CRYPTOPP_DISABLE_UNCAUGHT_EXCEPTION +#endif + +#ifndef CRYPTOPP_DISABLE_UNCAUGHT_EXCEPTION +#define CRYPTOPP_UNCAUGHT_EXCEPTION_AVAILABLE +#endif + +#ifdef CRYPTOPP_DISABLE_X86ASM // for backwards compatibility: this macro had both meanings +#define CRYPTOPP_DISABLE_ASM +#define CRYPTOPP_DISABLE_SSE2 +#endif + +#if !defined(CRYPTOPP_DISABLE_ASM) && ((defined(_MSC_VER) && defined(_M_IX86)) || (defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)))) + #define CRYPTOPP_X86_ASM_AVAILABLE + + #if !defined(CRYPTOPP_DISABLE_SSE2) && (defined(CRYPTOPP_MSVC6PP_OR_LATER) || CRYPTOPP_GCC_VERSION >= 30300) + #define CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE 1 + #else + #define CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE 0 + #endif + + // SSSE3 was actually introduced in GNU as 2.17, which was released 6/23/2006, but we can't tell what version of binutils is installed. + // GCC 4.1.2 was released on 2/13/2007, so we'll use that as a proxy for the binutils version. + #if !defined(CRYPTOPP_DISABLE_SSSE3) && (_MSC_VER >= 1400 || CRYPTOPP_GCC_VERSION >= 40102) + #define CRYPTOPP_BOOL_SSSE3_ASM_AVAILABLE 1 + #else + #define CRYPTOPP_BOOL_SSSE3_ASM_AVAILABLE 0 + #endif +#endif + +#if !defined(CRYPTOPP_DISABLE_ASM) && defined(_MSC_VER) && defined(_M_X64) + #define CRYPTOPP_X64_MASM_AVAILABLE +#endif + +#if !defined(CRYPTOPP_DISABLE_ASM) && defined(__GNUC__) && defined(__x86_64__) + #define CRYPTOPP_X64_ASM_AVAILABLE +#endif + +#if !defined(CRYPTOPP_DISABLE_SSE2) && (defined(CRYPTOPP_MSVC6PP_OR_LATER) || defined(__SSE2__)) + #define CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE 1 +#else + #define CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE 0 +#endif + +// how to allocate 16-byte aligned memory (for SSE2) +#if defined(CRYPTOPP_MSVC6PP_OR_LATER) + #define CRYPTOPP_MM_MALLOC_AVAILABLE +#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) + #define CRYPTOPP_MALLOC_ALIGNMENT_IS_16 +#elif defined(__linux__) || defined(__sun__) || defined(__CYGWIN__) + #define CRYPTOPP_MEMALIGN_AVAILABLE +#else + #define CRYPTOPP_NO_ALIGNED_ALLOC +#endif + +// how to disable inlining +#if defined(_MSC_VER) && _MSC_VER >= 1300 +# define CRYPTOPP_NOINLINE_DOTDOTDOT +# define CRYPTOPP_NOINLINE __declspec(noinline) +#elif defined(__GNUC__) +# define CRYPTOPP_NOINLINE_DOTDOTDOT +# define CRYPTOPP_NOINLINE __attribute__((noinline)) +#else +# define CRYPTOPP_NOINLINE_DOTDOTDOT ... +# define CRYPTOPP_NOINLINE +#endif + +// how to declare class constants +#if defined(_MSC_VER) && _MSC_VER <= 1300 +# define CRYPTOPP_CONSTANT(x) enum {x}; +#else +# define CRYPTOPP_CONSTANT(x) static const int x; +#endif + +#if defined(_M_X64) || defined(__x86_64__) + #define CRYPTOPP_BOOL_X64 1 +#else + #define CRYPTOPP_BOOL_X64 0 +#endif + +// see http://predef.sourceforge.net/prearch.html +#if defined(_M_IX86) || defined(__i386__) || defined(__i386) || defined(_X86_) || defined(__I86__) || defined(__INTEL__) + #define CRYPTOPP_BOOL_X86 1 +#else + #define CRYPTOPP_BOOL_X86 0 +#endif + +#if CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X86 + #define CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS +#endif + +#define CRYPTOPP_VERSION 552 + +// ***************** determine availability of OS features ******************** + +#ifndef NO_OS_DEPENDENCE + +#if defined(_WIN32) || defined(__CYGWIN__) +#define CRYPTOPP_WIN32_AVAILABLE +#endif + +#if defined(__unix__) || defined(__MACH__) || defined(__NetBSD__) || defined(__sun) +#define CRYPTOPP_UNIX_AVAILABLE +#endif + +#if defined(WORD64_AVAILABLE) && (defined(CRYPTOPP_WIN32_AVAILABLE) || defined(CRYPTOPP_UNIX_AVAILABLE)) +# define HIGHRES_TIMER_AVAILABLE +#endif + +#ifdef CRYPTOPP_UNIX_AVAILABLE +# define HAS_BERKELEY_STYLE_SOCKETS +#endif + +#ifdef CRYPTOPP_WIN32_AVAILABLE +# define HAS_WINDOWS_STYLE_SOCKETS +#endif + +#if defined(HIGHRES_TIMER_AVAILABLE) && (defined(HAS_BERKELEY_STYLE_SOCKETS) || defined(HAS_WINDOWS_STYLE_SOCKETS)) +# define SOCKETS_AVAILABLE +#endif + +#if defined(HAS_WINDOWS_STYLE_SOCKETS) && (!defined(HAS_BERKELEY_STYLE_SOCKETS) || defined(PREFER_WINDOWS_STYLE_SOCKETS)) +# define USE_WINDOWS_STYLE_SOCKETS +#else +# define USE_BERKELEY_STYLE_SOCKETS +#endif + +#if defined(HIGHRES_TIMER_AVAILABLE) && defined(CRYPTOPP_WIN32_AVAILABLE) && !defined(USE_BERKELEY_STYLE_SOCKETS) +# define WINDOWS_PIPES_AVAILABLE +#endif + +#if defined(CRYPTOPP_WIN32_AVAILABLE) && defined(USE_MS_CRYPTOAPI) +# define NONBLOCKING_RNG_AVAILABLE +# define OS_RNG_AVAILABLE +#endif + +#if defined(CRYPTOPP_UNIX_AVAILABLE) || defined(CRYPTOPP_DOXYGEN_PROCESSING) +# define NONBLOCKING_RNG_AVAILABLE +# define BLOCKING_RNG_AVAILABLE +# define OS_RNG_AVAILABLE +# define HAS_PTHREADS +# define THREADS_AVAILABLE +#endif + +#ifdef CRYPTOPP_WIN32_AVAILABLE +# define HAS_WINTHREADS +# define THREADS_AVAILABLE +#endif + +#endif // NO_OS_DEPENDENCE + +// ***************** DLL related ******************** + +#ifdef CRYPTOPP_WIN32_AVAILABLE + +#ifdef CRYPTOPP_EXPORTS +#define CRYPTOPP_IS_DLL +#define CRYPTOPP_DLL __declspec(dllexport) +#elif defined(CRYPTOPP_IMPORTS) +#define CRYPTOPP_IS_DLL +#define CRYPTOPP_DLL __declspec(dllimport) +#else +#define CRYPTOPP_DLL +#endif + +#define CRYPTOPP_API __cdecl + +#else // CRYPTOPP_WIN32_AVAILABLE + +#define CRYPTOPP_DLL +#define CRYPTOPP_API + +#endif // CRYPTOPP_WIN32_AVAILABLE + +#if defined(__MWERKS__) +#define CRYPTOPP_EXTERN_DLL_TEMPLATE_CLASS extern class CRYPTOPP_DLL +#elif defined(__BORLANDC__) || defined(__SUNPRO_CC) +#define CRYPTOPP_EXTERN_DLL_TEMPLATE_CLASS template class CRYPTOPP_DLL +#else +#define CRYPTOPP_EXTERN_DLL_TEMPLATE_CLASS extern template class CRYPTOPP_DLL +#endif + +#if defined(CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES) && !defined(CRYPTOPP_IMPORTS) +#define CRYPTOPP_DLL_TEMPLATE_CLASS template class CRYPTOPP_DLL +#else +#define CRYPTOPP_DLL_TEMPLATE_CLASS CRYPTOPP_EXTERN_DLL_TEMPLATE_CLASS +#endif + +#if defined(__MWERKS__) +#define CRYPTOPP_EXTERN_STATIC_TEMPLATE_CLASS extern class +#elif defined(__BORLANDC__) || defined(__SUNPRO_CC) +#define CRYPTOPP_EXTERN_STATIC_TEMPLATE_CLASS template class +#else +#define CRYPTOPP_EXTERN_STATIC_TEMPLATE_CLASS extern template class +#endif + +#if defined(CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES) && !defined(CRYPTOPP_EXPORTS) +#define CRYPTOPP_STATIC_TEMPLATE_CLASS template class +#else +#define CRYPTOPP_STATIC_TEMPLATE_CLASS CRYPTOPP_EXTERN_STATIC_TEMPLATE_CLASS +#endif + +#endif diff --git a/CryptoPP/crypto/cpu.cpp b/CryptoPP/crypto/cpu.cpp new file mode 100644 index 0000000..ab69052 --- /dev/null +++ b/CryptoPP/crypto/cpu.cpp @@ -0,0 +1,199 @@ +// cpu.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "cpu.h" +#include "misc.h" +#include + +#ifdef __GNUC__ +#include +#include +#endif + +#ifdef CRYPTOPP_MSVC6PP_OR_LATER +#include +#endif + +NAMESPACE_BEGIN(CryptoPP) + +#ifdef CRYPTOPP_X86_ASM_AVAILABLE + +#ifndef _MSC_VER +typedef void (*SigHandler)(int); + +static jmp_buf s_jmpNoCPUID; +static void SigIllHandlerCPUID(int) +{ + longjmp(s_jmpNoCPUID, 1); +} +#endif + +bool CpuId(word32 input, word32 *output) +{ +#ifdef _MSC_VER + __try + { + __asm + { + mov eax, input + cpuid + mov edi, output + mov [edi], eax + mov [edi+4], ebx + mov [edi+8], ecx + mov [edi+12], edx + } + } + __except (1) + { + return false; + } + return true; +#else + SigHandler oldHandler = signal(SIGILL, SigIllHandlerCPUID); + if (oldHandler == SIG_ERR) + return false; + + bool result = true; + if (setjmp(s_jmpNoCPUID)) + result = false; + else + { + __asm__ + ( + // save ebx in case -fPIC is being used +#if CRYPTOPP_BOOL_X86 + "push %%ebx; cpuid; mov %%ebx, %%edi; pop %%ebx" +#else + "pushq %%rbx; cpuid; mov %%ebx, %%edi; popq %%rbx" +#endif + : "=a" (output[0]), "=D" (output[1]), "=c" (output[2]), "=d" (output[3]) + : "a" (input) + ); + } + + signal(SIGILL, oldHandler); + return result; +#endif +} + +#ifndef _MSC_VER +static jmp_buf s_jmpNoSSE2; +static void SigIllHandlerSSE2(int) +{ + longjmp(s_jmpNoSSE2, 1); +} +#endif + +#elif _MSC_VER >= 1400 && CRYPTOPP_BOOL_X64 + +bool CpuId(word32 input, word32 *output) +{ + __cpuid((int *)output, input); + return true; +} + +#endif + +#ifdef CRYPTOPP_CPUID_AVAILABLE + +static bool TrySSE2() +{ +#if CRYPTOPP_BOOL_X64 + return true; +#elif defined(_MSC_VER) + __try + { +#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE + AS2(por xmm0, xmm0) // executing SSE2 instruction +#elif CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE + __mm128i x = _mm_setzero_si128(); + return _mm_cvtsi128_si32(x) == 0; +#endif + } + __except (1) + { + return false; + } + return true; +#elif defined(__GNUC__) + SigHandler oldHandler = signal(SIGILL, SigIllHandlerSSE2); + if (oldHandler == SIG_ERR) + return false; + + bool result = true; + if (setjmp(s_jmpNoSSE2)) + result = false; + else + { +#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE + __asm __volatile ("por %xmm0, %xmm0"); +#elif CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE + __mm128i x = _mm_setzero_si128(); + result = _mm_cvtsi128_si32(x) == 0; +#endif + } + + signal(SIGILL, oldHandler); + return result; +#else + return false; +#endif +} + +bool g_x86DetectionDone = false; +bool g_hasISSE = false, g_hasSSE2 = false, g_hasSSSE3 = false, g_hasMMX = false, g_isP4 = false; +word32 g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE; + +void DetectX86Features() +{ + word32 cpuid[4], cpuid1[4]; + if (!CpuId(0, cpuid)) + return; + if (!CpuId(1, cpuid1)) + return; + + g_hasMMX = (cpuid1[3] & (1 << 23)) != 0; + if ((cpuid1[3] & (1 << 26)) != 0) + g_hasSSE2 = TrySSE2(); + g_hasSSSE3 = g_hasSSE2 && (cpuid1[2] & (1<<9)); + + if ((cpuid1[3] & (1 << 25)) != 0) + g_hasISSE = true; + else + { + word32 cpuid2[4]; + CpuId(0x080000000, cpuid2); + if (cpuid2[0] >= 0x080000001) + { + CpuId(0x080000001, cpuid2); + g_hasISSE = (cpuid2[3] & (1 << 22)) != 0; + } + } + + std::swap(cpuid[2], cpuid[3]); + if (memcmp(cpuid+1, "GenuineIntel", 12) == 0) + { + g_isP4 = ((cpuid1[0] >> 8) & 0xf) == 0xf; + g_cacheLineSize = 8 * GETBYTE(cpuid1[1], 1); + } + else if (memcmp(cpuid+1, "AuthenticAMD", 12) == 0) + { + CpuId(0x80000005, cpuid); + g_cacheLineSize = GETBYTE(cpuid[2], 0); + } + + if (!g_cacheLineSize) + g_cacheLineSize = CRYPTOPP_L1_CACHE_LINE_SIZE; + + g_x86DetectionDone = true; +} + +#endif + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/cpu.h b/CryptoPP/crypto/cpu.h new file mode 100644 index 0000000..518e92f --- /dev/null +++ b/CryptoPP/crypto/cpu.h @@ -0,0 +1,260 @@ +#ifndef CRYPTOPP_CPU_H +#define CRYPTOPP_CPU_H + +#ifdef CRYPTOPP_GENERATE_X64_MASM + +#define CRYPTOPP_X86_ASM_AVAILABLE +#define CRYPTOPP_BOOL_X64 1 +#define CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE 1 +#define NAMESPACE_END + +#else + +#include "config.h" + +#ifdef CRYPTOPP_MSVC6PP_OR_LATER + #include +#endif + +NAMESPACE_BEGIN(CryptoPP) + +#if defined(CRYPTOPP_X86_ASM_AVAILABLE) || (_MSC_VER >= 1400 && CRYPTOPP_BOOL_X64) + +#define CRYPTOPP_CPUID_AVAILABLE + +// these should not be used directly +extern CRYPTOPP_DLL bool g_x86DetectionDone; +extern CRYPTOPP_DLL bool g_hasSSE2; +extern CRYPTOPP_DLL bool g_hasISSE; +extern CRYPTOPP_DLL bool g_hasMMX; +extern CRYPTOPP_DLL bool g_hasSSSE3; +extern CRYPTOPP_DLL bool g_isP4; +extern CRYPTOPP_DLL word32 g_cacheLineSize; +CRYPTOPP_DLL void CRYPTOPP_API DetectX86Features(); + +CRYPTOPP_DLL bool CRYPTOPP_API CpuId(word32 input, word32 *output); + +#if CRYPTOPP_BOOL_X64 +inline bool HasSSE2() {return true;} +inline bool HasISSE() {return true;} +inline bool HasMMX() {return true;} +#else + +inline bool HasSSE2() +{ + if (!g_x86DetectionDone) + DetectX86Features(); + return g_hasSSE2; +} + +inline bool HasISSE() +{ + if (!g_x86DetectionDone) + DetectX86Features(); + return g_hasISSE; +} + +inline bool HasMMX() +{ + if (!g_x86DetectionDone) + DetectX86Features(); + return g_hasMMX; +} + +#endif + +inline bool HasSSSE3() +{ + if (!g_x86DetectionDone) + DetectX86Features(); + return g_hasSSSE3; +} + +inline bool IsP4() +{ + if (!g_x86DetectionDone) + DetectX86Features(); + return g_isP4; +} + +inline int GetCacheLineSize() +{ + if (!g_x86DetectionDone) + DetectX86Features(); + return g_cacheLineSize; +} + +#else + +inline int GetCacheLineSize() +{ + return CRYPTOPP_L1_CACHE_LINE_SIZE; +} + +inline bool HasSSSE3() {return false;} +inline bool IsP4() {return false;} + +// assume MMX and SSE2 if intrinsics are enabled +#if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE || CRYPTOPP_BOOL_X64 +inline bool HasSSE2() {return true;} +inline bool HasISSE() {return true;} +inline bool HasMMX() {return true;} +#else +inline bool HasSSE2() {return false;} +inline bool HasISSE() {return false;} +inline bool HasMMX() {return false;} +#endif + +#endif // #ifdef CRYPTOPP_X86_ASM_AVAILABLE || _MSC_VER >= 1400 + +#endif + +#ifdef CRYPTOPP_GENERATE_X64_MASM + #define AS1(x) x*newline* + #define AS2(x, y) x, y*newline* + #define AS3(x, y, z) x, y, z*newline* + #define ASS(x, y, a, b, c, d) x, y, a*64+b*16+c*4+d*newline* + #define ASL(x) label##x:*newline* + #define ASJ(x, y, z) x label##y*newline* + #define ASC(x, y) x label##y*newline* + #define AS_HEX(y) y##h +#elif defined(__GNUC__) + // define these in two steps to allow arguments to be expanded + #define GNU_AS1(x) #x ";" + #define GNU_AS2(x, y) #x ", " #y ";" + #define GNU_AS3(x, y, z) #x ", " #y ", " #z ";" + #define GNU_ASL(x) "\n" #x ":" + #define GNU_ASJ(x, y, z) #x " " #y #z ";" + #define AS1(x) GNU_AS1(x) + #define AS2(x, y) GNU_AS2(x, y) + #define AS3(x, y, z) GNU_AS3(x, y, z) + #define ASS(x, y, a, b, c, d) #x ", " #y ", " #a "*64+" #b "*16+" #c "*4+" #d ";" + #define ASL(x) GNU_ASL(x) + #define ASJ(x, y, z) GNU_ASJ(x, y, z) + #define ASC(x, y) #x " " #y ";" + #define CRYPTOPP_NAKED + #define AS_HEX(y) 0x##y +#else + #define AS1(x) __asm {x} + #define AS2(x, y) __asm {x, y} + #define AS3(x, y, z) __asm {x, y, z} + #define ASS(x, y, a, b, c, d) __asm {x, y, _MM_SHUFFLE(a, b, c, d)} + #define ASL(x) __asm {label##x:} + #define ASJ(x, y, z) __asm {x label##y} + #define ASC(x, y) __asm {x label##y} + #define CRYPTOPP_NAKED __declspec(naked) + #define AS_HEX(y) 0x##y +#endif + +#ifdef CRYPTOPP_GENERATE_X64_MASM +#define ASM_MOD(x, y) ((x) MOD (y)) +#define XMMWORD_PTR XMMWORD PTR +#else +// GNU assembler doesn't seem to have mod operator +#define ASM_MOD(x, y) ((x)-((x)/(y))*(y)) +// GAS 2.15 doesn't support XMMWORD PTR. it seems necessary only for MASM +#define XMMWORD_PTR +#endif + +#if CRYPTOPP_BOOL_X86 + #define AS_REG_1 ecx + #define AS_REG_2 edx + #define AS_REG_3 esi + #define AS_REG_4 edi + #define AS_REG_5 eax + #define AS_REG_6 ebx + #define AS_REG_7 ebp + #define AS_REG_1d ecx + #define AS_REG_2d edx + #define AS_REG_3d esi + #define AS_REG_4d edi + #define AS_REG_5d eax + #define AS_REG_6d ebx + #define AS_REG_7d ebp + #define WORD_SZ 4 + #define WORD_REG(x) e##x + #define WORD_PTR DWORD PTR + #define AS_PUSH_IF86(x) AS1(push e##x) + #define AS_POP_IF86(x) AS1(pop e##x) + #define AS_JCXZ jecxz +#elif CRYPTOPP_BOOL_X64 + #ifdef CRYPTOPP_GENERATE_X64_MASM + #define AS_REG_1 rcx + #define AS_REG_2 rdx + #define AS_REG_3 r8 + #define AS_REG_4 r9 + #define AS_REG_5 rax + #define AS_REG_6 r10 + #define AS_REG_7 r11 + #define AS_REG_1d ecx + #define AS_REG_2d edx + #define AS_REG_3d r8d + #define AS_REG_4d r9d + #define AS_REG_5d eax + #define AS_REG_6d r10d + #define AS_REG_7d r11d + #else + #define AS_REG_1 rdi + #define AS_REG_2 rsi + #define AS_REG_3 rdx + #define AS_REG_4 rcx + #define AS_REG_5 r8 + #define AS_REG_6 r9 + #define AS_REG_7 r10 + #define AS_REG_1d edi + #define AS_REG_2d esi + #define AS_REG_3d edx + #define AS_REG_4d ecx + #define AS_REG_5d r8d + #define AS_REG_6d r9d + #define AS_REG_7d r10d + #endif + #define WORD_SZ 8 + #define WORD_REG(x) r##x + #define WORD_PTR QWORD PTR + #define AS_PUSH_IF86(x) + #define AS_POP_IF86(x) + #define AS_JCXZ jrcxz +#endif + +// helper macro for stream cipher output +#define AS_XMM_OUTPUT4(labelPrefix, inputPtr, outputPtr, x0, x1, x2, x3, t, p0, p1, p2, p3, increment)\ + AS2( test inputPtr, inputPtr)\ + ASC( jz, labelPrefix##3)\ + AS2( test inputPtr, 15)\ + ASC( jnz, labelPrefix##7)\ + AS2( pxor xmm##x0, [inputPtr+p0*16])\ + AS2( pxor xmm##x1, [inputPtr+p1*16])\ + AS2( pxor xmm##x2, [inputPtr+p2*16])\ + AS2( pxor xmm##x3, [inputPtr+p3*16])\ + AS2( add inputPtr, increment*16)\ + ASC( jmp, labelPrefix##3)\ + ASL(labelPrefix##7)\ + AS2( movdqu xmm##t, [inputPtr+p0*16])\ + AS2( pxor xmm##x0, xmm##t)\ + AS2( movdqu xmm##t, [inputPtr+p1*16])\ + AS2( pxor xmm##x1, xmm##t)\ + AS2( movdqu xmm##t, [inputPtr+p2*16])\ + AS2( pxor xmm##x2, xmm##t)\ + AS2( movdqu xmm##t, [inputPtr+p3*16])\ + AS2( pxor xmm##x3, xmm##t)\ + AS2( add inputPtr, increment*16)\ + ASL(labelPrefix##3)\ + AS2( test outputPtr, 15)\ + ASC( jnz, labelPrefix##8)\ + AS2( movdqa [outputPtr+p0*16], xmm##x0)\ + AS2( movdqa [outputPtr+p1*16], xmm##x1)\ + AS2( movdqa [outputPtr+p2*16], xmm##x2)\ + AS2( movdqa [outputPtr+p3*16], xmm##x3)\ + ASC( jmp, labelPrefix##9)\ + ASL(labelPrefix##8)\ + AS2( movdqu [outputPtr+p0*16], xmm##x0)\ + AS2( movdqu [outputPtr+p1*16], xmm##x1)\ + AS2( movdqu [outputPtr+p2*16], xmm##x2)\ + AS2( movdqu [outputPtr+p3*16], xmm##x3)\ + ASL(labelPrefix##9)\ + AS2( add outputPtr, increment*16) + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/crc.cpp b/CryptoPP/crypto/crc.cpp new file mode 100644 index 0000000..3a2cb4f --- /dev/null +++ b/CryptoPP/crypto/crc.cpp @@ -0,0 +1,160 @@ +// crc.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "crc.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +/* Table of CRC-32's of all single byte values (made by makecrc.c) */ +const word32 CRC32::m_tab[] = { +#ifdef IS_LITTLE_ENDIAN + 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, + 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, + 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, + 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, + 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, + 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, + 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, + 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, + 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, + 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, + 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, + 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, + 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, + 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, + 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, + 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, + 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, + 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, + 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, + 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, + 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, + 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, + 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, + 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, + 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, + 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, + 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, + 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, + 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, + 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, + 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, + 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, + 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, + 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, + 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, + 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, + 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, + 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, + 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, + 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, + 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, + 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, + 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, + 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, + 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, + 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, + 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, + 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, + 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, + 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, + 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, + 0x2d02ef8dL +#else + 0x00000000L, 0x96300777L, 0x2c610eeeL, 0xba510999L, 0x19c46d07L, + 0x8ff46a70L, 0x35a563e9L, 0xa395649eL, 0x3288db0eL, 0xa4b8dc79L, + 0x1ee9d5e0L, 0x88d9d297L, 0x2b4cb609L, 0xbd7cb17eL, 0x072db8e7L, + 0x911dbf90L, 0x6410b71dL, 0xf220b06aL, 0x4871b9f3L, 0xde41be84L, + 0x7dd4da1aL, 0xebe4dd6dL, 0x51b5d4f4L, 0xc785d383L, 0x56986c13L, + 0xc0a86b64L, 0x7af962fdL, 0xecc9658aL, 0x4f5c0114L, 0xd96c0663L, + 0x633d0ffaL, 0xf50d088dL, 0xc8206e3bL, 0x5e10694cL, 0xe44160d5L, + 0x727167a2L, 0xd1e4033cL, 0x47d4044bL, 0xfd850dd2L, 0x6bb50aa5L, + 0xfaa8b535L, 0x6c98b242L, 0xd6c9bbdbL, 0x40f9bcacL, 0xe36cd832L, + 0x755cdf45L, 0xcf0dd6dcL, 0x593dd1abL, 0xac30d926L, 0x3a00de51L, + 0x8051d7c8L, 0x1661d0bfL, 0xb5f4b421L, 0x23c4b356L, 0x9995bacfL, + 0x0fa5bdb8L, 0x9eb80228L, 0x0888055fL, 0xb2d90cc6L, 0x24e90bb1L, + 0x877c6f2fL, 0x114c6858L, 0xab1d61c1L, 0x3d2d66b6L, 0x9041dc76L, + 0x0671db01L, 0xbc20d298L, 0x2a10d5efL, 0x8985b171L, 0x1fb5b606L, + 0xa5e4bf9fL, 0x33d4b8e8L, 0xa2c90778L, 0x34f9000fL, 0x8ea80996L, + 0x18980ee1L, 0xbb0d6a7fL, 0x2d3d6d08L, 0x976c6491L, 0x015c63e6L, + 0xf4516b6bL, 0x62616c1cL, 0xd8306585L, 0x4e0062f2L, 0xed95066cL, + 0x7ba5011bL, 0xc1f40882L, 0x57c40ff5L, 0xc6d9b065L, 0x50e9b712L, + 0xeab8be8bL, 0x7c88b9fcL, 0xdf1ddd62L, 0x492dda15L, 0xf37cd38cL, + 0x654cd4fbL, 0x5861b24dL, 0xce51b53aL, 0x7400bca3L, 0xe230bbd4L, + 0x41a5df4aL, 0xd795d83dL, 0x6dc4d1a4L, 0xfbf4d6d3L, 0x6ae96943L, + 0xfcd96e34L, 0x468867adL, 0xd0b860daL, 0x732d0444L, 0xe51d0333L, + 0x5f4c0aaaL, 0xc97c0dddL, 0x3c710550L, 0xaa410227L, 0x10100bbeL, + 0x86200cc9L, 0x25b56857L, 0xb3856f20L, 0x09d466b9L, 0x9fe461ceL, + 0x0ef9de5eL, 0x98c9d929L, 0x2298d0b0L, 0xb4a8d7c7L, 0x173db359L, + 0x810db42eL, 0x3b5cbdb7L, 0xad6cbac0L, 0x2083b8edL, 0xb6b3bf9aL, + 0x0ce2b603L, 0x9ad2b174L, 0x3947d5eaL, 0xaf77d29dL, 0x1526db04L, + 0x8316dc73L, 0x120b63e3L, 0x843b6494L, 0x3e6a6d0dL, 0xa85a6a7aL, + 0x0bcf0ee4L, 0x9dff0993L, 0x27ae000aL, 0xb19e077dL, 0x44930ff0L, + 0xd2a30887L, 0x68f2011eL, 0xfec20669L, 0x5d5762f7L, 0xcb676580L, + 0x71366c19L, 0xe7066b6eL, 0x761bd4feL, 0xe02bd389L, 0x5a7ada10L, + 0xcc4add67L, 0x6fdfb9f9L, 0xf9efbe8eL, 0x43beb717L, 0xd58eb060L, + 0xe8a3d6d6L, 0x7e93d1a1L, 0xc4c2d838L, 0x52f2df4fL, 0xf167bbd1L, + 0x6757bca6L, 0xdd06b53fL, 0x4b36b248L, 0xda2b0dd8L, 0x4c1b0aafL, + 0xf64a0336L, 0x607a0441L, 0xc3ef60dfL, 0x55df67a8L, 0xef8e6e31L, + 0x79be6946L, 0x8cb361cbL, 0x1a8366bcL, 0xa0d26f25L, 0x36e26852L, + 0x95770cccL, 0x03470bbbL, 0xb9160222L, 0x2f260555L, 0xbe3bbac5L, + 0x280bbdb2L, 0x925ab42bL, 0x046ab35cL, 0xa7ffd7c2L, 0x31cfd0b5L, + 0x8b9ed92cL, 0x1daede5bL, 0xb0c2649bL, 0x26f263ecL, 0x9ca36a75L, + 0x0a936d02L, 0xa906099cL, 0x3f360eebL, 0x85670772L, 0x13570005L, + 0x824abf95L, 0x147ab8e2L, 0xae2bb17bL, 0x381bb60cL, 0x9b8ed292L, + 0x0dbed5e5L, 0xb7efdc7cL, 0x21dfdb0bL, 0xd4d2d386L, 0x42e2d4f1L, + 0xf8b3dd68L, 0x6e83da1fL, 0xcd16be81L, 0x5b26b9f6L, 0xe177b06fL, + 0x7747b718L, 0xe65a0888L, 0x706a0fffL, 0xca3b0666L, 0x5c0b0111L, + 0xff9e658fL, 0x69ae62f8L, 0xd3ff6b61L, 0x45cf6c16L, 0x78e20aa0L, + 0xeed20dd7L, 0x5483044eL, 0xc2b30339L, 0x612667a7L, 0xf71660d0L, + 0x4d476949L, 0xdb776e3eL, 0x4a6ad1aeL, 0xdc5ad6d9L, 0x660bdf40L, + 0xf03bd837L, 0x53aebca9L, 0xc59ebbdeL, 0x7fcfb247L, 0xe9ffb530L, + 0x1cf2bdbdL, 0x8ac2bacaL, 0x3093b353L, 0xa6a3b424L, 0x0536d0baL, + 0x9306d7cdL, 0x2957de54L, 0xbf67d923L, 0x2e7a66b3L, 0xb84a61c4L, + 0x021b685dL, 0x942b6f2aL, 0x37be0bb4L, 0xa18e0cc3L, 0x1bdf055aL, + 0x8def022dL +#endif +}; + +CRC32::CRC32() +{ + Reset(); +} + +void CRC32::Update(const byte *s, size_t n) +{ + word32 crc = m_crc; + + for(; !IsAligned(s) && n > 0; n--) + crc = m_tab[CRC32_INDEX(crc) ^ *s++] ^ CRC32_SHIFTED(crc); + + while (n >= 4) + { + crc ^= *(const word32 *)s; + crc = m_tab[CRC32_INDEX(crc)] ^ CRC32_SHIFTED(crc); + crc = m_tab[CRC32_INDEX(crc)] ^ CRC32_SHIFTED(crc); + crc = m_tab[CRC32_INDEX(crc)] ^ CRC32_SHIFTED(crc); + crc = m_tab[CRC32_INDEX(crc)] ^ CRC32_SHIFTED(crc); + n -= 4; + s += 4; + } + + while (n--) + crc = m_tab[CRC32_INDEX(crc) ^ *s++] ^ CRC32_SHIFTED(crc); + + m_crc = crc; +} + +void CRC32::TruncatedFinal(byte *hash, size_t size) +{ + ThrowIfInvalidTruncatedSize(size); + + m_crc ^= CRC32_NEGL; + for (size_t i=0; i> 8) +#else +#define CRC32_INDEX(c) (c >> 24) +#define CRC32_SHIFTED(c) (c << 8) +#endif + +//! CRC Checksum Calculation +class CRC32 : public HashTransformation +{ +public: + CRYPTOPP_CONSTANT(DIGESTSIZE = 4) + CRC32(); + void Update(const byte *input, size_t length); + void TruncatedFinal(byte *hash, size_t size); + unsigned int DigestSize() const {return DIGESTSIZE;} + std::string AlgorithmName() const {return "CRC32";} + + void UpdateByte(byte b) {m_crc = m_tab[CRC32_INDEX(m_crc) ^ b] ^ CRC32_SHIFTED(m_crc);} + byte GetCrcByte(size_t i) const {return ((byte *)&(m_crc))[i];} + +private: + void Reset() {m_crc = CRC32_NEGL;} + + static const word32 m_tab[256]; + word32 m_crc; +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/cryptdll.dsp b/CryptoPP/crypto/cryptdll.dsp new file mode 100644 index 0000000..9362507 --- /dev/null +++ b/CryptoPP/crypto/cryptdll.dsp @@ -0,0 +1,561 @@ +# Microsoft Developer Studio Project File - Name="cryptdll" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=cryptdll - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "cryptdll.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "cryptdll.mak" CFG="cryptdll - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "cryptdll - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "cryptdll - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "cryptdll - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "cryptdll___Win32_Release" +# PROP BASE Intermediate_Dir "cryptdll___Win32_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "DLL_Release" +# PROP Intermediate_Dir "DLL_Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CRYPTDLL_EXPORTS" /YX /FD /c +# ADD CPP /nologo /G5 /MT /W3 /GX /Zi /O1 /Ob2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CRYPTOPP_EXPORTS" /D CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2=1 /D "USE_PRECOMPILED_HEADERS" /Yu"pch.h" /FD /Zm200 /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 advapi32.lib /nologo /base:"0x42900000" /dll /map /debug /machine:I386 /out:"DLL_Release/cryptopp.dll" /opt:ref +# SUBTRACT LINK32 /pdb:none +# Begin Custom Build +OutDir=.\DLL_Release +TargetPath=.\DLL_Release\cryptopp.dll +InputPath=.\DLL_Release\cryptopp.dll +SOURCE="$(InputPath)" + +"$(OutDir)\cryptopp.mac.done" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + CTRelease\cryptest mac_dll $(TargetPath) + echo mac done > $(OutDir)\cryptopp.mac.done + +# End Custom Build + +!ELSEIF "$(CFG)" == "cryptdll - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "cryptdll___Win32_Debug" +# PROP BASE Intermediate_Dir "cryptdll___Win32_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "DLL_Debug" +# PROP Intermediate_Dir "DLL_Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CRYPTDLL_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /G5 /MTd /W3 /Gm /GX /Zi /Oi /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CRYPTOPP_EXPORTS" /D CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2=1 /D "USE_PRECOMPILED_HEADERS" /Yu"pch.h" /FD /GZ /Zm200 /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 advapi32.lib /nologo /base:"0x42900000" /dll /incremental:no /debug /machine:I386 /out:"DLL_Debug/cryptopp.dll" /opt:ref +# SUBTRACT LINK32 /pdb:none +# Begin Custom Build +OutDir=.\DLL_Debug +TargetPath=.\DLL_Debug\cryptopp.dll +InputPath=.\DLL_Debug\cryptopp.dll +SOURCE="$(InputPath)" + +"$(OutDir)\cryptopp.mac.done" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + CTDebug\cryptest mac_dll $(TargetPath) + echo mac done > $(OutDir)\cryptopp.mac.done + +# End Custom Build + +!ENDIF + +# Begin Target + +# Name "cryptdll - Win32 Release" +# Name "cryptdll - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\algebra.cpp +# End Source File +# Begin Source File + +SOURCE=.\algparam.cpp +# End Source File +# Begin Source File + +SOURCE=.\asn.cpp +# End Source File +# Begin Source File + +SOURCE=.\basecode.cpp +# End Source File +# Begin Source File + +SOURCE=.\cbcmac.cpp +# End Source File +# Begin Source File + +SOURCE=.\channels.cpp +# End Source File +# Begin Source File + +SOURCE=.\cpu.cpp +# End Source File +# Begin Source File + +SOURCE=.\cryptlib.cpp +# End Source File +# Begin Source File + +SOURCE=.\des.cpp +# End Source File +# Begin Source File + +SOURCE=.\dessp.cpp +# End Source File +# Begin Source File + +SOURCE=.\dh.cpp +# End Source File +# Begin Source File + +SOURCE=.\dll.cpp +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=.\dsa.cpp +# End Source File +# Begin Source File + +SOURCE=.\ec2n.cpp +# End Source File +# Begin Source File + +SOURCE=.\eccrypto.cpp +# End Source File +# Begin Source File + +SOURCE=.\ecp.cpp +# End Source File +# Begin Source File + +SOURCE=.\emsa2.cpp +# End Source File +# Begin Source File + +SOURCE=.\eprecomp.cpp +# End Source File +# Begin Source File + +SOURCE=.\files.cpp +# End Source File +# Begin Source File + +SOURCE=.\filters.cpp +# End Source File +# Begin Source File + +SOURCE=.\fips140.cpp +# End Source File +# Begin Source File + +SOURCE=.\fipstest.cpp +# End Source File +# Begin Source File + +SOURCE=.\gf2n.cpp +# End Source File +# Begin Source File + +SOURCE=.\gfpcrypt.cpp +# End Source File +# Begin Source File + +SOURCE=.\hex.cpp +# End Source File +# Begin Source File + +SOURCE=.\hmac.cpp +# End Source File +# Begin Source File + +SOURCE=.\hrtimer.cpp +# End Source File +# Begin Source File + +SOURCE=.\integer.cpp +# End Source File +# Begin Source File + +SOURCE=.\iterhash.cpp +# End Source File +# Begin Source File + +SOURCE=.\misc.cpp +# End Source File +# Begin Source File + +SOURCE=.\modes.cpp +# End Source File +# Begin Source File + +SOURCE=.\mqueue.cpp +# End Source File +# Begin Source File + +SOURCE=.\nbtheory.cpp +# End Source File +# Begin Source File + +SOURCE=.\oaep.cpp +# End Source File +# Begin Source File + +SOURCE=.\osrng.cpp +# End Source File +# Begin Source File + +SOURCE=.\pch.cpp +# ADD CPP /Yc"pch.h" +# End Source File +# Begin Source File + +SOURCE=.\pkcspad.cpp +# End Source File +# Begin Source File + +SOURCE=.\pssr.cpp +# End Source File +# Begin Source File + +SOURCE=.\pubkey.cpp +# End Source File +# Begin Source File + +SOURCE=.\queue.cpp +# End Source File +# Begin Source File + +SOURCE=.\randpool.cpp +# End Source File +# Begin Source File + +SOURCE=.\rdtables.cpp +# End Source File +# Begin Source File + +SOURCE=.\rijndael.cpp +# End Source File +# Begin Source File + +SOURCE=.\rng.cpp +# End Source File +# Begin Source File + +SOURCE=.\rsa.cpp +# End Source File +# Begin Source File + +SOURCE=.\rw.cpp +# End Source File +# Begin Source File + +SOURCE=.\sha.cpp +# End Source File +# Begin Source File + +SOURCE=.\simple.cpp +# End Source File +# Begin Source File + +SOURCE=.\skipjack.cpp +# End Source File +# Begin Source File + +SOURCE=.\strciphr.cpp +# End Source File +# Begin Source File + +SOURCE=.\trdlocal.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter ".h" +# Begin Source File + +SOURCE=.\aes.h +# End Source File +# Begin Source File + +SOURCE=.\algebra.h +# End Source File +# Begin Source File + +SOURCE=.\algparam.h +# End Source File +# Begin Source File + +SOURCE=.\argnames.h +# End Source File +# Begin Source File + +SOURCE=.\asn.h +# End Source File +# Begin Source File + +SOURCE=.\basecode.h +# End Source File +# Begin Source File + +SOURCE=.\cbcmac.h +# End Source File +# Begin Source File + +SOURCE=.\channels.h +# End Source File +# Begin Source File + +SOURCE=.\config.h +# End Source File +# Begin Source File + +SOURCE=.\cryptlib.h +# End Source File +# Begin Source File + +SOURCE=.\des.h +# End Source File +# Begin Source File + +SOURCE=.\dh.h +# End Source File +# Begin Source File + +SOURCE=.\dll.h +# End Source File +# Begin Source File + +SOURCE=.\dsa.h +# End Source File +# Begin Source File + +SOURCE=.\ec2n.h +# End Source File +# Begin Source File + +SOURCE=.\eccrypto.h +# End Source File +# Begin Source File + +SOURCE=.\ecp.h +# End Source File +# Begin Source File + +SOURCE=.\eprecomp.h +# End Source File +# Begin Source File + +SOURCE=.\files.h +# End Source File +# Begin Source File + +SOURCE=.\filters.h +# End Source File +# Begin Source File + +SOURCE=.\fips140.h +# End Source File +# Begin Source File + +SOURCE=.\fltrimpl.h +# End Source File +# Begin Source File + +SOURCE=.\gf2n.h +# End Source File +# Begin Source File + +SOURCE=.\gfpcrypt.h +# End Source File +# Begin Source File + +SOURCE=.\hex.h +# End Source File +# Begin Source File + +SOURCE=.\hmac.h +# End Source File +# Begin Source File + +SOURCE=.\integer.h +# End Source File +# Begin Source File + +SOURCE=.\iterhash.h +# End Source File +# Begin Source File + +SOURCE=.\mdc.h +# End Source File +# Begin Source File + +SOURCE=.\misc.h +# End Source File +# Begin Source File + +SOURCE=.\modarith.h +# End Source File +# Begin Source File + +SOURCE=.\modes.h +# End Source File +# Begin Source File + +SOURCE=.\modexppc.h +# End Source File +# Begin Source File + +SOURCE=.\mqueue.h +# End Source File +# Begin Source File + +SOURCE=.\mqv.h +# End Source File +# Begin Source File + +SOURCE=.\nbtheory.h +# End Source File +# Begin Source File + +SOURCE=.\oaep.h +# End Source File +# Begin Source File + +SOURCE=.\oids.h +# End Source File +# Begin Source File + +SOURCE=.\osrng.h +# End Source File +# Begin Source File + +SOURCE=.\pch.h +# End Source File +# Begin Source File + +SOURCE=.\pkcspad.h +# End Source File +# Begin Source File + +SOURCE=.\pubkey.h +# End Source File +# Begin Source File + +SOURCE=.\queue.h +# End Source File +# Begin Source File + +SOURCE=.\randpool.h +# End Source File +# Begin Source File + +SOURCE=.\rijndael.h +# End Source File +# Begin Source File + +SOURCE=.\rng.h +# End Source File +# Begin Source File + +SOURCE=.\rsa.h +# End Source File +# Begin Source File + +SOURCE=.\secblock.h +# End Source File +# Begin Source File + +SOURCE=.\seckey.h +# End Source File +# Begin Source File + +SOURCE=.\sha.h +# End Source File +# Begin Source File + +SOURCE=.\simple.h +# End Source File +# Begin Source File + +SOURCE=.\skipjack.h +# End Source File +# Begin Source File + +SOURCE=.\smartptr.h +# End Source File +# Begin Source File + +SOURCE=.\stdcpp.h +# End Source File +# Begin Source File + +SOURCE=.\strciphr.h +# End Source File +# Begin Source File + +SOURCE=.\trdlocal.h +# End Source File +# Begin Source File + +SOURCE=.\words.h +# End Source File +# End Group +# Begin Source File + +SOURCE=.\cryptopp.rc +# End Source File +# End Target +# End Project diff --git a/CryptoPP/crypto/cryptest.dsp b/CryptoPP/crypto/cryptest.dsp new file mode 100644 index 0000000..e384bc9 --- /dev/null +++ b/CryptoPP/crypto/cryptest.dsp @@ -0,0 +1,431 @@ +# Microsoft Developer Studio Project File - Name="cryptest" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=cryptest - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "cryptest.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "cryptest.mak" CFG="cryptest - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "cryptest - Win32 DLL-Import Release" (based on "Win32 (x86) Console Application") +!MESSAGE "cryptest - Win32 DLL-Import Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "cryptest - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "cryptest - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "cryptest - Win32 DLL-Import Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "cryptest___Win32_FIPS_140_Release" +# PROP BASE Intermediate_Dir "cryptest___Win32_FIPS_140_Release" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "CT_DLL_Import_Release" +# PROP Intermediate_Dir "CT_DLL_Import_Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /G5 /Gz /MT /W3 /GX /Zi /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /Zm200 /c +# ADD CPP /nologo /G5 /Gz /MT /W3 /GX /Zi /O1 /Ob2 /D "NDEBUG" /D "CRYPTOPP_IMPORTS" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /Zm400 /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /OPT:NOWIN98 +# ADD LINK32 Ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /out:"DLL_Release/cryptest.exe" /libpath:"DLL_Release" /OPT:NOWIN98 /OPT:REF /OPT:ICF +# SUBTRACT LINK32 /pdb:none /incremental:yes +# Begin Special Build Tool +SOURCE="$(InputPath)" +PreLink_Cmds=echo This configuration requires cryptopp.dll. echo You can build it yourself using the cryptdll project, or echo obtain a pre-built, FIPS 140-2 validated DLL. If you build it yourself echo the resulting DLL will not be considered FIPS validated echo unless it undergoes FIPS validation. +# End Special Build Tool + +!ELSEIF "$(CFG)" == "cryptest - Win32 DLL-Import Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "cryptest___Win32_FIPS_140_Debug" +# PROP BASE Intermediate_Dir "cryptest___Win32_FIPS_140_Debug" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "CT_DLL_Import_Debug" +# PROP Intermediate_Dir "CT_DLL_Import_Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /Zm200 /c +# ADD CPP /nologo /G5 /Gz /MTd /W3 /GX /Zi /Oi /D "_DEBUG" /D "CRYPTOPP_IMPORTS" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /YX /FD /Zm400 /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib Ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /OPT:NOWIN98 +# ADD LINK32 Ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /out:"DLL_Debug/cryptest.exe" /pdbtype:sept /libpath:"DLL_Debug" /OPT:NOWIN98 +# Begin Special Build Tool +SOURCE="$(InputPath)" +PreLink_Cmds=echo This configuration requires cryptopp.dll. echo You can build it yourself using the cryptdll project, or echo obtain a pre-built, FIPS 140-2 validated DLL. If you build it yourself echo the resulting DLL will not be considered FIPS validated echo unless it undergoes FIPS validation. +# End Special Build Tool + +!ELSEIF "$(CFG)" == "cryptest - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "cryptes0" +# PROP BASE Intermediate_Dir "cryptes0" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "CTRelease" +# PROP Intermediate_Dir "CTRelease" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /Zi /O1 /Ob2 /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "WIN32" /YX /FD /Zm400 /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 advapi32.lib Ws2_32.lib /nologo /subsystem:console /map /debug /machine:I386 /OPT:NOWIN98 /OPT:REF /OPT:ICF +# SUBTRACT LINK32 /pdb:none + +!ELSEIF "$(CFG)" == "cryptest - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "cryptes1" +# PROP BASE Intermediate_Dir "cryptes1" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "CTDebug" +# PROP Intermediate_Dir "CTDebug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MTd /W3 /GX /Zi /Oi /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "WIN32" /YX /FD /Zm400 /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 advapi32.lib Ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /OPT:NOWIN98 +# SUBTRACT LINK32 /pdb:none + +!ENDIF + +# Begin Target + +# Name "cryptest - Win32 DLL-Import Release" +# Name "cryptest - Win32 DLL-Import Debug" +# Name "cryptest - Win32 Release" +# Name "cryptest - Win32 Debug" +# Begin Group "Test Data" + +# PROP Default_Filter ".dat" +# Begin Source File + +SOURCE=.\3desval.dat +# End Source File +# Begin Source File + +SOURCE=.\3wayval.dat +# End Source File +# Begin Source File + +SOURCE=.\camellia.dat +# End Source File +# Begin Source File + +SOURCE=.\cast128v.dat +# End Source File +# Begin Source File + +SOURCE=.\cast256v.dat +# End Source File +# Begin Source File + +SOURCE=.\descert.dat +# End Source File +# Begin Source File + +SOURCE=.\dh1024.dat +# End Source File +# Begin Source File + +SOURCE=.\dh2048.dat +# End Source File +# Begin Source File + +SOURCE=.\diamond.dat +# End Source File +# Begin Source File + +SOURCE=.\dsa1024.dat +# End Source File +# Begin Source File + +SOURCE=.\dsa1024b.dat +# End Source File +# Begin Source File + +SOURCE=.\dsa512.dat +# End Source File +# Begin Source File + +SOURCE=.\elgc1024.dat +# End Source File +# Begin Source File + +SOURCE=.\esig1023.dat +# End Source File +# Begin Source File + +SOURCE=.\esig1536.dat +# End Source File +# Begin Source File + +SOURCE=.\esig2046.dat +# End Source File +# Begin Source File + +SOURCE=.\gostval.dat +# End Source File +# Begin Source File + +SOURCE=.\havalcer.dat +# End Source File +# Begin Source File + +SOURCE=.\ideaval.dat +# End Source File +# Begin Source File + +SOURCE=.\luc1024.dat +# End Source File +# Begin Source File + +SOURCE=.\luc2048.dat +# End Source File +# Begin Source File + +SOURCE=.\lucc1024.dat +# End Source File +# Begin Source File + +SOURCE=.\lucc512.dat +# End Source File +# Begin Source File + +SOURCE=.\lucd1024.dat +# End Source File +# Begin Source File + +SOURCE=.\lucd512.dat +# End Source File +# Begin Source File + +SOURCE=.\lucs1024.dat +# End Source File +# Begin Source File + +SOURCE=.\lucs512.dat +# End Source File +# Begin Source File + +SOURCE=.\marsval.dat +# End Source File +# Begin Source File + +SOURCE=.\mqv1024.dat +# End Source File +# Begin Source File + +SOURCE=.\mqv2048.dat +# End Source File +# Begin Source File + +SOURCE=.\nr1024.dat +# End Source File +# Begin Source File + +SOURCE=.\nr2048.dat +# End Source File +# Begin Source File + +SOURCE=.\rabi1024.dat +# End Source File +# Begin Source File + +SOURCE=.\rabi2048.dat +# End Source File +# Begin Source File + +SOURCE=.\rc2val.dat +# End Source File +# Begin Source File + +SOURCE=.\rc5val.dat +# End Source File +# Begin Source File + +SOURCE=.\rc6val.dat +# End Source File +# Begin Source File + +SOURCE=.\rijndael.dat +# End Source File +# Begin Source File + +SOURCE=.\rsa1024.dat +# End Source File +# Begin Source File + +SOURCE=.\rsa2048.dat +# End Source File +# Begin Source File + +SOURCE=.\rsa400pb.dat +# End Source File +# Begin Source File + +SOURCE=.\rsa400pv.dat +# End Source File +# Begin Source File + +SOURCE=.\rsa512a.dat +# End Source File +# Begin Source File + +SOURCE=.\rw1024.dat +# End Source File +# Begin Source File + +SOURCE=.\rw2048.dat +# End Source File +# Begin Source File + +SOURCE=.\saferval.dat +# End Source File +# Begin Source File + +SOURCE=.\serpentv.dat +# End Source File +# Begin Source File + +SOURCE=.\shacal2v.dat +# End Source File +# Begin Source File + +SOURCE=.\sharkval.dat +# End Source File +# Begin Source File + +SOURCE=.\skipjack.dat +# End Source File +# Begin Source File + +SOURCE=.\squareva.dat +# End Source File +# Begin Source File + +SOURCE=.\twofishv.dat +# End Source File +# Begin Source File + +SOURCE=.\usage.dat +# End Source File +# Begin Source File + +SOURCE=.\xtrdh171.dat +# End Source File +# Begin Source File + +SOURCE=.\xtrdh342.dat +# End Source File +# End Group +# Begin Group "Source Code" + +# PROP Default_Filter ".cpp;.h" +# Begin Source File + +SOURCE=.\adhoc.cpp +# End Source File +# Begin Source File + +SOURCE=.\bench.cpp +# End Source File +# Begin Source File + +SOURCE=.\bench.h +# End Source File +# Begin Source File + +SOURCE=.\bench2.cpp +# End Source File +# Begin Source File + +SOURCE=.\datatest.cpp +# End Source File +# Begin Source File + +SOURCE=.\dlltest.cpp +# End Source File +# Begin Source File + +SOURCE=.\fipsalgt.cpp +# End Source File +# Begin Source File + +SOURCE=.\regtest.cpp +# End Source File +# Begin Source File + +SOURCE=.\test.cpp +# End Source File +# Begin Source File + +SOURCE=.\validat1.cpp +# End Source File +# Begin Source File + +SOURCE=.\validat2.cpp +# End Source File +# Begin Source File + +SOURCE=.\validat3.cpp +# End Source File +# Begin Source File + +SOURCE=.\validate.h +# End Source File +# End Group +# End Target +# End Project diff --git a/CryptoPP/crypto/cryptest.dsw b/CryptoPP/crypto/cryptest.dsw new file mode 100644 index 0000000..a2f1411 --- /dev/null +++ b/CryptoPP/crypto/cryptest.dsw @@ -0,0 +1,74 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "cryptdll"=.\cryptdll.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name cryptest + End Project Dependency +}}} + +############################################################################### + +Project: "cryptest"=.\cryptest.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name cryptlib + End Project Dependency +}}} + +############################################################################### + +Project: "cryptlib"=.\cryptlib.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "dlltest"=.\dlltest.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name cryptdll + End Project Dependency +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CryptoPP/crypto/cryptlib.cpp b/CryptoPP/crypto/cryptlib.cpp new file mode 100644 index 0000000..c91d4e3 --- /dev/null +++ b/CryptoPP/crypto/cryptlib.cpp @@ -0,0 +1,721 @@ +// cryptlib.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "cryptlib.h" +#include "misc.h" +#include "filters.h" +#include "algparam.h" +#include "fips140.h" +#include "argnames.h" +#include "fltrimpl.h" +#include "trdlocal.h" +#include "osrng.h" + +#include + +NAMESPACE_BEGIN(CryptoPP) + +CRYPTOPP_COMPILE_ASSERT(sizeof(byte) == 1); +CRYPTOPP_COMPILE_ASSERT(sizeof(word16) == 2); +CRYPTOPP_COMPILE_ASSERT(sizeof(word32) == 4); +#ifdef WORD64_AVAILABLE +CRYPTOPP_COMPILE_ASSERT(sizeof(word64) == 8); +#endif +#ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE +CRYPTOPP_COMPILE_ASSERT(sizeof(dword) == 2*sizeof(word)); +#endif + +const std::string BufferedTransformation::NULL_CHANNEL; +const NullNameValuePairs g_nullNameValuePairs; + +BufferedTransformation & TheBitBucket() +{ + static BitBucket bitBucket; + return bitBucket; +} + +Algorithm::Algorithm(bool checkSelfTestStatus) +{ + if (checkSelfTestStatus && FIPS_140_2_ComplianceEnabled()) + { + if (GetPowerUpSelfTestStatus() == POWER_UP_SELF_TEST_NOT_DONE && !PowerUpSelfTestInProgressOnThisThread()) + throw SelfTestFailure("Cryptographic algorithms are disabled before the power-up self tests are performed."); + + if (GetPowerUpSelfTestStatus() == POWER_UP_SELF_TEST_FAILED) + throw SelfTestFailure("Cryptographic algorithms are disabled after a power-up self test failed."); + } +} + +void SimpleKeyingInterface::SetKey(const byte *key, size_t length, const NameValuePairs ¶ms) +{ + this->ThrowIfInvalidKeyLength(length); + this->UncheckedSetKey(key, (unsigned int)length, params); +} + +void SimpleKeyingInterface::SetKeyWithRounds(const byte *key, size_t length, int rounds) +{ + SetKey(key, length, MakeParameters(Name::Rounds(), rounds)); +} + +void SimpleKeyingInterface::SetKeyWithIV(const byte *key, size_t length, const byte *iv) +{ + SetKey(key, length, MakeParameters(Name::IV(), iv)); +} + +void SimpleKeyingInterface::ThrowIfInvalidKeyLength(size_t length) +{ + if (!IsValidKeyLength(length)) + throw InvalidKeyLength(GetAlgorithm().AlgorithmName(), length); +} + +void SimpleKeyingInterface::ThrowIfResynchronizable() +{ + if (IsResynchronizable()) + throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": this object requires an IV"); +} + +void SimpleKeyingInterface::ThrowIfInvalidIV(const byte *iv) +{ + if (!iv && !(IVRequirement() == INTERNALLY_GENERATED_IV || IVRequirement() == UNIQUE_IV || !IsResynchronizable())) + throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": this object cannot use a null IV"); +} + +const byte * SimpleKeyingInterface::GetIVAndThrowIfInvalid(const NameValuePairs ¶ms) +{ + const byte *iv; + if (params.GetValue(Name::IV(), iv)) + ThrowIfInvalidIV(iv); + else + ThrowIfResynchronizable(); + return iv; +} + +void SimpleKeyingInterface::GetNextIV(RandomNumberGenerator &rng, byte *IV) +{ + rng.GenerateBlock(IV, IVSize()); +} + +void BlockTransformation::ProcessAndXorMultipleBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t numberOfBlocks) const +{ + unsigned int blockSize = BlockSize(); + while (numberOfBlocks--) + { + ProcessAndXorBlock(inBlocks, xorBlocks, outBlocks); + inBlocks += blockSize; + outBlocks += blockSize; + if (xorBlocks) + xorBlocks += blockSize; + } +} + +unsigned int BlockTransformation::BlockAlignment() const +{ + return GetAlignmentOf(); +} + +void StreamTransformation::ProcessLastBlock(byte *outString, const byte *inString, size_t length) +{ + assert(MinLastBlockSize() == 0); // this function should be overriden otherwise + + if (length == MandatoryBlockSize()) + ProcessData(outString, inString, length); + else if (length != 0) + throw NotImplemented("StreamTransformation: this object does't support a special last block"); +} + +unsigned int RandomNumberGenerator::GenerateBit() +{ + return GenerateByte() & 1; +} + +byte RandomNumberGenerator::GenerateByte() +{ + byte b; + GenerateBlock(&b, 1); + return b; +} + +word32 RandomNumberGenerator::GenerateWord32(word32 min, word32 max) +{ + word32 range = max-min; + const int maxBits = BitPrecision(range); + + word32 value; + + do + { + GenerateBlock((byte *)&value, sizeof(value)); + value = Crop(value, maxBits); + } while (value > range); + + return value+min; +} + +void RandomNumberGenerator::GenerateBlock(byte *output, size_t size) +{ + ArraySink s(output, size); + GenerateIntoBufferedTransformation(s, BufferedTransformation::NULL_CHANNEL, size); +} + +void RandomNumberGenerator::DiscardBytes(size_t n) +{ + GenerateIntoBufferedTransformation(TheBitBucket(), BufferedTransformation::NULL_CHANNEL, n); +} + +void RandomNumberGenerator::GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length) +{ + FixedSizeSecBlock buffer; + while (length) + { + size_t len = UnsignedMin(buffer.size(), length); + GenerateBlock(buffer, len); + target.ChannelPut(channel, buffer, len); + length -= len; + } +} + +//! see NullRNG() +class ClassNullRNG : public RandomNumberGenerator +{ +public: + std::string AlgorithmName() const {return "NullRNG";} + void GenerateBlock(byte *output, size_t size) {throw NotImplemented("NullRNG: NullRNG should only be passed to functions that don't need to generate random bytes");} +}; + +RandomNumberGenerator & NullRNG() +{ + static ClassNullRNG s_nullRNG; + return s_nullRNG; +} + +bool HashTransformation::TruncatedVerify(const byte *digestIn, size_t digestLength) +{ + ThrowIfInvalidTruncatedSize(digestLength); + SecByteBlock digest(digestLength); + TruncatedFinal(digest, digestLength); + return memcmp(digest, digestIn, digestLength) == 0; +} + +void HashTransformation::ThrowIfInvalidTruncatedSize(size_t size) const +{ + if (size > DigestSize()) + throw InvalidArgument("HashTransformation: can't truncate a " + IntToString(DigestSize()) + " byte digest to " + IntToString(size) + " bytes"); +} + +unsigned int BufferedTransformation::GetMaxWaitObjectCount() const +{ + const BufferedTransformation *t = AttachedTransformation(); + return t ? t->GetMaxWaitObjectCount() : 0; +} + +void BufferedTransformation::GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack) +{ + BufferedTransformation *t = AttachedTransformation(); + if (t) + t->GetWaitObjects(container, callStack); // reduce clutter by not adding to stack here +} + +void BufferedTransformation::Initialize(const NameValuePairs ¶meters, int propagation) +{ + assert(!AttachedTransformation()); + IsolatedInitialize(parameters); +} + +bool BufferedTransformation::Flush(bool hardFlush, int propagation, bool blocking) +{ + assert(!AttachedTransformation()); + return IsolatedFlush(hardFlush, blocking); +} + +bool BufferedTransformation::MessageSeriesEnd(int propagation, bool blocking) +{ + assert(!AttachedTransformation()); + return IsolatedMessageSeriesEnd(blocking); +} + +byte * BufferedTransformation::ChannelCreatePutSpace(const std::string &channel, size_t &size) +{ + if (channel.empty()) + return CreatePutSpace(size); + else + throw NoChannelSupport(); +} + +size_t BufferedTransformation::ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking) +{ + if (channel.empty()) + return Put2(begin, length, messageEnd, blocking); + else + throw NoChannelSupport(); +} + +size_t BufferedTransformation::ChannelPutModifiable2(const std::string &channel, byte *begin, size_t length, int messageEnd, bool blocking) +{ + if (channel.empty()) + return PutModifiable2(begin, length, messageEnd, blocking); + else + return ChannelPut2(channel, begin, length, messageEnd, blocking); +} + +bool BufferedTransformation::ChannelFlush(const std::string &channel, bool completeFlush, int propagation, bool blocking) +{ + if (channel.empty()) + return Flush(completeFlush, propagation, blocking); + else + throw NoChannelSupport(); +} + +bool BufferedTransformation::ChannelMessageSeriesEnd(const std::string &channel, int propagation, bool blocking) +{ + if (channel.empty()) + return MessageSeriesEnd(propagation, blocking); + else + throw NoChannelSupport(); +} + +lword BufferedTransformation::MaxRetrievable() const +{ + if (AttachedTransformation()) + return AttachedTransformation()->MaxRetrievable(); + else + return CopyTo(TheBitBucket()); +} + +bool BufferedTransformation::AnyRetrievable() const +{ + if (AttachedTransformation()) + return AttachedTransformation()->AnyRetrievable(); + else + { + byte b; + return Peek(b) != 0; + } +} + +size_t BufferedTransformation::Get(byte &outByte) +{ + if (AttachedTransformation()) + return AttachedTransformation()->Get(outByte); + else + return Get(&outByte, 1); +} + +size_t BufferedTransformation::Get(byte *outString, size_t getMax) +{ + if (AttachedTransformation()) + return AttachedTransformation()->Get(outString, getMax); + else + { + ArraySink arraySink(outString, getMax); + return (size_t)TransferTo(arraySink, getMax); + } +} + +size_t BufferedTransformation::Peek(byte &outByte) const +{ + if (AttachedTransformation()) + return AttachedTransformation()->Peek(outByte); + else + return Peek(&outByte, 1); +} + +size_t BufferedTransformation::Peek(byte *outString, size_t peekMax) const +{ + if (AttachedTransformation()) + return AttachedTransformation()->Peek(outString, peekMax); + else + { + ArraySink arraySink(outString, peekMax); + return (size_t)CopyTo(arraySink, peekMax); + } +} + +lword BufferedTransformation::Skip(lword skipMax) +{ + if (AttachedTransformation()) + return AttachedTransformation()->Skip(skipMax); + else + return TransferTo(TheBitBucket(), skipMax); +} + +lword BufferedTransformation::TotalBytesRetrievable() const +{ + if (AttachedTransformation()) + return AttachedTransformation()->TotalBytesRetrievable(); + else + return MaxRetrievable(); +} + +unsigned int BufferedTransformation::NumberOfMessages() const +{ + if (AttachedTransformation()) + return AttachedTransformation()->NumberOfMessages(); + else + return CopyMessagesTo(TheBitBucket()); +} + +bool BufferedTransformation::AnyMessages() const +{ + if (AttachedTransformation()) + return AttachedTransformation()->AnyMessages(); + else + return NumberOfMessages() != 0; +} + +bool BufferedTransformation::GetNextMessage() +{ + if (AttachedTransformation()) + return AttachedTransformation()->GetNextMessage(); + else + { + assert(!AnyMessages()); + return false; + } +} + +unsigned int BufferedTransformation::SkipMessages(unsigned int count) +{ + if (AttachedTransformation()) + return AttachedTransformation()->SkipMessages(count); + else + return TransferMessagesTo(TheBitBucket(), count); +} + +size_t BufferedTransformation::TransferMessagesTo2(BufferedTransformation &target, unsigned int &messageCount, const std::string &channel, bool blocking) +{ + if (AttachedTransformation()) + return AttachedTransformation()->TransferMessagesTo2(target, messageCount, channel, blocking); + else + { + unsigned int maxMessages = messageCount; + for (messageCount=0; messageCount < maxMessages && AnyMessages(); messageCount++) + { + size_t blockedBytes; + lword transferredBytes; + + while (AnyRetrievable()) + { + transferredBytes = LWORD_MAX; + blockedBytes = TransferTo2(target, transferredBytes, channel, blocking); + if (blockedBytes > 0) + return blockedBytes; + } + + if (target.ChannelMessageEnd(channel, GetAutoSignalPropagation(), blocking)) + return 1; + + bool result = GetNextMessage(); + assert(result); + } + return 0; + } +} + +unsigned int BufferedTransformation::CopyMessagesTo(BufferedTransformation &target, unsigned int count, const std::string &channel) const +{ + if (AttachedTransformation()) + return AttachedTransformation()->CopyMessagesTo(target, count, channel); + else + return 0; +} + +void BufferedTransformation::SkipAll() +{ + if (AttachedTransformation()) + AttachedTransformation()->SkipAll(); + else + { + while (SkipMessages()) {} + while (Skip()) {} + } +} + +size_t BufferedTransformation::TransferAllTo2(BufferedTransformation &target, const std::string &channel, bool blocking) +{ + if (AttachedTransformation()) + return AttachedTransformation()->TransferAllTo2(target, channel, blocking); + else + { + assert(!NumberOfMessageSeries()); + + unsigned int messageCount; + do + { + messageCount = UINT_MAX; + size_t blockedBytes = TransferMessagesTo2(target, messageCount, channel, blocking); + if (blockedBytes) + return blockedBytes; + } + while (messageCount != 0); + + lword byteCount; + do + { + byteCount = ULONG_MAX; + size_t blockedBytes = TransferTo2(target, byteCount, channel, blocking); + if (blockedBytes) + return blockedBytes; + } + while (byteCount != 0); + + return 0; + } +} + +void BufferedTransformation::CopyAllTo(BufferedTransformation &target, const std::string &channel) const +{ + if (AttachedTransformation()) + AttachedTransformation()->CopyAllTo(target, channel); + else + { + assert(!NumberOfMessageSeries()); + while (CopyMessagesTo(target, UINT_MAX, channel)) {} + } +} + +void BufferedTransformation::SetRetrievalChannel(const std::string &channel) +{ + if (AttachedTransformation()) + AttachedTransformation()->SetRetrievalChannel(channel); +} + +size_t BufferedTransformation::ChannelPutWord16(const std::string &channel, word16 value, ByteOrder order, bool blocking) +{ + PutWord(false, order, m_buf, value); + return ChannelPut(channel, m_buf, 2, blocking); +} + +size_t BufferedTransformation::ChannelPutWord32(const std::string &channel, word32 value, ByteOrder order, bool blocking) +{ + PutWord(false, order, m_buf, value); + return ChannelPut(channel, m_buf, 4, blocking); +} + +size_t BufferedTransformation::PutWord16(word16 value, ByteOrder order, bool blocking) +{ + return ChannelPutWord16(NULL_CHANNEL, value, order, blocking); +} + +size_t BufferedTransformation::PutWord32(word32 value, ByteOrder order, bool blocking) +{ + return ChannelPutWord32(NULL_CHANNEL, value, order, blocking); +} + +size_t BufferedTransformation::PeekWord16(word16 &value, ByteOrder order) const +{ + byte buf[2] = {0, 0}; + size_t len = Peek(buf, 2); + + if (order) + value = (buf[0] << 8) | buf[1]; + else + value = (buf[1] << 8) | buf[0]; + + return len; +} + +size_t BufferedTransformation::PeekWord32(word32 &value, ByteOrder order) const +{ + byte buf[4] = {0, 0, 0, 0}; + size_t len = Peek(buf, 4); + + if (order) + value = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf [3]; + else + value = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf [0]; + + return len; +} + +size_t BufferedTransformation::GetWord16(word16 &value, ByteOrder order) +{ + return (size_t)Skip(PeekWord16(value, order)); +} + +size_t BufferedTransformation::GetWord32(word32 &value, ByteOrder order) +{ + return (size_t)Skip(PeekWord32(value, order)); +} + +void BufferedTransformation::Attach(BufferedTransformation *newOut) +{ + if (AttachedTransformation() && AttachedTransformation()->Attachable()) + AttachedTransformation()->Attach(newOut); + else + Detach(newOut); +} + +void GeneratableCryptoMaterial::GenerateRandomWithKeySize(RandomNumberGenerator &rng, unsigned int keySize) +{ + GenerateRandom(rng, MakeParameters("KeySize", (int)keySize)); +} + +class PK_DefaultEncryptionFilter : public Unflushable +{ +public: + PK_DefaultEncryptionFilter(RandomNumberGenerator &rng, const PK_Encryptor &encryptor, BufferedTransformation *attachment, const NameValuePairs ¶meters) + : m_rng(rng), m_encryptor(encryptor), m_parameters(parameters) + { + Detach(attachment); + } + + size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking) + { + FILTER_BEGIN; + m_plaintextQueue.Put(inString, length); + + if (messageEnd) + { + { + size_t plaintextLength; + if (!SafeConvert(m_plaintextQueue.CurrentSize(), plaintextLength)) + throw InvalidArgument("PK_DefaultEncryptionFilter: plaintext too long"); + size_t ciphertextLength = m_encryptor.CiphertextLength(plaintextLength); + + SecByteBlock plaintext(plaintextLength); + m_plaintextQueue.Get(plaintext, plaintextLength); + m_ciphertext.resize(ciphertextLength); + m_encryptor.Encrypt(m_rng, plaintext, plaintextLength, m_ciphertext, m_parameters); + } + + FILTER_OUTPUT(1, m_ciphertext, m_ciphertext.size(), messageEnd); + } + FILTER_END_NO_MESSAGE_END; + } + + RandomNumberGenerator &m_rng; + const PK_Encryptor &m_encryptor; + const NameValuePairs &m_parameters; + ByteQueue m_plaintextQueue; + SecByteBlock m_ciphertext; +}; + +BufferedTransformation * PK_Encryptor::CreateEncryptionFilter(RandomNumberGenerator &rng, BufferedTransformation *attachment, const NameValuePairs ¶meters) const +{ + return new PK_DefaultEncryptionFilter(rng, *this, attachment, parameters); +} + +class PK_DefaultDecryptionFilter : public Unflushable +{ +public: + PK_DefaultDecryptionFilter(RandomNumberGenerator &rng, const PK_Decryptor &decryptor, BufferedTransformation *attachment, const NameValuePairs ¶meters) + : m_rng(rng), m_decryptor(decryptor), m_parameters(parameters) + { + Detach(attachment); + } + + size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking) + { + FILTER_BEGIN; + m_ciphertextQueue.Put(inString, length); + + if (messageEnd) + { + { + size_t ciphertextLength; + if (!SafeConvert(m_ciphertextQueue.CurrentSize(), ciphertextLength)) + throw InvalidArgument("PK_DefaultDecryptionFilter: ciphertext too long"); + size_t maxPlaintextLength = m_decryptor.MaxPlaintextLength(ciphertextLength); + + SecByteBlock ciphertext(ciphertextLength); + m_ciphertextQueue.Get(ciphertext, ciphertextLength); + m_plaintext.resize(maxPlaintextLength); + m_result = m_decryptor.Decrypt(m_rng, ciphertext, ciphertextLength, m_plaintext, m_parameters); + if (!m_result.isValidCoding) + throw InvalidCiphertext(m_decryptor.AlgorithmName() + ": invalid ciphertext"); + } + + FILTER_OUTPUT(1, m_plaintext, m_result.messageLength, messageEnd); + } + FILTER_END_NO_MESSAGE_END; + } + + RandomNumberGenerator &m_rng; + const PK_Decryptor &m_decryptor; + const NameValuePairs &m_parameters; + ByteQueue m_ciphertextQueue; + SecByteBlock m_plaintext; + DecodingResult m_result; +}; + +BufferedTransformation * PK_Decryptor::CreateDecryptionFilter(RandomNumberGenerator &rng, BufferedTransformation *attachment, const NameValuePairs ¶meters) const +{ + return new PK_DefaultDecryptionFilter(rng, *this, attachment, parameters); +} + +size_t PK_Signer::Sign(RandomNumberGenerator &rng, PK_MessageAccumulator *messageAccumulator, byte *signature) const +{ + std::auto_ptr m(messageAccumulator); + return SignAndRestart(rng, *m, signature, false); +} + +size_t PK_Signer::SignMessage(RandomNumberGenerator &rng, const byte *message, size_t messageLen, byte *signature) const +{ + std::auto_ptr m(NewSignatureAccumulator(rng)); + m->Update(message, messageLen); + return SignAndRestart(rng, *m, signature, false); +} + +size_t PK_Signer::SignMessageWithRecovery(RandomNumberGenerator &rng, const byte *recoverableMessage, size_t recoverableMessageLength, + const byte *nonrecoverableMessage, size_t nonrecoverableMessageLength, byte *signature) const +{ + std::auto_ptr m(NewSignatureAccumulator(rng)); + InputRecoverableMessage(*m, recoverableMessage, recoverableMessageLength); + m->Update(nonrecoverableMessage, nonrecoverableMessageLength); + return SignAndRestart(rng, *m, signature, false); +} + +bool PK_Verifier::Verify(PK_MessageAccumulator *messageAccumulator) const +{ + std::auto_ptr m(messageAccumulator); + return VerifyAndRestart(*m); +} + +bool PK_Verifier::VerifyMessage(const byte *message, size_t messageLen, const byte *signature, size_t signatureLength) const +{ + std::auto_ptr m(NewVerificationAccumulator()); + InputSignature(*m, signature, signatureLength); + m->Update(message, messageLen); + return VerifyAndRestart(*m); +} + +DecodingResult PK_Verifier::Recover(byte *recoveredMessage, PK_MessageAccumulator *messageAccumulator) const +{ + std::auto_ptr m(messageAccumulator); + return RecoverAndRestart(recoveredMessage, *m); +} + +DecodingResult PK_Verifier::RecoverMessage(byte *recoveredMessage, + const byte *nonrecoverableMessage, size_t nonrecoverableMessageLength, + const byte *signature, size_t signatureLength) const +{ + std::auto_ptr m(NewVerificationAccumulator()); + InputSignature(*m, signature, signatureLength); + m->Update(nonrecoverableMessage, nonrecoverableMessageLength); + return RecoverAndRestart(recoveredMessage, *m); +} + +void SimpleKeyAgreementDomain::GenerateKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const +{ + GeneratePrivateKey(rng, privateKey); + GeneratePublicKey(rng, privateKey, publicKey); +} + +void AuthenticatedKeyAgreementDomain::GenerateStaticKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const +{ + GenerateStaticPrivateKey(rng, privateKey); + GenerateStaticPublicKey(rng, privateKey, publicKey); +} + +void AuthenticatedKeyAgreementDomain::GenerateEphemeralKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const +{ + GenerateEphemeralPrivateKey(rng, privateKey); + GenerateEphemeralPublicKey(rng, privateKey, publicKey); +} + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/cryptlib.dep b/CryptoPP/crypto/cryptlib.dep new file mode 100644 index 0000000..70fd5ea --- /dev/null +++ b/CryptoPP/crypto/cryptlib.dep @@ -0,0 +1,1968 @@ +# Microsoft Developer Studio Generated Dependency File, included by cryptlib.mak + +.\3way.cpp : \ + ".\3way.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +!IF "$(CFG)" == "cryptlib - Win32 DLL-Import Release" + +!ELSEIF "$(CFG)" == "cryptlib - Win32 DLL-Import Debug" + +!ELSEIF "$(CFG)" == "cryptlib - Win32 Release" + +!ELSEIF "$(CFG)" == "cryptlib - Win32 Debug" + +!ENDIF + +.\adler32.cpp : \ + ".\adler32.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\algebra.cpp : \ + ".\algebra.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\integer.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\algparam.cpp : \ + ".\algparam.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\arc4.cpp : \ + ".\arc4.h"\ + ".\argnames.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + ".\strciphr.h"\ + + +.\asn.cpp : \ + ".\algparam.h"\ + ".\asn.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\filters.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\queue.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\base32.cpp : \ + ".\algparam.h"\ + ".\argnames.h"\ + ".\base32.h"\ + ".\basecode.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\filters.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\queue.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\base64.cpp : \ + ".\algparam.h"\ + ".\argnames.h"\ + ".\base64.h"\ + ".\basecode.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\filters.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\queue.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\basecode.cpp : \ + ".\algparam.h"\ + ".\argnames.h"\ + ".\basecode.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\filters.h"\ + ".\fltrimpl.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\queue.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\bfinit.cpp : \ + ".\blowfish.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\blowfish.cpp : \ + ".\blowfish.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\blumshub.cpp : \ + ".\algebra.h"\ + ".\blumshub.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\integer.h"\ + ".\misc.h"\ + ".\modarith.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\camellia.cpp : \ + ".\camellia.h"\ + ".\config.h"\ + ".\cpu.h"\ + ".\cryptlib.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\cast.cpp : \ + ".\cast.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\casts.cpp : \ + ".\cast.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\cbcmac.cpp : \ + ".\cbcmac.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\channels.cpp : \ + ".\channels.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\cpu.cpp : \ + ".\config.h"\ + ".\cpu.h"\ + ".\cryptlib.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\crc.cpp : \ + ".\config.h"\ + ".\crc.h"\ + ".\cryptlib.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\cryptlib.cpp : \ + ".\aes.h"\ + ".\algparam.h"\ + ".\argnames.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\filters.h"\ + ".\fips140.h"\ + ".\fltrimpl.h"\ + ".\iterhash.h"\ + ".\misc.h"\ + ".\osrng.h"\ + ".\pch.h"\ + ".\queue.h"\ + ".\randpool.h"\ + ".\rijndael.h"\ + ".\rng.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\sha.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + ".\trdlocal.h"\ + + +.\default.cpp : \ + ".\algparam.h"\ + ".\argnames.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\default.h"\ + ".\des.h"\ + ".\filters.h"\ + ".\hmac.h"\ + ".\iterhash.h"\ + ".\misc.h"\ + ".\modes.h"\ + ".\pch.h"\ + ".\queue.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\sha.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + ".\strciphr.h"\ + + +.\des.cpp : \ + ".\config.h"\ + ".\cryptlib.h"\ + ".\des.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\dessp.cpp : \ + ".\config.h"\ + ".\cryptlib.h"\ + ".\des.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\dh.cpp : \ + ".\algebra.h"\ + ".\algparam.h"\ + ".\argnames.h"\ + ".\asn.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\dh.h"\ + ".\eprecomp.h"\ + ".\filters.h"\ + ".\fips140.h"\ + ".\gfpcrypt.h"\ + ".\hmac.h"\ + ".\integer.h"\ + ".\iterhash.h"\ + ".\misc.h"\ + ".\modarith.h"\ + ".\modexppc.h"\ + ".\pch.h"\ + ".\pubkey.h"\ + ".\queue.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\sha.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\dh2.cpp : \ + ".\config.h"\ + ".\cryptlib.h"\ + ".\dh2.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\dll.cpp : \ + ".\algparam.h"\ + ".\argnames.h"\ + ".\basecode.h"\ + ".\config.h"\ + ".\emsa2.h"\ + ".\filters.h"\ + ".\hex.h"\ + ".\hmac.h"\ + ".\mqueue.h"\ + ".\oaep.h"\ + ".\secblock.h"\ + ".\sha.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + ".\strciphr.cpp"\ + ".\strciphr.h"\ + ".\trdlocal.h"\ + + +.\dsa.cpp : \ + ".\algebra.h"\ + ".\algparam.h"\ + ".\argnames.h"\ + ".\asn.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\dsa.h"\ + ".\eprecomp.h"\ + ".\filters.h"\ + ".\fips140.h"\ + ".\gfpcrypt.h"\ + ".\hmac.h"\ + ".\integer.h"\ + ".\iterhash.h"\ + ".\misc.h"\ + ".\modarith.h"\ + ".\modexppc.h"\ + ".\nbtheory.h"\ + ".\pch.h"\ + ".\pubkey.h"\ + ".\queue.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\sha.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\ec2n.cpp : \ + ".\algebra.cpp"\ + ".\algebra.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\integer.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\eccrypto.cpp : \ + ".\algebra.h"\ + ".\algparam.h"\ + ".\argnames.h"\ + ".\asn.h"\ + ".\basecode.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\dh.h"\ + ".\ec2n.h"\ + ".\eccrypto.h"\ + ".\ecp.h"\ + ".\eprecomp.h"\ + ".\filters.h"\ + ".\fips140.h"\ + ".\gf2n.h"\ + ".\gfpcrypt.h"\ + ".\hex.h"\ + ".\hmac.h"\ + ".\integer.h"\ + ".\iterhash.h"\ + ".\misc.h"\ + ".\modarith.h"\ + ".\modexppc.h"\ + ".\mqv.h"\ + ".\nbtheory.h"\ + ".\oids.h"\ + ".\pch.h"\ + ".\pubkey.h"\ + ".\queue.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\sha.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\ecp.cpp : \ + ".\algebra.cpp"\ + ".\algebra.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\integer.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\elgamal.cpp : \ + ".\algebra.h"\ + ".\algparam.h"\ + ".\argnames.h"\ + ".\asn.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\dsa.h"\ + ".\elgamal.h"\ + ".\eprecomp.h"\ + ".\filters.h"\ + ".\fips140.h"\ + ".\gfpcrypt.h"\ + ".\hmac.h"\ + ".\integer.h"\ + ".\iterhash.h"\ + ".\misc.h"\ + ".\modarith.h"\ + ".\modexppc.h"\ + ".\nbtheory.h"\ + ".\pch.h"\ + ".\pubkey.h"\ + ".\queue.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\sha.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\emsa2.cpp : \ + ".\algebra.h"\ + ".\algparam.h"\ + ".\argnames.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\emsa2.h"\ + ".\eprecomp.h"\ + ".\filters.h"\ + ".\fips140.h"\ + ".\integer.h"\ + ".\misc.h"\ + ".\modarith.h"\ + ".\pch.h"\ + ".\pubkey.h"\ + ".\queue.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\eprecomp.cpp : \ + ".\algebra.h"\ + ".\algparam.h"\ + ".\asn.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\eprecomp.h"\ + ".\filters.h"\ + ".\integer.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\queue.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\esign.cpp : \ + ".\algebra.h"\ + ".\algparam.h"\ + ".\argnames.h"\ + ".\asn.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\eprecomp.h"\ + ".\esign.h"\ + ".\filters.h"\ + ".\fips140.h"\ + ".\integer.h"\ + ".\iterhash.h"\ + ".\misc.h"\ + ".\modarith.h"\ + ".\nbtheory.h"\ + ".\pch.h"\ + ".\pubkey.h"\ + ".\queue.h"\ + ".\secblock.h"\ + ".\sha.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\files.cpp : \ + ".\algparam.h"\ + ".\argnames.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\files.h"\ + ".\filters.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\queue.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\filters.cpp : \ + ".\algparam.h"\ + ".\argnames.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\filters.h"\ + ".\fltrimpl.h"\ + ".\misc.h"\ + ".\mqueue.h"\ + ".\pch.h"\ + ".\queue.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\fips140.cpp : \ + ".\config.h"\ + ".\cryptlib.h"\ + ".\fips140.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + ".\trdlocal.h"\ + + +.\fipstest.cpp : \ + ".\aes.h"\ + ".\algebra.h"\ + ".\algparam.h"\ + ".\argnames.h"\ + ".\asn.h"\ + ".\basecode.h"\ + ".\cbcmac.h"\ + ".\channels.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\des.h"\ + ".\dh.h"\ + ".\dll.h"\ + ".\dsa.h"\ + ".\ec2n.h"\ + ".\eccrypto.h"\ + ".\ecp.h"\ + ".\emsa2.h"\ + ".\eprecomp.h"\ + ".\files.h"\ + ".\filters.h"\ + ".\fips140.h"\ + ".\gf2n.h"\ + ".\gfpcrypt.h"\ + ".\hex.h"\ + ".\hmac.h"\ + ".\integer.h"\ + ".\iterhash.h"\ + ".\misc.h"\ + ".\modarith.h"\ + ".\modes.h"\ + ".\modexppc.h"\ + ".\mqueue.h"\ + ".\mqv.h"\ + ".\nbtheory.h"\ + ".\oaep.h"\ + ".\osrng.h"\ + ".\pch.h"\ + ".\pkcspad.h"\ + ".\pssr.h"\ + ".\pubkey.h"\ + ".\queue.h"\ + ".\randpool.h"\ + ".\rijndael.h"\ + ".\rng.h"\ + ".\rsa.h"\ + ".\rw.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\sha.h"\ + ".\simple.h"\ + ".\skipjack.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + ".\strciphr.h"\ + ".\trdlocal.h"\ + + +.\gf256.cpp : \ + ".\config.h"\ + ".\cryptlib.h"\ + ".\gf256.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\gf2_32.cpp : \ + ".\config.h"\ + ".\cryptlib.h"\ + ".\gf2_32.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\gf2n.cpp : \ + ".\algebra.h"\ + ".\algparam.h"\ + ".\asn.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\filters.h"\ + ".\gf2n.h"\ + ".\misc.h"\ + ".\oids.h"\ + ".\pch.h"\ + ".\queue.h"\ + ".\randpool.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + ".\words.h"\ + + +.\gfpcrypt.cpp : \ + ".\algebra.h"\ + ".\algparam.h"\ + ".\argnames.h"\ + ".\asn.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\eprecomp.h"\ + ".\filters.h"\ + ".\fips140.h"\ + ".\gfpcrypt.h"\ + ".\hmac.h"\ + ".\integer.h"\ + ".\iterhash.h"\ + ".\misc.h"\ + ".\modarith.h"\ + ".\modexppc.h"\ + ".\nbtheory.h"\ + ".\oids.h"\ + ".\pch.h"\ + ".\pubkey.h"\ + ".\queue.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\sha.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\gost.cpp : \ + ".\config.h"\ + ".\cryptlib.h"\ + ".\gost.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\gzip.cpp : \ + ".\algparam.h"\ + ".\config.h"\ + ".\crc.h"\ + ".\cryptlib.h"\ + ".\filters.h"\ + ".\gzip.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\queue.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + ".\zdeflate.h"\ + ".\zinflate.h"\ + + +.\hex.cpp : \ + ".\algparam.h"\ + ".\argnames.h"\ + ".\basecode.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\filters.h"\ + ".\hex.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\queue.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\hmac.cpp : \ + ".\config.h"\ + ".\cryptlib.h"\ + ".\hmac.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\hrtimer.cpp : \ + ".\config.h"\ + ".\cryptlib.h"\ + ".\hrtimer.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\ida.cpp : \ + ".\algebra.h"\ + ".\algparam.h"\ + ".\channels.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\filters.h"\ + ".\gf2_32.h"\ + ".\ida.h"\ + ".\misc.h"\ + ".\mqueue.h"\ + ".\pch.h"\ + ".\polynomi.cpp"\ + ".\polynomi.h"\ + ".\queue.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\idea.cpp : \ + ".\config.h"\ + ".\cryptlib.h"\ + ".\idea.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\integer.cpp : \ + ".\algebra.h"\ + ".\algparam.h"\ + ".\argnames.h"\ + ".\asn.h"\ + ".\config.h"\ + ".\cpu.h"\ + ".\cryptlib.h"\ + ".\eprecomp.h"\ + ".\filters.h"\ + ".\fips140.h"\ + ".\integer.h"\ + ".\iterhash.h"\ + ".\misc.h"\ + ".\modarith.h"\ + ".\nbtheory.h"\ + ".\oids.h"\ + ".\pch.h"\ + ".\pubkey.h"\ + ".\queue.h"\ + ".\secblock.h"\ + ".\sha.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + ".\words.h"\ + + +.\iterhash.cpp : \ + ".\config.h"\ + ".\cryptlib.h"\ + ".\iterhash.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\luc.cpp : \ + ".\algebra.h"\ + ".\algparam.h"\ + ".\argnames.h"\ + ".\asn.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\dh.h"\ + ".\eprecomp.h"\ + ".\filters.h"\ + ".\fips140.h"\ + ".\gfpcrypt.h"\ + ".\hmac.h"\ + ".\integer.h"\ + ".\iterhash.h"\ + ".\luc.h"\ + ".\misc.h"\ + ".\modarith.h"\ + ".\modexppc.h"\ + ".\nbtheory.h"\ + ".\oaep.h"\ + ".\pch.h"\ + ".\pkcspad.h"\ + ".\pubkey.h"\ + ".\queue.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\sha.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\mars.cpp : \ + ".\config.h"\ + ".\cryptlib.h"\ + ".\mars.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\marss.cpp : \ + ".\config.h"\ + ".\cryptlib.h"\ + ".\mars.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\md2.cpp : \ + ".\config.h"\ + ".\cryptlib.h"\ + ".\md2.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\md4.cpp : \ + ".\config.h"\ + ".\cryptlib.h"\ + ".\iterhash.h"\ + ".\md4.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\md5.cpp : \ + ".\config.h"\ + ".\cryptlib.h"\ + ".\iterhash.h"\ + ".\md5.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\misc.cpp : \ + ".\config.h"\ + ".\cryptlib.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + ".\words.h"\ + + +.\modes.cpp : \ + ".\algparam.h"\ + ".\argnames.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\misc.h"\ + ".\modes.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + ".\strciphr.h"\ + + +.\mqueue.cpp : \ + ".\algparam.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\filters.h"\ + ".\misc.h"\ + ".\mqueue.h"\ + ".\pch.h"\ + ".\queue.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\mqv.cpp : \ + ".\algebra.h"\ + ".\algparam.h"\ + ".\argnames.h"\ + ".\asn.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\eprecomp.h"\ + ".\filters.h"\ + ".\fips140.h"\ + ".\gfpcrypt.h"\ + ".\hmac.h"\ + ".\integer.h"\ + ".\iterhash.h"\ + ".\misc.h"\ + ".\modarith.h"\ + ".\modexppc.h"\ + ".\mqv.h"\ + ".\pch.h"\ + ".\pubkey.h"\ + ".\queue.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\sha.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\nbtheory.cpp : \ + ".\algebra.h"\ + ".\algparam.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\integer.h"\ + ".\misc.h"\ + ".\modarith.h"\ + ".\nbtheory.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\network.cpp : \ + ".\algparam.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\filters.h"\ + ".\hrtimer.h"\ + ".\misc.h"\ + ".\network.h"\ + ".\pch.h"\ + ".\queue.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + ".\wait.h"\ + + +.\oaep.cpp : \ + ".\algebra.h"\ + ".\algparam.h"\ + ".\argnames.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\eprecomp.h"\ + ".\filters.h"\ + ".\fips140.h"\ + ".\integer.h"\ + ".\iterhash.h"\ + ".\misc.h"\ + ".\modarith.h"\ + ".\oaep.h"\ + ".\pch.h"\ + ".\pubkey.h"\ + ".\queue.h"\ + ".\secblock.h"\ + ".\sha.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\osrng.cpp : \ + ".\aes.h"\ + ".\algparam.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\filters.h"\ + ".\fips140.h"\ + ".\iterhash.h"\ + ".\misc.h"\ + ".\osrng.h"\ + ".\pch.h"\ + ".\queue.h"\ + ".\randpool.h"\ + ".\rijndael.h"\ + ".\rng.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\sha.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\panama.cpp : \ + ".\argnames.h"\ + ".\config.h"\ + ".\cpu.h"\ + ".\cryptlib.h"\ + ".\iterhash.h"\ + ".\misc.h"\ + ".\panama.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + ".\strciphr.h"\ + + +.\pch.cpp : \ + ".\config.h"\ + ".\cryptlib.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\pkcspad.cpp : \ + ".\algebra.h"\ + ".\algparam.h"\ + ".\argnames.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\eprecomp.h"\ + ".\filters.h"\ + ".\fips140.h"\ + ".\integer.h"\ + ".\misc.h"\ + ".\modarith.h"\ + ".\pch.h"\ + ".\pkcspad.h"\ + ".\pubkey.h"\ + ".\queue.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\polynomi.cpp : \ + ".\algebra.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\polynomi.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\pssr.cpp : \ + ".\algebra.h"\ + ".\algparam.h"\ + ".\argnames.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\emsa2.h"\ + ".\eprecomp.h"\ + ".\filters.h"\ + ".\fips140.h"\ + ".\integer.h"\ + ".\misc.h"\ + ".\modarith.h"\ + ".\pch.h"\ + ".\pssr.h"\ + ".\pubkey.h"\ + ".\queue.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\pubkey.cpp : \ + ".\algebra.h"\ + ".\algparam.h"\ + ".\argnames.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\eprecomp.h"\ + ".\filters.h"\ + ".\fips140.h"\ + ".\integer.h"\ + ".\misc.h"\ + ".\modarith.h"\ + ".\pch.h"\ + ".\pubkey.h"\ + ".\queue.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\queue.cpp : \ + ".\algparam.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\filters.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\queue.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\rabin.cpp : \ + ".\algebra.h"\ + ".\algparam.h"\ + ".\argnames.h"\ + ".\asn.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\emsa2.h"\ + ".\eprecomp.h"\ + ".\filters.h"\ + ".\fips140.h"\ + ".\integer.h"\ + ".\iterhash.h"\ + ".\misc.h"\ + ".\modarith.h"\ + ".\nbtheory.h"\ + ".\oaep.h"\ + ".\pch.h"\ + ".\pssr.h"\ + ".\pubkey.h"\ + ".\queue.h"\ + ".\rabin.h"\ + ".\secblock.h"\ + ".\sha.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\randpool.cpp : \ + ".\aes.h"\ + ".\algparam.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\filters.h"\ + ".\hrtimer.h"\ + ".\iterhash.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\queue.h"\ + ".\randpool.h"\ + ".\rijndael.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\sha.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\rc2.cpp : \ + ".\algparam.h"\ + ".\argnames.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\rc2.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\rc5.cpp : \ + ".\config.h"\ + ".\cryptlib.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\rc5.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\rc6.cpp : \ + ".\config.h"\ + ".\cryptlib.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\rc6.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\rdtables.cpp : \ + ".\config.h"\ + ".\cryptlib.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\rijndael.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\rijndael.cpp : \ + ".\config.h"\ + ".\cpu.h"\ + ".\cryptlib.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\rijndael.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\ripemd.cpp : \ + ".\config.h"\ + ".\cryptlib.h"\ + ".\iterhash.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\ripemd.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\rng.cpp : \ + ".\algparam.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\filters.h"\ + ".\fips140.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\queue.h"\ + ".\rng.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\rsa.cpp : \ + ".\algebra.h"\ + ".\algparam.h"\ + ".\argnames.h"\ + ".\asn.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\emsa2.h"\ + ".\eprecomp.h"\ + ".\filters.h"\ + ".\fips140.h"\ + ".\integer.h"\ + ".\iterhash.h"\ + ".\misc.h"\ + ".\modarith.h"\ + ".\nbtheory.h"\ + ".\oaep.h"\ + ".\oids.h"\ + ".\pch.h"\ + ".\pkcspad.h"\ + ".\pubkey.h"\ + ".\queue.h"\ + ".\rsa.h"\ + ".\secblock.h"\ + ".\sha.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\rw.cpp : \ + ".\algebra.h"\ + ".\algparam.h"\ + ".\argnames.h"\ + ".\asn.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\eprecomp.h"\ + ".\filters.h"\ + ".\fips140.h"\ + ".\integer.h"\ + ".\misc.h"\ + ".\modarith.h"\ + ".\nbtheory.h"\ + ".\pch.h"\ + ".\pubkey.h"\ + ".\queue.h"\ + ".\rw.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\safer.cpp : \ + ".\argnames.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\safer.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\salsa.cpp : \ + ".\argnames.h"\ + ".\config.h"\ + ".\cpu.h"\ + ".\cryptlib.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\salsa.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + ".\strciphr.h"\ + + +.\seal.cpp : \ + ".\argnames.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\iterhash.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\seal.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\sha.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + ".\strciphr.h"\ + + +.\serpent.cpp : \ + ".\config.h"\ + ".\cryptlib.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\serpent.h"\ + ".\serpentp.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\sha.cpp : \ + ".\config.h"\ + ".\cpu.h"\ + ".\cryptlib.h"\ + ".\iterhash.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\sha.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\shacal2.cpp : \ + ".\config.h"\ + ".\cryptlib.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\shacal2.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\shark.cpp : \ + ".\algparam.h"\ + ".\argnames.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\gf256.h"\ + ".\misc.h"\ + ".\modes.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\shark.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + ".\strciphr.h"\ + + +.\sharkbox.cpp : \ + ".\config.h"\ + ".\cryptlib.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\shark.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\simple.cpp : \ + ".\config.h"\ + ".\cryptlib.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\skipjack.cpp : \ + ".\config.h"\ + ".\cryptlib.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\simple.h"\ + ".\skipjack.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\socketft.cpp : \ + ".\algparam.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\filters.h"\ + ".\hrtimer.h"\ + ".\misc.h"\ + ".\network.h"\ + ".\pch.h"\ + ".\queue.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\socketft.h"\ + ".\stdcpp.h"\ + ".\wait.h"\ + ".\winpipes.h"\ + + +.\sosemanuk.cpp : \ + ".\argnames.h"\ + ".\config.h"\ + ".\cpu.h"\ + ".\cryptlib.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\serpentp.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\sosemanuk.h"\ + ".\stdcpp.h"\ + ".\strciphr.h"\ + + +.\square.cpp : \ + ".\config.h"\ + ".\cryptlib.h"\ + ".\gf256.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\square.h"\ + ".\stdcpp.h"\ + + +.\squaretb.cpp : \ + ".\config.h"\ + ".\cryptlib.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\square.h"\ + ".\stdcpp.h"\ + + +.\strciphr.cpp : \ + ".\argnames.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + ".\strciphr.h"\ + + +.\tea.cpp : \ + ".\config.h"\ + ".\cryptlib.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + ".\tea.h"\ + + +.\tftables.cpp : \ + ".\config.h"\ + ".\cryptlib.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + ".\twofish.h"\ + + +.\tiger.cpp : \ + ".\config.h"\ + ".\cpu.h"\ + ".\cryptlib.h"\ + ".\iterhash.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + ".\tiger.h"\ + + +.\tigertab.cpp : \ + ".\config.h"\ + ".\cryptlib.h"\ + ".\iterhash.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + ".\tiger.h"\ + + +.\trdlocal.cpp : \ + ".\config.h"\ + ".\cryptlib.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + ".\trdlocal.h"\ + + +.\ttmac.cpp : \ + ".\config.h"\ + ".\cryptlib.h"\ + ".\iterhash.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + ".\ttmac.h"\ + + +.\twofish.cpp : \ + ".\config.h"\ + ".\cryptlib.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + ".\twofish.h"\ + + +.\vmac.cpp : \ + ".\argnames.h"\ + ".\config.h"\ + ".\cpu.h"\ + ".\cryptlib.h"\ + ".\iterhash.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + ".\vmac.h"\ + + +.\wait.cpp : \ + ".\config.h"\ + ".\cryptlib.h"\ + ".\hrtimer.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + ".\wait.h"\ + + +.\wake.cpp : \ + ".\argnames.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\seckey.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + ".\strciphr.h"\ + ".\wake.h"\ + + +.\whrlpool.cpp : \ + ".\config.h"\ + ".\cpu.h"\ + ".\cryptlib.h"\ + ".\iterhash.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + ".\whrlpool.h"\ + + +.\winpipes.cpp : \ + ".\algparam.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\filters.h"\ + ".\hrtimer.h"\ + ".\misc.h"\ + ".\network.h"\ + ".\pch.h"\ + ".\queue.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + ".\wait.h"\ + ".\winpipes.h"\ + + +.\xtr.cpp : \ + ".\algebra.cpp"\ + ".\algebra.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\integer.h"\ + ".\pch.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + + +.\xtrcrypt.cpp : \ + ".\algebra.h"\ + ".\algparam.h"\ + ".\argnames.h"\ + ".\asn.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\filters.h"\ + ".\integer.h"\ + ".\misc.h"\ + ".\modarith.h"\ + ".\nbtheory.h"\ + ".\pch.h"\ + ".\queue.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + ".\xtr.h"\ + ".\xtrcrypt.h"\ + + +.\zdeflate.cpp : \ + ".\algparam.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\filters.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\queue.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + ".\zdeflate.h"\ + + +.\zinflate.cpp : \ + ".\algparam.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\filters.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\queue.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + ".\zinflate.h"\ + + +.\zlib.cpp : \ + ".\adler32.h"\ + ".\algparam.h"\ + ".\config.h"\ + ".\cryptlib.h"\ + ".\filters.h"\ + ".\misc.h"\ + ".\pch.h"\ + ".\queue.h"\ + ".\secblock.h"\ + ".\simple.h"\ + ".\smartptr.h"\ + ".\stdcpp.h"\ + ".\zdeflate.h"\ + ".\zinflate.h"\ + ".\zlib.h"\ + diff --git a/CryptoPP/crypto/cryptlib.dsp b/CryptoPP/crypto/cryptlib.dsp new file mode 100644 index 0000000..8f6b1a3 --- /dev/null +++ b/CryptoPP/crypto/cryptlib.dsp @@ -0,0 +1,1155 @@ +# Microsoft Developer Studio Project File - Name="cryptlib" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=cryptlib - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "cryptlib.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "cryptlib.mak" CFG="cryptlib - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "cryptlib - Win32 DLL-Import Release" (based on "Win32 (x86) Static Library") +!MESSAGE "cryptlib - Win32 DLL-Import Debug" (based on "Win32 (x86) Static Library") +!MESSAGE "cryptlib - Win32 Release" (based on "Win32 (x86) Static Library") +!MESSAGE "cryptlib - Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "cryptlib - Win32 DLL-Import Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "cryptlib___Win32_FIPS_140_Release" +# PROP BASE Intermediate_Dir "cryptlib___Win32_FIPS_140_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "DLL_Import_Release" +# PROP Intermediate_Dir "DLL_Import_Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /G5 /Gz /MT /W3 /GX /Zi /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "USE_PRECOMPILED_HEADERS" /Yu"pch.h" /FD /c +# ADD CPP /nologo /G5 /Gz /MT /W3 /GX /Zi /O2 /Ob2 /D "NDEBUG" /D "_WINDOWS" /D "USE_PRECOMPILED_HEADERS" /D "WIN32" /D "CRYPTOPP_IMPORTS" /Yu"pch.h" /FD /Zm400 /c +# ADD BASE RSC /l 0x409 +# ADD RSC /l 0x409 +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "cryptlib - Win32 DLL-Import Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "cryptlib___Win32_FIPS_140_Debug" +# PROP BASE Intermediate_Dir "cryptlib___Win32_FIPS_140_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "DLL_Import_Debug" +# PROP Intermediate_Dir "DLL_Import_Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "USE_PRECOMPILED_HEADERS" /Yu"pch.h" /FD /c +# ADD CPP /nologo /G5 /Gz /MTd /W3 /GX /Zi /Oi /D "_DEBUG" /D "_WINDOWS" /D "USE_PRECOMPILED_HEADERS" /D "WIN32" /D "CRYPTOPP_IMPORTS" /Yu"pch.h" /FD /Zm400 /c +# ADD BASE RSC /l 0x409 +# ADD RSC /l 0x409 +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "cryptlib - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "cryptlib" +# PROP BASE Intermediate_Dir "cryptlib" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /Zi /O1 /Ob1 /D "NDEBUG" /D "_WINDOWS" /D "USE_PRECOMPILED_HEADERS" /D "WIN32" /Yu"pch.h" /FD /Zm400 /c +# ADD BASE RSC /l 0x409 +# ADD RSC /l 0x409 +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "cryptlib - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "cryptli0" +# PROP BASE Intermediate_Dir "cryptli0" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /FD /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Oi /D "_DEBUG" /D "_WINDOWS" /D "USE_PRECOMPILED_HEADERS" /D "WIN32" /Yu"pch.h" /FD /Zm400 /c +# ADD BASE RSC /l 0x409 +# ADD RSC /l 0x409 +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ENDIF + +# Begin Target + +# Name "cryptlib - Win32 DLL-Import Release" +# Name "cryptlib - Win32 DLL-Import Debug" +# Name "cryptlib - Win32 Release" +# Name "cryptlib - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter ".cpp" +# Begin Source File + +SOURCE=.\3way.cpp +# End Source File +# Begin Source File + +SOURCE=.\adhoc.cpp.proto + +!IF "$(CFG)" == "cryptlib - Win32 DLL-Import Release" + +# Begin Custom Build +InputPath=.\adhoc.cpp.proto + +"adhoc.cpp.copied" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + if not exist adhoc.cpp copy "$(InputPath)" adhoc.cpp + echo: >> adhoc.cpp.copied + +# End Custom Build + +!ELSEIF "$(CFG)" == "cryptlib - Win32 DLL-Import Debug" + +# Begin Custom Build +InputPath=.\adhoc.cpp.proto + +"adhoc.cpp.copied" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + if not exist adhoc.cpp copy "$(InputPath)" adhoc.cpp + echo: >> adhoc.cpp.copied + +# End Custom Build + +!ELSEIF "$(CFG)" == "cryptlib - Win32 Release" + +# Begin Custom Build +InputPath=.\adhoc.cpp.proto + +"adhoc.cpp.copied" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + if not exist adhoc.cpp copy "$(InputPath)" adhoc.cpp + echo: >> adhoc.cpp.copied + +# End Custom Build + +!ELSEIF "$(CFG)" == "cryptlib - Win32 Debug" + +# Begin Custom Build +InputPath=.\adhoc.cpp.proto + +"adhoc.cpp.copied" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + if not exist adhoc.cpp copy "$(InputPath)" adhoc.cpp + echo: >> adhoc.cpp.copied + +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\adler32.cpp +# End Source File +# Begin Source File + +SOURCE=.\algebra.cpp +# End Source File +# Begin Source File + +SOURCE=.\algparam.cpp +# End Source File +# Begin Source File + +SOURCE=.\arc4.cpp +# End Source File +# Begin Source File + +SOURCE=.\asn.cpp +# End Source File +# Begin Source File + +SOURCE=.\base32.cpp +# End Source File +# Begin Source File + +SOURCE=.\base64.cpp +# End Source File +# Begin Source File + +SOURCE=.\basecode.cpp +# End Source File +# Begin Source File + +SOURCE=.\bfinit.cpp +# End Source File +# Begin Source File + +SOURCE=.\blowfish.cpp +# End Source File +# Begin Source File + +SOURCE=.\blumshub.cpp +# End Source File +# Begin Source File + +SOURCE=.\camellia.cpp +# End Source File +# Begin Source File + +SOURCE=.\cast.cpp +# End Source File +# Begin Source File + +SOURCE=.\casts.cpp +# End Source File +# Begin Source File + +SOURCE=.\cbcmac.cpp +# End Source File +# Begin Source File + +SOURCE=.\channels.cpp +# End Source File +# Begin Source File + +SOURCE=.\cpu.cpp +# End Source File +# Begin Source File + +SOURCE=.\crc.cpp +# End Source File +# Begin Source File + +SOURCE=.\cryptlib.cpp +# End Source File +# Begin Source File + +SOURCE=.\default.cpp +# End Source File +# Begin Source File + +SOURCE=.\des.cpp +# End Source File +# Begin Source File + +SOURCE=.\dessp.cpp +# End Source File +# Begin Source File + +SOURCE=.\dh.cpp +# End Source File +# Begin Source File + +SOURCE=.\dh2.cpp +# End Source File +# Begin Source File + +SOURCE=.\dll.cpp +# SUBTRACT CPP /YX /Yc /Yu +# End Source File +# Begin Source File + +SOURCE=.\dsa.cpp +# End Source File +# Begin Source File + +SOURCE=.\ec2n.cpp +# End Source File +# Begin Source File + +SOURCE=.\eccrypto.cpp +# End Source File +# Begin Source File + +SOURCE=.\ecp.cpp +# End Source File +# Begin Source File + +SOURCE=.\elgamal.cpp +# End Source File +# Begin Source File + +SOURCE=.\emsa2.cpp +# End Source File +# Begin Source File + +SOURCE=.\eprecomp.cpp +# End Source File +# Begin Source File + +SOURCE=.\esign.cpp +# End Source File +# Begin Source File + +SOURCE=.\files.cpp +# End Source File +# Begin Source File + +SOURCE=.\filters.cpp +# End Source File +# Begin Source File + +SOURCE=.\fips140.cpp +# End Source File +# Begin Source File + +SOURCE=.\fipstest.cpp +# End Source File +# Begin Source File + +SOURCE=.\gf256.cpp +# End Source File +# Begin Source File + +SOURCE=.\gf2_32.cpp +# End Source File +# Begin Source File + +SOURCE=.\gf2n.cpp +# End Source File +# Begin Source File + +SOURCE=.\gfpcrypt.cpp +# End Source File +# Begin Source File + +SOURCE=.\gost.cpp +# End Source File +# Begin Source File + +SOURCE=.\gzip.cpp +# End Source File +# Begin Source File + +SOURCE=.\hex.cpp +# End Source File +# Begin Source File + +SOURCE=.\hmac.cpp +# End Source File +# Begin Source File + +SOURCE=.\hrtimer.cpp +# End Source File +# Begin Source File + +SOURCE=.\ida.cpp +# End Source File +# Begin Source File + +SOURCE=.\idea.cpp +# End Source File +# Begin Source File + +SOURCE=.\integer.cpp +# End Source File +# Begin Source File + +SOURCE=.\iterhash.cpp +# End Source File +# Begin Source File + +SOURCE=.\luc.cpp +# End Source File +# Begin Source File + +SOURCE=.\mars.cpp +# End Source File +# Begin Source File + +SOURCE=.\marss.cpp +# End Source File +# Begin Source File + +SOURCE=.\md2.cpp +# End Source File +# Begin Source File + +SOURCE=.\md4.cpp +# End Source File +# Begin Source File + +SOURCE=.\md5.cpp +# End Source File +# Begin Source File + +SOURCE=.\misc.cpp +# End Source File +# Begin Source File + +SOURCE=.\modes.cpp +# End Source File +# Begin Source File + +SOURCE=.\mqueue.cpp +# End Source File +# Begin Source File + +SOURCE=.\mqv.cpp +# End Source File +# Begin Source File + +SOURCE=.\nbtheory.cpp +# End Source File +# Begin Source File + +SOURCE=.\network.cpp +# End Source File +# Begin Source File + +SOURCE=.\oaep.cpp +# End Source File +# Begin Source File + +SOURCE=.\osrng.cpp +# End Source File +# Begin Source File + +SOURCE=.\panama.cpp +# End Source File +# Begin Source File + +SOURCE=.\pch.cpp +# ADD CPP /Yc"pch.h" +# End Source File +# Begin Source File + +SOURCE=.\pkcspad.cpp +# End Source File +# Begin Source File + +SOURCE=.\polynomi.cpp +# End Source File +# Begin Source File + +SOURCE=.\pssr.cpp +# End Source File +# Begin Source File + +SOURCE=.\pubkey.cpp +# End Source File +# Begin Source File + +SOURCE=.\queue.cpp +# End Source File +# Begin Source File + +SOURCE=.\rabin.cpp +# End Source File +# Begin Source File + +SOURCE=.\randpool.cpp +# End Source File +# Begin Source File + +SOURCE=.\rc2.cpp +# End Source File +# Begin Source File + +SOURCE=.\rc5.cpp +# End Source File +# Begin Source File + +SOURCE=.\rc6.cpp +# End Source File +# Begin Source File + +SOURCE=.\rdtables.cpp +# End Source File +# Begin Source File + +SOURCE=.\rijndael.cpp +# End Source File +# Begin Source File + +SOURCE=.\ripemd.cpp +# End Source File +# Begin Source File + +SOURCE=.\rng.cpp +# End Source File +# Begin Source File + +SOURCE=.\rsa.cpp +# End Source File +# Begin Source File + +SOURCE=.\rw.cpp +# End Source File +# Begin Source File + +SOURCE=.\safer.cpp +# End Source File +# Begin Source File + +SOURCE=.\salsa.cpp +# End Source File +# Begin Source File + +SOURCE=.\seal.cpp +# End Source File +# Begin Source File + +SOURCE=.\serpent.cpp +# End Source File +# Begin Source File + +SOURCE=.\sha.cpp +# End Source File +# Begin Source File + +SOURCE=.\shacal2.cpp +# End Source File +# Begin Source File + +SOURCE=.\shark.cpp +# End Source File +# Begin Source File + +SOURCE=.\sharkbox.cpp +# End Source File +# Begin Source File + +SOURCE=.\simple.cpp +# End Source File +# Begin Source File + +SOURCE=.\skipjack.cpp +# End Source File +# Begin Source File + +SOURCE=.\socketft.cpp +# End Source File +# Begin Source File + +SOURCE=.\sosemanuk.cpp +# End Source File +# Begin Source File + +SOURCE=.\square.cpp +# End Source File +# Begin Source File + +SOURCE=.\squaretb.cpp +# End Source File +# Begin Source File + +SOURCE=.\strciphr.cpp +# End Source File +# Begin Source File + +SOURCE=.\tea.cpp +# End Source File +# Begin Source File + +SOURCE=.\tftables.cpp +# End Source File +# Begin Source File + +SOURCE=.\tiger.cpp +# End Source File +# Begin Source File + +SOURCE=.\tigertab.cpp +# End Source File +# Begin Source File + +SOURCE=.\trdlocal.cpp +# End Source File +# Begin Source File + +SOURCE=.\ttmac.cpp +# End Source File +# Begin Source File + +SOURCE=.\twofish.cpp +# End Source File +# Begin Source File + +SOURCE=.\vmac.cpp +# End Source File +# Begin Source File + +SOURCE=.\wait.cpp +# End Source File +# Begin Source File + +SOURCE=.\wake.cpp +# End Source File +# Begin Source File + +SOURCE=.\whrlpool.cpp +# End Source File +# Begin Source File + +SOURCE=.\winpipes.cpp +# End Source File +# Begin Source File + +SOURCE=.\xtr.cpp +# End Source File +# Begin Source File + +SOURCE=.\xtrcrypt.cpp +# End Source File +# Begin Source File + +SOURCE=.\zdeflate.cpp +# End Source File +# Begin Source File + +SOURCE=.\zinflate.cpp +# End Source File +# Begin Source File + +SOURCE=.\zlib.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter ".;.h" +# Begin Source File + +SOURCE=.\3way.h +# End Source File +# Begin Source File + +SOURCE=.\adler32.h +# End Source File +# Begin Source File + +SOURCE=.\aes.h +# End Source File +# Begin Source File + +SOURCE=.\algebra.h +# End Source File +# Begin Source File + +SOURCE=.\algparam.h +# End Source File +# Begin Source File + +SOURCE=.\arc4.h +# End Source File +# Begin Source File + +SOURCE=.\argnames.h +# End Source File +# Begin Source File + +SOURCE=.\asn.h +# End Source File +# Begin Source File + +SOURCE=.\base32.h +# End Source File +# Begin Source File + +SOURCE=.\base64.h +# End Source File +# Begin Source File + +SOURCE=.\basecode.h +# End Source File +# Begin Source File + +SOURCE=.\blowfish.h +# End Source File +# Begin Source File + +SOURCE=.\blumshub.h +# End Source File +# Begin Source File + +SOURCE=.\camellia.h +# End Source File +# Begin Source File + +SOURCE=.\cast.h +# End Source File +# Begin Source File + +SOURCE=.\cbcmac.h +# End Source File +# Begin Source File + +SOURCE=.\channels.h +# End Source File +# Begin Source File + +SOURCE=.\config.h +# End Source File +# Begin Source File + +SOURCE=.\crc.h +# End Source File +# Begin Source File + +SOURCE=.\cryptlib.h +# End Source File +# Begin Source File + +SOURCE=.\default.h +# End Source File +# Begin Source File + +SOURCE=.\des.h +# End Source File +# Begin Source File + +SOURCE=.\dh.h +# End Source File +# Begin Source File + +SOURCE=.\dh2.h +# End Source File +# Begin Source File + +SOURCE=.\dmac.h +# End Source File +# Begin Source File + +SOURCE=.\dsa.h +# End Source File +# Begin Source File + +SOURCE=.\dword.h +# End Source File +# Begin Source File + +SOURCE=.\ec2n.h +# End Source File +# Begin Source File + +SOURCE=.\eccrypto.h +# End Source File +# Begin Source File + +SOURCE=.\ecp.h +# End Source File +# Begin Source File + +SOURCE=.\elgamal.h +# End Source File +# Begin Source File + +SOURCE=.\emsa2.h +# End Source File +# Begin Source File + +SOURCE=.\eprecomp.h +# End Source File +# Begin Source File + +SOURCE=.\esign.h +# End Source File +# Begin Source File + +SOURCE=.\factory.h +# End Source File +# Begin Source File + +SOURCE=.\files.h +# End Source File +# Begin Source File + +SOURCE=.\filters.h +# End Source File +# Begin Source File + +SOURCE=.\fips140.h +# End Source File +# Begin Source File + +SOURCE=.\fltrimpl.h +# End Source File +# Begin Source File + +SOURCE=.\gf256.h +# End Source File +# Begin Source File + +SOURCE=.\gf2_32.h +# End Source File +# Begin Source File + +SOURCE=.\gf2n.h +# End Source File +# Begin Source File + +SOURCE=.\gfpcrypt.h +# End Source File +# Begin Source File + +SOURCE=.\gost.h +# End Source File +# Begin Source File + +SOURCE=.\gzip.h +# End Source File +# Begin Source File + +SOURCE=.\hex.h +# End Source File +# Begin Source File + +SOURCE=.\hmac.h +# End Source File +# Begin Source File + +SOURCE=.\hrtimer.h +# End Source File +# Begin Source File + +SOURCE=.\ida.h +# End Source File +# Begin Source File + +SOURCE=.\idea.h +# End Source File +# Begin Source File + +SOURCE=.\integer.h +# End Source File +# Begin Source File + +SOURCE=.\iterhash.h +# End Source File +# Begin Source File + +SOURCE=.\lubyrack.h +# End Source File +# Begin Source File + +SOURCE=.\luc.h +# End Source File +# Begin Source File + +SOURCE=.\mars.h +# End Source File +# Begin Source File + +SOURCE=.\md2.h +# End Source File +# Begin Source File + +SOURCE=.\md4.h +# End Source File +# Begin Source File + +SOURCE=.\md5.h +# End Source File +# Begin Source File + +SOURCE=.\mdc.h +# End Source File +# Begin Source File + +SOURCE=.\misc.h +# End Source File +# Begin Source File + +SOURCE=.\modarith.h +# End Source File +# Begin Source File + +SOURCE=.\modes.h +# End Source File +# Begin Source File + +SOURCE=.\modexppc.h +# End Source File +# Begin Source File + +SOURCE=.\mqueue.h +# End Source File +# Begin Source File + +SOURCE=.\mqv.h +# End Source File +# Begin Source File + +SOURCE=.\nbtheory.h +# End Source File +# Begin Source File + +SOURCE=.\network.h +# End Source File +# Begin Source File + +SOURCE=.\nr.h +# End Source File +# Begin Source File + +SOURCE=.\oaep.h +# End Source File +# Begin Source File + +SOURCE=.\oids.h +# End Source File +# Begin Source File + +SOURCE=.\osrng.h +# End Source File +# Begin Source File + +SOURCE=.\panama.h +# End Source File +# Begin Source File + +SOURCE=.\pch.h +# End Source File +# Begin Source File + +SOURCE=.\pkcspad.h +# End Source File +# Begin Source File + +SOURCE=.\polynomi.h +# End Source File +# Begin Source File + +SOURCE=.\pssr.h +# End Source File +# Begin Source File + +SOURCE=.\pubkey.h +# End Source File +# Begin Source File + +SOURCE=.\pwdbased.h +# End Source File +# Begin Source File + +SOURCE=.\queue.h +# End Source File +# Begin Source File + +SOURCE=.\rabin.h +# End Source File +# Begin Source File + +SOURCE=.\randpool.h +# End Source File +# Begin Source File + +SOURCE=.\rc2.h +# End Source File +# Begin Source File + +SOURCE=.\rc5.h +# End Source File +# Begin Source File + +SOURCE=.\rc6.h +# End Source File +# Begin Source File + +SOURCE=.\rijndael.h +# End Source File +# Begin Source File + +SOURCE=.\ripemd.h +# End Source File +# Begin Source File + +SOURCE=.\rng.h +# End Source File +# Begin Source File + +SOURCE=.\rsa.h +# End Source File +# Begin Source File + +SOURCE=.\rw.h +# End Source File +# Begin Source File + +SOURCE=.\safer.h +# End Source File +# Begin Source File + +SOURCE=.\salsa.h +# End Source File +# Begin Source File + +SOURCE=.\seal.h +# End Source File +# Begin Source File + +SOURCE=.\secblock.h +# End Source File +# Begin Source File + +SOURCE=.\seckey.h +# End Source File +# Begin Source File + +SOURCE=.\serpent.h +# End Source File +# Begin Source File + +SOURCE=.\sha.h +# End Source File +# Begin Source File + +SOURCE=.\shacal2.h +# End Source File +# Begin Source File + +SOURCE=.\shark.h +# End Source File +# Begin Source File + +SOURCE=.\simple.h +# End Source File +# Begin Source File + +SOURCE=.\skipjack.h +# End Source File +# Begin Source File + +SOURCE=.\smartptr.h +# End Source File +# Begin Source File + +SOURCE=.\socketft.h +# End Source File +# Begin Source File + +SOURCE=.\square.h +# End Source File +# Begin Source File + +SOURCE=.\strciphr.h +# End Source File +# Begin Source File + +SOURCE=.\tea.h +# End Source File +# Begin Source File + +SOURCE=.\tiger.h +# End Source File +# Begin Source File + +SOURCE=.\trdlocal.h +# End Source File +# Begin Source File + +SOURCE=.\trunhash.h +# End Source File +# Begin Source File + +SOURCE=.\ttmac.h +# End Source File +# Begin Source File + +SOURCE=.\twofish.h +# End Source File +# Begin Source File + +SOURCE=.\wait.h +# End Source File +# Begin Source File + +SOURCE=.\wake.h +# End Source File +# Begin Source File + +SOURCE=.\whrlpool.h +# End Source File +# Begin Source File + +SOURCE=.\winpipes.h +# End Source File +# Begin Source File + +SOURCE=.\words.h +# End Source File +# Begin Source File + +SOURCE=.\xtr.h +# End Source File +# Begin Source File + +SOURCE=.\xtrcrypt.h +# End Source File +# Begin Source File + +SOURCE=.\zdeflate.h +# End Source File +# Begin Source File + +SOURCE=.\zinflate.h +# End Source File +# Begin Source File + +SOURCE=.\zlib.h +# End Source File +# End Group +# Begin Group "Miscellaneous" + +# PROP Default_Filter "" +# Begin Source File + +SOURCE=.\Doxyfile +# End Source File +# Begin Source File + +SOURCE=.\GNUmakefile +# End Source File +# Begin Source File + +SOURCE=.\license.txt +# End Source File +# Begin Source File + +SOURCE=.\readme.txt +# End Source File +# End Group +# End Target +# End Project diff --git a/CryptoPP/crypto/cryptlib.h b/CryptoPP/crypto/cryptlib.h new file mode 100644 index 0000000..8949e03 --- /dev/null +++ b/CryptoPP/crypto/cryptlib.h @@ -0,0 +1,1608 @@ +// cryptlib.h - written and placed in the public domain by Wei Dai +/*! \file + This file contains the declarations for the abstract base + classes that provide a uniform interface to this library. +*/ + +/*! \mainpage Crypto++® Library 5.5.2 Reference Manual +
+
Abstract Base Classes
+ cryptlib.h +
Symmetric Ciphers
+ SymmetricCipherDocumentation +
Hash Functions
+ SHA1, SHA224, SHA256, SHA384, SHA512, Tiger, Whirlpool, RIPEMD160, RIPEMD320, RIPEMD128, RIPEMD256, Weak1::MD2, Weak1::MD4, Weak1::MD5 +
Non-Cryptographic Checksums
+ CRC32, Adler32 +
Message Authentication Codes
+ VMAC, HMAC, CBC_MAC, DMAC, TTMAC +
Random Number Generators
+ NullRNG(), LC_RNG, RandomPool, BlockingRng, NonblockingRng, AutoSeededRandomPool, AutoSeededX917RNG, DefaultAutoSeededRNG +
Password-based Cryptography
+ PasswordBasedKeyDerivationFunction +
Public Key Cryptosystems
+ DLIES, ECIES, LUCES, RSAES, RabinES, LUC_IES +
Public Key Signature Schemes
+ DSA, GDSA, ECDSA, NR, ECNR, LUCSS, RSASS, RSASS_ISO, RabinSS, RWSS, ESIGN +
Key Agreement
+ #DH, DH2, #MQV, ECDH, ECMQV, XTR_DH +
Algebraic Structures
+ Integer, PolynomialMod2, PolynomialOver, RingOfPolynomialsOver, + ModularArithmetic, MontgomeryRepresentation, GFP2_ONB, + GF2NP, GF256, GF2_32, EC2N, ECP +
Secret Sharing and Information Dispersal
+ SecretSharing, SecretRecovery, InformationDispersal, InformationRecovery +
Compression
+ Deflator, Inflator, Gzip, Gunzip, ZlibCompressor, ZlibDecompressor +
Input Source Classes
+ StringSource, ArraySource, FileSource, SocketSource, WindowsPipeSource, RandomNumberSource +
Output Sink Classes
+ StringSinkTemplate, ArraySink, FileSink, SocketSink, WindowsPipeSink, RandomNumberSink +
Filter Wrappers
+ StreamTransformationFilter, HashFilter, HashVerificationFilter, SignerFilter, SignatureVerificationFilter +
Binary to Text Encoders and Decoders
+ HexEncoder, HexDecoder, Base64Encoder, Base64Decoder, Base32Encoder, Base32Decoder +
Wrappers for OS features
+ Timer, Socket, WindowsHandle, ThreadLocalStorage, ThreadUserTimer +
FIPS 140 related
+ fips140.h +
+ +In the FIPS 140-2 validated DLL version of Crypto++, only the following implementation class are available. +
+
Block Ciphers
+ AES, DES_EDE2, DES_EDE3, SKIPJACK +
Cipher Modes (replace template parameter BC with one of the block ciphers above)
+ ECB_Mode\, CTR_Mode\, CBC_Mode\, CFB_FIPS_Mode\, OFB_Mode\ +
Hash Functions
+ SHA1, SHA224, SHA256, SHA384, SHA512 +
Public Key Signature Schemes (replace template parameter H with one of the hash functions above)
+ RSASS\, RSASS\, RSASS_ISO\, RWSS\, DSA, ECDSA\, ECDSA\ +
Message Authentication Codes (replace template parameter H with one of the hash functions above)
+ HMAC\, CBC_MAC\, CBC_MAC\ +
Random Number Generators
+ DefaultAutoSeededRNG (AutoSeededX917RNG\) +
Key Agreement
+ #DH +
Public Key Cryptosystems
+ RSAES\ \> +
+ +

This reference manual is a work in progress. Some classes are still lacking detailed descriptions. +

Click here to download a zip archive containing this manual. +

Thanks to Ryan Phillips for providing the Doxygen configuration file +and getting me started with this manual. +*/ + +#ifndef CRYPTOPP_CRYPTLIB_H +#define CRYPTOPP_CRYPTLIB_H + +#include "config.h" +#include "stdcpp.h" + +NAMESPACE_BEGIN(CryptoPP) + +// forward declarations +class Integer; +class RandomNumberGenerator; +class BufferedTransformation; + +//! used to specify a direction for a cipher to operate in (encrypt or decrypt) +enum CipherDir {ENCRYPTION, DECRYPTION}; + +//! used to represent infinite time +const unsigned long INFINITE_TIME = ULONG_MAX; + +// VC60 workaround: using enums as template parameters causes problems +template +struct EnumToType +{ + static ENUM_TYPE ToEnum() {return (ENUM_TYPE)VALUE;} +}; + +enum ByteOrder {LITTLE_ENDIAN_ORDER = 0, BIG_ENDIAN_ORDER = 1}; +typedef EnumToType LittleEndian; +typedef EnumToType BigEndian; + +//! base class for all exceptions thrown by Crypto++ +class CRYPTOPP_DLL Exception : public std::exception +{ +public: + //! error types + enum ErrorType { + //! a method is not implemented + NOT_IMPLEMENTED, + //! invalid function argument + INVALID_ARGUMENT, + //! BufferedTransformation received a Flush(true) signal but can't flush buffers + CANNOT_FLUSH, + //! data integerity check (such as CRC or MAC) failed + DATA_INTEGRITY_CHECK_FAILED, + //! received input data that doesn't conform to expected format + INVALID_DATA_FORMAT, + //! error reading from input device or writing to output device + IO_ERROR, + //! some error not belong to any of the above categories + OTHER_ERROR + }; + + explicit Exception(ErrorType errorType, const std::string &s) : m_errorType(errorType), m_what(s) {} + virtual ~Exception() throw() {} + const char *what() const throw() {return (m_what.c_str());} + const std::string &GetWhat() const {return m_what;} + void SetWhat(const std::string &s) {m_what = s;} + ErrorType GetErrorType() const {return m_errorType;} + void SetErrorType(ErrorType errorType) {m_errorType = errorType;} + +private: + ErrorType m_errorType; + std::string m_what; +}; + +//! exception thrown when an invalid argument is detected +class CRYPTOPP_DLL InvalidArgument : public Exception +{ +public: + explicit InvalidArgument(const std::string &s) : Exception(INVALID_ARGUMENT, s) {} +}; + +//! exception thrown when input data is received that doesn't conform to expected format +class CRYPTOPP_DLL InvalidDataFormat : public Exception +{ +public: + explicit InvalidDataFormat(const std::string &s) : Exception(INVALID_DATA_FORMAT, s) {} +}; + +//! exception thrown by decryption filters when trying to decrypt an invalid ciphertext +class CRYPTOPP_DLL InvalidCiphertext : public InvalidDataFormat +{ +public: + explicit InvalidCiphertext(const std::string &s) : InvalidDataFormat(s) {} +}; + +//! exception thrown by a class if a non-implemented method is called +class CRYPTOPP_DLL NotImplemented : public Exception +{ +public: + explicit NotImplemented(const std::string &s) : Exception(NOT_IMPLEMENTED, s) {} +}; + +//! exception thrown by a class when Flush(true) is called but it can't completely flush its buffers +class CRYPTOPP_DLL CannotFlush : public Exception +{ +public: + explicit CannotFlush(const std::string &s) : Exception(CANNOT_FLUSH, s) {} +}; + +//! error reported by the operating system +class CRYPTOPP_DLL OS_Error : public Exception +{ +public: + OS_Error(ErrorType errorType, const std::string &s, const std::string& operation, int errorCode) + : Exception(errorType, s), m_operation(operation), m_errorCode(errorCode) {} + ~OS_Error() throw() {} + + // the operating system API that reported the error + const std::string & GetOperation() const {return m_operation;} + // the error code return by the operating system + int GetErrorCode() const {return m_errorCode;} + +protected: + std::string m_operation; + int m_errorCode; +}; + +//! used to return decoding results +struct CRYPTOPP_DLL DecodingResult +{ + explicit DecodingResult() : isValidCoding(false), messageLength(0) {} + explicit DecodingResult(size_t len) : isValidCoding(true), messageLength(len) {} + + bool operator==(const DecodingResult &rhs) const {return isValidCoding == rhs.isValidCoding && messageLength == rhs.messageLength;} + bool operator!=(const DecodingResult &rhs) const {return !operator==(rhs);} + + bool isValidCoding; + size_t messageLength; + +#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY + operator size_t() const {return isValidCoding ? messageLength : 0;} +#endif +}; + +//! interface for retrieving values given their names +/*! \note This class is used to safely pass a variable number of arbitrarily typed arguments to functions + and to read values from keys and crypto parameters. + \note To obtain an object that implements NameValuePairs for the purpose of parameter + passing, use the MakeParameters() function. + \note To get a value from NameValuePairs, you need to know the name and the type of the value. + Call GetValueNames() on a NameValuePairs object to obtain a list of value names that it supports. + Then look at the Name namespace documentation to see what the type of each value is, or + alternatively, call GetIntValue() with the value name, and if the type is not int, a + ValueTypeMismatch exception will be thrown and you can get the actual type from the exception object. +*/ +class CRYPTOPP_NO_VTABLE NameValuePairs +{ +public: + virtual ~NameValuePairs() {} + + //! exception thrown when trying to retrieve a value using a different type than expected + class CRYPTOPP_DLL ValueTypeMismatch : public InvalidArgument + { + public: + ValueTypeMismatch(const std::string &name, const std::type_info &stored, const std::type_info &retrieving) + : InvalidArgument("NameValuePairs: type mismatch for '" + name + "', stored '" + stored.name() + "', trying to retrieve '" + retrieving.name() + "'") + , m_stored(stored), m_retrieving(retrieving) {} + + const std::type_info & GetStoredTypeInfo() const {return m_stored;} + const std::type_info & GetRetrievingTypeInfo() const {return m_retrieving;} + + private: + const std::type_info &m_stored; + const std::type_info &m_retrieving; + }; + + //! get a copy of this object or a subobject of it + template + bool GetThisObject(T &object) const + { + return GetValue((std::string("ThisObject:")+typeid(T).name()).c_str(), object); + } + + //! get a pointer to this object, as a pointer to T + template + bool GetThisPointer(T *&p) const + { + return GetValue((std::string("ThisPointer:")+typeid(T).name()).c_str(), p); + } + + //! get a named value, returns true if the name exists + template + bool GetValue(const char *name, T &value) const + { + return GetVoidValue(name, typeid(T), &value); + } + + //! get a named value, returns the default if the name doesn't exist + template + T GetValueWithDefault(const char *name, T defaultValue) const + { + GetValue(name, defaultValue); + return defaultValue; + } + + //! get a list of value names that can be retrieved + CRYPTOPP_DLL std::string GetValueNames() const + {std::string result; GetValue("ValueNames", result); return result;} + + //! get a named value with type int + /*! used to ensure we don't accidentally try to get an unsigned int + or some other type when we mean int (which is the most common case) */ + CRYPTOPP_DLL bool GetIntValue(const char *name, int &value) const + {return GetValue(name, value);} + + //! get a named value with type int, with default + CRYPTOPP_DLL int GetIntValueWithDefault(const char *name, int defaultValue) const + {return GetValueWithDefault(name, defaultValue);} + + //! used by derived classes to check for type mismatch + CRYPTOPP_DLL static void CRYPTOPP_API ThrowIfTypeMismatch(const char *name, const std::type_info &stored, const std::type_info &retrieving) + {if (stored != retrieving) throw ValueTypeMismatch(name, stored, retrieving);} + + template + void GetRequiredParameter(const char *className, const char *name, T &value) const + { + if (!GetValue(name, value)) + throw InvalidArgument(std::string(className) + ": missing required parameter '" + name + "'"); + } + + CRYPTOPP_DLL void GetRequiredIntParameter(const char *className, const char *name, int &value) const + { + if (!GetIntValue(name, value)) + throw InvalidArgument(std::string(className) + ": missing required parameter '" + name + "'"); + } + + //! to be implemented by derived classes, users should use one of the above functions instead + CRYPTOPP_DLL virtual bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const =0; +}; + +//! namespace containing value name definitions +/*! value names, types and semantics: + + ThisObject:ClassName (ClassName, copy of this object or a subobject) + ThisPointer:ClassName (const ClassName *, pointer to this object or a subobject) +*/ +DOCUMENTED_NAMESPACE_BEGIN(Name) +// more names defined in argnames.h +DOCUMENTED_NAMESPACE_END + +//! empty set of name-value pairs +class CRYPTOPP_DLL NullNameValuePairs : public NameValuePairs +{ +public: + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const {return false;} +}; + +//! _ +extern CRYPTOPP_DLL const NullNameValuePairs g_nullNameValuePairs; + +// ******************************************************** + +//! interface for cloning objects, this is not implemented by most classes yet +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Clonable +{ +public: + virtual ~Clonable() {} + //! this is not implemented by most classes yet + virtual Clonable* Clone() const {throw NotImplemented("Clone() is not implemented yet.");} // TODO: make this =0 +}; + +//! interface for all crypto algorithms + +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Algorithm : public Clonable +{ +public: + /*! When FIPS 140-2 compliance is enabled and checkSelfTestStatus == true, + this constructor throws SelfTestFailure if the self test hasn't been run or fails. */ + Algorithm(bool checkSelfTestStatus = true); + //! returns name of this algorithm, not universally implemented yet + virtual std::string AlgorithmName() const {return "unknown";} +}; + +//! keying interface for crypto algorithms that take byte strings as keys + +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE SimpleKeyingInterface +{ +public: + virtual ~SimpleKeyingInterface() {} + + //! returns smallest valid key length in bytes */ + virtual size_t MinKeyLength() const =0; + //! returns largest valid key length in bytes */ + virtual size_t MaxKeyLength() const =0; + //! returns default (recommended) key length in bytes */ + virtual size_t DefaultKeyLength() const =0; + + //! returns the smallest valid key length in bytes that is >= min(n, GetMaxKeyLength()) + virtual size_t GetValidKeyLength(size_t n) const =0; + + //! returns whether n is a valid key length + virtual bool IsValidKeyLength(size_t n) const + {return n == GetValidKeyLength(n);} + + //! set or reset the key of this object + /*! \param params is used to specify Rounds, BlockSize, etc */ + virtual void SetKey(const byte *key, size_t length, const NameValuePairs ¶ms = g_nullNameValuePairs); + + //! calls SetKey() with an NameValuePairs object that just specifies "Rounds" + void SetKeyWithRounds(const byte *key, size_t length, int rounds); + + //! calls SetKey() with an NameValuePairs object that just specifies "IV" + void SetKeyWithIV(const byte *key, size_t length, const byte *iv); + + enum IV_Requirement {UNIQUE_IV = 0, RANDOM_IV, UNPREDICTABLE_RANDOM_IV, INTERNALLY_GENERATED_IV, NOT_RESYNCHRONIZABLE}; + //! returns the minimal requirement for secure IVs + virtual IV_Requirement IVRequirement() const =0; + + //! returns whether this object can be resynchronized (i.e. supports initialization vectors) + /*! If this function returns true, and no IV is passed to SetKey() and CanUseStructuredIVs()==true, an IV of all 0's will be assumed. */ + bool IsResynchronizable() const {return IVRequirement() < NOT_RESYNCHRONIZABLE;} + //! returns whether this object can use random IVs (in addition to ones returned by GetNextIV) + bool CanUseRandomIVs() const {return IVRequirement() <= UNPREDICTABLE_RANDOM_IV;} + //! returns whether this object can use random but possibly predictable IVs (in addition to ones returned by GetNextIV) + bool CanUsePredictableIVs() const {return IVRequirement() <= RANDOM_IV;} + //! returns whether this object can use structured IVs, for example a counter (in addition to ones returned by GetNextIV) + bool CanUseStructuredIVs() const {return IVRequirement() <= UNIQUE_IV;} + + //! returns size of IVs used by this object + virtual unsigned int IVSize() const {throw NotImplemented("SimpleKeyingInterface: this object doesn't support resynchronization");} + //! resynchronize with an IV + virtual void Resynchronize(const byte *IV) {throw NotImplemented("SimpleKeyingInterface: this object doesn't support resynchronization");} + //! get a secure IV for the next message + /*! This method should be called after you finish encrypting one message and are ready to start the next one. + After calling it, you must call SetKey() or Resynchronize() before using this object again. + This method is not implemented on decryption objects. */ + virtual void GetNextIV(RandomNumberGenerator &rng, byte *IV); + +protected: + virtual const Algorithm & GetAlgorithm() const =0; + virtual void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms) =0; + + void ThrowIfInvalidKeyLength(size_t length); + void ThrowIfResynchronizable(); // to be called when no IV is passed + void ThrowIfInvalidIV(const byte *iv); // check for NULL IV if it can't be used + const byte * GetIVAndThrowIfInvalid(const NameValuePairs ¶ms); + inline void AssertValidKeyLength(size_t length) const + {assert(IsValidKeyLength(length));} +}; + +//! interface for the data processing part of block ciphers + +/*! Classes derived from BlockTransformation are block ciphers + in ECB mode (for example the DES::Encryption class), which are stateless, + and they can make assumptions about the memory alignment of their inputs and outputs. + These classes should not be used directly, but only in combination with + a mode class (see CipherModeDocumentation in modes.h). +*/ +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE BlockTransformation : public Algorithm +{ +public: + //! encrypt or decrypt inBlock, xor with xorBlock, and write to outBlock + virtual void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const =0; + + //! encrypt or decrypt one block + /*! \pre size of inBlock and outBlock == BlockSize() */ + void ProcessBlock(const byte *inBlock, byte *outBlock) const + {ProcessAndXorBlock(inBlock, NULL, outBlock);} + + //! encrypt or decrypt one block in place + void ProcessBlock(byte *inoutBlock) const + {ProcessAndXorBlock(inoutBlock, NULL, inoutBlock);} + + //! block size of the cipher in bytes + virtual unsigned int BlockSize() const =0; + + //! block pointers must be divisible by this + virtual unsigned int BlockAlignment() const; // returns alignment of word32 by default + + //! returns true if this is a permutation (i.e. there is an inverse transformation) + virtual bool IsPermutation() const {return true;} + + //! returns true if this is an encryption object + virtual bool IsForwardTransformation() const =0; + + //! return number of blocks that can be processed in parallel, for bit-slicing implementations + virtual unsigned int OptimalNumberOfParallelBlocks() const {return 1;} + + //! encrypt or decrypt multiple blocks, for bit-slicing implementations + virtual void ProcessAndXorMultipleBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t numberOfBlocks) const; + + inline CipherDir GetCipherDirection() const {return IsForwardTransformation() ? ENCRYPTION : DECRYPTION;} +}; + +//! interface for the data processing part of stream ciphers + +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE StreamTransformation : public Algorithm +{ +public: + //! return a reference to this object, + /*! This function is useful for passing a temporary StreamTransformation object to a + function that takes a non-const reference. */ + StreamTransformation& Ref() {return *this;} + + //! returns block size, if input must be processed in blocks, otherwise 1 + virtual unsigned int MandatoryBlockSize() const {return 1;} + + //! returns the input block size that is most efficient for this cipher + /*! \note optimal input length is n * OptimalBlockSize() - GetOptimalBlockSizeUsed() for any n > 0 */ + virtual unsigned int OptimalBlockSize() const {return MandatoryBlockSize();} + //! returns how much of the current block is used up + virtual unsigned int GetOptimalBlockSizeUsed() const {return 0;} + + //! returns how input should be aligned for optimal performance + virtual unsigned int OptimalDataAlignment() const {return 1;} + + //! encrypt or decrypt an array of bytes of specified length + /*! \note either inString == outString, or they don't overlap */ + virtual void ProcessData(byte *outString, const byte *inString, size_t length) =0; + + //! for ciphers where the last block of data is special, encrypt or decrypt the last block of data + /*! For now the only use of this function is for CBC-CTS mode. */ + virtual void ProcessLastBlock(byte *outString, const byte *inString, size_t length); + //! returns the minimum size of the last block, 0 indicating the last block is not special + virtual unsigned int MinLastBlockSize() const {return 0;} + + //! same as ProcessData(inoutString, inoutString, length) + inline void ProcessString(byte *inoutString, size_t length) + {ProcessData(inoutString, inoutString, length);} + //! same as ProcessData(outString, inString, length) + inline void ProcessString(byte *outString, const byte *inString, size_t length) + {ProcessData(outString, inString, length);} + //! implemented as {ProcessData(&input, &input, 1); return input;} + inline byte ProcessByte(byte input) + {ProcessData(&input, &input, 1); return input;} + + //! returns whether this cipher supports random access + virtual bool IsRandomAccess() const =0; + //! for random access ciphers, seek to an absolute position + virtual void Seek(lword n) + { + assert(!IsRandomAccess()); + throw NotImplemented("StreamTransformation: this object doesn't support random access"); + } + + //! returns whether this transformation is self-inverting (e.g. xor with a keystream) + virtual bool IsSelfInverting() const =0; + //! returns whether this is an encryption object + virtual bool IsForwardTransformation() const =0; +}; + +//! interface for hash functions and data processing part of MACs + +/*! HashTransformation objects are stateful. They are created in an initial state, + change state as Update() is called, and return to the initial + state when Final() is called. This interface allows a large message to + be hashed in pieces by calling Update() on each piece followed by + calling Final(). +*/ +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE HashTransformation : public Algorithm +{ +public: + //! return a reference to this object, + /*! This function is useful for passing a temporary HashTransformation object to a + function that takes a non-const reference. */ + HashTransformation& Ref() {return *this;} + + //! process more input + virtual void Update(const byte *input, size_t length) =0; + + //! request space to write input into + virtual byte * CreateUpdateSpace(size_t &size) {size=0; return NULL;} + + //! compute hash for current message, then restart for a new message + /*! \pre size of digest == DigestSize(). */ + virtual void Final(byte *digest) + {TruncatedFinal(digest, DigestSize());} + + //! discard the current state, and restart with a new message + virtual void Restart() + {TruncatedFinal(NULL, 0);} + + //! size of the hash returned by Final() + virtual unsigned int DigestSize() const =0; + + //! block size of underlying compression function, or 0 if not block based + virtual unsigned int BlockSize() const {return 0;} + + //! input to Update() should have length a multiple of this for optimal speed + virtual unsigned int OptimalBlockSize() const {return 1;} + + //! returns how input should be aligned for optimal performance + virtual unsigned int OptimalDataAlignment() const {return 1;} + + //! use this if your input is in one piece and you don't want to call Update() and Final() separately + virtual void CalculateDigest(byte *digest, const byte *input, size_t length) + {Update(input, length); Final(digest);} + + //! verify that digest is a valid digest for the current message, then reinitialize the object + /*! Default implementation is to call Final() and do a bitwise comparison + between its output and digest. */ + virtual bool Verify(const byte *digest) + {return TruncatedVerify(digest, DigestSize());} + + //! use this if your input is in one piece and you don't want to call Update() and Verify() separately + virtual bool VerifyDigest(const byte *digest, const byte *input, size_t length) + {Update(input, length); return Verify(digest);} + + //! truncated version of Final() + virtual void TruncatedFinal(byte *digest, size_t digestSize) =0; + + //! truncated version of CalculateDigest() + virtual void CalculateTruncatedDigest(byte *digest, size_t digestSize, const byte *input, size_t length) + {Update(input, length); TruncatedFinal(digest, digestSize);} + + //! truncated version of Verify() + virtual bool TruncatedVerify(const byte *digest, size_t digestLength); + + //! truncated version of VerifyDigest() + virtual bool VerifyTruncatedDigest(const byte *digest, size_t digestLength, const byte *input, size_t length) + {Update(input, length); return TruncatedVerify(digest, digestLength);} + +protected: + void ThrowIfInvalidTruncatedSize(size_t size) const; +}; + +typedef HashTransformation HashFunction; + +template +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE SimpleKeyedTransformation : public T, public SimpleKeyingInterface +{ +protected: + const Algorithm & GetAlgorithm() const {return *this;} +}; + +#ifdef CRYPTOPP_DOXYGEN_PROCESSING +//! interface for one direction (encryption or decryption) of a block cipher +/*! \note These objects usually should not be used directly. See BlockTransformation for more details. */ +class BlockCipher : public BlockTransformation, public SimpleKeyingInterface {}; +//! interface for one direction (encryption or decryption) of a stream cipher or cipher mode +class SymmetricCipher : public StreamTransformation, public SimpleKeyingInterface {}; +//! interface for message authentication codes +class MessageAuthenticationCode : public HashTransformation, public SimpleKeyingInterface {}; +#else +typedef SimpleKeyedTransformation BlockCipher; +typedef SimpleKeyedTransformation SymmetricCipher; +typedef SimpleKeyedTransformation MessageAuthenticationCode; +#endif + +CRYPTOPP_DLL_TEMPLATE_CLASS SimpleKeyedTransformation; +CRYPTOPP_DLL_TEMPLATE_CLASS SimpleKeyedTransformation; +CRYPTOPP_DLL_TEMPLATE_CLASS SimpleKeyedTransformation; + +#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY +typedef SymmetricCipher StreamCipher; +#endif + +//! interface for random number generators +/*! All return values are uniformly distributed over the range specified. +*/ +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomNumberGenerator : public Algorithm +{ +public: + //! update RNG state with additional unpredictable values + virtual void IncorporateEntropy(const byte *input, size_t length) {throw NotImplemented("RandomNumberGenerator: IncorporateEntropy not implemented");} + + //! returns true if IncorporateEntropy is implemented + virtual bool CanIncorporateEntropy() const {return false;} + + //! generate new random byte and return it + virtual byte GenerateByte(); + + //! generate new random bit and return it + /*! Default implementation is to call GenerateByte() and return its lowest bit. */ + virtual unsigned int GenerateBit(); + + //! generate a random 32 bit word in the range min to max, inclusive + virtual word32 GenerateWord32(word32 a=0, word32 b=0xffffffffL); + + //! generate random array of bytes + virtual void GenerateBlock(byte *output, size_t size); + + //! generate and discard n bytes + virtual void DiscardBytes(size_t n); + + //! generate random bytes as input to a BufferedTransformation + virtual void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length); + + //! randomly shuffle the specified array, resulting permutation is uniformly distributed + template void Shuffle(IT begin, IT end) + { + for (; begin != end; ++begin) + std::iter_swap(begin, begin + GenerateWord32(0, end-begin-1)); + } + +#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY + byte GetByte() {return GenerateByte();} + unsigned int GetBit() {return GenerateBit();} + word32 GetLong(word32 a=0, word32 b=0xffffffffL) {return GenerateWord32(a, b);} + word16 GetShort(word16 a=0, word16 b=0xffff) {return (word16)GenerateWord32(a, b);} + void GetBlock(byte *output, size_t size) {GenerateBlock(output, size);} +#endif +}; + +//! returns a reference that can be passed to functions that ask for a RNG but doesn't actually use it +CRYPTOPP_DLL RandomNumberGenerator & CRYPTOPP_API NullRNG(); + +class WaitObjectContainer; +class CallStack; + +//! interface for objects that you can wait for + +class CRYPTOPP_NO_VTABLE Waitable +{ +public: + virtual ~Waitable() {} + + //! maximum number of wait objects that this object can return + virtual unsigned int GetMaxWaitObjectCount() const =0; + //! put wait objects into container + /*! \param callStack is used for tracing no wait loops, example: + something.GetWaitObjects(c, CallStack("my func after X", 0)); + - or in an outer GetWaitObjects() method that itself takes a callStack parameter: + innerThing.GetWaitObjects(c, CallStack("MyClass::GetWaitObjects at X", &callStack)); */ + virtual void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack) =0; + //! wait on this object + /*! same as creating an empty container, calling GetWaitObjects(), and calling Wait() on the container */ + bool Wait(unsigned long milliseconds, CallStack const& callStack); +}; + +//! interface for buffered transformations + +/*! BufferedTransformation is a generalization of BlockTransformation, + StreamTransformation, and HashTransformation. + + A buffered transformation is an object that takes a stream of bytes + as input (this may be done in stages), does some computation on them, and + then places the result into an internal buffer for later retrieval. Any + partial result already in the output buffer is not modified by further + input. + + If a method takes a "blocking" parameter, and you + pass "false" for it, the method will return before all input has been processed if + the input cannot be processed without waiting (for network buffers to become available, for example). + In this case the method will return true + or a non-zero integer value. When this happens you must continue to call the method with the same + parameters until it returns false or zero, before calling any other method on it or + attached BufferedTransformation. The integer return value in this case is approximately + the number of bytes left to be processed, and can be used to implement a progress bar. + + For functions that take a "propagation" parameter, propagation != 0 means pass on the signal to attached + BufferedTransformation objects, with propagation decremented at each step until it reaches 0. + -1 means unlimited propagation. + + \nosubgrouping +*/ +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE BufferedTransformation : public Algorithm, public Waitable +{ +public: + // placed up here for CW8 + static const std::string NULL_CHANNEL; // the empty string "" + + BufferedTransformation() : Algorithm(false) {} + + //! return a reference to this object + /*! This function is useful for passing a temporary BufferedTransformation object to a + function that takes a non-const reference. */ + BufferedTransformation& Ref() {return *this;} + + //! \name INPUT + //@{ + //! input a byte for processing + size_t Put(byte inByte, bool blocking=true) + {return Put(&inByte, 1, blocking);} + //! input multiple bytes + size_t Put(const byte *inString, size_t length, bool blocking=true) + {return Put2(inString, length, 0, blocking);} + + //! input a 16-bit word + size_t PutWord16(word16 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true); + //! input a 32-bit word + size_t PutWord32(word32 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true); + + //! request space which can be written into by the caller, and then used as input to Put() + /*! \param size is requested size (as a hint) for input, and size of the returned space for output */ + /*! \note The purpose of this method is to help avoid doing extra memory allocations. */ + virtual byte * CreatePutSpace(size_t &size) {size=0; return NULL;} + + virtual bool CanModifyInput() const {return false;} + + //! input multiple bytes that may be modified by callee + size_t PutModifiable(byte *inString, size_t length, bool blocking=true) + {return PutModifiable2(inString, length, 0, blocking);} + + bool MessageEnd(int propagation=-1, bool blocking=true) + {return !!Put2(NULL, 0, propagation < 0 ? -1 : propagation+1, blocking);} + size_t PutMessageEnd(const byte *inString, size_t length, int propagation=-1, bool blocking=true) + {return Put2(inString, length, propagation < 0 ? -1 : propagation+1, blocking);} + + //! input multiple bytes for blocking or non-blocking processing + /*! \param messageEnd means how many filters to signal MessageEnd to, including this one */ + virtual size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking) =0; + //! input multiple bytes that may be modified by callee for blocking or non-blocking processing + /*! \param messageEnd means how many filters to signal MessageEnd to, including this one */ + virtual size_t PutModifiable2(byte *inString, size_t length, int messageEnd, bool blocking) + {return Put2(inString, length, messageEnd, blocking);} + + //! thrown by objects that have not implemented nonblocking input processing + struct BlockingInputOnly : public NotImplemented + {BlockingInputOnly(const std::string &s) : NotImplemented(s + ": Nonblocking input is not implemented by this object.") {}}; + //@} + + //! \name WAITING + //@{ + unsigned int GetMaxWaitObjectCount() const; + void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack); + //@} + + //! \name SIGNALS + //@{ + virtual void IsolatedInitialize(const NameValuePairs ¶meters) {throw NotImplemented("BufferedTransformation: this object can't be reinitialized");} + virtual bool IsolatedFlush(bool hardFlush, bool blocking) =0; + virtual bool IsolatedMessageSeriesEnd(bool blocking) {return false;} + + //! initialize or reinitialize this object + virtual void Initialize(const NameValuePairs ¶meters=g_nullNameValuePairs, int propagation=-1); + //! flush buffered input and/or output + /*! \param hardFlush is used to indicate whether all data should be flushed + \note Hard flushes must be used with care. It means try to process and output everything, even if + there may not be enough data to complete the action. For example, hard flushing a HexDecoder would + cause an error if you do it after inputing an odd number of hex encoded characters. + For some types of filters, for example ZlibDecompressor, hard flushes can only + be done at "synchronization points". These synchronization points are positions in the data + stream that are created by hard flushes on the corresponding reverse filters, in this + example ZlibCompressor. This is useful when zlib compressed data is moved across a + network in packets and compression state is preserved across packets, as in the ssh2 protocol. + */ + virtual bool Flush(bool hardFlush, int propagation=-1, bool blocking=true); + //! mark end of a series of messages + /*! There should be a MessageEnd immediately before MessageSeriesEnd. */ + virtual bool MessageSeriesEnd(int propagation=-1, bool blocking=true); + + //! set propagation of automatically generated and transferred signals + /*! propagation == 0 means do not automaticly generate signals */ + virtual void SetAutoSignalPropagation(int propagation) {} + + //! + virtual int GetAutoSignalPropagation() const {return 0;} +public: + +#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY + void Close() {MessageEnd();} +#endif + //@} + + //! \name RETRIEVAL OF ONE MESSAGE + //@{ + //! returns number of bytes that is currently ready for retrieval + /*! All retrieval functions return the actual number of bytes + retrieved, which is the lesser of the request number and + MaxRetrievable(). */ + virtual lword MaxRetrievable() const; + + //! returns whether any bytes are currently ready for retrieval + virtual bool AnyRetrievable() const; + + //! try to retrieve a single byte + virtual size_t Get(byte &outByte); + //! try to retrieve multiple bytes + virtual size_t Get(byte *outString, size_t getMax); + + //! peek at the next byte without removing it from the output buffer + virtual size_t Peek(byte &outByte) const; + //! peek at multiple bytes without removing them from the output buffer + virtual size_t Peek(byte *outString, size_t peekMax) const; + + //! try to retrieve a 16-bit word + size_t GetWord16(word16 &value, ByteOrder order=BIG_ENDIAN_ORDER); + //! try to retrieve a 32-bit word + size_t GetWord32(word32 &value, ByteOrder order=BIG_ENDIAN_ORDER); + + //! try to peek at a 16-bit word + size_t PeekWord16(word16 &value, ByteOrder order=BIG_ENDIAN_ORDER) const; + //! try to peek at a 32-bit word + size_t PeekWord32(word32 &value, ByteOrder order=BIG_ENDIAN_ORDER) const; + + //! move transferMax bytes of the buffered output to target as input + lword TransferTo(BufferedTransformation &target, lword transferMax=LWORD_MAX, const std::string &channel=NULL_CHANNEL) + {TransferTo2(target, transferMax, channel); return transferMax;} + + //! discard skipMax bytes from the output buffer + virtual lword Skip(lword skipMax=LWORD_MAX); + + //! copy copyMax bytes of the buffered output to target as input + lword CopyTo(BufferedTransformation &target, lword copyMax=LWORD_MAX, const std::string &channel=NULL_CHANNEL) const + {return CopyRangeTo(target, 0, copyMax, channel);} + + //! copy copyMax bytes of the buffered output, starting at position (relative to current position), to target as input + lword CopyRangeTo(BufferedTransformation &target, lword position, lword copyMax=LWORD_MAX, const std::string &channel=NULL_CHANNEL) const + {lword i = position; CopyRangeTo2(target, i, i+copyMax, channel); return i-position;} + +#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY + unsigned long MaxRetrieveable() const {return MaxRetrievable();} +#endif + //@} + + //! \name RETRIEVAL OF MULTIPLE MESSAGES + //@{ + //! + virtual lword TotalBytesRetrievable() const; + //! number of times MessageEnd() has been received minus messages retrieved or skipped + virtual unsigned int NumberOfMessages() const; + //! returns true if NumberOfMessages() > 0 + virtual bool AnyMessages() const; + //! start retrieving the next message + /*! + Returns false if no more messages exist or this message + is not completely retrieved. + */ + virtual bool GetNextMessage(); + //! skip count number of messages + virtual unsigned int SkipMessages(unsigned int count=UINT_MAX); + //! + unsigned int TransferMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX, const std::string &channel=NULL_CHANNEL) + {TransferMessagesTo2(target, count, channel); return count;} + //! + unsigned int CopyMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX, const std::string &channel=NULL_CHANNEL) const; + + //! + virtual void SkipAll(); + //! + void TransferAllTo(BufferedTransformation &target, const std::string &channel=NULL_CHANNEL) + {TransferAllTo2(target, channel);} + //! + void CopyAllTo(BufferedTransformation &target, const std::string &channel=NULL_CHANNEL) const; + + virtual bool GetNextMessageSeries() {return false;} + virtual unsigned int NumberOfMessagesInThisSeries() const {return NumberOfMessages();} + virtual unsigned int NumberOfMessageSeries() const {return 0;} + //@} + + //! \name NON-BLOCKING TRANSFER OF OUTPUT + //@{ + //! upon return, byteCount contains number of bytes that have finished being transfered, and returns the number of bytes left in the current transfer block + virtual size_t TransferTo2(BufferedTransformation &target, lword &byteCount, const std::string &channel=NULL_CHANNEL, bool blocking=true) =0; + //! upon return, begin contains the start position of data yet to be finished copying, and returns the number of bytes left in the current transfer block + virtual size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=NULL_CHANNEL, bool blocking=true) const =0; + //! upon return, messageCount contains number of messages that have finished being transfered, and returns the number of bytes left in the current transfer block + size_t TransferMessagesTo2(BufferedTransformation &target, unsigned int &messageCount, const std::string &channel=NULL_CHANNEL, bool blocking=true); + //! returns the number of bytes left in the current transfer block + size_t TransferAllTo2(BufferedTransformation &target, const std::string &channel=NULL_CHANNEL, bool blocking=true); + //@} + + //! \name CHANNELS + //@{ + struct NoChannelSupport : public NotImplemented + {NoChannelSupport() : NotImplemented("BufferedTransformation: this object doesn't support multiple channels") {}}; + + size_t ChannelPut(const std::string &channel, byte inByte, bool blocking=true) + {return ChannelPut(channel, &inByte, 1, blocking);} + size_t ChannelPut(const std::string &channel, const byte *inString, size_t length, bool blocking=true) + {return ChannelPut2(channel, inString, length, 0, blocking);} + + size_t ChannelPutModifiable(const std::string &channel, byte *inString, size_t length, bool blocking=true) + {return ChannelPutModifiable2(channel, inString, length, 0, blocking);} + + size_t ChannelPutWord16(const std::string &channel, word16 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true); + size_t ChannelPutWord32(const std::string &channel, word32 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true); + + bool ChannelMessageEnd(const std::string &channel, int propagation=-1, bool blocking=true) + {return !!ChannelPut2(channel, NULL, 0, propagation < 0 ? -1 : propagation+1, blocking);} + size_t ChannelPutMessageEnd(const std::string &channel, const byte *inString, size_t length, int propagation=-1, bool blocking=true) + {return ChannelPut2(channel, inString, length, propagation < 0 ? -1 : propagation+1, blocking);} + + virtual byte * ChannelCreatePutSpace(const std::string &channel, size_t &size); + + virtual size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking); + virtual size_t ChannelPutModifiable2(const std::string &channel, byte *begin, size_t length, int messageEnd, bool blocking); + + virtual bool ChannelFlush(const std::string &channel, bool hardFlush, int propagation=-1, bool blocking=true); + virtual bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true); + + virtual void SetRetrievalChannel(const std::string &channel); + //@} + + //! \name ATTACHMENT + /*! Some BufferedTransformation objects (e.g. Filter objects) + allow other BufferedTransformation objects to be attached. When + this is done, the first object instead of buffering its output, + sents that output to the attached object as input. The entire + attachment chain is deleted when the anchor object is destructed. + */ + //@{ + //! returns whether this object allows attachment + virtual bool Attachable() {return false;} + //! returns the object immediately attached to this object or NULL for no attachment + virtual BufferedTransformation *AttachedTransformation() {assert(!Attachable()); return 0;} + //! + virtual const BufferedTransformation *AttachedTransformation() const + {return const_cast(this)->AttachedTransformation();} + //! delete the current attachment chain and replace it with newAttachment + virtual void Detach(BufferedTransformation *newAttachment = 0) + {assert(!Attachable()); throw NotImplemented("BufferedTransformation: this object is not attachable");} + //! add newAttachment to the end of attachment chain + virtual void Attach(BufferedTransformation *newAttachment); + //@} + +protected: + static int DecrementPropagation(int propagation) + {return propagation != 0 ? propagation - 1 : 0;} + +private: + byte m_buf[4]; // for ChannelPutWord16 and ChannelPutWord32, to ensure buffer isn't deallocated before non-blocking operation completes +}; + +//! returns a reference to a BufferedTransformation object that discards all input +BufferedTransformation & TheBitBucket(); + +//! interface for crypto material, such as public and private keys, and crypto parameters + +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CryptoMaterial : public NameValuePairs +{ +public: + //! exception thrown when invalid crypto material is detected + class CRYPTOPP_DLL InvalidMaterial : public InvalidDataFormat + { + public: + explicit InvalidMaterial(const std::string &s) : InvalidDataFormat(s) {} + }; + + //! assign values from source to this object + /*! \note This function can be used to create a public key from a private key. */ + virtual void AssignFrom(const NameValuePairs &source) =0; + + //! check this object for errors + /*! \param level denotes the level of thoroughness: + 0 - using this object won't cause a crash or exception (rng is ignored) + 1 - this object will probably function (encrypt, sign, etc.) correctly (but may not check for weak keys and such) + 2 - make sure this object will function correctly, and do reasonable security checks + 3 - do checks that may take a long time + \return true if the tests pass */ + virtual bool Validate(RandomNumberGenerator &rng, unsigned int level) const =0; + + //! throws InvalidMaterial if this object fails Validate() test + virtual void ThrowIfInvalid(RandomNumberGenerator &rng, unsigned int level) const + {if (!Validate(rng, level)) throw InvalidMaterial("CryptoMaterial: this object contains invalid values");} + +// virtual std::vector GetSupportedFormats(bool includeSaveOnly=false, bool includeLoadOnly=false); + + //! save key into a BufferedTransformation + virtual void Save(BufferedTransformation &bt) const + {throw NotImplemented("CryptoMaterial: this object does not support saving");} + + //! load key from a BufferedTransformation + /*! \throws KeyingErr if decode fails + \note Generally does not check that the key is valid. + Call ValidateKey() or ThrowIfInvalidKey() to check that. */ + virtual void Load(BufferedTransformation &bt) + {throw NotImplemented("CryptoMaterial: this object does not support loading");} + + //! \return whether this object supports precomputation + virtual bool SupportsPrecomputation() const {return false;} + //! do precomputation + /*! The exact semantics of Precompute() is varies, but + typically it means calculate a table of n objects + that can be used later to speed up computation. */ + virtual void Precompute(unsigned int n) + {assert(!SupportsPrecomputation()); throw NotImplemented("CryptoMaterial: this object does not support precomputation");} + //! retrieve previously saved precomputation + virtual void LoadPrecomputation(BufferedTransformation &storedPrecomputation) + {assert(!SupportsPrecomputation()); throw NotImplemented("CryptoMaterial: this object does not support precomputation");} + //! save precomputation for later use + virtual void SavePrecomputation(BufferedTransformation &storedPrecomputation) const + {assert(!SupportsPrecomputation()); throw NotImplemented("CryptoMaterial: this object does not support precomputation");} + + // for internal library use + void DoQuickSanityCheck() const {ThrowIfInvalid(NullRNG(), 0);} + +#ifdef __SUNPRO_CC + // Sun Studio 11/CC 5.8 workaround: it generates incorrect code when casting to an empty virtual base class + char m_sunCCworkaround; +#endif +}; + +//! interface for generatable crypto material, such as private keys and crypto parameters + +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE GeneratableCryptoMaterial : virtual public CryptoMaterial +{ +public: + //! generate a random key or crypto parameters + /*! \throws KeyingErr if algorithm parameters are invalid, or if a key can't be generated + (e.g., if this is a public key object) */ + virtual void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs ¶ms = g_nullNameValuePairs) + {throw NotImplemented("GeneratableCryptoMaterial: this object does not support key/parameter generation");} + + //! calls the above function with a NameValuePairs object that just specifies "KeySize" + void GenerateRandomWithKeySize(RandomNumberGenerator &rng, unsigned int keySize); +}; + +//! interface for public keys + +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PublicKey : virtual public CryptoMaterial +{ +}; + +//! interface for private keys + +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PrivateKey : public GeneratableCryptoMaterial +{ +}; + +//! interface for crypto prameters + +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CryptoParameters : public GeneratableCryptoMaterial +{ +}; + +//! interface for asymmetric algorithms + +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE AsymmetricAlgorithm : public Algorithm +{ +public: + //! returns a reference to the crypto material used by this object + virtual CryptoMaterial & AccessMaterial() =0; + //! returns a const reference to the crypto material used by this object + virtual const CryptoMaterial & GetMaterial() const =0; + + //! for backwards compatibility, calls AccessMaterial().Load(bt) + void BERDecode(BufferedTransformation &bt) + {AccessMaterial().Load(bt);} + //! for backwards compatibility, calls GetMaterial().Save(bt) + void DEREncode(BufferedTransformation &bt) const + {GetMaterial().Save(bt);} +}; + +//! interface for asymmetric algorithms using public keys + +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PublicKeyAlgorithm : public AsymmetricAlgorithm +{ +public: + // VC60 workaround: no co-variant return type + CryptoMaterial & AccessMaterial() {return AccessPublicKey();} + const CryptoMaterial & GetMaterial() const {return GetPublicKey();} + + virtual PublicKey & AccessPublicKey() =0; + virtual const PublicKey & GetPublicKey() const {return const_cast(this)->AccessPublicKey();} +}; + +//! interface for asymmetric algorithms using private keys + +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PrivateKeyAlgorithm : public AsymmetricAlgorithm +{ +public: + CryptoMaterial & AccessMaterial() {return AccessPrivateKey();} + const CryptoMaterial & GetMaterial() const {return GetPrivateKey();} + + virtual PrivateKey & AccessPrivateKey() =0; + virtual const PrivateKey & GetPrivateKey() const {return const_cast(this)->AccessPrivateKey();} +}; + +//! interface for key agreement algorithms + +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE KeyAgreementAlgorithm : public AsymmetricAlgorithm +{ +public: + CryptoMaterial & AccessMaterial() {return AccessCryptoParameters();} + const CryptoMaterial & GetMaterial() const {return GetCryptoParameters();} + + virtual CryptoParameters & AccessCryptoParameters() =0; + virtual const CryptoParameters & GetCryptoParameters() const {return const_cast(this)->AccessCryptoParameters();} +}; + +//! interface for public-key encryptors and decryptors + +/*! This class provides an interface common to encryptors and decryptors + for querying their plaintext and ciphertext lengths. +*/ +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_CryptoSystem +{ +public: + virtual ~PK_CryptoSystem() {} + + //! maximum length of plaintext for a given ciphertext length + /*! \note This function returns 0 if ciphertextLength is not valid (too long or too short). */ + virtual size_t MaxPlaintextLength(size_t ciphertextLength) const =0; + + //! calculate length of ciphertext given length of plaintext + /*! \note This function returns 0 if plaintextLength is not valid (too long). */ + virtual size_t CiphertextLength(size_t plaintextLength) const =0; + + //! this object supports the use of the parameter with the given name + /*! some possible parameter names: EncodingParameters, KeyDerivationParameters */ + virtual bool ParameterSupported(const char *name) const =0; + + //! return fixed ciphertext length, if one exists, otherwise return 0 + /*! \note "Fixed" here means length of ciphertext does not depend on length of plaintext. + It usually does depend on the key length. */ + virtual size_t FixedCiphertextLength() const {return 0;} + + //! return maximum plaintext length given the fixed ciphertext length, if one exists, otherwise return 0 + virtual size_t FixedMaxPlaintextLength() const {return 0;} + +#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY + size_t MaxPlainTextLength(size_t cipherTextLength) const {return MaxPlaintextLength(cipherTextLength);} + size_t CipherTextLength(size_t plainTextLength) const {return CiphertextLength(plainTextLength);} +#endif +}; + +//! interface for public-key encryptors +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_Encryptor : public PK_CryptoSystem, public PublicKeyAlgorithm +{ +public: + //! exception thrown when trying to encrypt plaintext of invalid length + class CRYPTOPP_DLL InvalidPlaintextLength : public Exception + { + public: + InvalidPlaintextLength() : Exception(OTHER_ERROR, "PK_Encryptor: invalid plaintext length") {} + }; + + //! encrypt a byte string + /*! \pre CiphertextLength(plaintextLength) != 0 (i.e., plaintext isn't too long) + \pre size of ciphertext == CiphertextLength(plaintextLength) + */ + virtual void Encrypt(RandomNumberGenerator &rng, + const byte *plaintext, size_t plaintextLength, + byte *ciphertext, const NameValuePairs ¶meters = g_nullNameValuePairs) const =0; + + //! create a new encryption filter + /*! \note The caller is responsible for deleting the returned pointer. + \note Encoding parameters should be passed in the "EP" channel. + */ + virtual BufferedTransformation * CreateEncryptionFilter(RandomNumberGenerator &rng, + BufferedTransformation *attachment=NULL, const NameValuePairs ¶meters = g_nullNameValuePairs) const; +}; + +//! interface for public-key decryptors + +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_Decryptor : public PK_CryptoSystem, public PrivateKeyAlgorithm +{ +public: + //! decrypt a byte string, and return the length of plaintext + /*! \pre size of plaintext == MaxPlaintextLength(ciphertextLength) bytes. + \return the actual length of the plaintext, indication that decryption failed. + */ + virtual DecodingResult Decrypt(RandomNumberGenerator &rng, + const byte *ciphertext, size_t ciphertextLength, + byte *plaintext, const NameValuePairs ¶meters = g_nullNameValuePairs) const =0; + + //! create a new decryption filter + /*! \note caller is responsible for deleting the returned pointer + */ + virtual BufferedTransformation * CreateDecryptionFilter(RandomNumberGenerator &rng, + BufferedTransformation *attachment=NULL, const NameValuePairs ¶meters = g_nullNameValuePairs) const; + + //! decrypt a fixed size ciphertext + DecodingResult FixedLengthDecrypt(RandomNumberGenerator &rng, const byte *ciphertext, byte *plaintext, const NameValuePairs ¶meters = g_nullNameValuePairs) const + {return Decrypt(rng, ciphertext, FixedCiphertextLength(), plaintext, parameters);} +}; + +#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY +typedef PK_CryptoSystem PK_FixedLengthCryptoSystem; +typedef PK_Encryptor PK_FixedLengthEncryptor; +typedef PK_Decryptor PK_FixedLengthDecryptor; +#endif + +//! interface for public-key signers and verifiers + +/*! This class provides an interface common to signers and verifiers + for querying scheme properties. +*/ +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_SignatureScheme +{ +public: + //! invalid key exception, may be thrown by any function in this class if the private or public key has a length that can't be used + class CRYPTOPP_DLL InvalidKeyLength : public Exception + { + public: + InvalidKeyLength(const std::string &message) : Exception(OTHER_ERROR, message) {} + }; + + //! key too short exception, may be thrown by any function in this class if the private or public key is too short to sign or verify anything + class CRYPTOPP_DLL KeyTooShort : public InvalidKeyLength + { + public: + KeyTooShort() : InvalidKeyLength("PK_Signer: key too short for this signature scheme") {} + }; + + virtual ~PK_SignatureScheme() {} + + //! signature length if it only depends on the key, otherwise 0 + virtual size_t SignatureLength() const =0; + + //! maximum signature length produced for a given length of recoverable message part + virtual size_t MaxSignatureLength(size_t recoverablePartLength = 0) const {return SignatureLength();} + + //! length of longest message that can be recovered, or 0 if this signature scheme does not support message recovery + virtual size_t MaxRecoverableLength() const =0; + + //! length of longest message that can be recovered from a signature of given length, or 0 if this signature scheme does not support message recovery + virtual size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const =0; + + //! requires a random number generator to sign + /*! if this returns false, NullRNG() can be passed to functions that take RandomNumberGenerator & */ + virtual bool IsProbabilistic() const =0; + + //! whether or not a non-recoverable message part can be signed + virtual bool AllowNonrecoverablePart() const =0; + + //! if this function returns true, during verification you must input the signature before the message, otherwise you can input it at anytime */ + virtual bool SignatureUpfront() const {return false;} + + //! whether you must input the recoverable part before the non-recoverable part during signing + virtual bool RecoverablePartFirst() const =0; +}; + +//! interface for accumulating messages to be signed or verified +/*! Only Update() should be called + on this class. No other functions inherited from HashTransformation should be called. +*/ +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_MessageAccumulator : public HashTransformation +{ +public: + //! should not be called on PK_MessageAccumulator + unsigned int DigestSize() const + {throw NotImplemented("PK_MessageAccumulator: DigestSize() should not be called");} + //! should not be called on PK_MessageAccumulator + void TruncatedFinal(byte *digest, size_t digestSize) + {throw NotImplemented("PK_MessageAccumulator: TruncatedFinal() should not be called");} +}; + +//! interface for public-key signers + +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_Signer : public PK_SignatureScheme, public PrivateKeyAlgorithm +{ +public: + //! create a new HashTransformation to accumulate the message to be signed + virtual PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng) const =0; + + virtual void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const =0; + + //! sign and delete messageAccumulator (even in case of exception thrown) + /*! \pre size of signature == MaxSignatureLength() + \return actual signature length + */ + virtual size_t Sign(RandomNumberGenerator &rng, PK_MessageAccumulator *messageAccumulator, byte *signature) const; + + //! sign and restart messageAccumulator + /*! \pre size of signature == MaxSignatureLength() + \return actual signature length + */ + virtual size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart=true) const =0; + + //! sign a message + /*! \pre size of signature == MaxSignatureLength() + \return actual signature length + */ + virtual size_t SignMessage(RandomNumberGenerator &rng, const byte *message, size_t messageLen, byte *signature) const; + + //! sign a recoverable message + /*! \pre size of signature == MaxSignatureLength(recoverableMessageLength) + \return actual signature length + */ + virtual size_t SignMessageWithRecovery(RandomNumberGenerator &rng, const byte *recoverableMessage, size_t recoverableMessageLength, + const byte *nonrecoverableMessage, size_t nonrecoverableMessageLength, byte *signature) const; +}; + +//! interface for public-key signature verifiers +/*! The Recover* functions throw NotImplemented if the signature scheme does not support + message recovery. + The Verify* functions throw InvalidDataFormat if the scheme does support message + recovery and the signature contains a non-empty recoverable message part. The + Recovery* functions should be used in that case. +*/ +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_Verifier : public PK_SignatureScheme, public PublicKeyAlgorithm +{ +public: + //! create a new HashTransformation to accumulate the message to be verified + virtual PK_MessageAccumulator * NewVerificationAccumulator() const =0; + + //! input signature into a message accumulator + virtual void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const =0; + + //! check whether messageAccumulator contains a valid signature and message, and delete messageAccumulator (even in case of exception thrown) + virtual bool Verify(PK_MessageAccumulator *messageAccumulator) const; + + //! check whether messageAccumulator contains a valid signature and message, and restart messageAccumulator + virtual bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const =0; + + //! check whether input signature is a valid signature for input message + virtual bool VerifyMessage(const byte *message, size_t messageLen, + const byte *signature, size_t signatureLength) const; + + //! recover a message from its signature + /*! \pre size of recoveredMessage == MaxRecoverableLengthFromSignatureLength(signatureLength) + */ + virtual DecodingResult Recover(byte *recoveredMessage, PK_MessageAccumulator *messageAccumulator) const; + + //! recover a message from its signature + /*! \pre size of recoveredMessage == MaxRecoverableLengthFromSignatureLength(signatureLength) + */ + virtual DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const =0; + + //! recover a message from its signature + /*! \pre size of recoveredMessage == MaxRecoverableLengthFromSignatureLength(signatureLength) + */ + virtual DecodingResult RecoverMessage(byte *recoveredMessage, + const byte *nonrecoverableMessage, size_t nonrecoverableMessageLength, + const byte *signature, size_t signatureLength) const; +}; + +//! interface for domains of simple key agreement protocols + +/*! A key agreement domain is a set of parameters that must be shared + by two parties in a key agreement protocol, along with the algorithms + for generating key pairs and deriving agreed values. +*/ +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE SimpleKeyAgreementDomain : public KeyAgreementAlgorithm +{ +public: + //! return length of agreed value produced + virtual unsigned int AgreedValueLength() const =0; + //! return length of private keys in this domain + virtual unsigned int PrivateKeyLength() const =0; + //! return length of public keys in this domain + virtual unsigned int PublicKeyLength() const =0; + //! generate private key + /*! \pre size of privateKey == PrivateKeyLength() */ + virtual void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const =0; + //! generate public key + /*! \pre size of publicKey == PublicKeyLength() */ + virtual void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const =0; + //! generate private/public key pair + /*! \note equivalent to calling GeneratePrivateKey() and then GeneratePublicKey() */ + virtual void GenerateKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const; + //! derive agreed value from your private key and couterparty's public key, return false in case of failure + /*! \note If you have previously validated the public key, use validateOtherPublicKey=false to save time. + \pre size of agreedValue == AgreedValueLength() + \pre length of privateKey == PrivateKeyLength() + \pre length of otherPublicKey == PublicKeyLength() + */ + virtual bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const =0; + +#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY + bool ValidateDomainParameters(RandomNumberGenerator &rng) const + {return GetCryptoParameters().Validate(rng, 2);} +#endif +}; + +//! interface for domains of authenticated key agreement protocols + +/*! In an authenticated key agreement protocol, each party has two + key pairs. The long-lived key pair is called the static key pair, + and the short-lived key pair is called the ephemeral key pair. +*/ +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE AuthenticatedKeyAgreementDomain : public KeyAgreementAlgorithm +{ +public: + //! return length of agreed value produced + virtual unsigned int AgreedValueLength() const =0; + + //! return length of static private keys in this domain + virtual unsigned int StaticPrivateKeyLength() const =0; + //! return length of static public keys in this domain + virtual unsigned int StaticPublicKeyLength() const =0; + //! generate static private key + /*! \pre size of privateKey == PrivateStaticKeyLength() */ + virtual void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const =0; + //! generate static public key + /*! \pre size of publicKey == PublicStaticKeyLength() */ + virtual void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const =0; + //! generate private/public key pair + /*! \note equivalent to calling GenerateStaticPrivateKey() and then GenerateStaticPublicKey() */ + virtual void GenerateStaticKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const; + + //! return length of ephemeral private keys in this domain + virtual unsigned int EphemeralPrivateKeyLength() const =0; + //! return length of ephemeral public keys in this domain + virtual unsigned int EphemeralPublicKeyLength() const =0; + //! generate ephemeral private key + /*! \pre size of privateKey == PrivateEphemeralKeyLength() */ + virtual void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const =0; + //! generate ephemeral public key + /*! \pre size of publicKey == PublicEphemeralKeyLength() */ + virtual void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const =0; + //! generate private/public key pair + /*! \note equivalent to calling GenerateEphemeralPrivateKey() and then GenerateEphemeralPublicKey() */ + virtual void GenerateEphemeralKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const; + + //! derive agreed value from your private keys and couterparty's public keys, return false in case of failure + /*! \note The ephemeral public key will always be validated. + If you have previously validated the static public key, use validateStaticOtherPublicKey=false to save time. + \pre size of agreedValue == AgreedValueLength() + \pre length of staticPrivateKey == StaticPrivateKeyLength() + \pre length of ephemeralPrivateKey == EphemeralPrivateKeyLength() + \pre length of staticOtherPublicKey == StaticPublicKeyLength() + \pre length of ephemeralOtherPublicKey == EphemeralPublicKeyLength() + */ + virtual bool Agree(byte *agreedValue, + const byte *staticPrivateKey, const byte *ephemeralPrivateKey, + const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey, + bool validateStaticOtherPublicKey=true) const =0; + +#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY + bool ValidateDomainParameters(RandomNumberGenerator &rng) const + {return GetCryptoParameters().Validate(rng, 2);} +#endif +}; + +// interface for password authenticated key agreement protocols, not implemented yet +#if 0 +//! interface for protocol sessions +/*! The methods should be called in the following order: + + InitializeSession(rng, parameters); // or call initialize method in derived class + while (true) + { + if (OutgoingMessageAvailable()) + { + length = GetOutgoingMessageLength(); + GetOutgoingMessage(message); + ; // send outgoing message + } + + if (LastMessageProcessed()) + break; + + ; // receive incoming message + ProcessIncomingMessage(message); + } + ; // call methods in derived class to obtain result of protocol session +*/ +class ProtocolSession +{ +public: + //! exception thrown when an invalid protocol message is processed + class ProtocolError : public Exception + { + public: + ProtocolError(ErrorType errorType, const std::string &s) : Exception(errorType, s) {} + }; + + //! exception thrown when a function is called unexpectedly + /*! for example calling ProcessIncomingMessage() when ProcessedLastMessage() == true */ + class UnexpectedMethodCall : public Exception + { + public: + UnexpectedMethodCall(const std::string &s) : Exception(OTHER_ERROR, s) {} + }; + + ProtocolSession() : m_rng(NULL), m_throwOnProtocolError(true), m_validState(false) {} + virtual ~ProtocolSession() {} + + virtual void InitializeSession(RandomNumberGenerator &rng, const NameValuePairs ¶meters) =0; + + bool GetThrowOnProtocolError() const {return m_throwOnProtocolError;} + void SetThrowOnProtocolError(bool throwOnProtocolError) {m_throwOnProtocolError = throwOnProtocolError;} + + bool HasValidState() const {return m_validState;} + + virtual bool OutgoingMessageAvailable() const =0; + virtual unsigned int GetOutgoingMessageLength() const =0; + virtual void GetOutgoingMessage(byte *message) =0; + + virtual bool LastMessageProcessed() const =0; + virtual void ProcessIncomingMessage(const byte *message, unsigned int messageLength) =0; + +protected: + void HandleProtocolError(Exception::ErrorType errorType, const std::string &s) const; + void CheckAndHandleInvalidState() const; + void SetValidState(bool valid) {m_validState = valid;} + + RandomNumberGenerator *m_rng; + +private: + bool m_throwOnProtocolError, m_validState; +}; + +class KeyAgreementSession : public ProtocolSession +{ +public: + virtual unsigned int GetAgreedValueLength() const =0; + virtual void GetAgreedValue(byte *agreedValue) const =0; +}; + +class PasswordAuthenticatedKeyAgreementSession : public KeyAgreementSession +{ +public: + void InitializePasswordAuthenticatedKeyAgreementSession(RandomNumberGenerator &rng, + const byte *myId, unsigned int myIdLength, + const byte *counterPartyId, unsigned int counterPartyIdLength, + const byte *passwordOrVerifier, unsigned int passwordOrVerifierLength); +}; + +class PasswordAuthenticatedKeyAgreementDomain : public KeyAgreementAlgorithm +{ +public: + //! return whether the domain parameters stored in this object are valid + virtual bool ValidateDomainParameters(RandomNumberGenerator &rng) const + {return GetCryptoParameters().Validate(rng, 2);} + + virtual unsigned int GetPasswordVerifierLength(const byte *password, unsigned int passwordLength) const =0; + virtual void GeneratePasswordVerifier(RandomNumberGenerator &rng, const byte *userId, unsigned int userIdLength, const byte *password, unsigned int passwordLength, byte *verifier) const =0; + + enum RoleFlags {CLIENT=1, SERVER=2, INITIATOR=4, RESPONDER=8}; + + virtual bool IsValidRole(unsigned int role) =0; + virtual PasswordAuthenticatedKeyAgreementSession * CreateProtocolSession(unsigned int role) const =0; +}; +#endif + +//! BER Decode Exception Class, may be thrown during an ASN1 BER decode operation +class CRYPTOPP_DLL BERDecodeErr : public InvalidArgument +{ +public: + BERDecodeErr() : InvalidArgument("BER decode error") {} + BERDecodeErr(const std::string &s) : InvalidArgument(s) {} +}; + +//! interface for encoding and decoding ASN1 objects +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE ASN1Object +{ +public: + virtual ~ASN1Object() {} + //! decode this object from a BufferedTransformation, using BER (Basic Encoding Rules) + virtual void BERDecode(BufferedTransformation &bt) =0; + //! encode this object into a BufferedTransformation, using DER (Distinguished Encoding Rules) + virtual void DEREncode(BufferedTransformation &bt) const =0; + //! encode this object into a BufferedTransformation, using BER + /*! this may be useful if DEREncode() would be too inefficient */ + virtual void BEREncode(BufferedTransformation &bt) const {DEREncode(bt);} +}; + +#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY +typedef PK_SignatureScheme PK_SignatureSystem; +typedef SimpleKeyAgreementDomain PK_SimpleKeyAgreementDomain; +typedef AuthenticatedKeyAgreementDomain PK_AuthenticatedKeyAgreementDomain; +#endif + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/cryptlib.mak b/CryptoPP/crypto/cryptlib.mak new file mode 100644 index 0000000..b9f57df --- /dev/null +++ b/CryptoPP/crypto/cryptlib.mak @@ -0,0 +1,1942 @@ +# Microsoft Developer Studio Generated NMAKE File, Based on cryptlib.dsp +!IF "$(CFG)" == "" +CFG=cryptlib - Win32 Debug +!MESSAGE No configuration specified. Defaulting to cryptlib - Win32 Debug. +!ENDIF + +!IF "$(CFG)" != "cryptlib - Win32 DLL-Import Release" && "$(CFG)" != "cryptlib - Win32 DLL-Import Debug" && "$(CFG)" != "cryptlib - Win32 Release" && "$(CFG)" != "cryptlib - Win32 Debug" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "cryptlib.mak" CFG="cryptlib - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "cryptlib - Win32 DLL-Import Release" (based on "Win32 (x86) Static Library") +!MESSAGE "cryptlib - Win32 DLL-Import Debug" (based on "Win32 (x86) Static Library") +!MESSAGE "cryptlib - Win32 Release" (based on "Win32 (x86) Static Library") +!MESSAGE "cryptlib - Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF + +!IF "$(CFG)" == "cryptlib - Win32 DLL-Import Release" + +OUTDIR=.\DLL_Import_Release +INTDIR=.\DLL_Import_Release +# Begin Custom Macros +OutDir=.\DLL_Import_Release +# End Custom Macros + +ALL : ".\adhoc.cpp.copied" "$(OUTDIR)\cryptlib.lib" + + +CLEAN : + -@erase "$(INTDIR)\3way.obj" + -@erase "$(INTDIR)\adler32.obj" + -@erase "$(INTDIR)\algebra.obj" + -@erase "$(INTDIR)\algparam.obj" + -@erase "$(INTDIR)\arc4.obj" + -@erase "$(INTDIR)\asn.obj" + -@erase "$(INTDIR)\base32.obj" + -@erase "$(INTDIR)\base64.obj" + -@erase "$(INTDIR)\basecode.obj" + -@erase "$(INTDIR)\bfinit.obj" + -@erase "$(INTDIR)\blowfish.obj" + -@erase "$(INTDIR)\blumshub.obj" + -@erase "$(INTDIR)\camellia.obj" + -@erase "$(INTDIR)\cast.obj" + -@erase "$(INTDIR)\casts.obj" + -@erase "$(INTDIR)\cbcmac.obj" + -@erase "$(INTDIR)\channels.obj" + -@erase "$(INTDIR)\cpu.obj" + -@erase "$(INTDIR)\crc.obj" + -@erase "$(INTDIR)\cryptlib.obj" + -@erase "$(INTDIR)\cryptlib.pch" + -@erase "$(INTDIR)\default.obj" + -@erase "$(INTDIR)\des.obj" + -@erase "$(INTDIR)\dessp.obj" + -@erase "$(INTDIR)\dh.obj" + -@erase "$(INTDIR)\dh2.obj" + -@erase "$(INTDIR)\dll.obj" + -@erase "$(INTDIR)\dsa.obj" + -@erase "$(INTDIR)\ec2n.obj" + -@erase "$(INTDIR)\eccrypto.obj" + -@erase "$(INTDIR)\ecp.obj" + -@erase "$(INTDIR)\elgamal.obj" + -@erase "$(INTDIR)\emsa2.obj" + -@erase "$(INTDIR)\eprecomp.obj" + -@erase "$(INTDIR)\esign.obj" + -@erase "$(INTDIR)\files.obj" + -@erase "$(INTDIR)\filters.obj" + -@erase "$(INTDIR)\fips140.obj" + -@erase "$(INTDIR)\fipstest.obj" + -@erase "$(INTDIR)\gf256.obj" + -@erase "$(INTDIR)\gf2_32.obj" + -@erase "$(INTDIR)\gf2n.obj" + -@erase "$(INTDIR)\gfpcrypt.obj" + -@erase "$(INTDIR)\gost.obj" + -@erase "$(INTDIR)\gzip.obj" + -@erase "$(INTDIR)\hex.obj" + -@erase "$(INTDIR)\hmac.obj" + -@erase "$(INTDIR)\hrtimer.obj" + -@erase "$(INTDIR)\ida.obj" + -@erase "$(INTDIR)\idea.obj" + -@erase "$(INTDIR)\integer.obj" + -@erase "$(INTDIR)\iterhash.obj" + -@erase "$(INTDIR)\luc.obj" + -@erase "$(INTDIR)\mars.obj" + -@erase "$(INTDIR)\marss.obj" + -@erase "$(INTDIR)\md2.obj" + -@erase "$(INTDIR)\md4.obj" + -@erase "$(INTDIR)\md5.obj" + -@erase "$(INTDIR)\misc.obj" + -@erase "$(INTDIR)\modes.obj" + -@erase "$(INTDIR)\mqueue.obj" + -@erase "$(INTDIR)\mqv.obj" + -@erase "$(INTDIR)\nbtheory.obj" + -@erase "$(INTDIR)\network.obj" + -@erase "$(INTDIR)\oaep.obj" + -@erase "$(INTDIR)\osrng.obj" + -@erase "$(INTDIR)\panama.obj" + -@erase "$(INTDIR)\pch.obj" + -@erase "$(INTDIR)\pkcspad.obj" + -@erase "$(INTDIR)\polynomi.obj" + -@erase "$(INTDIR)\pssr.obj" + -@erase "$(INTDIR)\pubkey.obj" + -@erase "$(INTDIR)\queue.obj" + -@erase "$(INTDIR)\rabin.obj" + -@erase "$(INTDIR)\randpool.obj" + -@erase "$(INTDIR)\rc2.obj" + -@erase "$(INTDIR)\rc5.obj" + -@erase "$(INTDIR)\rc6.obj" + -@erase "$(INTDIR)\rdtables.obj" + -@erase "$(INTDIR)\rijndael.obj" + -@erase "$(INTDIR)\ripemd.obj" + -@erase "$(INTDIR)\rng.obj" + -@erase "$(INTDIR)\rsa.obj" + -@erase "$(INTDIR)\rw.obj" + -@erase "$(INTDIR)\safer.obj" + -@erase "$(INTDIR)\salsa.obj" + -@erase "$(INTDIR)\seal.obj" + -@erase "$(INTDIR)\serpent.obj" + -@erase "$(INTDIR)\sha.obj" + -@erase "$(INTDIR)\shacal2.obj" + -@erase "$(INTDIR)\shark.obj" + -@erase "$(INTDIR)\sharkbox.obj" + -@erase "$(INTDIR)\simple.obj" + -@erase "$(INTDIR)\skipjack.obj" + -@erase "$(INTDIR)\socketft.obj" + -@erase "$(INTDIR)\sosemanuk.obj" + -@erase "$(INTDIR)\square.obj" + -@erase "$(INTDIR)\squaretb.obj" + -@erase "$(INTDIR)\strciphr.obj" + -@erase "$(INTDIR)\tea.obj" + -@erase "$(INTDIR)\tftables.obj" + -@erase "$(INTDIR)\tiger.obj" + -@erase "$(INTDIR)\tigertab.obj" + -@erase "$(INTDIR)\trdlocal.obj" + -@erase "$(INTDIR)\ttmac.obj" + -@erase "$(INTDIR)\twofish.obj" + -@erase "$(INTDIR)\vc60.idb" + -@erase "$(INTDIR)\vc60.pdb" + -@erase "$(INTDIR)\vmac.obj" + -@erase "$(INTDIR)\wait.obj" + -@erase "$(INTDIR)\wake.obj" + -@erase "$(INTDIR)\whrlpool.obj" + -@erase "$(INTDIR)\winpipes.obj" + -@erase "$(INTDIR)\xtr.obj" + -@erase "$(INTDIR)\xtrcrypt.obj" + -@erase "$(INTDIR)\zdeflate.obj" + -@erase "$(INTDIR)\zinflate.obj" + -@erase "$(INTDIR)\zlib.obj" + -@erase "$(OUTDIR)\cryptlib.lib" + -@erase "adhoc.cpp.copied" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +CPP_PROJ=/nologo /G5 /Gz /MT /W3 /GX /Zi /O2 /Ob2 /D "NDEBUG" /D "_WINDOWS" /D "USE_PRECOMPILED_HEADERS" /D "WIN32" /D "CRYPTOPP_IMPORTS" /Fp"$(INTDIR)\cryptlib.pch" /Yu"pch.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /Zm400 /c + +.c{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +RSC=rc.exe +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\cryptlib.bsc" +BSC32_SBRS= \ + +LIB32=link.exe -lib +LIB32_FLAGS=/nologo /out:"$(OUTDIR)\cryptlib.lib" +LIB32_OBJS= \ + "$(INTDIR)\3way.obj" \ + "$(INTDIR)\adler32.obj" \ + "$(INTDIR)\algebra.obj" \ + "$(INTDIR)\algparam.obj" \ + "$(INTDIR)\arc4.obj" \ + "$(INTDIR)\asn.obj" \ + "$(INTDIR)\base32.obj" \ + "$(INTDIR)\base64.obj" \ + "$(INTDIR)\basecode.obj" \ + "$(INTDIR)\bfinit.obj" \ + "$(INTDIR)\blowfish.obj" \ + "$(INTDIR)\blumshub.obj" \ + "$(INTDIR)\camellia.obj" \ + "$(INTDIR)\cast.obj" \ + "$(INTDIR)\casts.obj" \ + "$(INTDIR)\cbcmac.obj" \ + "$(INTDIR)\channels.obj" \ + "$(INTDIR)\cpu.obj" \ + "$(INTDIR)\crc.obj" \ + "$(INTDIR)\cryptlib.obj" \ + "$(INTDIR)\default.obj" \ + "$(INTDIR)\des.obj" \ + "$(INTDIR)\dessp.obj" \ + "$(INTDIR)\dh.obj" \ + "$(INTDIR)\dh2.obj" \ + "$(INTDIR)\dll.obj" \ + "$(INTDIR)\dsa.obj" \ + "$(INTDIR)\ec2n.obj" \ + "$(INTDIR)\eccrypto.obj" \ + "$(INTDIR)\ecp.obj" \ + "$(INTDIR)\elgamal.obj" \ + "$(INTDIR)\emsa2.obj" \ + "$(INTDIR)\eprecomp.obj" \ + "$(INTDIR)\esign.obj" \ + "$(INTDIR)\files.obj" \ + "$(INTDIR)\filters.obj" \ + "$(INTDIR)\fips140.obj" \ + "$(INTDIR)\fipstest.obj" \ + "$(INTDIR)\gf256.obj" \ + "$(INTDIR)\gf2_32.obj" \ + "$(INTDIR)\gf2n.obj" \ + "$(INTDIR)\gfpcrypt.obj" \ + "$(INTDIR)\gost.obj" \ + "$(INTDIR)\gzip.obj" \ + "$(INTDIR)\hex.obj" \ + "$(INTDIR)\hmac.obj" \ + "$(INTDIR)\hrtimer.obj" \ + "$(INTDIR)\ida.obj" \ + "$(INTDIR)\idea.obj" \ + "$(INTDIR)\integer.obj" \ + "$(INTDIR)\iterhash.obj" \ + "$(INTDIR)\luc.obj" \ + "$(INTDIR)\mars.obj" \ + "$(INTDIR)\marss.obj" \ + "$(INTDIR)\md2.obj" \ + "$(INTDIR)\md4.obj" \ + "$(INTDIR)\md5.obj" \ + "$(INTDIR)\misc.obj" \ + "$(INTDIR)\modes.obj" \ + "$(INTDIR)\mqueue.obj" \ + "$(INTDIR)\mqv.obj" \ + "$(INTDIR)\nbtheory.obj" \ + "$(INTDIR)\network.obj" \ + "$(INTDIR)\oaep.obj" \ + "$(INTDIR)\osrng.obj" \ + "$(INTDIR)\panama.obj" \ + "$(INTDIR)\pch.obj" \ + "$(INTDIR)\pkcspad.obj" \ + "$(INTDIR)\polynomi.obj" \ + "$(INTDIR)\pssr.obj" \ + "$(INTDIR)\pubkey.obj" \ + "$(INTDIR)\queue.obj" \ + "$(INTDIR)\rabin.obj" \ + "$(INTDIR)\randpool.obj" \ + "$(INTDIR)\rc2.obj" \ + "$(INTDIR)\rc5.obj" \ + "$(INTDIR)\rc6.obj" \ + "$(INTDIR)\rdtables.obj" \ + "$(INTDIR)\rijndael.obj" \ + "$(INTDIR)\ripemd.obj" \ + "$(INTDIR)\rng.obj" \ + "$(INTDIR)\rsa.obj" \ + "$(INTDIR)\rw.obj" \ + "$(INTDIR)\safer.obj" \ + "$(INTDIR)\salsa.obj" \ + "$(INTDIR)\seal.obj" \ + "$(INTDIR)\serpent.obj" \ + "$(INTDIR)\sha.obj" \ + "$(INTDIR)\shacal2.obj" \ + "$(INTDIR)\shark.obj" \ + "$(INTDIR)\sharkbox.obj" \ + "$(INTDIR)\simple.obj" \ + "$(INTDIR)\skipjack.obj" \ + "$(INTDIR)\socketft.obj" \ + "$(INTDIR)\sosemanuk.obj" \ + "$(INTDIR)\square.obj" \ + "$(INTDIR)\squaretb.obj" \ + "$(INTDIR)\strciphr.obj" \ + "$(INTDIR)\tea.obj" \ + "$(INTDIR)\tftables.obj" \ + "$(INTDIR)\tiger.obj" \ + "$(INTDIR)\tigertab.obj" \ + "$(INTDIR)\trdlocal.obj" \ + "$(INTDIR)\ttmac.obj" \ + "$(INTDIR)\twofish.obj" \ + "$(INTDIR)\vmac.obj" \ + "$(INTDIR)\wait.obj" \ + "$(INTDIR)\wake.obj" \ + "$(INTDIR)\whrlpool.obj" \ + "$(INTDIR)\winpipes.obj" \ + "$(INTDIR)\xtr.obj" \ + "$(INTDIR)\xtrcrypt.obj" \ + "$(INTDIR)\zdeflate.obj" \ + "$(INTDIR)\zinflate.obj" \ + "$(INTDIR)\zlib.obj" + +"$(OUTDIR)\cryptlib.lib" : "$(OUTDIR)" $(DEF_FILE) $(LIB32_OBJS) + $(LIB32) @<< + $(LIB32_FLAGS) $(DEF_FLAGS) $(LIB32_OBJS) +<< + +!ELSEIF "$(CFG)" == "cryptlib - Win32 DLL-Import Debug" + +OUTDIR=.\DLL_Import_Debug +INTDIR=.\DLL_Import_Debug +# Begin Custom Macros +OutDir=.\DLL_Import_Debug +# End Custom Macros + +ALL : ".\adhoc.cpp.copied" "$(OUTDIR)\cryptlib.lib" + + +CLEAN : + -@erase "$(INTDIR)\3way.obj" + -@erase "$(INTDIR)\adler32.obj" + -@erase "$(INTDIR)\algebra.obj" + -@erase "$(INTDIR)\algparam.obj" + -@erase "$(INTDIR)\arc4.obj" + -@erase "$(INTDIR)\asn.obj" + -@erase "$(INTDIR)\base32.obj" + -@erase "$(INTDIR)\base64.obj" + -@erase "$(INTDIR)\basecode.obj" + -@erase "$(INTDIR)\bfinit.obj" + -@erase "$(INTDIR)\blowfish.obj" + -@erase "$(INTDIR)\blumshub.obj" + -@erase "$(INTDIR)\camellia.obj" + -@erase "$(INTDIR)\cast.obj" + -@erase "$(INTDIR)\casts.obj" + -@erase "$(INTDIR)\cbcmac.obj" + -@erase "$(INTDIR)\channels.obj" + -@erase "$(INTDIR)\cpu.obj" + -@erase "$(INTDIR)\crc.obj" + -@erase "$(INTDIR)\cryptlib.obj" + -@erase "$(INTDIR)\cryptlib.pch" + -@erase "$(INTDIR)\default.obj" + -@erase "$(INTDIR)\des.obj" + -@erase "$(INTDIR)\dessp.obj" + -@erase "$(INTDIR)\dh.obj" + -@erase "$(INTDIR)\dh2.obj" + -@erase "$(INTDIR)\dll.obj" + -@erase "$(INTDIR)\dsa.obj" + -@erase "$(INTDIR)\ec2n.obj" + -@erase "$(INTDIR)\eccrypto.obj" + -@erase "$(INTDIR)\ecp.obj" + -@erase "$(INTDIR)\elgamal.obj" + -@erase "$(INTDIR)\emsa2.obj" + -@erase "$(INTDIR)\eprecomp.obj" + -@erase "$(INTDIR)\esign.obj" + -@erase "$(INTDIR)\files.obj" + -@erase "$(INTDIR)\filters.obj" + -@erase "$(INTDIR)\fips140.obj" + -@erase "$(INTDIR)\fipstest.obj" + -@erase "$(INTDIR)\gf256.obj" + -@erase "$(INTDIR)\gf2_32.obj" + -@erase "$(INTDIR)\gf2n.obj" + -@erase "$(INTDIR)\gfpcrypt.obj" + -@erase "$(INTDIR)\gost.obj" + -@erase "$(INTDIR)\gzip.obj" + -@erase "$(INTDIR)\hex.obj" + -@erase "$(INTDIR)\hmac.obj" + -@erase "$(INTDIR)\hrtimer.obj" + -@erase "$(INTDIR)\ida.obj" + -@erase "$(INTDIR)\idea.obj" + -@erase "$(INTDIR)\integer.obj" + -@erase "$(INTDIR)\iterhash.obj" + -@erase "$(INTDIR)\luc.obj" + -@erase "$(INTDIR)\mars.obj" + -@erase "$(INTDIR)\marss.obj" + -@erase "$(INTDIR)\md2.obj" + -@erase "$(INTDIR)\md4.obj" + -@erase "$(INTDIR)\md5.obj" + -@erase "$(INTDIR)\misc.obj" + -@erase "$(INTDIR)\modes.obj" + -@erase "$(INTDIR)\mqueue.obj" + -@erase "$(INTDIR)\mqv.obj" + -@erase "$(INTDIR)\nbtheory.obj" + -@erase "$(INTDIR)\network.obj" + -@erase "$(INTDIR)\oaep.obj" + -@erase "$(INTDIR)\osrng.obj" + -@erase "$(INTDIR)\panama.obj" + -@erase "$(INTDIR)\pch.obj" + -@erase "$(INTDIR)\pkcspad.obj" + -@erase "$(INTDIR)\polynomi.obj" + -@erase "$(INTDIR)\pssr.obj" + -@erase "$(INTDIR)\pubkey.obj" + -@erase "$(INTDIR)\queue.obj" + -@erase "$(INTDIR)\rabin.obj" + -@erase "$(INTDIR)\randpool.obj" + -@erase "$(INTDIR)\rc2.obj" + -@erase "$(INTDIR)\rc5.obj" + -@erase "$(INTDIR)\rc6.obj" + -@erase "$(INTDIR)\rdtables.obj" + -@erase "$(INTDIR)\rijndael.obj" + -@erase "$(INTDIR)\ripemd.obj" + -@erase "$(INTDIR)\rng.obj" + -@erase "$(INTDIR)\rsa.obj" + -@erase "$(INTDIR)\rw.obj" + -@erase "$(INTDIR)\safer.obj" + -@erase "$(INTDIR)\salsa.obj" + -@erase "$(INTDIR)\seal.obj" + -@erase "$(INTDIR)\serpent.obj" + -@erase "$(INTDIR)\sha.obj" + -@erase "$(INTDIR)\shacal2.obj" + -@erase "$(INTDIR)\shark.obj" + -@erase "$(INTDIR)\sharkbox.obj" + -@erase "$(INTDIR)\simple.obj" + -@erase "$(INTDIR)\skipjack.obj" + -@erase "$(INTDIR)\socketft.obj" + -@erase "$(INTDIR)\sosemanuk.obj" + -@erase "$(INTDIR)\square.obj" + -@erase "$(INTDIR)\squaretb.obj" + -@erase "$(INTDIR)\strciphr.obj" + -@erase "$(INTDIR)\tea.obj" + -@erase "$(INTDIR)\tftables.obj" + -@erase "$(INTDIR)\tiger.obj" + -@erase "$(INTDIR)\tigertab.obj" + -@erase "$(INTDIR)\trdlocal.obj" + -@erase "$(INTDIR)\ttmac.obj" + -@erase "$(INTDIR)\twofish.obj" + -@erase "$(INTDIR)\vc60.idb" + -@erase "$(INTDIR)\vc60.pdb" + -@erase "$(INTDIR)\vmac.obj" + -@erase "$(INTDIR)\wait.obj" + -@erase "$(INTDIR)\wake.obj" + -@erase "$(INTDIR)\whrlpool.obj" + -@erase "$(INTDIR)\winpipes.obj" + -@erase "$(INTDIR)\xtr.obj" + -@erase "$(INTDIR)\xtrcrypt.obj" + -@erase "$(INTDIR)\zdeflate.obj" + -@erase "$(INTDIR)\zinflate.obj" + -@erase "$(INTDIR)\zlib.obj" + -@erase "$(OUTDIR)\cryptlib.lib" + -@erase "adhoc.cpp.copied" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +CPP_PROJ=/nologo /G5 /Gz /MTd /W3 /GX /Zi /Oi /D "_DEBUG" /D "_WINDOWS" /D "USE_PRECOMPILED_HEADERS" /D "WIN32" /D "CRYPTOPP_IMPORTS" /Fp"$(INTDIR)\cryptlib.pch" /Yu"pch.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /Zm400 /c + +.c{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +RSC=rc.exe +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\cryptlib.bsc" +BSC32_SBRS= \ + +LIB32=link.exe -lib +LIB32_FLAGS=/nologo /out:"$(OUTDIR)\cryptlib.lib" +LIB32_OBJS= \ + "$(INTDIR)\3way.obj" \ + "$(INTDIR)\adler32.obj" \ + "$(INTDIR)\algebra.obj" \ + "$(INTDIR)\algparam.obj" \ + "$(INTDIR)\arc4.obj" \ + "$(INTDIR)\asn.obj" \ + "$(INTDIR)\base32.obj" \ + "$(INTDIR)\base64.obj" \ + "$(INTDIR)\basecode.obj" \ + "$(INTDIR)\bfinit.obj" \ + "$(INTDIR)\blowfish.obj" \ + "$(INTDIR)\blumshub.obj" \ + "$(INTDIR)\camellia.obj" \ + "$(INTDIR)\cast.obj" \ + "$(INTDIR)\casts.obj" \ + "$(INTDIR)\cbcmac.obj" \ + "$(INTDIR)\channels.obj" \ + "$(INTDIR)\cpu.obj" \ + "$(INTDIR)\crc.obj" \ + "$(INTDIR)\cryptlib.obj" \ + "$(INTDIR)\default.obj" \ + "$(INTDIR)\des.obj" \ + "$(INTDIR)\dessp.obj" \ + "$(INTDIR)\dh.obj" \ + "$(INTDIR)\dh2.obj" \ + "$(INTDIR)\dll.obj" \ + "$(INTDIR)\dsa.obj" \ + "$(INTDIR)\ec2n.obj" \ + "$(INTDIR)\eccrypto.obj" \ + "$(INTDIR)\ecp.obj" \ + "$(INTDIR)\elgamal.obj" \ + "$(INTDIR)\emsa2.obj" \ + "$(INTDIR)\eprecomp.obj" \ + "$(INTDIR)\esign.obj" \ + "$(INTDIR)\files.obj" \ + "$(INTDIR)\filters.obj" \ + "$(INTDIR)\fips140.obj" \ + "$(INTDIR)\fipstest.obj" \ + "$(INTDIR)\gf256.obj" \ + "$(INTDIR)\gf2_32.obj" \ + "$(INTDIR)\gf2n.obj" \ + "$(INTDIR)\gfpcrypt.obj" \ + "$(INTDIR)\gost.obj" \ + "$(INTDIR)\gzip.obj" \ + "$(INTDIR)\hex.obj" \ + "$(INTDIR)\hmac.obj" \ + "$(INTDIR)\hrtimer.obj" \ + "$(INTDIR)\ida.obj" \ + "$(INTDIR)\idea.obj" \ + "$(INTDIR)\integer.obj" \ + "$(INTDIR)\iterhash.obj" \ + "$(INTDIR)\luc.obj" \ + "$(INTDIR)\mars.obj" \ + "$(INTDIR)\marss.obj" \ + "$(INTDIR)\md2.obj" \ + "$(INTDIR)\md4.obj" \ + "$(INTDIR)\md5.obj" \ + "$(INTDIR)\misc.obj" \ + "$(INTDIR)\modes.obj" \ + "$(INTDIR)\mqueue.obj" \ + "$(INTDIR)\mqv.obj" \ + "$(INTDIR)\nbtheory.obj" \ + "$(INTDIR)\network.obj" \ + "$(INTDIR)\oaep.obj" \ + "$(INTDIR)\osrng.obj" \ + "$(INTDIR)\panama.obj" \ + "$(INTDIR)\pch.obj" \ + "$(INTDIR)\pkcspad.obj" \ + "$(INTDIR)\polynomi.obj" \ + "$(INTDIR)\pssr.obj" \ + "$(INTDIR)\pubkey.obj" \ + "$(INTDIR)\queue.obj" \ + "$(INTDIR)\rabin.obj" \ + "$(INTDIR)\randpool.obj" \ + "$(INTDIR)\rc2.obj" \ + "$(INTDIR)\rc5.obj" \ + "$(INTDIR)\rc6.obj" \ + "$(INTDIR)\rdtables.obj" \ + "$(INTDIR)\rijndael.obj" \ + "$(INTDIR)\ripemd.obj" \ + "$(INTDIR)\rng.obj" \ + "$(INTDIR)\rsa.obj" \ + "$(INTDIR)\rw.obj" \ + "$(INTDIR)\safer.obj" \ + "$(INTDIR)\salsa.obj" \ + "$(INTDIR)\seal.obj" \ + "$(INTDIR)\serpent.obj" \ + "$(INTDIR)\sha.obj" \ + "$(INTDIR)\shacal2.obj" \ + "$(INTDIR)\shark.obj" \ + "$(INTDIR)\sharkbox.obj" \ + "$(INTDIR)\simple.obj" \ + "$(INTDIR)\skipjack.obj" \ + "$(INTDIR)\socketft.obj" \ + "$(INTDIR)\sosemanuk.obj" \ + "$(INTDIR)\square.obj" \ + "$(INTDIR)\squaretb.obj" \ + "$(INTDIR)\strciphr.obj" \ + "$(INTDIR)\tea.obj" \ + "$(INTDIR)\tftables.obj" \ + "$(INTDIR)\tiger.obj" \ + "$(INTDIR)\tigertab.obj" \ + "$(INTDIR)\trdlocal.obj" \ + "$(INTDIR)\ttmac.obj" \ + "$(INTDIR)\twofish.obj" \ + "$(INTDIR)\vmac.obj" \ + "$(INTDIR)\wait.obj" \ + "$(INTDIR)\wake.obj" \ + "$(INTDIR)\whrlpool.obj" \ + "$(INTDIR)\winpipes.obj" \ + "$(INTDIR)\xtr.obj" \ + "$(INTDIR)\xtrcrypt.obj" \ + "$(INTDIR)\zdeflate.obj" \ + "$(INTDIR)\zinflate.obj" \ + "$(INTDIR)\zlib.obj" + +"$(OUTDIR)\cryptlib.lib" : "$(OUTDIR)" $(DEF_FILE) $(LIB32_OBJS) + $(LIB32) @<< + $(LIB32_FLAGS) $(DEF_FLAGS) $(LIB32_OBJS) +<< + +!ELSEIF "$(CFG)" == "cryptlib - Win32 Release" + +OUTDIR=.\Release +INTDIR=.\Release +# Begin Custom Macros +OutDir=.\Release +# End Custom Macros + +ALL : ".\adhoc.cpp.copied" "$(OUTDIR)\cryptlib.lib" + + +CLEAN : + -@erase "$(INTDIR)\3way.obj" + -@erase "$(INTDIR)\adler32.obj" + -@erase "$(INTDIR)\algebra.obj" + -@erase "$(INTDIR)\algparam.obj" + -@erase "$(INTDIR)\arc4.obj" + -@erase "$(INTDIR)\asn.obj" + -@erase "$(INTDIR)\base32.obj" + -@erase "$(INTDIR)\base64.obj" + -@erase "$(INTDIR)\basecode.obj" + -@erase "$(INTDIR)\bfinit.obj" + -@erase "$(INTDIR)\blowfish.obj" + -@erase "$(INTDIR)\blumshub.obj" + -@erase "$(INTDIR)\camellia.obj" + -@erase "$(INTDIR)\cast.obj" + -@erase "$(INTDIR)\casts.obj" + -@erase "$(INTDIR)\cbcmac.obj" + -@erase "$(INTDIR)\channels.obj" + -@erase "$(INTDIR)\cpu.obj" + -@erase "$(INTDIR)\crc.obj" + -@erase "$(INTDIR)\cryptlib.obj" + -@erase "$(INTDIR)\cryptlib.pch" + -@erase "$(INTDIR)\default.obj" + -@erase "$(INTDIR)\des.obj" + -@erase "$(INTDIR)\dessp.obj" + -@erase "$(INTDIR)\dh.obj" + -@erase "$(INTDIR)\dh2.obj" + -@erase "$(INTDIR)\dll.obj" + -@erase "$(INTDIR)\dsa.obj" + -@erase "$(INTDIR)\ec2n.obj" + -@erase "$(INTDIR)\eccrypto.obj" + -@erase "$(INTDIR)\ecp.obj" + -@erase "$(INTDIR)\elgamal.obj" + -@erase "$(INTDIR)\emsa2.obj" + -@erase "$(INTDIR)\eprecomp.obj" + -@erase "$(INTDIR)\esign.obj" + -@erase "$(INTDIR)\files.obj" + -@erase "$(INTDIR)\filters.obj" + -@erase "$(INTDIR)\fips140.obj" + -@erase "$(INTDIR)\fipstest.obj" + -@erase "$(INTDIR)\gf256.obj" + -@erase "$(INTDIR)\gf2_32.obj" + -@erase "$(INTDIR)\gf2n.obj" + -@erase "$(INTDIR)\gfpcrypt.obj" + -@erase "$(INTDIR)\gost.obj" + -@erase "$(INTDIR)\gzip.obj" + -@erase "$(INTDIR)\hex.obj" + -@erase "$(INTDIR)\hmac.obj" + -@erase "$(INTDIR)\hrtimer.obj" + -@erase "$(INTDIR)\ida.obj" + -@erase "$(INTDIR)\idea.obj" + -@erase "$(INTDIR)\integer.obj" + -@erase "$(INTDIR)\iterhash.obj" + -@erase "$(INTDIR)\luc.obj" + -@erase "$(INTDIR)\mars.obj" + -@erase "$(INTDIR)\marss.obj" + -@erase "$(INTDIR)\md2.obj" + -@erase "$(INTDIR)\md4.obj" + -@erase "$(INTDIR)\md5.obj" + -@erase "$(INTDIR)\misc.obj" + -@erase "$(INTDIR)\modes.obj" + -@erase "$(INTDIR)\mqueue.obj" + -@erase "$(INTDIR)\mqv.obj" + -@erase "$(INTDIR)\nbtheory.obj" + -@erase "$(INTDIR)\network.obj" + -@erase "$(INTDIR)\oaep.obj" + -@erase "$(INTDIR)\osrng.obj" + -@erase "$(INTDIR)\panama.obj" + -@erase "$(INTDIR)\pch.obj" + -@erase "$(INTDIR)\pkcspad.obj" + -@erase "$(INTDIR)\polynomi.obj" + -@erase "$(INTDIR)\pssr.obj" + -@erase "$(INTDIR)\pubkey.obj" + -@erase "$(INTDIR)\queue.obj" + -@erase "$(INTDIR)\rabin.obj" + -@erase "$(INTDIR)\randpool.obj" + -@erase "$(INTDIR)\rc2.obj" + -@erase "$(INTDIR)\rc5.obj" + -@erase "$(INTDIR)\rc6.obj" + -@erase "$(INTDIR)\rdtables.obj" + -@erase "$(INTDIR)\rijndael.obj" + -@erase "$(INTDIR)\ripemd.obj" + -@erase "$(INTDIR)\rng.obj" + -@erase "$(INTDIR)\rsa.obj" + -@erase "$(INTDIR)\rw.obj" + -@erase "$(INTDIR)\safer.obj" + -@erase "$(INTDIR)\salsa.obj" + -@erase "$(INTDIR)\seal.obj" + -@erase "$(INTDIR)\serpent.obj" + -@erase "$(INTDIR)\sha.obj" + -@erase "$(INTDIR)\shacal2.obj" + -@erase "$(INTDIR)\shark.obj" + -@erase "$(INTDIR)\sharkbox.obj" + -@erase "$(INTDIR)\simple.obj" + -@erase "$(INTDIR)\skipjack.obj" + -@erase "$(INTDIR)\socketft.obj" + -@erase "$(INTDIR)\sosemanuk.obj" + -@erase "$(INTDIR)\square.obj" + -@erase "$(INTDIR)\squaretb.obj" + -@erase "$(INTDIR)\strciphr.obj" + -@erase "$(INTDIR)\tea.obj" + -@erase "$(INTDIR)\tftables.obj" + -@erase "$(INTDIR)\tiger.obj" + -@erase "$(INTDIR)\tigertab.obj" + -@erase "$(INTDIR)\trdlocal.obj" + -@erase "$(INTDIR)\ttmac.obj" + -@erase "$(INTDIR)\twofish.obj" + -@erase "$(INTDIR)\vc60.idb" + -@erase "$(INTDIR)\vc60.pdb" + -@erase "$(INTDIR)\vmac.obj" + -@erase "$(INTDIR)\wait.obj" + -@erase "$(INTDIR)\wake.obj" + -@erase "$(INTDIR)\whrlpool.obj" + -@erase "$(INTDIR)\winpipes.obj" + -@erase "$(INTDIR)\xtr.obj" + -@erase "$(INTDIR)\xtrcrypt.obj" + -@erase "$(INTDIR)\zdeflate.obj" + -@erase "$(INTDIR)\zinflate.obj" + -@erase "$(INTDIR)\zlib.obj" + -@erase "$(OUTDIR)\cryptlib.lib" + -@erase "adhoc.cpp.copied" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +CPP_PROJ=/nologo /MD /W3 /GX /Zi /O1 /D "NDEBUG" /D "_WINDOWS" /D "USE_PRECOMPILED_HEADERS" /D "WIN32" /Fp"$(INTDIR)\cryptlib.pch" /Yu"pch.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /Zm400 /c + +.c{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +RSC=rc.exe +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\cryptlib.bsc" +BSC32_SBRS= \ + +LIB32=link.exe -lib +LIB32_FLAGS=/nologo /out:"$(OUTDIR)\cryptlib.lib" +LIB32_OBJS= \ + "$(INTDIR)\3way.obj" \ + "$(INTDIR)\adler32.obj" \ + "$(INTDIR)\algebra.obj" \ + "$(INTDIR)\algparam.obj" \ + "$(INTDIR)\arc4.obj" \ + "$(INTDIR)\asn.obj" \ + "$(INTDIR)\base32.obj" \ + "$(INTDIR)\base64.obj" \ + "$(INTDIR)\basecode.obj" \ + "$(INTDIR)\bfinit.obj" \ + "$(INTDIR)\blowfish.obj" \ + "$(INTDIR)\blumshub.obj" \ + "$(INTDIR)\camellia.obj" \ + "$(INTDIR)\cast.obj" \ + "$(INTDIR)\casts.obj" \ + "$(INTDIR)\cbcmac.obj" \ + "$(INTDIR)\channels.obj" \ + "$(INTDIR)\cpu.obj" \ + "$(INTDIR)\crc.obj" \ + "$(INTDIR)\cryptlib.obj" \ + "$(INTDIR)\default.obj" \ + "$(INTDIR)\des.obj" \ + "$(INTDIR)\dessp.obj" \ + "$(INTDIR)\dh.obj" \ + "$(INTDIR)\dh2.obj" \ + "$(INTDIR)\dll.obj" \ + "$(INTDIR)\dsa.obj" \ + "$(INTDIR)\ec2n.obj" \ + "$(INTDIR)\eccrypto.obj" \ + "$(INTDIR)\ecp.obj" \ + "$(INTDIR)\elgamal.obj" \ + "$(INTDIR)\emsa2.obj" \ + "$(INTDIR)\eprecomp.obj" \ + "$(INTDIR)\esign.obj" \ + "$(INTDIR)\files.obj" \ + "$(INTDIR)\filters.obj" \ + "$(INTDIR)\fips140.obj" \ + "$(INTDIR)\fipstest.obj" \ + "$(INTDIR)\gf256.obj" \ + "$(INTDIR)\gf2_32.obj" \ + "$(INTDIR)\gf2n.obj" \ + "$(INTDIR)\gfpcrypt.obj" \ + "$(INTDIR)\gost.obj" \ + "$(INTDIR)\gzip.obj" \ + "$(INTDIR)\hex.obj" \ + "$(INTDIR)\hmac.obj" \ + "$(INTDIR)\hrtimer.obj" \ + "$(INTDIR)\ida.obj" \ + "$(INTDIR)\idea.obj" \ + "$(INTDIR)\integer.obj" \ + "$(INTDIR)\iterhash.obj" \ + "$(INTDIR)\luc.obj" \ + "$(INTDIR)\mars.obj" \ + "$(INTDIR)\marss.obj" \ + "$(INTDIR)\md2.obj" \ + "$(INTDIR)\md4.obj" \ + "$(INTDIR)\md5.obj" \ + "$(INTDIR)\misc.obj" \ + "$(INTDIR)\modes.obj" \ + "$(INTDIR)\mqueue.obj" \ + "$(INTDIR)\mqv.obj" \ + "$(INTDIR)\nbtheory.obj" \ + "$(INTDIR)\network.obj" \ + "$(INTDIR)\oaep.obj" \ + "$(INTDIR)\osrng.obj" \ + "$(INTDIR)\panama.obj" \ + "$(INTDIR)\pch.obj" \ + "$(INTDIR)\pkcspad.obj" \ + "$(INTDIR)\polynomi.obj" \ + "$(INTDIR)\pssr.obj" \ + "$(INTDIR)\pubkey.obj" \ + "$(INTDIR)\queue.obj" \ + "$(INTDIR)\rabin.obj" \ + "$(INTDIR)\randpool.obj" \ + "$(INTDIR)\rc2.obj" \ + "$(INTDIR)\rc5.obj" \ + "$(INTDIR)\rc6.obj" \ + "$(INTDIR)\rdtables.obj" \ + "$(INTDIR)\rijndael.obj" \ + "$(INTDIR)\ripemd.obj" \ + "$(INTDIR)\rng.obj" \ + "$(INTDIR)\rsa.obj" \ + "$(INTDIR)\rw.obj" \ + "$(INTDIR)\safer.obj" \ + "$(INTDIR)\salsa.obj" \ + "$(INTDIR)\seal.obj" \ + "$(INTDIR)\serpent.obj" \ + "$(INTDIR)\sha.obj" \ + "$(INTDIR)\shacal2.obj" \ + "$(INTDIR)\shark.obj" \ + "$(INTDIR)\sharkbox.obj" \ + "$(INTDIR)\simple.obj" \ + "$(INTDIR)\skipjack.obj" \ + "$(INTDIR)\socketft.obj" \ + "$(INTDIR)\sosemanuk.obj" \ + "$(INTDIR)\square.obj" \ + "$(INTDIR)\squaretb.obj" \ + "$(INTDIR)\strciphr.obj" \ + "$(INTDIR)\tea.obj" \ + "$(INTDIR)\tftables.obj" \ + "$(INTDIR)\tiger.obj" \ + "$(INTDIR)\tigertab.obj" \ + "$(INTDIR)\trdlocal.obj" \ + "$(INTDIR)\ttmac.obj" \ + "$(INTDIR)\twofish.obj" \ + "$(INTDIR)\vmac.obj" \ + "$(INTDIR)\wait.obj" \ + "$(INTDIR)\wake.obj" \ + "$(INTDIR)\whrlpool.obj" \ + "$(INTDIR)\winpipes.obj" \ + "$(INTDIR)\xtr.obj" \ + "$(INTDIR)\xtrcrypt.obj" \ + "$(INTDIR)\zdeflate.obj" \ + "$(INTDIR)\zinflate.obj" \ + "$(INTDIR)\zlib.obj" + +"$(OUTDIR)\cryptlib.lib" : "$(OUTDIR)" $(DEF_FILE) $(LIB32_OBJS) + $(LIB32) @<< + $(LIB32_FLAGS) $(DEF_FLAGS) $(LIB32_OBJS) +<< + +!ELSEIF "$(CFG)" == "cryptlib - Win32 Debug" + +OUTDIR=.\Debug +INTDIR=.\Debug +# Begin Custom Macros +OutDir=.\Debug +# End Custom Macros + +ALL : ".\adhoc.cpp.copied" "$(OUTDIR)\cryptlib.lib" + + +CLEAN : + -@erase "$(INTDIR)\3way.obj" + -@erase "$(INTDIR)\adler32.obj" + -@erase "$(INTDIR)\algebra.obj" + -@erase "$(INTDIR)\algparam.obj" + -@erase "$(INTDIR)\arc4.obj" + -@erase "$(INTDIR)\asn.obj" + -@erase "$(INTDIR)\base32.obj" + -@erase "$(INTDIR)\base64.obj" + -@erase "$(INTDIR)\basecode.obj" + -@erase "$(INTDIR)\bfinit.obj" + -@erase "$(INTDIR)\blowfish.obj" + -@erase "$(INTDIR)\blumshub.obj" + -@erase "$(INTDIR)\camellia.obj" + -@erase "$(INTDIR)\cast.obj" + -@erase "$(INTDIR)\casts.obj" + -@erase "$(INTDIR)\cbcmac.obj" + -@erase "$(INTDIR)\channels.obj" + -@erase "$(INTDIR)\cpu.obj" + -@erase "$(INTDIR)\crc.obj" + -@erase "$(INTDIR)\cryptlib.obj" + -@erase "$(INTDIR)\cryptlib.pch" + -@erase "$(INTDIR)\default.obj" + -@erase "$(INTDIR)\des.obj" + -@erase "$(INTDIR)\dessp.obj" + -@erase "$(INTDIR)\dh.obj" + -@erase "$(INTDIR)\dh2.obj" + -@erase "$(INTDIR)\dll.obj" + -@erase "$(INTDIR)\dsa.obj" + -@erase "$(INTDIR)\ec2n.obj" + -@erase "$(INTDIR)\eccrypto.obj" + -@erase "$(INTDIR)\ecp.obj" + -@erase "$(INTDIR)\elgamal.obj" + -@erase "$(INTDIR)\emsa2.obj" + -@erase "$(INTDIR)\eprecomp.obj" + -@erase "$(INTDIR)\esign.obj" + -@erase "$(INTDIR)\files.obj" + -@erase "$(INTDIR)\filters.obj" + -@erase "$(INTDIR)\fips140.obj" + -@erase "$(INTDIR)\fipstest.obj" + -@erase "$(INTDIR)\gf256.obj" + -@erase "$(INTDIR)\gf2_32.obj" + -@erase "$(INTDIR)\gf2n.obj" + -@erase "$(INTDIR)\gfpcrypt.obj" + -@erase "$(INTDIR)\gost.obj" + -@erase "$(INTDIR)\gzip.obj" + -@erase "$(INTDIR)\hex.obj" + -@erase "$(INTDIR)\hmac.obj" + -@erase "$(INTDIR)\hrtimer.obj" + -@erase "$(INTDIR)\ida.obj" + -@erase "$(INTDIR)\idea.obj" + -@erase "$(INTDIR)\integer.obj" + -@erase "$(INTDIR)\iterhash.obj" + -@erase "$(INTDIR)\luc.obj" + -@erase "$(INTDIR)\mars.obj" + -@erase "$(INTDIR)\marss.obj" + -@erase "$(INTDIR)\md2.obj" + -@erase "$(INTDIR)\md4.obj" + -@erase "$(INTDIR)\md5.obj" + -@erase "$(INTDIR)\misc.obj" + -@erase "$(INTDIR)\modes.obj" + -@erase "$(INTDIR)\mqueue.obj" + -@erase "$(INTDIR)\mqv.obj" + -@erase "$(INTDIR)\nbtheory.obj" + -@erase "$(INTDIR)\network.obj" + -@erase "$(INTDIR)\oaep.obj" + -@erase "$(INTDIR)\osrng.obj" + -@erase "$(INTDIR)\panama.obj" + -@erase "$(INTDIR)\pch.obj" + -@erase "$(INTDIR)\pkcspad.obj" + -@erase "$(INTDIR)\polynomi.obj" + -@erase "$(INTDIR)\pssr.obj" + -@erase "$(INTDIR)\pubkey.obj" + -@erase "$(INTDIR)\queue.obj" + -@erase "$(INTDIR)\rabin.obj" + -@erase "$(INTDIR)\randpool.obj" + -@erase "$(INTDIR)\rc2.obj" + -@erase "$(INTDIR)\rc5.obj" + -@erase "$(INTDIR)\rc6.obj" + -@erase "$(INTDIR)\rdtables.obj" + -@erase "$(INTDIR)\rijndael.obj" + -@erase "$(INTDIR)\ripemd.obj" + -@erase "$(INTDIR)\rng.obj" + -@erase "$(INTDIR)\rsa.obj" + -@erase "$(INTDIR)\rw.obj" + -@erase "$(INTDIR)\safer.obj" + -@erase "$(INTDIR)\salsa.obj" + -@erase "$(INTDIR)\seal.obj" + -@erase "$(INTDIR)\serpent.obj" + -@erase "$(INTDIR)\sha.obj" + -@erase "$(INTDIR)\shacal2.obj" + -@erase "$(INTDIR)\shark.obj" + -@erase "$(INTDIR)\sharkbox.obj" + -@erase "$(INTDIR)\simple.obj" + -@erase "$(INTDIR)\skipjack.obj" + -@erase "$(INTDIR)\socketft.obj" + -@erase "$(INTDIR)\sosemanuk.obj" + -@erase "$(INTDIR)\square.obj" + -@erase "$(INTDIR)\squaretb.obj" + -@erase "$(INTDIR)\strciphr.obj" + -@erase "$(INTDIR)\tea.obj" + -@erase "$(INTDIR)\tftables.obj" + -@erase "$(INTDIR)\tiger.obj" + -@erase "$(INTDIR)\tigertab.obj" + -@erase "$(INTDIR)\trdlocal.obj" + -@erase "$(INTDIR)\ttmac.obj" + -@erase "$(INTDIR)\twofish.obj" + -@erase "$(INTDIR)\vc60.idb" + -@erase "$(INTDIR)\vc60.pdb" + -@erase "$(INTDIR)\vmac.obj" + -@erase "$(INTDIR)\wait.obj" + -@erase "$(INTDIR)\wake.obj" + -@erase "$(INTDIR)\whrlpool.obj" + -@erase "$(INTDIR)\winpipes.obj" + -@erase "$(INTDIR)\xtr.obj" + -@erase "$(INTDIR)\xtrcrypt.obj" + -@erase "$(INTDIR)\zdeflate.obj" + -@erase "$(INTDIR)\zinflate.obj" + -@erase "$(INTDIR)\zlib.obj" + -@erase "$(OUTDIR)\cryptlib.lib" + -@erase "adhoc.cpp.copied" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +CPP_PROJ=/nologo /MDd /W3 /GX /Zi /Oi /D "_DEBUG" /D "_WINDOWS" /D "USE_PRECOMPILED_HEADERS" /D "WIN32" /Fp"$(INTDIR)\cryptlib.pch" /Yu"pch.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /Zm400 /c + +.c{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +RSC=rc.exe +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\cryptlib.bsc" +BSC32_SBRS= \ + +LIB32=link.exe -lib +LIB32_FLAGS=/nologo /out:"$(OUTDIR)\cryptlib.lib" +LIB32_OBJS= \ + "$(INTDIR)\3way.obj" \ + "$(INTDIR)\adler32.obj" \ + "$(INTDIR)\algebra.obj" \ + "$(INTDIR)\algparam.obj" \ + "$(INTDIR)\arc4.obj" \ + "$(INTDIR)\asn.obj" \ + "$(INTDIR)\base32.obj" \ + "$(INTDIR)\base64.obj" \ + "$(INTDIR)\basecode.obj" \ + "$(INTDIR)\bfinit.obj" \ + "$(INTDIR)\blowfish.obj" \ + "$(INTDIR)\blumshub.obj" \ + "$(INTDIR)\camellia.obj" \ + "$(INTDIR)\cast.obj" \ + "$(INTDIR)\casts.obj" \ + "$(INTDIR)\cbcmac.obj" \ + "$(INTDIR)\channels.obj" \ + "$(INTDIR)\cpu.obj" \ + "$(INTDIR)\crc.obj" \ + "$(INTDIR)\cryptlib.obj" \ + "$(INTDIR)\default.obj" \ + "$(INTDIR)\des.obj" \ + "$(INTDIR)\dessp.obj" \ + "$(INTDIR)\dh.obj" \ + "$(INTDIR)\dh2.obj" \ + "$(INTDIR)\dll.obj" \ + "$(INTDIR)\dsa.obj" \ + "$(INTDIR)\ec2n.obj" \ + "$(INTDIR)\eccrypto.obj" \ + "$(INTDIR)\ecp.obj" \ + "$(INTDIR)\elgamal.obj" \ + "$(INTDIR)\emsa2.obj" \ + "$(INTDIR)\eprecomp.obj" \ + "$(INTDIR)\esign.obj" \ + "$(INTDIR)\files.obj" \ + "$(INTDIR)\filters.obj" \ + "$(INTDIR)\fips140.obj" \ + "$(INTDIR)\fipstest.obj" \ + "$(INTDIR)\gf256.obj" \ + "$(INTDIR)\gf2_32.obj" \ + "$(INTDIR)\gf2n.obj" \ + "$(INTDIR)\gfpcrypt.obj" \ + "$(INTDIR)\gost.obj" \ + "$(INTDIR)\gzip.obj" \ + "$(INTDIR)\hex.obj" \ + "$(INTDIR)\hmac.obj" \ + "$(INTDIR)\hrtimer.obj" \ + "$(INTDIR)\ida.obj" \ + "$(INTDIR)\idea.obj" \ + "$(INTDIR)\integer.obj" \ + "$(INTDIR)\iterhash.obj" \ + "$(INTDIR)\luc.obj" \ + "$(INTDIR)\mars.obj" \ + "$(INTDIR)\marss.obj" \ + "$(INTDIR)\md2.obj" \ + "$(INTDIR)\md4.obj" \ + "$(INTDIR)\md5.obj" \ + "$(INTDIR)\misc.obj" \ + "$(INTDIR)\modes.obj" \ + "$(INTDIR)\mqueue.obj" \ + "$(INTDIR)\mqv.obj" \ + "$(INTDIR)\nbtheory.obj" \ + "$(INTDIR)\network.obj" \ + "$(INTDIR)\oaep.obj" \ + "$(INTDIR)\osrng.obj" \ + "$(INTDIR)\panama.obj" \ + "$(INTDIR)\pch.obj" \ + "$(INTDIR)\pkcspad.obj" \ + "$(INTDIR)\polynomi.obj" \ + "$(INTDIR)\pssr.obj" \ + "$(INTDIR)\pubkey.obj" \ + "$(INTDIR)\queue.obj" \ + "$(INTDIR)\rabin.obj" \ + "$(INTDIR)\randpool.obj" \ + "$(INTDIR)\rc2.obj" \ + "$(INTDIR)\rc5.obj" \ + "$(INTDIR)\rc6.obj" \ + "$(INTDIR)\rdtables.obj" \ + "$(INTDIR)\rijndael.obj" \ + "$(INTDIR)\ripemd.obj" \ + "$(INTDIR)\rng.obj" \ + "$(INTDIR)\rsa.obj" \ + "$(INTDIR)\rw.obj" \ + "$(INTDIR)\safer.obj" \ + "$(INTDIR)\salsa.obj" \ + "$(INTDIR)\seal.obj" \ + "$(INTDIR)\serpent.obj" \ + "$(INTDIR)\sha.obj" \ + "$(INTDIR)\shacal2.obj" \ + "$(INTDIR)\shark.obj" \ + "$(INTDIR)\sharkbox.obj" \ + "$(INTDIR)\simple.obj" \ + "$(INTDIR)\skipjack.obj" \ + "$(INTDIR)\socketft.obj" \ + "$(INTDIR)\sosemanuk.obj" \ + "$(INTDIR)\square.obj" \ + "$(INTDIR)\squaretb.obj" \ + "$(INTDIR)\strciphr.obj" \ + "$(INTDIR)\tea.obj" \ + "$(INTDIR)\tftables.obj" \ + "$(INTDIR)\tiger.obj" \ + "$(INTDIR)\tigertab.obj" \ + "$(INTDIR)\trdlocal.obj" \ + "$(INTDIR)\ttmac.obj" \ + "$(INTDIR)\twofish.obj" \ + "$(INTDIR)\vmac.obj" \ + "$(INTDIR)\wait.obj" \ + "$(INTDIR)\wake.obj" \ + "$(INTDIR)\whrlpool.obj" \ + "$(INTDIR)\winpipes.obj" \ + "$(INTDIR)\xtr.obj" \ + "$(INTDIR)\xtrcrypt.obj" \ + "$(INTDIR)\zdeflate.obj" \ + "$(INTDIR)\zinflate.obj" \ + "$(INTDIR)\zlib.obj" + +"$(OUTDIR)\cryptlib.lib" : "$(OUTDIR)" $(DEF_FILE) $(LIB32_OBJS) + $(LIB32) @<< + $(LIB32_FLAGS) $(DEF_FLAGS) $(LIB32_OBJS) +<< + +!ENDIF + + +!IF "$(NO_EXTERNAL_DEPS)" != "1" +!IF EXISTS("cryptlib.dep") +!INCLUDE "cryptlib.dep" +!ELSE +!MESSAGE Warning: cannot find "cryptlib.dep" +!ENDIF +!ENDIF + + +!IF "$(CFG)" == "cryptlib - Win32 DLL-Import Release" || "$(CFG)" == "cryptlib - Win32 DLL-Import Debug" || "$(CFG)" == "cryptlib - Win32 Release" || "$(CFG)" == "cryptlib - Win32 Debug" +SOURCE=.\3way.cpp + +"$(INTDIR)\3way.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\adhoc.cpp.proto + +!IF "$(CFG)" == "cryptlib - Win32 DLL-Import Release" + +InputPath=.\adhoc.cpp.proto + +".\adhoc.cpp.copied" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + <> adhoc.cpp.copied +<< + + +!ELSEIF "$(CFG)" == "cryptlib - Win32 DLL-Import Debug" + +InputPath=.\adhoc.cpp.proto + +".\adhoc.cpp.copied" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + <> adhoc.cpp.copied +<< + + +!ELSEIF "$(CFG)" == "cryptlib - Win32 Release" + +InputPath=.\adhoc.cpp.proto + +".\adhoc.cpp.copied" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + <> adhoc.cpp.copied +<< + + +!ELSEIF "$(CFG)" == "cryptlib - Win32 Debug" + +InputPath=.\adhoc.cpp.proto + +".\adhoc.cpp.copied" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + <> adhoc.cpp.copied +<< + + +!ENDIF + +SOURCE=.\adler32.cpp + +"$(INTDIR)\adler32.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\algebra.cpp + +"$(INTDIR)\algebra.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\algparam.cpp + +"$(INTDIR)\algparam.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\arc4.cpp + +"$(INTDIR)\arc4.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\asn.cpp + +"$(INTDIR)\asn.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\base32.cpp + +"$(INTDIR)\base32.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\base64.cpp + +"$(INTDIR)\base64.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\basecode.cpp + +"$(INTDIR)\basecode.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\bfinit.cpp + +"$(INTDIR)\bfinit.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\blowfish.cpp + +"$(INTDIR)\blowfish.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\blumshub.cpp + +"$(INTDIR)\blumshub.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\camellia.cpp + +"$(INTDIR)\camellia.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\cast.cpp + +"$(INTDIR)\cast.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\casts.cpp + +"$(INTDIR)\casts.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\cbcmac.cpp + +"$(INTDIR)\cbcmac.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\channels.cpp + +"$(INTDIR)\channels.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\cpu.cpp + +"$(INTDIR)\cpu.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\crc.cpp + +"$(INTDIR)\crc.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\cryptlib.cpp + +"$(INTDIR)\cryptlib.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\default.cpp + +"$(INTDIR)\default.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\des.cpp + +"$(INTDIR)\des.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\dessp.cpp + +"$(INTDIR)\dessp.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\dh.cpp + +"$(INTDIR)\dh.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\dh2.cpp + +"$(INTDIR)\dh2.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\dll.cpp + +!IF "$(CFG)" == "cryptlib - Win32 DLL-Import Release" + +CPP_SWITCHES=/nologo /G5 /Gz /MT /W3 /GX /Zi /O2 /Ob2 /D "NDEBUG" /D "_WINDOWS" /D "USE_PRECOMPILED_HEADERS" /D "WIN32" /D "CRYPTOPP_IMPORTS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /Zm400 /c + +"$(INTDIR)\dll.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) @<< + $(CPP_SWITCHES) $(SOURCE) +<< + + +!ELSEIF "$(CFG)" == "cryptlib - Win32 DLL-Import Debug" + +CPP_SWITCHES=/nologo /G5 /Gz /MTd /W3 /GX /Zi /Oi /D "_DEBUG" /D "_WINDOWS" /D "USE_PRECOMPILED_HEADERS" /D "WIN32" /D "CRYPTOPP_IMPORTS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /Zm400 /c + +"$(INTDIR)\dll.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) @<< + $(CPP_SWITCHES) $(SOURCE) +<< + + +!ELSEIF "$(CFG)" == "cryptlib - Win32 Release" + +CPP_SWITCHES=/nologo /MD /W3 /GX /Zi /O1 /D "NDEBUG" /D "_WINDOWS" /D "USE_PRECOMPILED_HEADERS" /D "WIN32" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /Zm400 /c + +"$(INTDIR)\dll.obj" : $(SOURCE) "$(INTDIR)" ".\strciphr.cpp" + $(CPP) @<< + $(CPP_SWITCHES) $(SOURCE) +<< + + +!ELSEIF "$(CFG)" == "cryptlib - Win32 Debug" + +CPP_SWITCHES=/nologo /MDd /W3 /GX /Zi /Oi /D "_DEBUG" /D "_WINDOWS" /D "USE_PRECOMPILED_HEADERS" /D "WIN32" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /Zm400 /c + +"$(INTDIR)\dll.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) @<< + $(CPP_SWITCHES) $(SOURCE) +<< + + +!ENDIF + +SOURCE=.\dsa.cpp + +"$(INTDIR)\dsa.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\ec2n.cpp + +"$(INTDIR)\ec2n.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\eccrypto.cpp + +"$(INTDIR)\eccrypto.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\ecp.cpp + +"$(INTDIR)\ecp.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\elgamal.cpp + +"$(INTDIR)\elgamal.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\emsa2.cpp + +"$(INTDIR)\emsa2.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\eprecomp.cpp + +"$(INTDIR)\eprecomp.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\esign.cpp + +"$(INTDIR)\esign.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\files.cpp + +"$(INTDIR)\files.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\filters.cpp + +"$(INTDIR)\filters.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\fips140.cpp + +"$(INTDIR)\fips140.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\fipstest.cpp + +"$(INTDIR)\fipstest.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\gf256.cpp + +"$(INTDIR)\gf256.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\gf2_32.cpp + +"$(INTDIR)\gf2_32.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\gf2n.cpp + +"$(INTDIR)\gf2n.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\gfpcrypt.cpp + +"$(INTDIR)\gfpcrypt.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\gost.cpp + +"$(INTDIR)\gost.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\gzip.cpp + +"$(INTDIR)\gzip.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\hex.cpp + +"$(INTDIR)\hex.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\hmac.cpp + +"$(INTDIR)\hmac.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\hrtimer.cpp + +"$(INTDIR)\hrtimer.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\ida.cpp + +"$(INTDIR)\ida.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\idea.cpp + +"$(INTDIR)\idea.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\integer.cpp + +"$(INTDIR)\integer.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\iterhash.cpp + +"$(INTDIR)\iterhash.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\luc.cpp + +"$(INTDIR)\luc.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\mars.cpp + +"$(INTDIR)\mars.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\marss.cpp + +"$(INTDIR)\marss.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\md2.cpp + +"$(INTDIR)\md2.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\md4.cpp + +"$(INTDIR)\md4.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\md5.cpp + +"$(INTDIR)\md5.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\misc.cpp + +"$(INTDIR)\misc.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\modes.cpp + +"$(INTDIR)\modes.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\mqueue.cpp + +"$(INTDIR)\mqueue.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\mqv.cpp + +"$(INTDIR)\mqv.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\nbtheory.cpp + +"$(INTDIR)\nbtheory.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\network.cpp + +"$(INTDIR)\network.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\oaep.cpp + +"$(INTDIR)\oaep.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\osrng.cpp + +"$(INTDIR)\osrng.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\panama.cpp + +"$(INTDIR)\panama.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\pch.cpp + +!IF "$(CFG)" == "cryptlib - Win32 DLL-Import Release" + +CPP_SWITCHES=/nologo /G5 /Gz /MT /W3 /GX /Zi /O2 /Ob2 /D "NDEBUG" /D "_WINDOWS" /D "USE_PRECOMPILED_HEADERS" /D "WIN32" /D "CRYPTOPP_IMPORTS" /Fp"$(INTDIR)\cryptlib.pch" /Yc"pch.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /Zm400 /c + +"$(INTDIR)\pch.obj" "$(INTDIR)\cryptlib.pch" : $(SOURCE) "$(INTDIR)" + $(CPP) @<< + $(CPP_SWITCHES) $(SOURCE) +<< + + +!ELSEIF "$(CFG)" == "cryptlib - Win32 DLL-Import Debug" + +CPP_SWITCHES=/nologo /G5 /Gz /MTd /W3 /GX /Zi /Oi /D "_DEBUG" /D "_WINDOWS" /D "USE_PRECOMPILED_HEADERS" /D "WIN32" /D "CRYPTOPP_IMPORTS" /Fp"$(INTDIR)\cryptlib.pch" /Yc"pch.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /Zm400 /c + +"$(INTDIR)\pch.obj" "$(INTDIR)\cryptlib.pch" : $(SOURCE) "$(INTDIR)" + $(CPP) @<< + $(CPP_SWITCHES) $(SOURCE) +<< + + +!ELSEIF "$(CFG)" == "cryptlib - Win32 Release" + +CPP_SWITCHES=/nologo /MD /W3 /GX /Zi /O1 /D "NDEBUG" /D "_WINDOWS" /D "USE_PRECOMPILED_HEADERS" /D "WIN32" /Fp"$(INTDIR)\cryptlib.pch" /Yc"pch.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /Zm400 /c + +"$(INTDIR)\pch.obj" "$(INTDIR)\cryptlib.pch" : $(SOURCE) "$(INTDIR)" + $(CPP) @<< + $(CPP_SWITCHES) $(SOURCE) +<< + + +!ELSEIF "$(CFG)" == "cryptlib - Win32 Debug" + +CPP_SWITCHES=/nologo /MDd /W3 /GX /Zi /Oi /D "_DEBUG" /D "_WINDOWS" /D "USE_PRECOMPILED_HEADERS" /D "WIN32" /Fp"$(INTDIR)\cryptlib.pch" /Yc"pch.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /Zm400 /c + +"$(INTDIR)\pch.obj" "$(INTDIR)\cryptlib.pch" : $(SOURCE) "$(INTDIR)" + $(CPP) @<< + $(CPP_SWITCHES) $(SOURCE) +<< + + +!ENDIF + +SOURCE=.\pkcspad.cpp + +"$(INTDIR)\pkcspad.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\polynomi.cpp + +"$(INTDIR)\polynomi.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\pssr.cpp + +"$(INTDIR)\pssr.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\pubkey.cpp + +"$(INTDIR)\pubkey.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\queue.cpp + +"$(INTDIR)\queue.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\rabin.cpp + +"$(INTDIR)\rabin.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\randpool.cpp + +"$(INTDIR)\randpool.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\rc2.cpp + +"$(INTDIR)\rc2.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\rc5.cpp + +"$(INTDIR)\rc5.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\rc6.cpp + +"$(INTDIR)\rc6.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\rdtables.cpp + +"$(INTDIR)\rdtables.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\rijndael.cpp + +"$(INTDIR)\rijndael.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\ripemd.cpp + +"$(INTDIR)\ripemd.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\rng.cpp + +"$(INTDIR)\rng.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\rsa.cpp + +"$(INTDIR)\rsa.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\rw.cpp + +"$(INTDIR)\rw.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\safer.cpp + +"$(INTDIR)\safer.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\salsa.cpp + +"$(INTDIR)\salsa.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\seal.cpp + +"$(INTDIR)\seal.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\serpent.cpp + +"$(INTDIR)\serpent.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\sha.cpp + +"$(INTDIR)\sha.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\shacal2.cpp + +"$(INTDIR)\shacal2.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\shark.cpp + +"$(INTDIR)\shark.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\sharkbox.cpp + +"$(INTDIR)\sharkbox.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\simple.cpp + +"$(INTDIR)\simple.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\skipjack.cpp + +"$(INTDIR)\skipjack.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\socketft.cpp + +"$(INTDIR)\socketft.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\sosemanuk.cpp + +"$(INTDIR)\sosemanuk.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\square.cpp + +"$(INTDIR)\square.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\squaretb.cpp + +"$(INTDIR)\squaretb.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\strciphr.cpp + +"$(INTDIR)\strciphr.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\tea.cpp + +"$(INTDIR)\tea.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\tftables.cpp + +"$(INTDIR)\tftables.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\tiger.cpp + +"$(INTDIR)\tiger.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\tigertab.cpp + +"$(INTDIR)\tigertab.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\trdlocal.cpp + +"$(INTDIR)\trdlocal.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\ttmac.cpp + +"$(INTDIR)\ttmac.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\twofish.cpp + +"$(INTDIR)\twofish.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\vmac.cpp + +"$(INTDIR)\vmac.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\wait.cpp + +"$(INTDIR)\wait.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\wake.cpp + +"$(INTDIR)\wake.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\whrlpool.cpp + +"$(INTDIR)\whrlpool.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\winpipes.cpp + +"$(INTDIR)\winpipes.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\xtr.cpp + +"$(INTDIR)\xtr.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\xtrcrypt.cpp + +"$(INTDIR)\xtrcrypt.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\zdeflate.cpp + +"$(INTDIR)\zdeflate.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\zinflate.cpp + +"$(INTDIR)\zinflate.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + +SOURCE=.\zlib.cpp + +"$(INTDIR)\zlib.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptlib.pch" + + + +!ENDIF + diff --git a/CryptoPP/crypto/cryptlib_9.vcproj b/CryptoPP/crypto/cryptlib_9.vcproj new file mode 100644 index 0000000..e8383f8 --- /dev/null +++ b/CryptoPP/crypto/cryptlib_9.vcproj @@ -0,0 +1,5012 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CryptoPP/crypto/cryptlib_bds.cpp b/CryptoPP/crypto/cryptlib_bds.cpp new file mode 100644 index 0000000..40fc247 --- /dev/null +++ b/CryptoPP/crypto/cryptlib_bds.cpp @@ -0,0 +1,10 @@ +//--------------------------------------------------------------------------- + +/* +#include +#pragma hdrstop +*/ +#define Library + +// To add a file to the library use the Project menu 'Add to Project'. + diff --git a/CryptoPP/crypto/crypto54msvc6.patch b/CryptoPP/crypto/crypto54msvc6.patch new file mode 100644 index 0000000..5a5b57b --- /dev/null +++ b/CryptoPP/crypto/crypto54msvc6.patch @@ -0,0 +1,241 @@ +Index: config.h +=================================================================== +RCS file: /cvsroot/cryptopp/c5/config.h,v +retrieving revision 1.28 +diff -c -r1.28 config.h +*** config.h 20 Dec 2006 15:20:00 -0000 1.28 +--- config.h 25 Dec 2006 08:07:27 -0000 +*************** +*** 154,159 **** +--- 154,161 ---- + const unsigned int WORD_SIZE = sizeof(word); + const unsigned int WORD_BITS = WORD_SIZE * 8; + ++ NAMESPACE_END ++ + #if defined(_MSC_VER) // || defined(__BORLANDC__) intrinsics don't work on BCB 2006 + #define INTEL_INTRINSICS + #define FAST_ROTATE +*************** +*** 171,188 **** + #define CRYPTOPP_L1_CACHE_LINE_SIZE 32 + #endif + + #ifndef CRYPTOPP_L1_CACHE_ALIGN +! #if defined(_MSC_VER) + #define CRYPTOPP_L1_CACHE_ALIGN(x) __declspec(align(CRYPTOPP_L1_CACHE_LINE_SIZE)) x + #elif defined(__GNUC__) + #define CRYPTOPP_L1_CACHE_ALIGN(x) x __attribute__((aligned(CRYPTOPP_L1_CACHE_LINE_SIZE))) + #else + #define CRYPTOPP_L1_CACHE_ALIGN(x) x + #endif + #endif + +- NAMESPACE_END +- + // VC60 workaround: it doesn't allow typename in some places + #if defined(_MSC_VER) && (_MSC_VER < 1300) + #define CPP_TYPENAME +--- 173,198 ---- + #define CRYPTOPP_L1_CACHE_LINE_SIZE 32 + #endif + ++ #if defined(_MSC_VER) ++ #if _MSC_VER == 1200 ++ #include ++ #endif ++ #if _MSC_VER > 1200 || defined(_mm_free) ++ #define CRYPTOPP_MSVC6PP_OR_LATER // VC 6 processor pack or later ++ #endif ++ #endif ++ + #ifndef CRYPTOPP_L1_CACHE_ALIGN +! #if defined(CRYPTOPP_MSVC6PP_OR_LATER) + #define CRYPTOPP_L1_CACHE_ALIGN(x) __declspec(align(CRYPTOPP_L1_CACHE_LINE_SIZE)) x + #elif defined(__GNUC__) + #define CRYPTOPP_L1_CACHE_ALIGN(x) x __attribute__((aligned(CRYPTOPP_L1_CACHE_LINE_SIZE))) + #else ++ #define CRYPTOPP_L1_CACHE_ALIGN_NOT_AVAILABLE + #define CRYPTOPP_L1_CACHE_ALIGN(x) x + #endif + #endif + + // VC60 workaround: it doesn't allow typename in some places + #if defined(_MSC_VER) && (_MSC_VER < 1300) + #define CPP_TYPENAME +*************** +*** 190,195 **** +--- 200,212 ---- + #define CPP_TYPENAME typename + #endif + ++ // VC60 workaround: can't cast unsigned __int64 to float or double ++ #if defined(_MSC_VER) && !defined(CRYPTOPP_MSVC6PP_OR_LATER) ++ #define CRYPTOPP_VC6_INT64 (__int64) ++ #else ++ #define CRYPTOPP_VC6_INT64 ++ #endif ++ + #ifdef _MSC_VER + #define CRYPTOPP_NO_VTABLE __declspec(novtable) + #else +*************** +*** 239,255 **** + #endif + + // how to declare class constants +! #if defined(_MSC_VER) && _MSC_VER < 1300 + # define CRYPTOPP_CONSTANT(x) enum {x}; + #else + # define CRYPTOPP_CONSTANT(x) static const int x; + #endif + +! // how to allocate 16-byte aligned memory (for SSE2) +! #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) +! # define CRYPTOPP_MALLOC_ALIGNMENT_IS_16 +! #elif defined(__linux__) || defined(__sun__) || defined(__CYGWIN__) +! # define CRYPTOPP_MEMALIGN_AVAILABLE + #endif + + // ***************** determine availability of OS features ******************** +--- 256,282 ---- + #endif + + // how to declare class constants +! #if defined(_MSC_VER) && _MSC_VER <= 1300 + # define CRYPTOPP_CONSTANT(x) enum {x}; + #else + # define CRYPTOPP_CONSTANT(x) static const int x; + #endif + +! #ifdef CRYPTOPP_X86ASM_AVAILABLE +! #if defined(CRYPTOPP_MSVC6PP_OR_LATER) || (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 500)) || (defined(__ICL) && (__ICL >= 500)) +! #define SSE2_INTRINSICS_AVAILABLE +! #define CRYPTOPP_MM_MALLOC_AVAILABLE +! #endif +! // SSE2 intrinsics work in GCC 3.3 or later +! #if defined(__SSE2__) && (__GNUC__ > 3 || __GNUC_MINOR__ > 2) +! #define SSE2_INTRINSICS_AVAILABLE +! // how to allocate 16-byte aligned memory (for SSE2) +! #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) +! #define CRYPTOPP_MALLOC_ALIGNMENT_IS_16 +! #elif defined(__linux__) || defined(__sun__) || defined(__CYGWIN__) +! #define CRYPTOPP_MEMALIGN_AVAILABLE +! #endif +! #endif + #endif + + // ***************** determine availability of OS features ******************** +Index: hrtimer.cpp +=================================================================== +RCS file: /cvsroot/cryptopp/c5/hrtimer.cpp,v +retrieving revision 1.11 +diff -c -r1.11 hrtimer.cpp +*** hrtimer.cpp 18 Dec 2006 02:34:32 -0000 1.11 +--- hrtimer.cpp 25 Dec 2006 08:07:27 -0000 +*************** +*** 23,35 **** + static unsigned long unitsPerSecondTable[] = {1, 1000, 1000*1000, 1000*1000*1000}; + + assert(unit < sizeof(unitsPerSecondTable) / sizeof(unitsPerSecondTable[0])); +! #if defined(_MSC_VER) && (_MSC_VER < 1300) +! // MSVC 6 workaround +! return (double)(__int64)t * unitsPerSecondTable[unit] / (__int64)TicksPerSecond(); +! #else +! return (double)t * unitsPerSecondTable[unit] / TicksPerSecond(); +! #endif +! + } + + void TimerBase::StartTimer() +--- 23,29 ---- + static unsigned long unitsPerSecondTable[] = {1, 1000, 1000*1000, 1000*1000*1000}; + + assert(unit < sizeof(unitsPerSecondTable) / sizeof(unitsPerSecondTable[0])); +! return (double)CRYPTOPP_VC6_INT64 t * unitsPerSecondTable[unit] / CRYPTOPP_VC6_INT64 TicksPerSecond(); + } + + void TimerBase::StartTimer() +Index: integer.h +=================================================================== +RCS file: /cvsroot/cryptopp/c5/integer.h,v +retrieving revision 1.13 +diff -c -r1.13 integer.h +*** integer.h 9 Jun 2006 06:28:22 -0000 1.13 +--- integer.h 25 Dec 2006 08:07:27 -0000 +*************** +*** 9,37 **** + #include + #include + +- #ifdef CRYPTOPP_X86ASM_AVAILABLE +- +- #ifdef _M_IX86 +- #if (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 500)) || (defined(__ICL) && (__ICL >= 500)) +- #define SSE2_INTRINSICS_AVAILABLE +- #define CRYPTOPP_MM_MALLOC_AVAILABLE +- #elif defined(_MSC_VER) +- // _mm_free seems to be the only way to tell if the Processor Pack is installed or not +- #include +- #if defined(_mm_free) +- #define SSE2_INTRINSICS_AVAILABLE +- #define CRYPTOPP_MM_MALLOC_AVAILABLE +- #endif +- #endif +- #endif +- +- // SSE2 intrinsics work in GCC 3.3 or later +- #if defined(__SSE2__) && (__GNUC__ > 3 || __GNUC_MINOR__ > 2) +- #define SSE2_INTRINSICS_AVAILABLE +- #endif +- +- #endif +- + NAMESPACE_BEGIN(CryptoPP) + + #if defined(SSE2_INTRINSICS_AVAILABLE) +--- 9,14 ---- +Index: network.cpp +=================================================================== +RCS file: /cvsroot/cryptopp/c5/network.cpp,v +retrieving revision 1.8 +diff -c -r1.8 network.cpp +*** network.cpp 18 Dec 2006 02:34:32 -0000 1.8 +--- network.cpp 25 Dec 2006 08:07:27 -0000 +*************** +*** 395,401 **** + float NetworkSink::GetMaxObservedSpeed() const + { + lword m = GetMaxBytesPerSecond(); +! return m ? STDMIN(m_maxObservedSpeed, float(m)) : m_maxObservedSpeed; + } + + unsigned int NetworkSink::GetMaxWaitObjectCount() const +--- 395,401 ---- + float NetworkSink::GetMaxObservedSpeed() const + { + lword m = GetMaxBytesPerSecond(); +! return m ? STDMIN(m_maxObservedSpeed, float(CRYPTOPP_VC6_INT64 m)) : m_maxObservedSpeed; + } + + unsigned int NetworkSink::GetMaxWaitObjectCount() const +Index: rijndael.cpp +=================================================================== +RCS file: /cvsroot/cryptopp/c5/rijndael.cpp,v +retrieving revision 1.5 +diff -c -r1.5 rijndael.cpp +*** rijndael.cpp 14 Dec 2006 11:41:31 -0000 1.5 +--- rijndael.cpp 25 Dec 2006 08:07:27 -0000 +*************** +*** 52,57 **** +--- 52,61 ---- + #include "rijndael.h" + #include "misc.h" + ++ #ifdef CRYPTOPP_L1_CACHE_ALIGN_NOT_AVAILABLE ++ #pragma message("Don't know how to align data on L1 cache boundary. Defense against AES timing attack may be affected.") ++ #endif ++ + NAMESPACE_BEGIN(CryptoPP) + + void Rijndael::Base::UncheckedSetKey(const byte *userKey, unsigned int keylen, const NameValuePairs &) diff --git a/CryptoPP/crypto/cryptopp.rc b/CryptoPP/crypto/cryptopp.rc new file mode 100644 index 0000000..8ebf925 --- /dev/null +++ b/CryptoPP/crypto/cryptopp.rc @@ -0,0 +1,104 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 5,5,2,0 + PRODUCTVERSION 5,5,2,0 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "Comments", "free crypto library, more information available at www.cryptopp.com" + VALUE "CompanyName", "Wei Dai" + VALUE "FileDescription", "Crypto++® Library DLL" + VALUE "FileVersion", "5, 5, 2, 0" + VALUE "InternalName", "cryptopp" + VALUE "LegalCopyright", "Copyright © 1995-2007 by Wei Dai" + VALUE "LegalTrademarks", "Crypto++®" + VALUE "OriginalFilename", "cryptopp.dll" + VALUE "ProductName", "Crypto++® Library" + VALUE "ProductVersion", "5, 5, 2, 0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/CryptoPP/crypto/datatest.cpp b/CryptoPP/crypto/datatest.cpp new file mode 100644 index 0000000..4a6fb04 --- /dev/null +++ b/CryptoPP/crypto/datatest.cpp @@ -0,0 +1,564 @@ +#include "factory.h" +#include "integer.h" +#include "filters.h" +#include "hex.h" +#include "randpool.h" +#include "files.h" +#include "trunhash.h" +#include "queue.h" +#include "validate.h" +#include +#include + +USING_NAMESPACE(CryptoPP) +USING_NAMESPACE(std) + +typedef std::map TestData; + +class TestFailure : public Exception +{ +public: + TestFailure() : Exception(OTHER_ERROR, "Validation test failed") {} +}; + +static const TestData *s_currentTestData = NULL; + +static void OutputTestData(const TestData &v) +{ + for (TestData::const_iterator i = v.begin(); i != v.end(); ++i) + { + cerr << i->first << ": " << i->second << endl; + } +} + +static void SignalTestFailure() +{ + OutputTestData(*s_currentTestData); + throw TestFailure(); +} + +static void SignalTestError() +{ + OutputTestData(*s_currentTestData); + throw Exception(Exception::OTHER_ERROR, "Unexpected error during validation test"); +} + +const std::string & GetRequiredDatum(const TestData &data, const char *name) +{ + TestData::const_iterator i = data.find(name); + if (i == data.end()) + SignalTestError(); + return i->second; +} + +void PutDecodedDatumInto(const TestData &data, const char *name, BufferedTransformation &target) +{ + std::string s1 = GetRequiredDatum(data, name), s2; + + while (!s1.empty()) + { + while (s1[0] == ' ') + s1 = s1.substr(1); + + int repeat = 1; + if (s1[0] == 'r') + { + repeat = atoi(s1.c_str()+1); + s1 = s1.substr(s1.find(' ')+1); + } + + s2 = ""; // MSVC 6 doesn't have clear(); + + if (s1[0] == '\"') + { + s2 = s1.substr(1, s1.find('\"', 1)-1); + s1 = s1.substr(s2.length() + 2); + } + else if (s1.substr(0, 2) == "0x") + { + StringSource(s1.substr(2, s1.find(' ')), true, new HexDecoder(new StringSink(s2))); + s1 = s1.substr(STDMIN(s1.find(' '), s1.length())); + } + else + { + StringSource(s1.substr(0, s1.find(' ')), true, new HexDecoder(new StringSink(s2))); + s1 = s1.substr(STDMIN(s1.find(' '), s1.length())); + } + + ByteQueue q; + while (repeat--) + { + q.Put((const byte *)s2.data(), s2.size()); + if (q.MaxRetrievable() > 4*1024 || repeat == 0) + q.TransferTo(target); + } + } +} + +std::string GetDecodedDatum(const TestData &data, const char *name) +{ + std::string s; + PutDecodedDatumInto(data, name, StringSink(s).Ref()); + return s; +} + +class TestDataNameValuePairs : public NameValuePairs +{ +public: + TestDataNameValuePairs(const TestData &data) : m_data(data) {} + + virtual bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const + { + TestData::const_iterator i = m_data.find(name); + if (i == m_data.end()) + return false; + + const std::string &value = i->second; + + if (valueType == typeid(int)) + *reinterpret_cast(pValue) = atoi(value.c_str()); + else if (valueType == typeid(Integer)) + *reinterpret_cast(pValue) = Integer((std::string(value) + "h").c_str()); + else if (valueType == typeid(ConstByteArrayParameter)) + { + m_temp.resize(0); + PutDecodedDatumInto(m_data, name, StringSink(m_temp).Ref()); + reinterpret_cast(pValue)->Assign((const byte *)m_temp.data(), m_temp.size(), true); + } + else if (valueType == typeid(const byte *)) + { + m_temp.resize(0); + PutDecodedDatumInto(m_data, name, StringSink(m_temp).Ref()); + *reinterpret_cast(pValue) = (const byte *)m_temp.data(); + } + else + throw ValueTypeMismatch(name, typeid(std::string), valueType); + + return true; + } + +private: + const TestData &m_data; + mutable std::string m_temp; +}; + +void TestKeyPairValidAndConsistent(CryptoMaterial &pub, const CryptoMaterial &priv) +{ + if (!pub.Validate(GlobalRNG(), 3)) + SignalTestFailure(); + if (!priv.Validate(GlobalRNG(), 3)) + SignalTestFailure(); + +/* EqualityComparisonFilter comparison; + pub.Save(ChannelSwitch(comparison, "0")); + pub.AssignFrom(priv); + pub.Save(ChannelSwitch(comparison, "1")); + comparison.ChannelMessageSeriesEnd("0"); + comparison.ChannelMessageSeriesEnd("1"); +*/ +} + +void TestSignatureScheme(TestData &v) +{ + std::string name = GetRequiredDatum(v, "Name"); + std::string test = GetRequiredDatum(v, "Test"); + + std::auto_ptr signer(ObjectFactoryRegistry::Registry().CreateObject(name.c_str())); + std::auto_ptr verifier(ObjectFactoryRegistry::Registry().CreateObject(name.c_str())); + + TestDataNameValuePairs pairs(v); + std::string keyFormat = GetRequiredDatum(v, "KeyFormat"); + + if (keyFormat == "DER") + verifier->AccessMaterial().Load(StringStore(GetDecodedDatum(v, "PublicKey")).Ref()); + else if (keyFormat == "Component") + verifier->AccessMaterial().AssignFrom(pairs); + + if (test == "Verify" || test == "NotVerify") + { + VerifierFilter verifierFilter(*verifier, NULL, VerifierFilter::SIGNATURE_AT_BEGIN); + PutDecodedDatumInto(v, "Signature", verifierFilter); + PutDecodedDatumInto(v, "Message", verifierFilter); + verifierFilter.MessageEnd(); + if (verifierFilter.GetLastResult() == (test == "NotVerify")) + SignalTestFailure(); + } + else if (test == "PublicKeyValid") + { + if (!verifier->GetMaterial().Validate(GlobalRNG(), 3)) + SignalTestFailure(); + } + else + goto privateKeyTests; + + return; + +privateKeyTests: + if (keyFormat == "DER") + signer->AccessMaterial().Load(StringStore(GetDecodedDatum(v, "PrivateKey")).Ref()); + else if (keyFormat == "Component") + signer->AccessMaterial().AssignFrom(pairs); + + if (test == "KeyPairValidAndConsistent") + { + TestKeyPairValidAndConsistent(verifier->AccessMaterial(), signer->GetMaterial()); + } + else if (test == "Sign") + { + SignerFilter f(GlobalRNG(), *signer, new HexEncoder(new FileSink(cout))); + StringSource ss(GetDecodedDatum(v, "Message"), true, new Redirector(f)); + SignalTestFailure(); + } + else if (test == "DeterministicSign") + { + SignalTestError(); + assert(false); // TODO: implement + } + else if (test == "RandomSign") + { + SignalTestError(); + assert(false); // TODO: implement + } + else if (test == "GenerateKey") + { + SignalTestError(); + assert(false); + } + else + { + SignalTestError(); + assert(false); + } +} + +void TestAsymmetricCipher(TestData &v) +{ + std::string name = GetRequiredDatum(v, "Name"); + std::string test = GetRequiredDatum(v, "Test"); + + std::auto_ptr encryptor(ObjectFactoryRegistry::Registry().CreateObject(name.c_str())); + std::auto_ptr decryptor(ObjectFactoryRegistry::Registry().CreateObject(name.c_str())); + + std::string keyFormat = GetRequiredDatum(v, "KeyFormat"); + + if (keyFormat == "DER") + { + decryptor->AccessMaterial().Load(StringStore(GetDecodedDatum(v, "PrivateKey")).Ref()); + encryptor->AccessMaterial().Load(StringStore(GetDecodedDatum(v, "PublicKey")).Ref()); + } + else if (keyFormat == "Component") + { + TestDataNameValuePairs pairs(v); + decryptor->AccessMaterial().AssignFrom(pairs); + encryptor->AccessMaterial().AssignFrom(pairs); + } + + if (test == "DecryptMatch") + { + std::string decrypted, expected = GetDecodedDatum(v, "Plaintext"); + StringSource ss(GetDecodedDatum(v, "Ciphertext"), true, new PK_DecryptorFilter(GlobalRNG(), *decryptor, new StringSink(decrypted))); + if (decrypted != expected) + SignalTestFailure(); + } + else if (test == "KeyPairValidAndConsistent") + { + TestKeyPairValidAndConsistent(encryptor->AccessMaterial(), decryptor->GetMaterial()); + } + else + { + SignalTestError(); + assert(false); + } +} + +void TestSymmetricCipher(TestData &v) +{ + std::string name = GetRequiredDatum(v, "Name"); + std::string test = GetRequiredDatum(v, "Test"); + + std::string key = GetDecodedDatum(v, "Key"); + std::string plaintext = GetDecodedDatum(v, "Plaintext"); + + TestDataNameValuePairs pairs(v); + + if (test == "Encrypt" || test == "EncryptXorDigest") + { + std::auto_ptr encryptor(ObjectFactoryRegistry::Registry().CreateObject(name.c_str())); + std::auto_ptr decryptor(ObjectFactoryRegistry::Registry().CreateObject(name.c_str())); + ConstByteArrayParameter iv; + if (pairs.GetValue(Name::IV(), iv) && iv.size() != encryptor->IVSize()) + SignalTestFailure(); + encryptor->SetKey((const byte *)key.data(), key.size(), pairs); + decryptor->SetKey((const byte *)key.data(), key.size(), pairs); + int seek = pairs.GetIntValueWithDefault("Seek", 0); + if (seek) + { + encryptor->Seek(seek); + decryptor->Seek(seek); + } + std::string encrypted, xorDigest, ciphertext, ciphertextXorDigest; + StringSource ss(plaintext, false, new StreamTransformationFilter(*encryptor, new StringSink(encrypted), StreamTransformationFilter::NO_PADDING)); + ss.Pump(plaintext.size()/2 + 1); + ss.PumpAll(); + /*{ + std::string z; + encryptor->Seek(seek); + StringSource ss(plaintext, false, new StreamTransformationFilter(*encryptor, new StringSink(z), StreamTransformationFilter::NO_PADDING)); + while (ss.Pump(64)) {} + ss.PumpAll(); + for (int i=0; i mac; + member_ptr hash; + HashTransformation *pHash = NULL; + + TestDataNameValuePairs pairs(v); + + if (testDigest) + { + hash.reset(ObjectFactoryRegistry::Registry().CreateObject(name.c_str())); + pHash = hash.get(); + } + else + { + mac.reset(ObjectFactoryRegistry::Registry().CreateObject(name.c_str())); + pHash = mac.get(); + ConstByteArrayParameter iv; + if (pairs.GetValue(Name::IV(), iv) && iv.size() != mac->IVSize()) + SignalTestFailure(); + std::string key = GetDecodedDatum(v, "Key"); + mac->SetKey((const byte *)key.c_str(), key.size(), pairs); + } + + if (test == "Verify" || test == "VerifyTruncated" || test == "NotVerify") + { + int digestSize = pHash->DigestSize(); + if (test == "VerifyTruncated") + digestSize = atoi(GetRequiredDatum(v, "TruncatedSize").c_str()); + TruncatedHashModule thash(*pHash, digestSize); + HashVerificationFilter verifierFilter(thash, NULL, HashVerificationFilter::HASH_AT_BEGIN); + PutDecodedDatumInto(v, "Digest", verifierFilter); + PutDecodedDatumInto(v, "Message", verifierFilter); + verifierFilter.MessageEnd(); + if (verifierFilter.GetLastResult() == (test == "NotVerify")) + SignalTestFailure(); + } + else + { + SignalTestError(); + assert(false); + } +} + +bool GetField(std::istream &is, std::string &name, std::string &value) +{ + name.resize(0); // GCC workaround: 2.95.3 doesn't have clear() + is >> name; + if (name.empty()) + return false; + + if (name[name.size()-1] != ':') + SignalTestError(); + name.erase(name.size()-1); + + while (is.peek() == ' ') + is.ignore(1); + + // VC60 workaround: getline bug + char buffer[128]; + value.resize(0); // GCC workaround: 2.95.3 doesn't have clear() + bool continueLine; + + do + { + do + { + is.get(buffer, sizeof(buffer)); + value += buffer; + } + while (buffer[0] != 0); + is.clear(); + is.ignore(); + + if (!value.empty() && value[value.size()-1] == '\r') + value.resize(value.size()-1); + + if (!value.empty() && value[value.size()-1] == '\\') + { + value.resize(value.size()-1); + continueLine = true; + } + else + continueLine = false; + + std::string::size_type i = value.find('#'); + if (i != std::string::npos) + value.erase(i); + } + while (continueLine); + + return true; +} + +void OutputPair(const NameValuePairs &v, const char *name) +{ + Integer x; + bool b = v.GetValue(name, x); + assert(b); + cout << name << ": \\\n "; + x.Encode(HexEncoder(new FileSink(cout), false, 64, "\\\n ").Ref(), x.MinEncodedSize()); + cout << endl; +} + +void OutputNameValuePairs(const NameValuePairs &v) +{ + std::string names = v.GetValueNames(); + string::size_type i = 0; + while (i < names.size()) + { + string::size_type j = names.find_first_of (';', i); + + if (j == string::npos) + return; + else + { + std::string name = names.substr(i, j-i); + if (name.find(':') == string::npos) + OutputPair(v, name.c_str()); + } + + i = j + 1; + } +} + +void TestDataFile(const std::string &filename, unsigned int &totalTests, unsigned int &failedTests) +{ + std::ifstream file(filename.c_str()); + if (!file.good()) + throw Exception(Exception::OTHER_ERROR, "Can not open file " + filename + " for reading"); + TestData v; + s_currentTestData = &v; + std::string name, value, lastAlgName; + + while (file) + { + while (file.peek() == '#') + file.ignore(INT_MAX, '\n'); + + if (file.peek() == '\n') + v.clear(); + + if (!GetField(file, name, value)) + break; + v[name] = value; + + if (name == "Test") + { + bool failed = true; + std::string algType = GetRequiredDatum(v, "AlgorithmType"); + + if (lastAlgName != GetRequiredDatum(v, "Name")) + { + lastAlgName = GetRequiredDatum(v, "Name"); + cout << "\nTesting " << algType.c_str() << " algorithm " << lastAlgName.c_str() << ".\n"; + } + + try + { + if (algType == "Signature") + TestSignatureScheme(v); + else if (algType == "SymmetricCipher") + TestSymmetricCipher(v); + else if (algType == "AsymmetricCipher") + TestAsymmetricCipher(v); + else if (algType == "MessageDigest") + TestDigestOrMAC(v, true); + else if (algType == "MAC") + TestDigestOrMAC(v, false); + else if (algType == "FileList") + TestDataFile(GetRequiredDatum(v, "Test"), totalTests, failedTests); + else + SignalTestError(); + failed = false; + } + catch (TestFailure &) + { + cout << "\nTest failed.\n"; + } + catch (CryptoPP::Exception &e) + { + cout << "\nCryptoPP::Exception caught: " << e.what() << endl; + } + catch (std::exception &e) + { + cout << "\nstd::exception caught: " << e.what() << endl; + } + + if (failed) + { + cout << "Skipping to next test.\n"; + failedTests++; + } + else + cout << "." << flush; + + totalTests++; + } + } +} + +bool RunTestDataFile(const char *filename) +{ + unsigned int totalTests = 0, failedTests = 0; + TestDataFile(filename, totalTests, failedTests); + cout << "\nTests complete. Total tests = " << totalTests << ". Failed tests = " << failedTests << ".\n"; + if (failedTests != 0) + cout << "SOME TESTS FAILED!\n"; + return failedTests == 0; +} diff --git a/CryptoPP/crypto/default.cpp b/CryptoPP/crypto/default.cpp new file mode 100644 index 0000000..c7f9b2c --- /dev/null +++ b/CryptoPP/crypto/default.cpp @@ -0,0 +1,258 @@ +// default.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "default.h" +#include "queue.h" +#include +#include + +NAMESPACE_BEGIN(CryptoPP) + +static const unsigned int MASH_ITERATIONS = 200; +static const unsigned int SALTLENGTH = 8; +static const unsigned int BLOCKSIZE = Default_BlockCipher::Encryption::BLOCKSIZE; +static const unsigned int KEYLENGTH = Default_BlockCipher::Encryption::DEFAULT_KEYLENGTH; + +// The purpose of this function Mash() is to take an arbitrary length input +// string and *deterministicly* produce an arbitrary length output string such +// that (1) it looks random, (2) no information about the input is +// deducible from it, and (3) it contains as much entropy as it can hold, or +// the amount of entropy in the input string, whichever is smaller. + +static void Mash(const byte *in, size_t inLen, byte *out, size_t outLen, int iterations) +{ + if (BytePrecision(outLen) > 2) + throw InvalidArgument("Mash: output legnth too large"); + + size_t bufSize = RoundUpToMultipleOf(outLen, (size_t)DefaultHashModule::DIGESTSIZE); + byte b[2]; + SecByteBlock buf(bufSize); + SecByteBlock outBuf(bufSize); + DefaultHashModule hash; + + unsigned int i; + for(i=0; i> 8); + b[1] = (byte) i; + hash.Update(b, 2); + hash.Update(in, inLen); + hash.Final(outBuf+i); + } + + while (iterations-- > 1) + { + memcpy(buf, outBuf, bufSize); + for (i=0; i> 8); + b[1] = (byte) i; + hash.Update(b, 2); + hash.Update(buf, bufSize); + hash.Final(outBuf+i); + } + } + + memcpy(out, outBuf, outLen); +} + +static void GenerateKeyIV(const byte *passphrase, size_t passphraseLength, const byte *salt, size_t saltLength, byte *key, byte *IV) +{ + SecByteBlock temp(passphraseLength+saltLength); + memcpy(temp, passphrase, passphraseLength); + memcpy(temp+passphraseLength, salt, saltLength); + SecByteBlock keyIV(KEYLENGTH+BLOCKSIZE); + Mash(temp, passphraseLength + saltLength, keyIV, KEYLENGTH+BLOCKSIZE, MASH_ITERATIONS); + memcpy(key, keyIV, KEYLENGTH); + memcpy(IV, keyIV+KEYLENGTH, BLOCKSIZE); +} + +// ******************************************************** + +DefaultEncryptor::DefaultEncryptor(const char *passphrase, BufferedTransformation *attachment) + : ProxyFilter(NULL, 0, 0, attachment), m_passphrase((const byte *)passphrase, strlen(passphrase)) +{ +} + +DefaultEncryptor::DefaultEncryptor(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment) + : ProxyFilter(NULL, 0, 0, attachment), m_passphrase(passphrase, passphraseLength) +{ +} + + +void DefaultEncryptor::FirstPut(const byte *) +{ + // VC60 workaround: __LINE__ expansion bug + CRYPTOPP_COMPILE_ASSERT_INSTANCE(SALTLENGTH <= DefaultHashModule::DIGESTSIZE, 1); + CRYPTOPP_COMPILE_ASSERT_INSTANCE(BLOCKSIZE <= DefaultHashModule::DIGESTSIZE, 2); + + SecByteBlock salt(DefaultHashModule::DIGESTSIZE), keyCheck(DefaultHashModule::DIGESTSIZE); + DefaultHashModule hash; + + // use hash(passphrase | time | clock) as salt + hash.Update(m_passphrase, m_passphrase.size()); + time_t t=time(0); + hash.Update((byte *)&t, sizeof(t)); + clock_t c=clock(); + hash.Update((byte *)&c, sizeof(c)); + hash.Final(salt); + + // use hash(passphrase | salt) as key check + hash.Update(m_passphrase, m_passphrase.size()); + hash.Update(salt, SALTLENGTH); + hash.Final(keyCheck); + + AttachedTransformation()->Put(salt, SALTLENGTH); + + // mash passphrase and salt together into key and IV + SecByteBlock key(KEYLENGTH); + SecByteBlock IV(BLOCKSIZE); + GenerateKeyIV(m_passphrase, m_passphrase.size(), salt, SALTLENGTH, key, IV); + + m_cipher.SetKeyWithIV(key, key.size(), IV); + SetFilter(new StreamTransformationFilter(m_cipher)); + + m_filter->Put(keyCheck, BLOCKSIZE); +} + +void DefaultEncryptor::LastPut(const byte *inString, size_t length) +{ + m_filter->MessageEnd(); +} + +// ******************************************************** + +DefaultDecryptor::DefaultDecryptor(const char *p, BufferedTransformation *attachment, bool throwException) + : ProxyFilter(NULL, SALTLENGTH+BLOCKSIZE, 0, attachment) + , m_state(WAITING_FOR_KEYCHECK) + , m_passphrase((const byte *)p, strlen(p)) + , m_throwException(throwException) +{ +} + +DefaultDecryptor::DefaultDecryptor(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment, bool throwException) + : ProxyFilter(NULL, SALTLENGTH+BLOCKSIZE, 0, attachment) + , m_state(WAITING_FOR_KEYCHECK) + , m_passphrase(passphrase, passphraseLength) + , m_throwException(throwException) +{ +} + +void DefaultDecryptor::FirstPut(const byte *inString) +{ + CheckKey(inString, inString+SALTLENGTH); +} + +void DefaultDecryptor::LastPut(const byte *inString, size_t length) +{ + if (m_filter.get() == NULL) + { + m_state = KEY_BAD; + if (m_throwException) + throw KeyBadErr(); + } + else + { + m_filter->MessageEnd(); + m_state = WAITING_FOR_KEYCHECK; + } +} + +void DefaultDecryptor::CheckKey(const byte *salt, const byte *keyCheck) +{ + SecByteBlock check(STDMAX((unsigned int)2*BLOCKSIZE, (unsigned int)DefaultHashModule::DIGESTSIZE)); + + DefaultHashModule hash; + hash.Update(m_passphrase, m_passphrase.size()); + hash.Update(salt, SALTLENGTH); + hash.Final(check); + + SecByteBlock key(KEYLENGTH); + SecByteBlock IV(BLOCKSIZE); + GenerateKeyIV(m_passphrase, m_passphrase.size(), salt, SALTLENGTH, key, IV); + + m_cipher.SetKeyWithIV(key, key.size(), IV); + std::auto_ptr decryptor(new StreamTransformationFilter(m_cipher)); + + decryptor->Put(keyCheck, BLOCKSIZE); + decryptor->ForceNextPut(); + decryptor->Get(check+BLOCKSIZE, BLOCKSIZE); + + SetFilter(decryptor.release()); + + if (memcmp(check, check+BLOCKSIZE, BLOCKSIZE)) + { + m_state = KEY_BAD; + if (m_throwException) + throw KeyBadErr(); + } + else + m_state = KEY_GOOD; +} + +// ******************************************************** + +static DefaultMAC * NewDefaultEncryptorMAC(const byte *passphrase, size_t passphraseLength) +{ + size_t macKeyLength = DefaultMAC::StaticGetValidKeyLength(16); + SecByteBlock macKey(macKeyLength); + // since the MAC is encrypted there is no reason to mash the passphrase for many iterations + Mash(passphrase, passphraseLength, macKey, macKeyLength, 1); + return new DefaultMAC(macKey, macKeyLength); +} + +DefaultEncryptorWithMAC::DefaultEncryptorWithMAC(const char *passphrase, BufferedTransformation *attachment) + : ProxyFilter(NULL, 0, 0, attachment) + , m_mac(NewDefaultEncryptorMAC((const byte *)passphrase, strlen(passphrase))) +{ + SetFilter(new HashFilter(*m_mac, new DefaultEncryptor(passphrase), true)); +} + +DefaultEncryptorWithMAC::DefaultEncryptorWithMAC(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment) + : ProxyFilter(NULL, 0, 0, attachment) + , m_mac(NewDefaultEncryptorMAC(passphrase, passphraseLength)) +{ + SetFilter(new HashFilter(*m_mac, new DefaultEncryptor(passphrase, passphraseLength), true)); +} + +void DefaultEncryptorWithMAC::LastPut(const byte *inString, size_t length) +{ + m_filter->MessageEnd(); +} + +// ******************************************************** + +DefaultDecryptorWithMAC::DefaultDecryptorWithMAC(const char *passphrase, BufferedTransformation *attachment, bool throwException) + : ProxyFilter(NULL, 0, 0, attachment) + , m_mac(NewDefaultEncryptorMAC((const byte *)passphrase, strlen(passphrase))) + , m_throwException(throwException) +{ + SetFilter(new DefaultDecryptor(passphrase, m_hashVerifier=new HashVerifier(*m_mac, NULL, HashVerifier::PUT_MESSAGE), throwException)); +} + +DefaultDecryptorWithMAC::DefaultDecryptorWithMAC(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment, bool throwException) + : ProxyFilter(NULL, 0, 0, attachment) + , m_mac(NewDefaultEncryptorMAC(passphrase, passphraseLength)) + , m_throwException(throwException) +{ + SetFilter(new DefaultDecryptor(passphrase, passphraseLength, m_hashVerifier=new HashVerifier(*m_mac, NULL, HashVerifier::PUT_MESSAGE), throwException)); +} + +DefaultDecryptor::State DefaultDecryptorWithMAC::CurrentState() const +{ + return static_cast(m_filter.get())->CurrentState(); +} + +bool DefaultDecryptorWithMAC::CheckLastMAC() const +{ + return m_hashVerifier->GetLastResult(); +} + +void DefaultDecryptorWithMAC::LastPut(const byte *inString, size_t length) +{ + m_filter->MessageEnd(); + if (m_throwException && !CheckLastMAC()) + throw MACBadErr(); +} + +NAMESPACE_END diff --git a/CryptoPP/crypto/default.h b/CryptoPP/crypto/default.h new file mode 100644 index 0000000..fd3eb48 --- /dev/null +++ b/CryptoPP/crypto/default.h @@ -0,0 +1,104 @@ +#ifndef CRYPTOPP_DEFAULT_H +#define CRYPTOPP_DEFAULT_H + +#include "sha.h" +#include "hmac.h" +#include "des.h" +#include "filters.h" +#include "modes.h" + +NAMESPACE_BEGIN(CryptoPP) + +typedef DES_EDE2 Default_BlockCipher; +typedef SHA DefaultHashModule; +typedef HMAC DefaultMAC; + +//! Password-Based Encryptor using DES-EDE2 +class DefaultEncryptor : public ProxyFilter +{ +public: + DefaultEncryptor(const char *passphrase, BufferedTransformation *attachment = NULL); + DefaultEncryptor(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment = NULL); + +protected: + void FirstPut(const byte *); + void LastPut(const byte *inString, size_t length); + +private: + SecByteBlock m_passphrase; + CBC_Mode::Encryption m_cipher; +}; + +//! Password-Based Decryptor using DES-EDE2 +class DefaultDecryptor : public ProxyFilter +{ +public: + DefaultDecryptor(const char *passphrase, BufferedTransformation *attachment = NULL, bool throwException=true); + DefaultDecryptor(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment = NULL, bool throwException=true); + + class Err : public Exception + { + public: + Err(const std::string &s) + : Exception(DATA_INTEGRITY_CHECK_FAILED, s) {} + }; + class KeyBadErr : public Err {public: KeyBadErr() : Err("DefaultDecryptor: cannot decrypt message with this passphrase") {}}; + + enum State {WAITING_FOR_KEYCHECK, KEY_GOOD, KEY_BAD}; + State CurrentState() const {return m_state;} + +protected: + void FirstPut(const byte *inString); + void LastPut(const byte *inString, size_t length); + + State m_state; + +private: + void CheckKey(const byte *salt, const byte *keyCheck); + + SecByteBlock m_passphrase; + CBC_Mode::Decryption m_cipher; + member_ptr m_decryptor; + bool m_throwException; +}; + +//! Password-Based Encryptor using DES-EDE2 and HMAC/SHA-1 +class DefaultEncryptorWithMAC : public ProxyFilter +{ +public: + DefaultEncryptorWithMAC(const char *passphrase, BufferedTransformation *attachment = NULL); + DefaultEncryptorWithMAC(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment = NULL); + +protected: + void FirstPut(const byte *inString) {} + void LastPut(const byte *inString, size_t length); + +private: + member_ptr m_mac; +}; + +//! Password-Based Decryptor using DES-EDE2 and HMAC/SHA-1 +class DefaultDecryptorWithMAC : public ProxyFilter +{ +public: + class MACBadErr : public DefaultDecryptor::Err {public: MACBadErr() : DefaultDecryptor::Err("DefaultDecryptorWithMAC: MAC check failed") {}}; + + DefaultDecryptorWithMAC(const char *passphrase, BufferedTransformation *attachment = NULL, bool throwException=true); + DefaultDecryptorWithMAC(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment = NULL, bool throwException=true); + + DefaultDecryptor::State CurrentState() const; + bool CheckLastMAC() const; + +protected: + void FirstPut(const byte *inString) {} + void LastPut(const byte *inString, size_t length); + +private: + member_ptr m_mac; + HashVerifier *m_hashVerifier; + bool m_throwException; +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/des.cpp b/CryptoPP/crypto/des.cpp new file mode 100644 index 0000000..5002f26 --- /dev/null +++ b/CryptoPP/crypto/des.cpp @@ -0,0 +1,449 @@ +// des.cpp - modified by Wei Dai from Phil Karn's des.c +// The original code and all modifications are in the public domain. + +/* + * This is a major rewrite of my old public domain DES code written + * circa 1987, which in turn borrowed heavily from Jim Gillogly's 1977 + * public domain code. I pretty much kept my key scheduling code, but + * the actual encrypt/decrypt routines are taken from from Richard + * Outerbridge's DES code as printed in Schneier's "Applied Cryptography." + * + * This code is in the public domain. I would appreciate bug reports and + * enhancements. + * + * Phil Karn KA9Q, karn@unix.ka9q.ampr.org, August 1994. + */ + +#include "pch.h" +#include "misc.h" +#include "des.h" + +NAMESPACE_BEGIN(CryptoPP) + +typedef BlockGetAndPut Block; + +// Richard Outerbridge's initial permutation algorithm +/* +inline void IPERM(word32 &left, word32 &right) +{ + word32 work; + + work = ((left >> 4) ^ right) & 0x0f0f0f0f; + right ^= work; + left ^= work << 4; + work = ((left >> 16) ^ right) & 0xffff; + right ^= work; + left ^= work << 16; + work = ((right >> 2) ^ left) & 0x33333333; + left ^= work; + right ^= (work << 2); + work = ((right >> 8) ^ left) & 0xff00ff; + left ^= work; + right ^= (work << 8); + right = rotl(right, 1); + work = (left ^ right) & 0xaaaaaaaa; + left ^= work; + right ^= work; + left = rotl(left, 1); +} +inline void FPERM(word32 &left, word32 &right) +{ + word32 work; + + right = rotr(right, 1); + work = (left ^ right) & 0xaaaaaaaa; + left ^= work; + right ^= work; + left = rotr(left, 1); + work = ((left >> 8) ^ right) & 0xff00ff; + right ^= work; + left ^= work << 8; + work = ((left >> 2) ^ right) & 0x33333333; + right ^= work; + left ^= work << 2; + work = ((right >> 16) ^ left) & 0xffff; + left ^= work; + right ^= work << 16; + work = ((right >> 4) ^ left) & 0x0f0f0f0f; + left ^= work; + right ^= work << 4; +} +*/ + +// Wei Dai's modification to Richard Outerbridge's initial permutation +// algorithm, this one is faster if you have access to rotate instructions +// (like in MSVC) +static inline void IPERM(word32 &left, word32 &right) +{ + word32 work; + + right = rotlFixed(right, 4U); + work = (left ^ right) & 0xf0f0f0f0; + left ^= work; + right = rotrFixed(right^work, 20U); + work = (left ^ right) & 0xffff0000; + left ^= work; + right = rotrFixed(right^work, 18U); + work = (left ^ right) & 0x33333333; + left ^= work; + right = rotrFixed(right^work, 6U); + work = (left ^ right) & 0x00ff00ff; + left ^= work; + right = rotlFixed(right^work, 9U); + work = (left ^ right) & 0xaaaaaaaa; + left = rotlFixed(left^work, 1U); + right ^= work; +} + +static inline void FPERM(word32 &left, word32 &right) +{ + word32 work; + + right = rotrFixed(right, 1U); + work = (left ^ right) & 0xaaaaaaaa; + right ^= work; + left = rotrFixed(left^work, 9U); + work = (left ^ right) & 0x00ff00ff; + right ^= work; + left = rotlFixed(left^work, 6U); + work = (left ^ right) & 0x33333333; + right ^= work; + left = rotlFixed(left^work, 18U); + work = (left ^ right) & 0xffff0000; + right ^= work; + left = rotlFixed(left^work, 20U); + work = (left ^ right) & 0xf0f0f0f0; + right ^= work; + left = rotrFixed(left^work, 4U); +} + +void DES::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs &) +{ + AssertValidKeyLength(length); + + RawSetKey(GetCipherDirection(), userKey); +} + +#ifndef CRYPTOPP_IMPORTS + +/* Tables defined in the Data Encryption Standard documents + * Three of these tables, the initial permutation, the final + * permutation and the expansion operator, are regular enough that + * for speed, we hard-code them. They're here for reference only. + * Also, the S and P boxes are used by a separate program, gensp.c, + * to build the combined SP box, Spbox[]. They're also here just + * for reference. + */ +#ifdef notdef +/* initial permutation IP */ +static byte ip[] = { + 58, 50, 42, 34, 26, 18, 10, 2, + 60, 52, 44, 36, 28, 20, 12, 4, + 62, 54, 46, 38, 30, 22, 14, 6, + 64, 56, 48, 40, 32, 24, 16, 8, + 57, 49, 41, 33, 25, 17, 9, 1, + 59, 51, 43, 35, 27, 19, 11, 3, + 61, 53, 45, 37, 29, 21, 13, 5, + 63, 55, 47, 39, 31, 23, 15, 7 +}; + +/* final permutation IP^-1 */ +static byte fp[] = { + 40, 8, 48, 16, 56, 24, 64, 32, + 39, 7, 47, 15, 55, 23, 63, 31, + 38, 6, 46, 14, 54, 22, 62, 30, + 37, 5, 45, 13, 53, 21, 61, 29, + 36, 4, 44, 12, 52, 20, 60, 28, + 35, 3, 43, 11, 51, 19, 59, 27, + 34, 2, 42, 10, 50, 18, 58, 26, + 33, 1, 41, 9, 49, 17, 57, 25 +}; +/* expansion operation matrix */ +static byte ei[] = { + 32, 1, 2, 3, 4, 5, + 4, 5, 6, 7, 8, 9, + 8, 9, 10, 11, 12, 13, + 12, 13, 14, 15, 16, 17, + 16, 17, 18, 19, 20, 21, + 20, 21, 22, 23, 24, 25, + 24, 25, 26, 27, 28, 29, + 28, 29, 30, 31, 32, 1 +}; +/* The (in)famous S-boxes */ +static byte sbox[8][64] = { + /* S1 */ + 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, + 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, + 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0, + 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13, + + /* S2 */ + 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, + 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5, + 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15, + 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9, + + /* S3 */ + 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, + 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1, + 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7, + 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12, + + /* S4 */ + 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, + 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9, + 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4, + 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14, + + /* S5 */ + 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9, + 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6, + 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14, + 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3, + + /* S6 */ + 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11, + 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8, + 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6, + 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13, + + /* S7 */ + 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1, + 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6, + 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2, + 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12, + + /* S8 */ + 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7, + 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2, + 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8, + 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 +}; + +/* 32-bit permutation function P used on the output of the S-boxes */ +static byte p32i[] = { + 16, 7, 20, 21, + 29, 12, 28, 17, + 1, 15, 23, 26, + 5, 18, 31, 10, + 2, 8, 24, 14, + 32, 27, 3, 9, + 19, 13, 30, 6, + 22, 11, 4, 25 +}; +#endif + +/* permuted choice table (key) */ +static const byte pc1[] = { + 57, 49, 41, 33, 25, 17, 9, + 1, 58, 50, 42, 34, 26, 18, + 10, 2, 59, 51, 43, 35, 27, + 19, 11, 3, 60, 52, 44, 36, + + 63, 55, 47, 39, 31, 23, 15, + 7, 62, 54, 46, 38, 30, 22, + 14, 6, 61, 53, 45, 37, 29, + 21, 13, 5, 28, 20, 12, 4 +}; + +/* number left rotations of pc1 */ +static const byte totrot[] = { + 1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28 +}; + +/* permuted choice key (table) */ +static const byte pc2[] = { + 14, 17, 11, 24, 1, 5, + 3, 28, 15, 6, 21, 10, + 23, 19, 12, 4, 26, 8, + 16, 7, 27, 20, 13, 2, + 41, 52, 31, 37, 47, 55, + 30, 40, 51, 45, 33, 48, + 44, 49, 39, 56, 34, 53, + 46, 42, 50, 36, 29, 32 +}; + +/* End of DES-defined tables */ + +/* bit 0 is left-most in byte */ +static const int bytebit[] = { + 0200,0100,040,020,010,04,02,01 +}; + +/* Set key (initialize key schedule array) */ +void RawDES::RawSetKey(CipherDir dir, const byte *key) +{ + SecByteBlock buffer(56+56+8); + byte *const pc1m=buffer; /* place to modify pc1 into */ + byte *const pcr=pc1m+56; /* place to rotate pc1 into */ + byte *const ks=pcr+56; + register int i,j,l; + int m; + + for (j=0; j<56; j++) { /* convert pc1 to bits of key */ + l=pc1[j]-1; /* integer bit location */ + m = l & 07; /* find bit */ + pc1m[j]=(key[l>>3] & /* find which key byte l is in */ + bytebit[m]) /* and which bit of that byte */ + ? 1 : 0; /* and store 1-bit result */ + } + for (i=0; i<16; i++) { /* key chunk for each iteration */ + memset(ks,0,8); /* Clear key schedule */ + for (j=0; j<56; j++) /* rotate pc1 the right amount */ + pcr[j] = pc1m[(l=j+totrot[i])<(j<28? 28 : 56) ? l: l-28]; + /* rotate left and right halves independently */ + for (j=0; j<48; j++){ /* select bits individually */ + /* check bit that goes to ks[j] */ + if (pcr[pc2[j]-1]){ + /* mask it in if it's there */ + l= j % 6; + ks[j/6] |= bytebit[l] >> 2; + } + } + /* Now convert to odd/even interleaved form for use in F */ + k[2*i] = ((word32)ks[0] << 24) + | ((word32)ks[2] << 16) + | ((word32)ks[4] << 8) + | ((word32)ks[6]); + k[2*i+1] = ((word32)ks[1] << 24) + | ((word32)ks[3] << 16) + | ((word32)ks[5] << 8) + | ((word32)ks[7]); + } + + if (dir==DECRYPTION) // reverse key schedule order + for (i=0; i<16; i+=2) + { + std::swap(k[i], k[32-2-i]); + std::swap(k[i+1], k[32-1-i]); + } +} + +void RawDES::RawProcessBlock(word32 &l_, word32 &r_) const +{ + word32 l = l_, r = r_; + const word32 *kptr=k; + + for (unsigned i=0; i<8; i++) + { + word32 work = rotrFixed(r, 4U) ^ kptr[4*i+0]; + l ^= Spbox[6][(work) & 0x3f] + ^ Spbox[4][(work >> 8) & 0x3f] + ^ Spbox[2][(work >> 16) & 0x3f] + ^ Spbox[0][(work >> 24) & 0x3f]; + work = r ^ kptr[4*i+1]; + l ^= Spbox[7][(work) & 0x3f] + ^ Spbox[5][(work >> 8) & 0x3f] + ^ Spbox[3][(work >> 16) & 0x3f] + ^ Spbox[1][(work >> 24) & 0x3f]; + + work = rotrFixed(l, 4U) ^ kptr[4*i+2]; + r ^= Spbox[6][(work) & 0x3f] + ^ Spbox[4][(work >> 8) & 0x3f] + ^ Spbox[2][(work >> 16) & 0x3f] + ^ Spbox[0][(work >> 24) & 0x3f]; + work = l ^ kptr[4*i+3]; + r ^= Spbox[7][(work) & 0x3f] + ^ Spbox[5][(work >> 8) & 0x3f] + ^ Spbox[3][(work >> 16) & 0x3f] + ^ Spbox[1][(work >> 24) & 0x3f]; + } + + l_ = l; r_ = r; +} + +void DES_EDE2::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs &) +{ + AssertValidKeyLength(length); + + m_des1.RawSetKey(GetCipherDirection(), userKey); + m_des2.RawSetKey(ReverseCipherDir(GetCipherDirection()), userKey+8); +} + +void DES_EDE2::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word32 l,r; + Block::Get(inBlock)(l)(r); + IPERM(l,r); + m_des1.RawProcessBlock(l, r); + m_des2.RawProcessBlock(r, l); + m_des1.RawProcessBlock(l, r); + FPERM(l,r); + Block::Put(xorBlock, outBlock)(r)(l); +} + +void DES_EDE3::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs &) +{ + AssertValidKeyLength(length); + + m_des1.RawSetKey(GetCipherDirection(), userKey + (IsForwardTransformation() ? 0 : 16)); + m_des2.RawSetKey(ReverseCipherDir(GetCipherDirection()), userKey + 8); + m_des3.RawSetKey(GetCipherDirection(), userKey + (IsForwardTransformation() ? 16 : 0)); +} + +void DES_EDE3::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word32 l,r; + Block::Get(inBlock)(l)(r); + IPERM(l,r); + m_des1.RawProcessBlock(l, r); + m_des2.RawProcessBlock(r, l); + m_des3.RawProcessBlock(l, r); + FPERM(l,r); + Block::Put(xorBlock, outBlock)(r)(l); +} + +#endif // #ifndef CRYPTOPP_IMPORTS + +static inline bool CheckParity(byte b) +{ + unsigned int a = b ^ (b >> 4); + return ((a ^ (a>>1) ^ (a>>2) ^ (a>>3)) & 1) == 1; +} + +bool DES::CheckKeyParityBits(const byte *key) +{ + for (unsigned int i=0; i<8; i++) + if (!CheckParity(key[i])) + return false; + return true; +} + +void DES::CorrectKeyParityBits(byte *key) +{ + for (unsigned int i=0; i<8; i++) + if (!CheckParity(key[i])) + key[i] ^= 1; +} + +// Encrypt or decrypt a block of data in ECB mode +void DES::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word32 l,r; + Block::Get(inBlock)(l)(r); + IPERM(l,r); + RawProcessBlock(l, r); + FPERM(l,r); + Block::Put(xorBlock, outBlock)(r)(l); +} + +void DES_XEX3::Base::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &) +{ + AssertValidKeyLength(length); + + if (!m_des.get()) + m_des.reset(new DES::Encryption); + + memcpy(m_x1, key + (IsForwardTransformation() ? 0 : 16), BLOCKSIZE); + m_des->RawSetKey(GetCipherDirection(), key + 8); + memcpy(m_x3, key + (IsForwardTransformation() ? 16 : 0), BLOCKSIZE); +} + +void DES_XEX3::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + xorbuf(outBlock, inBlock, m_x1, BLOCKSIZE); + m_des->ProcessAndXorBlock(outBlock, xorBlock, outBlock); + xorbuf(outBlock, m_x3, BLOCKSIZE); +} + +NAMESPACE_END diff --git a/CryptoPP/crypto/des.h b/CryptoPP/crypto/des.h new file mode 100644 index 0000000..a6aaa79 --- /dev/null +++ b/CryptoPP/crypto/des.h @@ -0,0 +1,144 @@ +#ifndef CRYPTOPP_DES_H +#define CRYPTOPP_DES_H + +/** \file +*/ + +#include "seckey.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +class CRYPTOPP_DLL RawDES +{ +public: + void RawSetKey(CipherDir direction, const byte *userKey); + void RawProcessBlock(word32 &l, word32 &r) const; + +protected: + static const word32 Spbox[8][64]; + + FixedSizeSecBlock k; +}; + +//! _ +struct DES_Info : public FixedBlockSize<8>, public FixedKeyLength<8> +{ + // disable DES in DLL version by not exporting this function + static const char * StaticAlgorithmName() {return "DES";} +}; + +/// DES +/*! The DES implementation in Crypto++ ignores the parity bits + (the least significant bits of each byte) in the key. However + you can use CheckKeyParityBits() and CorrectKeyParityBits() to + check or correct the parity bits if you wish. */ +class DES : public DES_Info, public BlockCipherDocumentation +{ + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl, public RawDES + { + public: + void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + +public: + //! check DES key parity bits + static bool CheckKeyParityBits(const byte *key); + //! correct DES key parity bits + static void CorrectKeyParityBits(byte *key); + + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +//! _ +struct DES_EDE2_Info : public FixedBlockSize<8>, public FixedKeyLength<16> +{ + CRYPTOPP_DLL static const char * CRYPTOPP_API StaticAlgorithmName() {return "DES-EDE2";} +}; + +/// DES-EDE2 +class DES_EDE2 : public DES_EDE2_Info, public BlockCipherDocumentation +{ + class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + public: + void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + + protected: + RawDES m_des1, m_des2; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +//! _ +struct DES_EDE3_Info : public FixedBlockSize<8>, public FixedKeyLength<24> +{ + CRYPTOPP_DLL static const char * CRYPTOPP_API StaticAlgorithmName() {return "DES-EDE3";} +}; + +/// DES-EDE3 +class DES_EDE3 : public DES_EDE3_Info, public BlockCipherDocumentation +{ + class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + public: + void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + + protected: + RawDES m_des1, m_des2, m_des3; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +//! _ +struct DES_XEX3_Info : public FixedBlockSize<8>, public FixedKeyLength<24> +{ + static const char *StaticAlgorithmName() {return "DES-XEX3";} +}; + +/// DES-XEX3, AKA DESX +class DES_XEX3 : public DES_XEX3_Info, public BlockCipherDocumentation +{ + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + public: + void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + + protected: + FixedSizeSecBlock m_x1, m_x3; + // VS2005 workaround: calling modules compiled with /clr gets unresolved external symbol DES::Base::ProcessAndXorBlock + // if we use DES::Encryption here directly without value_ptr. + value_ptr m_des; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef DES::Encryption DESEncryption; +typedef DES::Decryption DESDecryption; + +typedef DES_EDE2::Encryption DES_EDE2_Encryption; +typedef DES_EDE2::Decryption DES_EDE2_Decryption; + +typedef DES_EDE3::Encryption DES_EDE3_Encryption; +typedef DES_EDE3::Decryption DES_EDE3_Decryption; + +typedef DES_XEX3::Encryption DES_XEX3_Encryption; +typedef DES_XEX3::Decryption DES_XEX3_Decryption; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/descert.dat b/CryptoPP/crypto/descert.dat new file mode 100644 index 0000000..7fea954 --- /dev/null +++ b/CryptoPP/crypto/descert.dat @@ -0,0 +1,171 @@ +0101010101010101 95F8A5E5DD31D900 8000000000000000 +0101010101010101 DD7F121CA5015619 4000000000000000 +0101010101010101 2E8653104F3834EA 2000000000000000 +0101010101010101 4BD388FF6CD81D4F 1000000000000000 +0101010101010101 20B9E767B2FB1456 0800000000000000 +0101010101010101 55579380D77138EF 0400000000000000 +0101010101010101 6CC5DEFAAF04512F 0200000000000000 +0101010101010101 0D9F279BA5D87260 0100000000000000 +0101010101010101 D9031B0271BD5A0A 0080000000000000 +0101010101010101 424250B37C3DD951 0040000000000000 +0101010101010101 B8061B7ECD9A21E5 0020000000000000 +0101010101010101 F15D0F286B65BD28 0010000000000000 +0101010101010101 ADD0CC8D6E5DEBA1 0008000000000000 +0101010101010101 E6D5F82752AD63D1 0004000000000000 +0101010101010101 ECBFE3BD3F591A5E 0002000000000000 +0101010101010101 F356834379D165CD 0001000000000000 +0101010101010101 2B9F982F20037FA9 0000800000000000 +0101010101010101 889DE068A16F0BE6 0000400000000000 +0101010101010101 E19E275D846A1298 0000200000000000 +0101010101010101 329A8ED523D71AEC 0000100000000000 +0101010101010101 E7FCE22557D23C97 0000080000000000 +0101010101010101 12A9F5817FF2D65D 0000040000000000 +0101010101010101 A484C3AD38DC9C19 0000020000000000 +0101010101010101 FBE00A8A1EF8AD72 0000010000000000 +0101010101010101 750D079407521363 0000008000000000 +0101010101010101 64FEED9C724C2FAF 0000004000000000 +0101010101010101 F02B263B328E2B60 0000002000000000 +0101010101010101 9D64555A9A10B852 0000001000000000 +0101010101010101 D106FF0BED5255D7 0000000800000000 +0101010101010101 E1652C6B138C64A5 0000000400000000 +0101010101010101 E428581186EC8F46 0000000200000000 +0101010101010101 AEB5F5EDE22D1A36 0000000100000000 +0101010101010101 E943D7568AEC0C5C 0000000080000000 +0101010101010101 DF98C8276F54B04B 0000000040000000 +0101010101010101 B160E4680F6C696F 0000000020000000 +0101010101010101 FA0752B07D9C4AB8 0000000010000000 +0101010101010101 CA3A2B036DBC8502 0000000008000000 +0101010101010101 5E0905517BB59BCF 0000000004000000 +0101010101010101 814EEB3B91D90726 0000000002000000 +0101010101010101 4D49DB1532919C9F 0000000001000000 +0101010101010101 25EB5FC3F8CF0621 0000000000800000 +0101010101010101 AB6A20C0620D1C6F 0000000000400000 +0101010101010101 79E90DBC98F92CCA 0000000000200000 +0101010101010101 866ECEDD8072BB0E 0000000000100000 +0101010101010101 8B54536F2F3E64A8 0000000000080000 +0101010101010101 EA51D3975595B86B 0000000000040000 +0101010101010101 CAFFC6AC4542DE31 0000000000020000 +0101010101010101 8DD45A2DDF90796C 0000000000010000 +0101010101010101 1029D55E880EC2D0 0000000000008000 +0101010101010101 5D86CB23639DBEA9 0000000000004000 +0101010101010101 1D1CA853AE7C0C5F 0000000000002000 +0101010101010101 CE332329248F3228 0000000000001000 +0101010101010101 8405D1ABE24FB942 0000000000000800 +0101010101010101 E643D78090CA4207 0000000000000400 +0101010101010101 48221B9937748A23 0000000000000200 +0101010101010101 DD7C0BBD61FAFD54 0000000000000100 +0101010101010101 2FBC291A570DB5C4 0000000000000080 +0101010101010101 E07C30D7E4E26E12 0000000000000040 +0101010101010101 0953E2258E8E90A1 0000000000000020 +0101010101010101 5B711BC4CEEBF2EE 0000000000000010 +0101010101010101 CC083F1E6D9E85F6 0000000000000008 +0101010101010101 D2FD8867D50D2DFE 0000000000000004 +0101010101010101 06E7EA22CE92708F 0000000000000002 +0101010101010101 166B40B44ABA4BD6 0000000000000001 +8001010101010101 0000000000000000 95A8D72813DAA94D +4001010101010101 0000000000000000 0EEC1487DD8C26D5 +2001010101010101 0000000000000000 7AD16FFB79C45926 +1001010101010101 0000000000000000 D3746294CA6A6CF3 +0801010101010101 0000000000000000 809F5F873C1FD761 +0401010101010101 0000000000000000 C02FAFFEC989D1FC +0201010101010101 0000000000000000 4615AA1D33E72F10 +0180010101010101 0000000000000000 2055123350C00858 +0140010101010101 0000000000000000 DF3B99D6577397C8 +0120010101010101 0000000000000000 31FE17369B5288C9 +0110010101010101 0000000000000000 DFDD3CC64DAE1642 +0108010101010101 0000000000000000 178C83CE2B399D94 +0104010101010101 0000000000000000 50F636324A9B7F80 +0102010101010101 0000000000000000 A8468EE3BC18F06D +0101800101010101 0000000000000000 A2DC9E92FD3CDE92 +0101400101010101 0000000000000000 CAC09F797D031287 +0101200101010101 0000000000000000 90BA680B22AEB525 +0101100101010101 0000000000000000 CE7A24F350E280B6 +0101080101010101 0000000000000000 882BFF0AA01A0B87 +0101040101010101 0000000000000000 25610288924511C2 +0101020101010101 0000000000000000 C71516C29C75D170 +0101018001010101 0000000000000000 5199C29A52C9F059 +0101014001010101 0000000000000000 C22F0A294A71F29F +0101012001010101 0000000000000000 EE371483714C02EA +0101011001010101 0000000000000000 A81FBD448F9E522F +0101010801010101 0000000000000000 4F644C92E192DFED +0101010401010101 0000000000000000 1AFA9A66A6DF92AE +0101010201010101 0000000000000000 B3C1CC715CB879D8 +0101010180010101 0000000000000000 19D032E64AB0BD8B +0101010140010101 0000000000000000 3CFAA7A7DC8720DC +0101010120010101 0000000000000000 B7265F7F447AC6F3 +0101010110010101 0000000000000000 9DB73B3C0D163F54 +0101010108010101 0000000000000000 8181B65BABF4A975 +0101010104010101 0000000000000000 93C9B64042EAA240 +0101010102010101 0000000000000000 5570530829705592 +0101010101800101 0000000000000000 8638809E878787A0 +0101010101400101 0000000000000000 41B9A79AF79AC208 +0101010101200101 0000000000000000 7A9BE42F2009A892 +0101010101100101 0000000000000000 29038D56BA6D2745 +0101010101080101 0000000000000000 5495C6ABF1E5DF51 +0101010101040101 0000000000000000 AE13DBD561488933 +0101010101020101 0000000000000000 024D1FFA8904E389 +0101010101018001 0000000000000000 D1399712F99BF02E +0101010101014001 0000000000000000 14C1D7C1CFFEC79E +0101010101012001 0000000000000000 1DE5279DAE3BED6F +0101010101011001 0000000000000000 E941A33F85501303 +0101010101010801 0000000000000000 DA99DBBC9A03F379 +0101010101010401 0000000000000000 B7FC92F91D8E92E9 +0101010101010201 0000000000000000 AE8E5CAA3CA04E85 +0101010101010180 0000000000000000 9CC62DF43B6EED74 +0101010101010140 0000000000000000 D863DBB5C59A91A0 +0101010101010120 0000000000000000 A1AB2190545B91D7 +0101010101010110 0000000000000000 0875041E64C570F7 +0101010101010108 0000000000000000 5A594528BEBEF1CC +0101010101010104 0000000000000000 FCDB3291DE21F0C0 +0101010101010102 0000000000000000 869EFD7F9F265A09 +1046913489980131 0000000000000000 88D55E54F54C97B4 +1007103489988020 0000000000000000 0C0CC00C83EA48FD +10071034C8980120 0000000000000000 83BC8EF3A6570183 +1046103489988020 0000000000000000 DF725DCAD94EA2E9 +1086911519190101 0000000000000000 E652B53B550BE8B0 +1086911519580101 0000000000000000 AF527120C485CBB0 +5107B01519580101 0000000000000000 0F04CE393DB926D5 +1007B01519190101 0000000000000000 C9F00FFC74079067 +3107915498080101 0000000000000000 7CFD82A593252B4E +3107919498080101 0000000000000000 CB49A2F9E91363E3 +10079115B9080140 0000000000000000 00B588BE70D23F56 +3107911598090140 0000000000000000 406A9A6AB43399AE +1007D01589980101 0000000000000000 6CB773611DCA9ADA +9107911589980101 0000000000000000 67FD21C17DBB5D70 +9107D01589190101 0000000000000000 9592CB4110430787 +1007D01598980120 0000000000000000 A6B7FF68A318DDD3 +1007940498190101 0000000000000000 4D102196C914CA16 +0107910491190401 0000000000000000 2DFA9F4573594965 +0107910491190101 0000000000000000 B46604816C0E0774 +0107940491190401 0000000000000000 6E7E6221A4F34E87 +19079210981A0101 0000000000000000 AA85E74643233199 +1007911998190801 0000000000000000 2E5A19DB4D1962D6 +10079119981A0801 0000000000000000 23A866A809D30894 +1007921098190101 0000000000000000 D812D961F017D320 +100791159819010B 0000000000000000 055605816E58608F +1004801598190101 0000000000000000 ABD88E8B1B7716F1 +1004801598190102 0000000000000000 537AC95BE69DA1E1 +1004801598190108 0000000000000000 AED0F6AE3C25CDD8 +1002911598100104 0000000000000000 B3E35A5EE53E7B8D +1002911598190104 0000000000000000 61C79C71921A2EF8 +1002911598100201 0000000000000000 E2F5728F0995013C +1002911698100101 0000000000000000 1AEAC39A61F0A464 +7CA110454A1A6E57 01A1D6D039776742 690F5B0D9A26939B +0131D9619DC1376E 5CD54CA83DEF57DA 7A389D10354BD271 +07A1133E4A0B2686 0248D43806F67172 868EBB51CAB4599A +3849674C2602319E 51454B582DDF440A 7178876E01F19B2A +04B915BA43FEB5B6 42FD443059577FA2 AF37FB421F8C4095 +0113B970FD34F2CE 059B5E0851CF143A 86A560F10EC6D85B +0170F175468FB5E6 0756D8E0774761D2 0CD3DA020021DC09 +43297FAD38E373FE 762514B829BF486A EA676B2CB7DB2B7A +07A7137045DA2A16 3BDD119049372802 DFD64A815CAF1A0F +04689104C2FD3B2F 26955F6835AF609A 5C513C9C4886C088 +37D06BB516CB7546 164D5E404F275232 0A2AEEAE3FF4AB77 +1F08260D1AC2465E 6B056E18759F5CCA EF1BF03E5DFA575A +584023641ABA6176 004BD6EF09176062 88BF0DB6D70DEE56 +025816164629B007 480D39006EE762F2 A1F9915541020B56 +49793EBC79B3258F 437540C8698F3CFA 6FBF1CAFCFFD0556 +4FB05E1515AB73A7 072D43A077075292 2F22E49BAB7CA1AC +49E95D6D4CA229BF 02FE55778117F12A 5A6B612CC26CCE4A +018310DC409B26D6 1D9D5C5018F728C2 5F4C038ED12B2E41 +1C587F1C13924FEF 305532286D6F295A 63FAC0D034D9F793 diff --git a/CryptoPP/crypto/dessp.cpp b/CryptoPP/crypto/dessp.cpp new file mode 100644 index 0000000..9382721 --- /dev/null +++ b/CryptoPP/crypto/dessp.cpp @@ -0,0 +1,95 @@ +// This file is mostly generated by Phil Karn's gensp.c + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "des.h" + +NAMESPACE_BEGIN(CryptoPP) + +// VC60 workaround: gives a C4786 warning without this function +// when runtime lib is set to multithread debug DLL +// even though warning 4786 is disabled! +void DES_VC60Workaround() +{ +} + +const word32 RawDES::Spbox[8][64] = { +{ +0x01010400,0x00000000,0x00010000,0x01010404, 0x01010004,0x00010404,0x00000004,0x00010000, +0x00000400,0x01010400,0x01010404,0x00000400, 0x01000404,0x01010004,0x01000000,0x00000004, +0x00000404,0x01000400,0x01000400,0x00010400, 0x00010400,0x01010000,0x01010000,0x01000404, +0x00010004,0x01000004,0x01000004,0x00010004, 0x00000000,0x00000404,0x00010404,0x01000000, +0x00010000,0x01010404,0x00000004,0x01010000, 0x01010400,0x01000000,0x01000000,0x00000400, +0x01010004,0x00010000,0x00010400,0x01000004, 0x00000400,0x00000004,0x01000404,0x00010404, +0x01010404,0x00010004,0x01010000,0x01000404, 0x01000004,0x00000404,0x00010404,0x01010400, +0x00000404,0x01000400,0x01000400,0x00000000, 0x00010004,0x00010400,0x00000000,0x01010004}, +{ +0x80108020,0x80008000,0x00008000,0x00108020, 0x00100000,0x00000020,0x80100020,0x80008020, +0x80000020,0x80108020,0x80108000,0x80000000, 0x80008000,0x00100000,0x00000020,0x80100020, +0x00108000,0x00100020,0x80008020,0x00000000, 0x80000000,0x00008000,0x00108020,0x80100000, +0x00100020,0x80000020,0x00000000,0x00108000, 0x00008020,0x80108000,0x80100000,0x00008020, +0x00000000,0x00108020,0x80100020,0x00100000, 0x80008020,0x80100000,0x80108000,0x00008000, +0x80100000,0x80008000,0x00000020,0x80108020, 0x00108020,0x00000020,0x00008000,0x80000000, +0x00008020,0x80108000,0x00100000,0x80000020, 0x00100020,0x80008020,0x80000020,0x00100020, +0x00108000,0x00000000,0x80008000,0x00008020, 0x80000000,0x80100020,0x80108020,0x00108000}, +{ +0x00000208,0x08020200,0x00000000,0x08020008, 0x08000200,0x00000000,0x00020208,0x08000200, +0x00020008,0x08000008,0x08000008,0x00020000, 0x08020208,0x00020008,0x08020000,0x00000208, +0x08000000,0x00000008,0x08020200,0x00000200, 0x00020200,0x08020000,0x08020008,0x00020208, +0x08000208,0x00020200,0x00020000,0x08000208, 0x00000008,0x08020208,0x00000200,0x08000000, +0x08020200,0x08000000,0x00020008,0x00000208, 0x00020000,0x08020200,0x08000200,0x00000000, +0x00000200,0x00020008,0x08020208,0x08000200, 0x08000008,0x00000200,0x00000000,0x08020008, +0x08000208,0x00020000,0x08000000,0x08020208, 0x00000008,0x00020208,0x00020200,0x08000008, +0x08020000,0x08000208,0x00000208,0x08020000, 0x00020208,0x00000008,0x08020008,0x00020200}, +{ +0x00802001,0x00002081,0x00002081,0x00000080, 0x00802080,0x00800081,0x00800001,0x00002001, +0x00000000,0x00802000,0x00802000,0x00802081, 0x00000081,0x00000000,0x00800080,0x00800001, +0x00000001,0x00002000,0x00800000,0x00802001, 0x00000080,0x00800000,0x00002001,0x00002080, +0x00800081,0x00000001,0x00002080,0x00800080, 0x00002000,0x00802080,0x00802081,0x00000081, +0x00800080,0x00800001,0x00802000,0x00802081, 0x00000081,0x00000000,0x00000000,0x00802000, +0x00002080,0x00800080,0x00800081,0x00000001, 0x00802001,0x00002081,0x00002081,0x00000080, +0x00802081,0x00000081,0x00000001,0x00002000, 0x00800001,0x00002001,0x00802080,0x00800081, +0x00002001,0x00002080,0x00800000,0x00802001, 0x00000080,0x00800000,0x00002000,0x00802080}, +{ +0x00000100,0x02080100,0x02080000,0x42000100, 0x00080000,0x00000100,0x40000000,0x02080000, +0x40080100,0x00080000,0x02000100,0x40080100, 0x42000100,0x42080000,0x00080100,0x40000000, +0x02000000,0x40080000,0x40080000,0x00000000, 0x40000100,0x42080100,0x42080100,0x02000100, +0x42080000,0x40000100,0x00000000,0x42000000, 0x02080100,0x02000000,0x42000000,0x00080100, +0x00080000,0x42000100,0x00000100,0x02000000, 0x40000000,0x02080000,0x42000100,0x40080100, +0x02000100,0x40000000,0x42080000,0x02080100, 0x40080100,0x00000100,0x02000000,0x42080000, +0x42080100,0x00080100,0x42000000,0x42080100, 0x02080000,0x00000000,0x40080000,0x42000000, +0x00080100,0x02000100,0x40000100,0x00080000, 0x00000000,0x40080000,0x02080100,0x40000100}, +{ +0x20000010,0x20400000,0x00004000,0x20404010, 0x20400000,0x00000010,0x20404010,0x00400000, +0x20004000,0x00404010,0x00400000,0x20000010, 0x00400010,0x20004000,0x20000000,0x00004010, +0x00000000,0x00400010,0x20004010,0x00004000, 0x00404000,0x20004010,0x00000010,0x20400010, +0x20400010,0x00000000,0x00404010,0x20404000, 0x00004010,0x00404000,0x20404000,0x20000000, +0x20004000,0x00000010,0x20400010,0x00404000, 0x20404010,0x00400000,0x00004010,0x20000010, +0x00400000,0x20004000,0x20000000,0x00004010, 0x20000010,0x20404010,0x00404000,0x20400000, +0x00404010,0x20404000,0x00000000,0x20400010, 0x00000010,0x00004000,0x20400000,0x00404010, +0x00004000,0x00400010,0x20004010,0x00000000, 0x20404000,0x20000000,0x00400010,0x20004010}, +{ +0x00200000,0x04200002,0x04000802,0x00000000, 0x00000800,0x04000802,0x00200802,0x04200800, +0x04200802,0x00200000,0x00000000,0x04000002, 0x00000002,0x04000000,0x04200002,0x00000802, +0x04000800,0x00200802,0x00200002,0x04000800, 0x04000002,0x04200000,0x04200800,0x00200002, +0x04200000,0x00000800,0x00000802,0x04200802, 0x00200800,0x00000002,0x04000000,0x00200800, +0x04000000,0x00200800,0x00200000,0x04000802, 0x04000802,0x04200002,0x04200002,0x00000002, +0x00200002,0x04000000,0x04000800,0x00200000, 0x04200800,0x00000802,0x00200802,0x04200800, +0x00000802,0x04000002,0x04200802,0x04200000, 0x00200800,0x00000000,0x00000002,0x04200802, +0x00000000,0x00200802,0x04200000,0x00000800, 0x04000002,0x04000800,0x00000800,0x00200002}, +{ +0x10001040,0x00001000,0x00040000,0x10041040, 0x10000000,0x10001040,0x00000040,0x10000000, +0x00040040,0x10040000,0x10041040,0x00041000, 0x10041000,0x00041040,0x00001000,0x00000040, +0x10040000,0x10000040,0x10001000,0x00001040, 0x00041000,0x00040040,0x10040040,0x10041000, +0x00001040,0x00000000,0x00000000,0x10040040, 0x10000040,0x10001000,0x00041040,0x00040000, +0x00041040,0x00040000,0x10041000,0x00001000, 0x00000040,0x10040040,0x00001000,0x00041040, +0x10001000,0x00000040,0x10000040,0x10040000, 0x10040040,0x10000000,0x00040000,0x10001040, +0x00000000,0x10041040,0x00040040,0x10000040, 0x10040000,0x10001000,0x10001040,0x00000000, +0x10041040,0x00041000,0x00041000,0x00001040, 0x00001040,0x00040040,0x10000000,0x10041000} +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/dh.cpp b/CryptoPP/crypto/dh.cpp new file mode 100644 index 0000000..b0b2e7c --- /dev/null +++ b/CryptoPP/crypto/dh.cpp @@ -0,0 +1,19 @@ +// dh.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "dh.h" + +NAMESPACE_BEGIN(CryptoPP) + +void DH_TestInstantiations() +{ + DH dh1; + DH dh2(NullRNG(), 10); +} + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/dh.h b/CryptoPP/crypto/dh.h new file mode 100644 index 0000000..590b9bb --- /dev/null +++ b/CryptoPP/crypto/dh.h @@ -0,0 +1,99 @@ +#ifndef CRYPTOPP_DH_H +#define CRYPTOPP_DH_H + +/** \file +*/ + +#include "gfpcrypt.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! , +template +class DH_Domain : public DL_SimpleKeyAgreementDomainBase +{ + typedef DL_SimpleKeyAgreementDomainBase Base; + +public: + typedef GROUP_PARAMETERS GroupParameters; + typedef typename GroupParameters::Element Element; + typedef DL_KeyAgreementAlgorithm_DH DH_Algorithm; + typedef DH_Domain Domain; + + DH_Domain() {} + + DH_Domain(const GroupParameters ¶ms) + : m_groupParameters(params) {} + + DH_Domain(BufferedTransformation &bt) + {m_groupParameters.BERDecode(bt);} + + template + DH_Domain(RandomNumberGenerator &v1, const T2 &v2) + {m_groupParameters.Initialize(v1, v2);} + + template + DH_Domain(RandomNumberGenerator &v1, const T2 &v2, const T3 &v3) + {m_groupParameters.Initialize(v1, v2, v3);} + + template + DH_Domain(RandomNumberGenerator &v1, const T2 &v2, const T3 &v3, const T4 &v4) + {m_groupParameters.Initialize(v1, v2, v3, v4);} + + template + DH_Domain(const T1 &v1, const T2 &v2) + {m_groupParameters.Initialize(v1, v2);} + + template + DH_Domain(const T1 &v1, const T2 &v2, const T3 &v3) + {m_groupParameters.Initialize(v1, v2, v3);} + + template + DH_Domain(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4) + {m_groupParameters.Initialize(v1, v2, v3, v4);} + + const GroupParameters & GetGroupParameters() const {return m_groupParameters;} + GroupParameters & AccessGroupParameters() {return m_groupParameters;} + + void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const + { + Base::GeneratePublicKey(rng, privateKey, publicKey); + + if (FIPS_140_2_ComplianceEnabled()) + { + SecByteBlock privateKey2(this->PrivateKeyLength()); + this->GeneratePrivateKey(rng, privateKey2); + + SecByteBlock publicKey2(this->PublicKeyLength()); + Base::GeneratePublicKey(rng, privateKey2, publicKey2); + + SecByteBlock agreedValue(this->AgreedValueLength()), agreedValue2(this->AgreedValueLength()); + this->Agree(agreedValue, privateKey, publicKey2); + this->Agree(agreedValue2, privateKey2, publicKey); + + if (agreedValue != agreedValue2) + throw SelfTestFailure(this->AlgorithmName() + ": pairwise consistency test failed"); + } + } + + static std::string CRYPTOPP_API StaticAlgorithmName() + {return GroupParameters::StaticAlgorithmNamePrefix() + DH_Algorithm::StaticAlgorithmName();} + std::string AlgorithmName() const {return StaticAlgorithmName();} + +private: + const DL_KeyAgreementAlgorithm & GetKeyAgreementAlgorithm() const + {return Singleton().Ref();} + DL_GroupParameters & AccessAbstractGroupParameters() + {return m_groupParameters;} + + GroupParameters m_groupParameters; +}; + +CRYPTOPP_DLL_TEMPLATE_CLASS DH_Domain; + +//! Diffie-Hellman in GF(p) with key validation +typedef DH_Domain DH; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/dh1024.dat b/CryptoPP/crypto/dh1024.dat new file mode 100644 index 0000000..86a9551 --- /dev/null +++ b/CryptoPP/crypto/dh1024.dat @@ -0,0 +1 @@ +30818702818100DA9A18547FF03B385CC16508C173A7EF4EB61CB40EF8FEF3B31F145051676166BCDC3FE6B799FC394D08C26385F9413F896E09117E46209D6923602683CEA100924A6EE695281775C619DAA94EA8CB3691B4275B0183F1D39639EBC92995FE645D6C1BC28D409E585549BBD2C5DCDD6C208B04EADD8B7A6D997F72CBAD88390F020102 \ No newline at end of file diff --git a/CryptoPP/crypto/dh2.cpp b/CryptoPP/crypto/dh2.cpp new file mode 100644 index 0000000..4a292af --- /dev/null +++ b/CryptoPP/crypto/dh2.cpp @@ -0,0 +1,22 @@ +// dh2.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "dh2.h" + +NAMESPACE_BEGIN(CryptoPP) + +void DH2_TestInstantiations() +{ + DH2 dh(*(SimpleKeyAgreementDomain*)NULL); +} + +bool DH2::Agree(byte *agreedValue, + const byte *staticSecretKey, const byte *ephemeralSecretKey, + const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey, + bool validateStaticOtherPublicKey) const +{ + return d1.Agree(agreedValue, staticSecretKey, staticOtherPublicKey, validateStaticOtherPublicKey) + && d2.Agree(agreedValue+d1.AgreedValueLength(), ephemeralSecretKey, ephemeralOtherPublicKey, true); +} + +NAMESPACE_END diff --git a/CryptoPP/crypto/dh2.h b/CryptoPP/crypto/dh2.h new file mode 100644 index 0000000..1dfd5e2 --- /dev/null +++ b/CryptoPP/crypto/dh2.h @@ -0,0 +1,58 @@ +#ifndef CRYPTOPP_DH2_H +#define CRYPTOPP_DH2_H + +/** \file +*/ + +#include "cryptlib.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// Unified Diffie-Hellman +class DH2 : public AuthenticatedKeyAgreementDomain +{ +public: + DH2(SimpleKeyAgreementDomain &domain) + : d1(domain), d2(domain) {} + DH2(SimpleKeyAgreementDomain &staticDomain, SimpleKeyAgreementDomain &ephemeralDomain) + : d1(staticDomain), d2(ephemeralDomain) {} + + CryptoParameters & AccessCryptoParameters() {return d1.AccessCryptoParameters();} + + unsigned int AgreedValueLength() const + {return d1.AgreedValueLength() + d2.AgreedValueLength();} + + unsigned int StaticPrivateKeyLength() const + {return d1.PrivateKeyLength();} + unsigned int StaticPublicKeyLength() const + {return d1.PublicKeyLength();} + void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const + {d1.GeneratePrivateKey(rng, privateKey);} + void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const + {d1.GeneratePublicKey(rng, privateKey, publicKey);} + void GenerateStaticKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const + {d1.GenerateKeyPair(rng, privateKey, publicKey);} + + unsigned int EphemeralPrivateKeyLength() const + {return d2.PrivateKeyLength();} + unsigned int EphemeralPublicKeyLength() const + {return d2.PublicKeyLength();} + void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const + {d2.GeneratePrivateKey(rng, privateKey);} + void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const + {d2.GeneratePublicKey(rng, privateKey, publicKey);} + void GenerateEphemeralKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const + {d2.GenerateKeyPair(rng, privateKey, publicKey);} + + bool Agree(byte *agreedValue, + const byte *staticPrivateKey, const byte *ephemeralPrivateKey, + const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey, + bool validateStaticOtherPublicKey=true) const; + +protected: + SimpleKeyAgreementDomain &d1, &d2; +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/dh2048.dat b/CryptoPP/crypto/dh2048.dat new file mode 100644 index 0000000..bd5255f --- /dev/null +++ b/CryptoPP/crypto/dh2048.dat @@ -0,0 +1 @@ +308201080282010100EB60DBD494AAFBCD2EAC6A36DB8E7DD4A2A64512A5BBB15B9BFB581C7C1CAFB647D4612973C3770C2166D75EEA695F67EA8261557591DB78BCF5A886AA5294F3AEE4D25B57C8EE8C7FE8DBF70C132CD7FFCB6F89426F807F552C5DAE2FB1F329E340094E4B30D8EF6265AB4D350E9837B151C86AC524DE4E1FC04746C668BE318275E420D51AEDDFBDF887D435CDEEF6AC81293DB45287132F8236A43AD8F4D6642D7CA6732DA06A1DE008259008C9D74403B68ADAC788CF8AB5BEFFC310DCCCD32901D1F290E5B7A993D2CF6A652AF81B6DA0FD2E70678D1AE086150E41444522F20621195AD2A1F0975652B4AF7DE5261A9FD46B9EA8B443641F3BBA695B9B020103 \ No newline at end of file diff --git a/CryptoPP/crypto/dlie1024.dat b/CryptoPP/crypto/dlie1024.dat new file mode 100644 index 0000000..2b2c85c --- /dev/null +++ b/CryptoPP/crypto/dlie1024.dat @@ -0,0 +1 @@ +308201A40201003082011706072A8648CE3804013082010A028181008B333697371663F8869E3EC80A414E46BBAFE41F6D40E754A01ADA60FE7D12ACD16DE311C4115293114F6B92A54195909276380F04BCD4ED5CD993ED7F516DF7A752B928E5035E0D3A1A979A1CDE8387734338793C02001D59B662D4FC8F2BF0EABB1F553F9F46F57E74BCABCBA4E458812DB601FCD04609D435317181236B9702818045999B4B9B8B31FC434F1F640520A7235DD7F20FB6A073AA500D6D307F3E895668B6F188E208A94988A7B5C952A0CAC8493B1C07825E6A76AE6CC9F6BFA8B6FBD3A95C947281AF069D0D4BCD0E6F41C3B9A19C3C9E01000EACDB316A7E4795F8755D8FAA9FCFA37ABF3A5E55E5D2722C4096DB00FE682304EA1A98B8C091B5CB02010204818302818045999B4B9B8B31FC434F1F640520A7235DD7F20FB6A073AA500D6D307F3E895668B6F188E208A94988A7B5C952A0CAC8493B1C07825E6A76AE6CC9F6BFA8B6FBD3A95C947281AF069D0D4BCD0E6F41C3B9A19C3C9E01000EACDB316A7E4795F8755D8FAA9FCFA37ABF3A5E2958F40032EF29CB145C7481380458812D62F09287 diff --git a/CryptoPP/crypto/dlie2048.dat b/CryptoPP/crypto/dlie2048.dat new file mode 100644 index 0000000..e2289c7 --- /dev/null +++ b/CryptoPP/crypto/dlie2048.dat @@ -0,0 +1 @@ +308203280201003082021906072A8648CE3804013082020C0282010100A2D27D91489706E93358E6F57E7F85B986A972EFC2D5F2150B5981AE5C82AF3DCB99EB2B05EBDB4E3F7B7463536AD58AAE4E679E02B580E0A0952E88B3C5CEF73274C0458BD2CB0498E1431DF7EFC570F4D3A58686C498A3A0D404B1F68BDF1961A1160F4099EEC91CED5982B924610ECA12882F74B8CEDB49B5153E68B62ACE0ED93AD8019680CA333EF4B237AE43C1359C46281092A23DDAFFA915F639EDE93001D5D3C5CECF808B1FBC9D1FC941597137A811606DBCF643E73DF844532B540FD7A60566B5C859BC5B56C8CC5591D30E765E45CB33EFDF32322C29A843341AEA6E35348F5749E510783E8DAC70E7A646F6C8FEA25C7465DE8D58041F5CD8F30282010051693EC8A44B837499AC737ABF3FC2DCC354B977E16AF90A85ACC0D72E41579EE5CCF59582F5EDA71FBDBA31A9B56AC5572733CF015AC070504A974459E2E77B993A6022C5E965824C70A18EFBF7E2B87A69D2C343624C51D06A0258FB45EF8CB0D08B07A04CF7648E76ACC15C92308765094417BA5C676DA4DA8A9F345B1567076C9D6C00CB4065199F7A591BD721E09ACE23140849511EED7FD48AFB1CF6F49800EAE9E2E767C0458FDE4E8FE4A0ACB89BD408B036DE7B21F39EFC222995AA07EBD302B35AE42CDE2DAB64662AC8E9873B2F22E599F7EF99191614D4219A0D75371A9A47ABA4F2883C1F46D63873D3237B647F512E3A32EF46AC020FAE6C79020103048201040282010051693EC8A44B837499AC737ABF3FC2DCC354B977E16AF90A85ACC0D72E41579EE5CCF59582F5EDA71FBDBA31A9B56AC5572733CF015AC070504A974459E2E77B993A6022C5E965824C70A18EFBF7E2B87A69D2C343624C51D06A0258FB45EF8CB0D08B07A04CF7648E76ACC15C92308765094417BA5C676DA4DA8A9F345B1567076C9D6C00CB4065199F7A591BD721E09ACE23140849511EED7FD48AFB1CF6F49800EAE9E2E767C0458FDE4E8FE4A0ACB89BD408B036DE7B21F39EFC222995AA07EBD302B35AE42CDE2DAB64662AC8E9873B2F22E599F7EF99191614D4219A0D75371A943DF2A781AEF1E87084B0419C5988BF5EF581798F6CBFAD827CE75642 diff --git a/CryptoPP/crypto/dll.cpp b/CryptoPP/crypto/dll.cpp new file mode 100644 index 0000000..5f64457 --- /dev/null +++ b/CryptoPP/crypto/dll.cpp @@ -0,0 +1,146 @@ +// dll.cpp - written and placed in the public domain by Wei Dai + +#define CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES +#define CRYPTOPP_DEFAULT_NO_DLL + +#include "dll.h" +#pragma warning(default: 4660) + +#if defined(CRYPTOPP_EXPORTS) && defined(CRYPTOPP_WIN32_AVAILABLE) +#include +#endif + +#ifndef CRYPTOPP_IMPORTS + +NAMESPACE_BEGIN(CryptoPP) + +template<> const byte PKCS_DigestDecoration::decoration[] = {0x30,0x21,0x30,0x09,0x06,0x05,0x2B,0x0E,0x03,0x02,0x1A,0x05,0x00,0x04,0x14}; +template<> const unsigned int PKCS_DigestDecoration::length = sizeof(PKCS_DigestDecoration::decoration); + +template<> const byte PKCS_DigestDecoration::decoration[] = {0x30,0x2d,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x04,0x05,0x00,0x04,0x1c}; +template<> const unsigned int PKCS_DigestDecoration::length = sizeof(PKCS_DigestDecoration::decoration); + +template<> const byte PKCS_DigestDecoration::decoration[] = {0x30,0x31,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,0x04,0x20}; +template<> const unsigned int PKCS_DigestDecoration::length = sizeof(PKCS_DigestDecoration::decoration); + +template<> const byte PKCS_DigestDecoration::decoration[] = {0x30,0x41,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02,0x05,0x00,0x04,0x30}; +template<> const unsigned int PKCS_DigestDecoration::length = sizeof(PKCS_DigestDecoration::decoration); + +template<> const byte PKCS_DigestDecoration::decoration[] = {0x30,0x51,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03,0x05,0x00,0x04,0x40}; +template<> const unsigned int PKCS_DigestDecoration::length = sizeof(PKCS_DigestDecoration::decoration); + +template<> const byte EMSA2HashId::id = 0x33; +template<> const byte EMSA2HashId::id = 0x38; +template<> const byte EMSA2HashId::id = 0x34; +template<> const byte EMSA2HashId::id = 0x36; +template<> const byte EMSA2HashId::id = 0x35; + +NAMESPACE_END + +#endif + +#ifdef CRYPTOPP_EXPORTS + +USING_NAMESPACE(CryptoPP) + +#if !(defined(_MSC_VER) && (_MSC_VER < 1300)) +using std::set_new_handler; +#endif + +static PNew s_pNew = NULL; +static PDelete s_pDelete = NULL; + +static void * New (size_t size) +{ + void *p; + while (!(p = malloc(size))) + CallNewHandler(); + + return p; +} + +static void SetNewAndDeleteFunctionPointers() +{ + void *p = NULL; + HMODULE hModule = NULL; + MEMORY_BASIC_INFORMATION mbi; + + while (true) + { + VirtualQuery(p, &mbi, sizeof(mbi)); + + if (p >= (char *)mbi.BaseAddress + mbi.RegionSize) + break; + + p = (char *)mbi.BaseAddress + mbi.RegionSize; + + if (!mbi.AllocationBase || mbi.AllocationBase == hModule) + continue; + + hModule = HMODULE(mbi.AllocationBase); + + PGetNewAndDelete pGetNewAndDelete = (PGetNewAndDelete)GetProcAddress(hModule, "GetNewAndDeleteForCryptoPP"); + if (pGetNewAndDelete) + { + pGetNewAndDelete(s_pNew, s_pDelete); + return; + } + + PSetNewAndDelete pSetNewAndDelete = (PSetNewAndDelete)GetProcAddress(hModule, "SetNewAndDeleteFromCryptoPP"); + if (pSetNewAndDelete) + { + s_pNew = &New; + s_pDelete = &free; + pSetNewAndDelete(s_pNew, s_pDelete, &set_new_handler); + return; + } + } + + // try getting these directly using mangled names of new and delete operators + + hModule = GetModuleHandle("msvcrtd"); + if (!hModule) + hModule = GetModuleHandle("msvcrt"); + if (hModule) + { + // 32-bit versions + s_pNew = (PNew)GetProcAddress(hModule, "??2@YAPAXI@Z"); + s_pDelete = (PDelete)GetProcAddress(hModule, "??3@YAXPAX@Z"); + if (s_pNew && s_pDelete) + return; + + // 64-bit versions + s_pNew = (PNew)GetProcAddress(hModule, "??2@YAPEAX_K@Z"); + s_pDelete = (PDelete)GetProcAddress(hModule, "??3@YAXPEAX@Z"); + if (s_pNew && s_pDelete) + return; + } + + OutputDebugString("Crypto++ was not able to obtain new and delete function pointers.\n"); + throw 0; +} + +void * operator new (size_t size) +{ + if (!s_pNew) + SetNewAndDeleteFunctionPointers(); + + return s_pNew(size); +} + +void operator delete (void * p) +{ + s_pDelete(p); +} + +void * operator new [] (size_t size) +{ + return operator new (size); +} + +void operator delete [] (void * p) +{ + operator delete (p); +} + +#endif // #ifdef CRYPTOPP_EXPORTS diff --git a/CryptoPP/crypto/dll.h b/CryptoPP/crypto/dll.h new file mode 100644 index 0000000..274e8b6 --- /dev/null +++ b/CryptoPP/crypto/dll.h @@ -0,0 +1,68 @@ +#ifndef CRYPTOPP_DLL_H +#define CRYPTOPP_DLL_H + +#if !defined(CRYPTOPP_IMPORTS) && !defined(CRYPTOPP_EXPORTS) && !defined(CRYPTOPP_DEFAULT_NO_DLL) +#ifdef CRYPTOPP_CONFIG_H +#error To use the DLL version of Crypto++, this file must be included before any other Crypto++ header files. +#endif +#define CRYPTOPP_IMPORTS +#endif + +#include "aes.h" +#include "cbcmac.h" +#include "channels.h" +#include "des.h" +#include "dh.h" +#include "dsa.h" +#include "ec2n.h" +#include "eccrypto.h" +#include "ecp.h" +#include "files.h" +#include "fips140.h" +#include "hex.h" +#include "hmac.h" +#include "modes.h" +#include "mqueue.h" +#include "nbtheory.h" +#include "osrng.h" +#include "pkcspad.h" +#include "pssr.h" +#include "randpool.h" +#include "rsa.h" +#include "rw.h" +#include "sha.h" +#include "skipjack.h" +#include "trdlocal.h" + +#ifdef CRYPTOPP_IMPORTS + +#ifdef _DLL +// cause CRT DLL to be initialized before Crypto++ so that we can use malloc and free during DllMain() +#ifdef NDEBUG +#pragma comment(lib, "msvcrt") +#else +#pragma comment(lib, "msvcrtd") +#endif +#endif + +#pragma comment(lib, "cryptopp") + +#endif // #ifdef CRYPTOPP_IMPORTS + +#include // for new_handler + +NAMESPACE_BEGIN(CryptoPP) + +#if !(defined(_MSC_VER) && (_MSC_VER < 1300)) +using std::new_handler; +#endif + +typedef void * (CRYPTOPP_API * PNew)(size_t); +typedef void (CRYPTOPP_API * PDelete)(void *); +typedef void (CRYPTOPP_API * PGetNewAndDelete)(PNew &, PDelete &); +typedef new_handler (CRYPTOPP_API * PSetNewHandler)(new_handler); +typedef void (CRYPTOPP_API * PSetNewAndDelete)(PNew, PDelete, PSetNewHandler); + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/dlltest.cpp b/CryptoPP/crypto/dlltest.cpp new file mode 100644 index 0000000..0b3287d --- /dev/null +++ b/CryptoPP/crypto/dlltest.cpp @@ -0,0 +1,206 @@ +#ifndef CRYPTOPP_DLL_ONLY +#define CRYPTOPP_DEFAULT_NO_DLL +#endif + +#include "dll.h" +#include + +USING_NAMESPACE(CryptoPP) +USING_NAMESPACE(std) + +void FIPS140_SampleApplication() +{ + if (!FIPS_140_2_ComplianceEnabled()) + { + cerr << "FIPS 140-2 compliance was turned off at compile time.\n"; + abort(); + } + + // check self test status + if (GetPowerUpSelfTestStatus() != POWER_UP_SELF_TEST_PASSED) + { + cerr << "Automatic power-up self test failed.\n"; + abort(); + } + cout << "0. Automatic power-up self test passed.\n"; + + // simulate a power-up self test error + SimulatePowerUpSelfTestFailure(); + try + { + // trying to use a crypto algorithm after power-up self test error will result in an exception + AES::Encryption aes; + + // should not be here + cerr << "Use of AES failed to cause an exception after power-up self test error.\n"; + abort(); + } + catch (SelfTestFailure &e) + { + cout << "1. Caught expected exception when simulating self test failure. Exception message follows: "; + cout << e.what() << endl; + } + + // clear the self test error state and redo power-up self test + DoDllPowerUpSelfTest(); + if (GetPowerUpSelfTestStatus() != POWER_UP_SELF_TEST_PASSED) + { + cerr << "Re-do power-up self test failed.\n"; + abort(); + } + cout << "2. Re-do power-up self test passed.\n"; + + // encrypt and decrypt + const byte key[] = {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef, 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef, 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}; + const byte iv[] = {0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef}; + const byte plaintext[] = { // "Now is the time for all " without tailing 0 + 0x4e,0x6f,0x77,0x20,0x69,0x73,0x20,0x74, + 0x68,0x65,0x20,0x74,0x69,0x6d,0x65,0x20, + 0x66,0x6f,0x72,0x20,0x61,0x6c,0x6c,0x20}; + byte ciphertext[24]; + byte decrypted[24]; + + CFB_FIPS_Mode::Encryption encryption_DES_EDE3_CFB; + encryption_DES_EDE3_CFB.SetKeyWithIV(key, sizeof(key), iv); + encryption_DES_EDE3_CFB.ProcessString(ciphertext, plaintext, 24); + + CFB_FIPS_Mode::Decryption decryption_DES_EDE3_CFB; + decryption_DES_EDE3_CFB.SetKeyWithIV(key, sizeof(key), iv); + decryption_DES_EDE3_CFB.ProcessString(decrypted, ciphertext, 24); + + if (memcmp(plaintext, decrypted, 24) != 0) + { + cerr << "DES-EDE3-CFB Encryption/decryption failed.\n"; + abort(); + } + cout << "3. DES-EDE3-CFB Encryption/decryption succeeded.\n"; + + // hash + const byte message[] = {'a', 'b', 'c'}; + const byte expectedDigest[] = {0xA9,0x99,0x3E,0x36,0x47,0x06,0x81,0x6A,0xBA,0x3E,0x25,0x71,0x78,0x50,0xC2,0x6C,0x9C,0xD0,0xD8,0x9D}; + byte digest[20]; + + SHA1 sha; + sha.Update(message, 3); + sha.Final(digest); + + if (memcmp(digest, expectedDigest, 20) != 0) + { + cerr << "SHA-1 hash failed.\n"; + abort(); + } + cout << "4. SHA-1 hash succeeded.\n"; + + // create auto-seeded X9.17 RNG object, if available +#ifdef OS_RNG_AVAILABLE + AutoSeededX917RNG rng; +#else + // this is used to allow this function to compile on platforms that don't have auto-seeded RNGs + RandomNumberGenerator &rng(NullRNG()); +#endif + + // generate DSA key + DSA::PrivateKey dsaPrivateKey; + dsaPrivateKey.GenerateRandomWithKeySize(rng, 1024); + DSA::PublicKey dsaPublicKey; + dsaPublicKey.AssignFrom(dsaPrivateKey); + if (!dsaPrivateKey.Validate(rng, 3) || !dsaPublicKey.Validate(rng, 3)) + { + cerr << "DSA key generation failed.\n"; + abort(); + } + cout << "5. DSA key generation succeeded.\n"; + + // encode DSA key + std::string encodedDsaPublicKey, encodedDsaPrivateKey; + dsaPublicKey.DEREncode(StringSink(encodedDsaPublicKey).Ref()); + dsaPrivateKey.DEREncode(StringSink(encodedDsaPrivateKey).Ref()); + + // decode DSA key + DSA::PrivateKey decodedDsaPrivateKey; + decodedDsaPrivateKey.BERDecode(StringStore(encodedDsaPrivateKey).Ref()); + DSA::PublicKey decodedDsaPublicKey; + decodedDsaPublicKey.BERDecode(StringStore(encodedDsaPublicKey).Ref()); + + if (!decodedDsaPrivateKey.Validate(rng, 3) || !decodedDsaPublicKey.Validate(rng, 3)) + { + cerr << "DSA key encode/decode failed.\n"; + abort(); + } + cout << "6. DSA key encode/decode succeeded.\n"; + + // sign and verify + byte signature[40]; + DSA::Signer signer(dsaPrivateKey); + assert(signer.SignatureLength() == 40); + signer.SignMessage(rng, message, 3, signature); + + DSA::Verifier verifier(dsaPublicKey); + if (!verifier.VerifyMessage(message, 3, signature, sizeof(signature))) + { + cerr << "DSA signature and verification failed.\n"; + abort(); + } + cout << "7. DSA signature and verification succeeded.\n"; + + + // try to verify an invalid signature + signature[0] ^= 1; + if (verifier.VerifyMessage(message, 3, signature, sizeof(signature))) + { + cerr << "DSA signature verification failed to detect bad signature.\n"; + abort(); + } + cout << "8. DSA signature verification successfully detected bad signature.\n"; + + // try to use an invalid key length + try + { + ECB_Mode::Encryption encryption_DES_EDE3_ECB; + encryption_DES_EDE3_ECB.SetKey(key, 5); + + // should not be here + cerr << "DES-EDE3 implementation did not detect use of invalid key length.\n"; + abort(); + } + catch (InvalidArgument &e) + { + cout << "9. Caught expected exception when using invalid key length. Exception message follows: "; + cout << e.what() << endl; + } + + cout << "\nFIPS 140-2 Sample Application completed normally.\n"; +} + +#ifdef CRYPTOPP_IMPORTS + +static PNew s_pNew = NULL; +static PDelete s_pDelete = NULL; + +extern "C" __declspec(dllexport) void __cdecl SetNewAndDeleteFromCryptoPP(PNew pNew, PDelete pDelete, PSetNewHandler pSetNewHandler) +{ + s_pNew = pNew; + s_pDelete = pDelete; +} + +void * __cdecl operator new (size_t size) +{ + return s_pNew(size); +} + +void __cdecl operator delete (void * p) +{ + s_pDelete(p); +} + +#endif + +#ifdef CRYPTOPP_DLL_ONLY + +int __cdecl main() +{ + FIPS140_SampleApplication(); + return 0; +} + +#endif diff --git a/CryptoPP/crypto/dlltest.dsp b/CryptoPP/crypto/dlltest.dsp new file mode 100644 index 0000000..d69f75c --- /dev/null +++ b/CryptoPP/crypto/dlltest.dsp @@ -0,0 +1,90 @@ +# Microsoft Developer Studio Project File - Name="dlltest" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=dlltest - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "dlltest.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "dlltest.mak" CFG="dlltest - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "dlltest - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "dlltest - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "dlltest - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "dlltest___Win32_Release" +# PROP BASE Intermediate_Dir "dlltest___Win32_Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "dlltest___Win32_Release" +# PROP Intermediate_Dir "dlltest___Win32_Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /Gz /MT /W3 /GX /Zi /O1 /Ob2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "CRYPTOPP_DLL_ONLY" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 /nologo /subsystem:console /map /debug /machine:I386 /out:"DLL_Release/dlltest.exe" /libpath:"DLL_Release" + +!ELSEIF "$(CFG)" == "dlltest - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "dlltest___Win32_Debug" +# PROP BASE Intermediate_Dir "dlltest___Win32_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "dlltest___Win32_Debug" +# PROP Intermediate_Dir "dlltest___Win32_Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /Gz /MTd /W3 /Gm /GX /Zi /Oi /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "CRYPTOPP_DLL_ONLY" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 /nologo /subsystem:console /debug /machine:I386 /out:"DLL_Debug/dlltest.exe" /pdbtype:sept /libpath:"DLL_Debug" + +!ENDIF + +# Begin Target + +# Name "dlltest - Win32 Release" +# Name "dlltest - Win32 Debug" +# Begin Source File + +SOURCE=.\dlltest.cpp +# End Source File +# End Target +# End Project diff --git a/CryptoPP/crypto/dmac.h b/CryptoPP/crypto/dmac.h new file mode 100644 index 0000000..054e6cb --- /dev/null +++ b/CryptoPP/crypto/dmac.h @@ -0,0 +1,91 @@ +#ifndef CRYPTOPP_DMAC_H +#define CRYPTOPP_DMAC_H + +#include "cbcmac.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! _ +template +class CRYPTOPP_NO_VTABLE DMAC_Base : public SameKeyLengthAs, public MessageAuthenticationCode +{ +public: + static std::string StaticAlgorithmName() {return std::string("DMAC(") + T::StaticAlgorithmName() + ")";} + + CRYPTOPP_CONSTANT(DIGESTSIZE=T::BLOCKSIZE) + + DMAC_Base() {} + + void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms); + void Update(const byte *input, size_t length); + void TruncatedFinal(byte *mac, size_t size); + unsigned int DigestSize() const {return DIGESTSIZE;} + +private: + byte *GenerateSubKeys(const byte *key, size_t keylength); + + size_t m_subkeylength; + SecByteBlock m_subkeys; + CBC_MAC m_mac1; + typename T::Encryption m_f2; + unsigned int m_counter; +}; + +//! DMAC +/*! Based on "CBC MAC for Real-Time Data Sources" by Erez Petrank + and Charles Rackoff. T should be a class derived from BlockCipherDocumentation. +*/ +template +class DMAC : public MessageAuthenticationCodeFinal > +{ +public: + DMAC() {} + DMAC(const byte *key, size_t length=DMAC_Base::DEFAULT_KEYLENGTH) + {this->SetKey(key, length);} +}; + +template +void DMAC_Base::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms) +{ + m_subkeylength = T::StaticGetValidKeyLength(T::BLOCKSIZE); + m_subkeys.resize(2*UnsignedMin((unsigned int)T::BLOCKSIZE, m_subkeylength)); + m_mac1.SetKey(GenerateSubKeys(key, length), m_subkeylength, params); + m_f2.SetKey(m_subkeys+m_subkeys.size()/2, m_subkeylength, params); + m_counter = 0; + m_subkeys.resize(0); +} + +template +void DMAC_Base::Update(const byte *input, size_t length) +{ + m_mac1.Update(input, length); + m_counter = (unsigned int)((m_counter + length) % T::BLOCKSIZE); +} + +template +void DMAC_Base::TruncatedFinal(byte *mac, size_t size) +{ + ThrowIfInvalidTruncatedSize(size); + + byte pad[T::BLOCKSIZE]; + byte padByte = byte(T::BLOCKSIZE-m_counter); + memset(pad, padByte, padByte); + m_mac1.Update(pad, padByte); + m_mac1.TruncatedFinal(mac, size); + m_f2.ProcessBlock(mac); +} + +template +byte *DMAC_Base::GenerateSubKeys(const byte *key, size_t keylength) +{ + typename T::Encryption cipher(key, keylength); + memset(m_subkeys, 0, m_subkeys.size()); + cipher.ProcessBlock(m_subkeys); + m_subkeys[m_subkeys.size()/2 + T::BLOCKSIZE - 1] = 1; + cipher.ProcessBlock(m_subkeys+m_subkeys.size()/2); + return m_subkeys; +} + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/dsa.cpp b/CryptoPP/crypto/dsa.cpp new file mode 100644 index 0000000..4b130d7 --- /dev/null +++ b/CryptoPP/crypto/dsa.cpp @@ -0,0 +1,119 @@ +// dsa.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "dsa.h" +#include "nbtheory.h" + +NAMESPACE_BEGIN(CryptoPP) + +size_t DSAConvertSignatureFormat(byte *buffer, size_t bufferSize, DSASignatureFormat toFormat, const byte *signature, size_t signatureLen, DSASignatureFormat fromFormat) +{ + Integer r, s; + StringStore store(signature, signatureLen); + ArraySink sink(buffer, bufferSize); + + switch (fromFormat) + { + case DSA_P1363: + r.Decode(store, signatureLen/2); + s.Decode(store, signatureLen/2); + break; + case DSA_DER: + { + BERSequenceDecoder seq(store); + r.BERDecode(seq); + s.BERDecode(seq); + seq.MessageEnd(); + break; + } + case DSA_OPENPGP: + r.OpenPGPDecode(store); + s.OpenPGPDecode(store); + break; + } + + switch (toFormat) + { + case DSA_P1363: + r.Encode(sink, bufferSize/2); + s.Encode(sink, bufferSize/2); + break; + case DSA_DER: + { + DERSequenceEncoder seq(sink); + r.DEREncode(seq); + s.DEREncode(seq); + seq.MessageEnd(); + break; + } + case DSA_OPENPGP: + r.OpenPGPEncode(sink); + s.OpenPGPEncode(sink); + break; + } + + return (size_t)sink.TotalPutLength(); +} + +bool DSA::GeneratePrimes(const byte *seedIn, unsigned int g, int &counter, + Integer &p, unsigned int L, Integer &q, bool useInputCounterValue) +{ + assert(g%8 == 0); + + SHA sha; + SecByteBlock seed(seedIn, g/8); + SecByteBlock U(SHA::DIGESTSIZE); + SecByteBlock temp(SHA::DIGESTSIZE); + SecByteBlock W(((L-1)/160+1) * SHA::DIGESTSIZE); + const int n = (L-1) / 160; + const int b = (L-1) % 160; + Integer X; + + sha.CalculateDigest(U, seed, g/8); + + for (int i=g/8-1, carry=true; i>=0 && carry; i--) + carry=!++seed[i]; + + sha.CalculateDigest(temp, seed, g/8); + xorbuf(U, temp, SHA::DIGESTSIZE); + + U[0] |= 0x80; + U[SHA::DIGESTSIZE-1] |= 1; + q.Decode(U, SHA::DIGESTSIZE); + + if (!IsPrime(q)) + return false; + + int counterEnd = useInputCounterValue ? counter+1 : 4096; + + for (int c = 0; c < counterEnd; c++) + { + for (int k=0; k<=n; k++) + { + for (int i=g/8-1, carry=true; i>=0 && carry; i--) + carry=!++seed[i]; + if (!useInputCounterValue || c == counter) + sha.CalculateDigest(W+(n-k)*SHA::DIGESTSIZE, seed, g/8); + } + if (!useInputCounterValue || c == counter) + { + W[SHA::DIGESTSIZE - 1 - b/8] |= 0x80; + X.Decode(W + SHA::DIGESTSIZE - 1 - b/8, L/8); + p = X-((X % (2*q))-1); + + if (p.GetBit(L-1) && IsPrime(p)) + { + counter = c; + return true; + } + } + } + return false; +} + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/dsa.h b/CryptoPP/crypto/dsa.h new file mode 100644 index 0000000..96ba3c1 --- /dev/null +++ b/CryptoPP/crypto/dsa.h @@ -0,0 +1,35 @@ +#ifndef CRYPTOPP_DSA_H +#define CRYPTOPP_DSA_H + +/** \file +*/ + +#include "gfpcrypt.h" + +NAMESPACE_BEGIN(CryptoPP) + +/*! The DSA signature format used by Crypto++ is as defined by IEEE P1363. + Java uses the DER format, and OpenPGP uses the OpenPGP format. */ +enum DSASignatureFormat {DSA_P1363, DSA_DER, DSA_OPENPGP}; +/** This function converts between these formats, and returns length of signature in the target format. + If toFormat == DSA_P1363, bufferSize must equal publicKey.SignatureLength() */ +size_t DSAConvertSignatureFormat(byte *buffer, size_t bufferSize, DSASignatureFormat toFormat, + const byte *signature, size_t signatureLen, DSASignatureFormat fromFormat); + +#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY + +typedef DSA::Signer DSAPrivateKey; +typedef DSA::Verifier DSAPublicKey; + +const int MIN_DSA_PRIME_LENGTH = DSA::MIN_PRIME_LENGTH; +const int MAX_DSA_PRIME_LENGTH = DSA::MAX_PRIME_LENGTH; +const int DSA_PRIME_LENGTH_MULTIPLE = DSA::PRIME_LENGTH_MULTIPLE; + +inline bool GenerateDSAPrimes(const byte *seed, size_t seedLength, int &counter, Integer &p, unsigned int primeLength, Integer &q) + {return DSA::GeneratePrimes(seed, seedLength, counter, p, primeLength, q);} + +#endif + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/dsa1024.dat b/CryptoPP/crypto/dsa1024.dat new file mode 100644 index 0000000..8e59120 --- /dev/null +++ b/CryptoPP/crypto/dsa1024.dat @@ -0,0 +1 @@ +3082014A0201003082012B06072A8648CE3804013082011E02818100F468699A6F6EBCC0120D3B34C8E007F125EC7D81F763B8D0F33869AE3BD6B9F2ECCC7DF34DF84C0307449E9B85D30D57194BCCEB310F48141914DD13A077AAF9B624A6CBE666BBA1D7EBEA95B5BA6F54417FD5D4E4220C601E071D316A24EA814E8B0122DBF47EE8AEEFD319EBB01DD95683F10DBB4FEB023F8262A07EAEB7FD02150082AD4E034DA6EEACDFDAE68C36F2BAD614F9E53B02818071AAF73361A26081529F7D84078ADAFCA48E031DB54AD57FB1A833ADBD8672328AABAA0C756247998D7A5B10DACA359D231332CE8120B483A784FE07D46EEBFF0D7D374A10691F78653E6DC29E27CCB1B174923960DFE5B959B919B2C3816C19251832AFD8E35D810E598F82877ABF7D40A041565168BD7F0E21E3FE2A8D8C1C0416021426EBA66E846E755169F84A1DA981D86502405DDF \ No newline at end of file diff --git a/CryptoPP/crypto/dsa1024b.dat b/CryptoPP/crypto/dsa1024b.dat new file mode 100644 index 0000000..edfb808 --- /dev/null +++ b/CryptoPP/crypto/dsa1024b.dat @@ -0,0 +1 @@ +308201B73082012B06072A8648CE3804013082011E02818100F468699A6F6EBCC0120D3B34C8E007F125EC7D81F763B8D0F33869AE3BD6B9F2ECCC7DF34DF84C0307449E9B85D30D57194BCCEB310F48141914DD13A077AAF9B624A6CBE666BBA1D7EBEA95B5BA6F54417FD5D4E4220C601E071D316A24EA814E8B0122DBF47EE8AEEFD319EBB01DD95683F10DBB4FEB023F8262A07EAEB7FD02150082AD4E034DA6EEACDFDAE68C36F2BAD614F9E53B02818071AAF73361A26081529F7D84078ADAFCA48E031DB54AD57FB1A833ADBD8672328AABAA0C756247998D7A5B10DACA359D231332CE8120B483A784FE07D46EEBFF0D7D374A10691F78653E6DC29E27CCB1B174923960DFE5B959B919B2C3816C19251832AFD8E35D810E598F82877ABF7D40A041565168BD7F0E21E3FE2A8D8C1C0381850002818100D30312B7179661DA4691EDE39A71CB961199CD792C50AED6EA7E1A24C53590B6BCD92F26509D3372B2849A17C99C0962FBE4A2606CA37E6DF10244805363450FFAA24A7C274DF0B5D24AE7F31A8319FD2AA6E98AC6E7E3364E7AEDE575A9993609B0DFA387084141EA0B5B2D59B6DE718C0DAB4F86BC59F0DBE8602AED933494 \ No newline at end of file diff --git a/CryptoPP/crypto/dsa512.dat b/CryptoPP/crypto/dsa512.dat new file mode 100644 index 0000000..0d63cfd --- /dev/null +++ b/CryptoPP/crypto/dsa512.dat @@ -0,0 +1 @@ +3081C60201003081A806072A8648CE38040130819C0241008DF2A494492276AA3D25759BB06869CBEAC0D83AFB8D0CF7CBB8324F0D7882E5D0762FC5B7210EAFC2E9ADAC32AB7AAC49693DFBF83724C2EC0736EE31C80291021500C773218C737EC8EE993B4F2DED30F48EDACE915F0240626D027839EA0A13413163A55B4CB500299D5522956CEFCB3BFF10F399CE2C2E71CB9DE5FA24BABF58E5B79521925C9CC42E9F6F464B088CC572AF53E6D78802041602142070B3223DBA372FDE1C0FFC7B2E3B498B260614 \ No newline at end of file diff --git a/CryptoPP/crypto/ec2n.cpp b/CryptoPP/crypto/ec2n.cpp new file mode 100644 index 0000000..e2cf4ad --- /dev/null +++ b/CryptoPP/crypto/ec2n.cpp @@ -0,0 +1,288 @@ +// ec2n.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "ec2n.h" +#include "asn.h" + +#include "algebra.cpp" +#include "eprecomp.cpp" + +NAMESPACE_BEGIN(CryptoPP) + +EC2N::EC2N(BufferedTransformation &bt) + : m_field(BERDecodeGF2NP(bt)) +{ + BERSequenceDecoder seq(bt); + m_field->BERDecodeElement(seq, m_a); + m_field->BERDecodeElement(seq, m_b); + // skip optional seed + if (!seq.EndReached()) + BERDecodeOctetString(seq, TheBitBucket()); + seq.MessageEnd(); +} + +void EC2N::DEREncode(BufferedTransformation &bt) const +{ + m_field->DEREncode(bt); + DERSequenceEncoder seq(bt); + m_field->DEREncodeElement(seq, m_a); + m_field->DEREncodeElement(seq, m_b); + seq.MessageEnd(); +} + +bool EC2N::DecodePoint(EC2N::Point &P, const byte *encodedPoint, size_t encodedPointLen) const +{ + StringStore store(encodedPoint, encodedPointLen); + return DecodePoint(P, store, encodedPointLen); +} + +bool EC2N::DecodePoint(EC2N::Point &P, BufferedTransformation &bt, size_t encodedPointLen) const +{ + byte type; + if (encodedPointLen < 1 || !bt.Get(type)) + return false; + + switch (type) + { + case 0: + P.identity = true; + return true; + case 2: + case 3: + { + if (encodedPointLen != EncodedPointSize(true)) + return false; + + P.identity = false; + P.x.Decode(bt, m_field->MaxElementByteLength()); + + if (P.x.IsZero()) + { + P.y = m_field->SquareRoot(m_b); + return true; + } + + FieldElement z = m_field->Square(P.x); + assert(P.x == m_field->SquareRoot(z)); + P.y = m_field->Divide(m_field->Add(m_field->Multiply(z, m_field->Add(P.x, m_a)), m_b), z); + assert(P.x == m_field->Subtract(m_field->Divide(m_field->Subtract(m_field->Multiply(P.y, z), m_b), z), m_a)); + z = m_field->SolveQuadraticEquation(P.y); + assert(m_field->Add(m_field->Square(z), z) == P.y); + z.SetCoefficient(0, type & 1); + + P.y = m_field->Multiply(z, P.x); + return true; + } + case 4: + { + if (encodedPointLen != EncodedPointSize(false)) + return false; + + unsigned int len = m_field->MaxElementByteLength(); + P.identity = false; + P.x.Decode(bt, len); + P.y.Decode(bt, len); + return true; + } + default: + return false; + } +} + +void EC2N::EncodePoint(BufferedTransformation &bt, const Point &P, bool compressed) const +{ + if (P.identity) + NullStore().TransferTo(bt, EncodedPointSize(compressed)); + else if (compressed) + { + bt.Put(2 + (!P.x ? 0 : m_field->Divide(P.y, P.x).GetBit(0))); + P.x.Encode(bt, m_field->MaxElementByteLength()); + } + else + { + unsigned int len = m_field->MaxElementByteLength(); + bt.Put(4); // uncompressed + P.x.Encode(bt, len); + P.y.Encode(bt, len); + } +} + +void EC2N::EncodePoint(byte *encodedPoint, const Point &P, bool compressed) const +{ + ArraySink sink(encodedPoint, EncodedPointSize(compressed)); + EncodePoint(sink, P, compressed); + assert(sink.TotalPutLength() == EncodedPointSize(compressed)); +} + +EC2N::Point EC2N::BERDecodePoint(BufferedTransformation &bt) const +{ + SecByteBlock str; + BERDecodeOctetString(bt, str); + Point P; + if (!DecodePoint(P, str, str.size())) + BERDecodeError(); + return P; +} + +void EC2N::DEREncodePoint(BufferedTransformation &bt, const Point &P, bool compressed) const +{ + SecByteBlock str(EncodedPointSize(compressed)); + EncodePoint(str, P, compressed); + DEREncodeOctetString(bt, str); +} + +bool EC2N::ValidateParameters(RandomNumberGenerator &rng, unsigned int level) const +{ + bool pass = !!m_b; + pass = pass && m_a.CoefficientCount() <= m_field->MaxElementBitLength(); + pass = pass && m_b.CoefficientCount() <= m_field->MaxElementBitLength(); + + if (level >= 1) + pass = pass && m_field->GetModulus().IsIrreducible(); + + return pass; +} + +bool EC2N::VerifyPoint(const Point &P) const +{ + const FieldElement &x = P.x, &y = P.y; + return P.identity || + (x.CoefficientCount() <= m_field->MaxElementBitLength() + && y.CoefficientCount() <= m_field->MaxElementBitLength() + && !(((x+m_a)*x*x+m_b-(x+y)*y)%m_field->GetModulus())); +} + +bool EC2N::Equal(const Point &P, const Point &Q) const +{ + if (P.identity && Q.identity) + return true; + + if (P.identity && !Q.identity) + return false; + + if (!P.identity && Q.identity) + return false; + + return (m_field->Equal(P.x,Q.x) && m_field->Equal(P.y,Q.y)); +} + +const EC2N::Point& EC2N::Identity() const +{ + return Singleton().Ref(); +} + +const EC2N::Point& EC2N::Inverse(const Point &P) const +{ + if (P.identity) + return P; + else + { + m_R.identity = false; + m_R.y = m_field->Add(P.x, P.y); + m_R.x = P.x; + return m_R; + } +} + +const EC2N::Point& EC2N::Add(const Point &P, const Point &Q) const +{ + if (P.identity) return Q; + if (Q.identity) return P; + if (Equal(P, Q)) return Double(P); + if (m_field->Equal(P.x, Q.x) && m_field->Equal(P.y, m_field->Add(Q.x, Q.y))) return Identity(); + + FieldElement t = m_field->Add(P.y, Q.y); + t = m_field->Divide(t, m_field->Add(P.x, Q.x)); + FieldElement x = m_field->Square(t); + m_field->Accumulate(x, t); + m_field->Accumulate(x, Q.x); + m_field->Accumulate(x, m_a); + m_R.y = m_field->Add(P.y, m_field->Multiply(t, x)); + m_field->Accumulate(x, P.x); + m_field->Accumulate(m_R.y, x); + + m_R.x.swap(x); + m_R.identity = false; + return m_R; +} + +const EC2N::Point& EC2N::Double(const Point &P) const +{ + if (P.identity) return P; + if (!m_field->IsUnit(P.x)) return Identity(); + + FieldElement t = m_field->Divide(P.y, P.x); + m_field->Accumulate(t, P.x); + m_R.y = m_field->Square(P.x); + m_R.x = m_field->Square(t); + m_field->Accumulate(m_R.x, t); + m_field->Accumulate(m_R.x, m_a); + m_field->Accumulate(m_R.y, m_field->Multiply(t, m_R.x)); + m_field->Accumulate(m_R.y, m_R.x); + + m_R.identity = false; + return m_R; +} + +// ******************************************************** + +/* +EcPrecomputation& EcPrecomputation::operator=(const EcPrecomputation &rhs) +{ + m_ec = rhs.m_ec; + m_ep = rhs.m_ep; + m_ep.m_group = m_ec.get(); + return *this; +} + +void EcPrecomputation::SetCurveAndBase(const EC2N &ec, const EC2N::Point &base) +{ + m_ec.reset(new EC2N(ec)); + m_ep.SetGroupAndBase(*m_ec, base); +} + +void EcPrecomputation::Precompute(unsigned int maxExpBits, unsigned int storage) +{ + m_ep.Precompute(maxExpBits, storage); +} + +void EcPrecomputation::Load(BufferedTransformation &bt) +{ + BERSequenceDecoder seq(bt); + word32 version; + BERDecodeUnsigned(seq, version, INTEGER, 1, 1); + m_ep.m_exponentBase.BERDecode(seq); + m_ep.m_windowSize = m_ep.m_exponentBase.BitCount() - 1; + m_ep.m_bases.clear(); + while (!seq.EndReached()) + m_ep.m_bases.push_back(m_ec->BERDecodePoint(seq)); + seq.MessageEnd(); +} + +void EcPrecomputation::Save(BufferedTransformation &bt) const +{ + DERSequenceEncoder seq(bt); + DEREncodeUnsigned(seq, 1); // version + m_ep.m_exponentBase.DEREncode(seq); + for (unsigned i=0; iDEREncodePoint(seq, m_ep.m_bases[i]); + seq.MessageEnd(); +} + +EC2N::Point EcPrecomputation::Exponentiate(const Integer &exponent) const +{ + return m_ep.Exponentiate(exponent); +} + +EC2N::Point EcPrecomputation::CascadeExponentiate(const Integer &exponent, const DL_FixedBasePrecomputation &pc2, const Integer &exponent2) const +{ + return m_ep.CascadeExponentiate(exponent, static_cast &>(pc2).m_ep, exponent2); +} +*/ + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/ec2n.h b/CryptoPP/crypto/ec2n.h new file mode 100644 index 0000000..ebcaf4d --- /dev/null +++ b/CryptoPP/crypto/ec2n.h @@ -0,0 +1,113 @@ +#ifndef CRYPTOPP_EC2N_H +#define CRYPTOPP_EC2N_H + +#include "gf2n.h" +#include "eprecomp.h" +#include "smartptr.h" +#include "pubkey.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! Elliptic Curve Point +struct CRYPTOPP_DLL EC2NPoint +{ + EC2NPoint() : identity(true) {} + EC2NPoint(const PolynomialMod2 &x, const PolynomialMod2 &y) + : identity(false), x(x), y(y) {} + + bool operator==(const EC2NPoint &t) const + {return (identity && t.identity) || (!identity && !t.identity && x==t.x && y==t.y);} + bool operator< (const EC2NPoint &t) const + {return identity ? !t.identity : (!t.identity && (x; + +//! Elliptic Curve over GF(2^n) +class CRYPTOPP_DLL EC2N : public AbstractGroup +{ +public: + typedef GF2NP Field; + typedef Field::Element FieldElement; + typedef EC2NPoint Point; + + EC2N() {} + EC2N(const Field &field, const Field::Element &a, const Field::Element &b) + : m_field(field), m_a(a), m_b(b) {} + // construct from BER encoded parameters + // this constructor will decode and extract the the fields fieldID and curve of the sequence ECParameters + EC2N(BufferedTransformation &bt); + + // encode the fields fieldID and curve of the sequence ECParameters + void DEREncode(BufferedTransformation &bt) const; + + bool Equal(const Point &P, const Point &Q) const; + const Point& Identity() const; + const Point& Inverse(const Point &P) const; + bool InversionIsFast() const {return true;} + const Point& Add(const Point &P, const Point &Q) const; + const Point& Double(const Point &P) const; + + Point Multiply(const Integer &k, const Point &P) const + {return ScalarMultiply(P, k);} + Point CascadeMultiply(const Integer &k1, const Point &P, const Integer &k2, const Point &Q) const + {return CascadeScalarMultiply(P, k1, Q, k2);} + + bool ValidateParameters(RandomNumberGenerator &rng, unsigned int level=3) const; + bool VerifyPoint(const Point &P) const; + + unsigned int EncodedPointSize(bool compressed = false) const + {return 1 + (compressed?1:2)*m_field->MaxElementByteLength();} + // returns false if point is compressed and not valid (doesn't check if uncompressed) + bool DecodePoint(Point &P, BufferedTransformation &bt, size_t len) const; + bool DecodePoint(Point &P, const byte *encodedPoint, size_t len) const; + void EncodePoint(byte *encodedPoint, const Point &P, bool compressed) const; + void EncodePoint(BufferedTransformation &bt, const Point &P, bool compressed) const; + + Point BERDecodePoint(BufferedTransformation &bt) const; + void DEREncodePoint(BufferedTransformation &bt, const Point &P, bool compressed) const; + + Integer FieldSize() const {return Integer::Power2(m_field->MaxElementBitLength());} + const Field & GetField() const {return *m_field;} + const FieldElement & GetA() const {return m_a;} + const FieldElement & GetB() const {return m_b;} + + bool operator==(const EC2N &rhs) const + {return GetField() == rhs.GetField() && m_a == rhs.m_a && m_b == rhs.m_b;} + +private: + clonable_ptr m_field; + FieldElement m_a, m_b; + mutable Point m_R; +}; + +CRYPTOPP_DLL_TEMPLATE_CLASS DL_FixedBasePrecomputationImpl; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupPrecomputation; + +template class EcPrecomputation; + +//! EC2N precomputation +template<> class EcPrecomputation : public DL_GroupPrecomputation +{ +public: + typedef EC2N EllipticCurve; + + // DL_GroupPrecomputation + const AbstractGroup & GetGroup() const {return m_ec;} + Element BERDecodeElement(BufferedTransformation &bt) const {return m_ec.BERDecodePoint(bt);} + void DEREncodeElement(BufferedTransformation &bt, const Element &v) const {m_ec.DEREncodePoint(bt, v, false);} + + // non-inherited + void SetCurve(const EC2N &ec) {m_ec = ec;} + const EC2N & GetCurve() const {return m_ec;} + +private: + EC2N m_ec; +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/eccrypto.cpp b/CryptoPP/crypto/eccrypto.cpp new file mode 100644 index 0000000..c08df9e --- /dev/null +++ b/CryptoPP/crypto/eccrypto.cpp @@ -0,0 +1,650 @@ +// eccrypto.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" + +// prevent Sun's CC compiler from including this file automatically +#if !defined(__SUNPRO_CC) || defined(CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES) + +#ifndef CRYPTOPP_IMPORTS + +#include "eccrypto.h" +#include "nbtheory.h" +#include "oids.h" +#include "hex.h" +#include "argnames.h" +#include "ec2n.h" + +NAMESPACE_BEGIN(CryptoPP) + +#if 0 +static void ECDSA_TestInstantiations() +{ + ECDSA::Signer t1; + ECDSA::Verifier t2(t1); + ECNR::Signer t3; + ECNR::Verifier t4(t3); + ECIES::Encryptor t5; + ECIES::Decryptor t6; + ECDH::Domain t7; + ECMQV::Domain t8; +} +#endif + +// VC60 workaround: complains when these functions are put into an anonymous namespace +static Integer ConvertToInteger(const PolynomialMod2 &x) +{ + unsigned int l = x.ByteCount(); + SecByteBlock temp(l); + x.Encode(temp, l); + return Integer(temp, l); +} + +static inline Integer ConvertToInteger(const Integer &x) +{ + return x; +} + +static bool CheckMOVCondition(const Integer &q, const Integer &r) +{ + // see "Updated standards for validating elliptic curves", http://eprint.iacr.org/2007/343 + Integer t = 1; + unsigned int n = q.IsEven() ? 1 : q.BitCount(), m = r.BitCount(); + + for (unsigned int i=n; DiscreteLogWorkFactor(i) struct EcRecommendedParameters; + +template<> struct EcRecommendedParameters +{ + EcRecommendedParameters(const OID &oid, unsigned int t2, unsigned int t3, unsigned int t4, const char *a, const char *b, const char *g, const char *n, unsigned int h) + : oid(oid), t0(0), t1(0), t2(t2), t3(t3), t4(t4), a(a), b(b), g(g), n(n), h(h) {} + EcRecommendedParameters(const OID &oid, unsigned int t0, unsigned int t1, unsigned int t2, unsigned int t3, unsigned int t4, const char *a, const char *b, const char *g, const char *n, unsigned int h) + : oid(oid), t0(t0), t1(t1), t2(t2), t3(t3), t4(t4), a(a), b(b), g(g), n(n), h(h) {} + EC2N *NewEC() const + { + StringSource ssA(a, true, new HexDecoder); + StringSource ssB(b, true, new HexDecoder); + if (t0 == 0) + return new EC2N(GF2NT(t2, t3, t4), EC2N::FieldElement(ssA, (size_t)ssA.MaxRetrievable()), EC2N::FieldElement(ssB, (size_t)ssB.MaxRetrievable())); + else + return new EC2N(GF2NPP(t0, t1, t2, t3, t4), EC2N::FieldElement(ssA, (size_t)ssA.MaxRetrievable()), EC2N::FieldElement(ssB, (size_t)ssB.MaxRetrievable())); + }; + + OID oid; + unsigned int t0, t1, t2, t3, t4; + const char *a, *b, *g, *n; + unsigned int h; +}; + +template<> struct EcRecommendedParameters +{ + EcRecommendedParameters(const OID &oid, const char *p, const char *a, const char *b, const char *g, const char *n, unsigned int h) + : oid(oid), p(p), a(a), b(b), g(g), n(n), h(h) {} + ECP *NewEC() const + { + StringSource ssP(p, true, new HexDecoder); + StringSource ssA(a, true, new HexDecoder); + StringSource ssB(b, true, new HexDecoder); + return new ECP(Integer(ssP, (size_t)ssP.MaxRetrievable()), ECP::FieldElement(ssA, (size_t)ssA.MaxRetrievable()), ECP::FieldElement(ssB, (size_t)ssB.MaxRetrievable())); + }; + + OID oid; + const char *p; + const char *a, *b, *g, *n; + unsigned int h; +}; + +struct OIDLessThan +{ + template + inline bool operator()(const EcRecommendedParameters& a, const OID& b) {return a.oid < b;} + template + inline bool operator()(const OID& a, const EcRecommendedParameters& b) {return a < b.oid;} + template + inline bool operator()(const EcRecommendedParameters& a, const EcRecommendedParameters& b) {return a.oid < b.oid;} +}; + +static void GetRecommendedParameters(const EcRecommendedParameters *&begin, const EcRecommendedParameters *&end) +{ + // this array must be sorted by OID + static const EcRecommendedParameters rec[] = { + EcRecommendedParameters(ASN1::sect163k1(), + 163, 7, 6, 3, 0, + "000000000000000000000000000000000000000001", + "000000000000000000000000000000000000000001", + "0402FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE80289070FB05D38FF58321F2E800536D538CCDAA3D9", + "04000000000000000000020108A2E0CC0D99F8A5EF", + 2), + EcRecommendedParameters(ASN1::sect163r1(), + 163, 7, 6, 3, 0, + "07B6882CAAEFA84F9554FF8428BD88E246D2782AE2", + "0713612DCDDCB40AAB946BDA29CA91F73AF958AFD9", + "040369979697AB43897789566789567F787A7876A65400435EDB42EFAFB2989D51FEFCE3C80988F41FF883", + "03FFFFFFFFFFFFFFFFFFFF48AAB689C29CA710279B", + 2), + EcRecommendedParameters(ASN1::sect239k1(), + 239, 158, 0, + "000000000000000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000000000000001", + "0429A0B6A887A983E9730988A68727A8B2D126C44CC2CC7B2A6555193035DC76310804F12E549BDB011C103089E73510ACB275FC312A5DC6B76553F0CA", + "2000000000000000000000000000005A79FEC67CB6E91F1C1DA800E478A5", + 4), + EcRecommendedParameters(ASN1::sect113r1(), + 113, 9, 0, + "003088250CA6E7C7FE649CE85820F7", + "00E8BEE4D3E2260744188BE0E9C723", + "04009D73616F35F4AB1407D73562C10F00A52830277958EE84D1315ED31886", + "0100000000000000D9CCEC8A39E56F", + 2), + EcRecommendedParameters(ASN1::sect113r2(), + 113, 9, 0, + "00689918DBEC7E5A0DD6DFC0AA55C7", + "0095E9A9EC9B297BD4BF36E059184F", + "0401A57A6A7B26CA5EF52FCDB816479700B3ADC94ED1FE674C06E695BABA1D", + "010000000000000108789B2496AF93", + 2), + EcRecommendedParameters(ASN1::sect163r2(), + 163, 7, 6, 3, 0, + "000000000000000000000000000000000000000001", + "020A601907B8C953CA1481EB10512F78744A3205FD", + "0403F0EBA16286A2D57EA0991168D4994637E8343E3600D51FBC6C71A0094FA2CDD545B11C5C0C797324F1", + "040000000000000000000292FE77E70C12A4234C33", + 2), + EcRecommendedParameters(ASN1::sect283k1(), + 283, 12, 7, 5, 0, + "000000000000000000000000000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000000000000000000000000001", + "040503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC245849283601CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259", + "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61", + 4), + EcRecommendedParameters(ASN1::sect283r1(), + 283, 12, 7, 5, 0, + "000000000000000000000000000000000000000000000000000000000000000000000001", + "027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5", + "0405F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B1205303676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4", + "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307", + 2), + EcRecommendedParameters(ASN1::sect131r1(), + 131, 8, 3, 2, 0, + "07A11B09A76B562144418FF3FF8C2570B8", + "0217C05610884B63B9C6C7291678F9D341", + "040081BAF91FDF9833C40F9C181343638399078C6E7EA38C001F73C8134B1B4EF9E150", + "0400000000000000023123953A9464B54D", + 2), + EcRecommendedParameters(ASN1::sect131r2(), + 131, 8, 3, 2, 0, + "03E5A88919D7CAFCBF415F07C2176573B2", + "04B8266A46C55657AC734CE38F018F2192", + "040356DCD8F2F95031AD652D23951BB366A80648F06D867940A5366D9E265DE9EB240F", + "0400000000000000016954A233049BA98F", + 2), + EcRecommendedParameters(ASN1::sect193r1(), + 193, 15, 0, + "0017858FEB7A98975169E171F77B4087DE098AC8A911DF7B01", + "00FDFB49BFE6C3A89FACADAA7A1E5BBC7CC1C2E5D831478814", + "0401F481BC5F0FF84A74AD6CDF6FDEF4BF6179625372D8C0C5E10025E399F2903712CCF3EA9E3A1AD17FB0B3201B6AF7CE1B05", + "01000000000000000000000000C7F34A778F443ACC920EBA49", + 2), + EcRecommendedParameters(ASN1::sect193r2(), + 193, 15, 0, + "0163F35A5137C2CE3EA6ED8667190B0BC43ECD69977702709B", + "00C9BB9E8927D4D64C377E2AB2856A5B16E3EFB7F61D4316AE", + "0400D9B67D192E0367C803F39E1A7E82CA14A651350AAE617E8F01CE94335607C304AC29E7DEFBD9CA01F596F927224CDECF6C", + "010000000000000000000000015AAB561B005413CCD4EE99D5", + 2), + EcRecommendedParameters(ASN1::sect233k1(), + 233, 74, 0, + "000000000000000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000000000000001", + "04017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD612601DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3", + "8000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF", + 4), + EcRecommendedParameters(ASN1::sect233r1(), + 233, 74, 0, + "000000000000000000000000000000000000000000000000000000000001", + "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD", + "0400FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052", + "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7", + 2), + EcRecommendedParameters(ASN1::sect409k1(), + 409, 87, 0, + "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", + "040060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE902374601E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B", + "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF", + 4), + EcRecommendedParameters(ASN1::sect409r1(), + 409, 87, 0, + "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", + "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F", + "04015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A70061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706", + "010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173", + 2), + EcRecommendedParameters(ASN1::sect571k1(), + 571, 10, 5, 2, 0, + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", + "04026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C89720349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3", + "020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001", + 4), + EcRecommendedParameters(ASN1::sect571r1(), + 571, 10, 5, 2, 0, + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", + "02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A", + "040303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B", + "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47", + 2), + }; + begin = rec; + end = rec + sizeof(rec)/sizeof(rec[0]); +} + +static void GetRecommendedParameters(const EcRecommendedParameters *&begin, const EcRecommendedParameters *&end) +{ + // this array must be sorted by OID + static const EcRecommendedParameters rec[] = { + EcRecommendedParameters(ASN1::secp192r1(), + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", + "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", + "04188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF101207192B95FFC8DA78631011ED6B24CDD573F977A11E794811", + "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", + 1), + EcRecommendedParameters(ASN1::secp256r1(), + "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", + "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", + "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", + "046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", + "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", + 1), + EcRecommendedParameters(ASN1::secp112r1(), + "DB7C2ABF62E35E668076BEAD208B", + "DB7C2ABF62E35E668076BEAD2088", + "659EF8BA043916EEDE8911702B22", + "0409487239995A5EE76B55F9C2F098A89CE5AF8724C0A23E0E0FF77500", + "DB7C2ABF62E35E7628DFAC6561C5", + 1), + EcRecommendedParameters(ASN1::secp112r2(), + "DB7C2ABF62E35E668076BEAD208B", + "6127C24C05F38A0AAAF65C0EF02C", + "51DEF1815DB5ED74FCC34C85D709", + "044BA30AB5E892B4E1649DD0928643ADCD46F5882E3747DEF36E956E97", + "36DF0AAFD8B8D7597CA10520D04B", + 4), + EcRecommendedParameters(ASN1::secp160r1(), + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", + "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", + "044A96B5688EF573284664698968C38BB913CBFC8223A628553168947D59DCC912042351377AC5FB32", + "0100000000000000000001F4C8F927AED3CA752257", + 1), + EcRecommendedParameters(ASN1::secp160k1(), + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", + "0000000000000000000000000000000000000000", + "0000000000000000000000000000000000000007", + "043B4C382CE37AA192A4019E763036F4F5DD4D7EBB938CF935318FDCED6BC28286531733C3F03C4FEE", + "0100000000000000000001B8FA16DFAB9ACA16B6B3", + 1), + EcRecommendedParameters(ASN1::secp256k1(), + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", + "0000000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000007", + "0479BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", + 1), + EcRecommendedParameters(ASN1::secp128r1(), + "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", + "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC", + "E87579C11079F43DD824993C2CEE5ED3", + "04161FF7528B899B2D0C28607CA52C5B86CF5AC8395BAFEB13C02DA292DDED7A83", + "FFFFFFFE0000000075A30D1B9038A115", + 1), + EcRecommendedParameters(ASN1::secp128r2(), + "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", + "D6031998D1B3BBFEBF59CC9BBFF9AEE1", + "5EEEFCA380D02919DC2C6558BB6D8A5D", + "047B6AA5D85E572983E6FB32A7CDEBC14027B6916A894D3AEE7106FE805FC34B44", + "3FFFFFFF7FFFFFFFBE0024720613B5A3", + 4), + EcRecommendedParameters(ASN1::secp160r2(), + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70", + "B4E134D3FB59EB8BAB57274904664D5AF50388BA", + "0452DCB034293A117E1F4FF11B30F7199D3144CE6DFEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E", + "0100000000000000000000351EE786A818F3A1A16B", + 1), + EcRecommendedParameters(ASN1::secp192k1(), + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", + "000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000003", + "04DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D", + "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D", + 1), + EcRecommendedParameters(ASN1::secp224k1(), + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", + "00000000000000000000000000000000000000000000000000000000", + "00000000000000000000000000000000000000000000000000000005", + "04A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5", + "010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7", + 1), + EcRecommendedParameters(ASN1::secp224r1(), + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", + "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", + "04B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", + 1), + EcRecommendedParameters(ASN1::secp384r1(), + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", + "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", + "04AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB73617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", + 1), + EcRecommendedParameters(ASN1::secp521r1(), + "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", + "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", + "0400C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650", + "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", + 1), + }; + begin = rec; + end = rec + sizeof(rec)/sizeof(rec[0]); +} + +template OID DL_GroupParameters_EC::GetNextRecommendedParametersOID(const OID &oid) +{ + const EcRecommendedParameters *begin, *end; + GetRecommendedParameters(begin, end); + const EcRecommendedParameters *it = std::upper_bound(begin, end, oid, OIDLessThan()); + return (it == end ? OID() : it->oid); +} + +template void DL_GroupParameters_EC::Initialize(const OID &oid) +{ + const EcRecommendedParameters *begin, *end; + GetRecommendedParameters(begin, end); + const EcRecommendedParameters *it = std::lower_bound(begin, end, oid, OIDLessThan()); + if (it == end || it->oid != oid) + throw UnknownOID(); + + const EcRecommendedParameters ¶m = *it; + m_oid = oid; + std::auto_ptr ec(param.NewEC()); + this->m_groupPrecomputation.SetCurve(*ec); + + StringSource ssG(param.g, true, new HexDecoder); + Element G; + bool result = GetCurve().DecodePoint(G, ssG, (size_t)ssG.MaxRetrievable()); + SetSubgroupGenerator(G); + assert(result); + + StringSource ssN(param.n, true, new HexDecoder); + m_n.Decode(ssN, (size_t)ssN.MaxRetrievable()); + m_k = param.h; +} + +template +bool DL_GroupParameters_EC::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const +{ + if (strcmp(name, Name::GroupOID()) == 0) + { + if (m_oid.m_values.empty()) + return false; + + this->ThrowIfTypeMismatch(name, typeid(OID), valueType); + *reinterpret_cast(pValue) = m_oid; + return true; + } + else + return GetValueHelper >(this, name, valueType, pValue).Assignable() + CRYPTOPP_GET_FUNCTION_ENTRY(Curve); +} + +template +void DL_GroupParameters_EC::AssignFrom(const NameValuePairs &source) +{ + OID oid; + if (source.GetValue(Name::GroupOID(), oid)) + Initialize(oid); + else + { + EllipticCurve ec; + Point G; + Integer n; + + source.GetRequiredParameter("DL_GroupParameters_EC", Name::Curve(), ec); + source.GetRequiredParameter("DL_GroupParameters_EC", Name::SubgroupGenerator(), G); + source.GetRequiredParameter("DL_GroupParameters_EC", Name::SubgroupOrder(), n); + Integer k = source.GetValueWithDefault(Name::Cofactor(), Integer::Zero()); + + Initialize(ec, G, n, k); + } +} + +template +void DL_GroupParameters_EC::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg) +{ + try + { + AssignFrom(alg); + } + catch (InvalidArgument &) + { + throw NotImplemented("DL_GroupParameters_EC: curve generation is not implemented yet"); + } +} + +template +void DL_GroupParameters_EC::BERDecode(BufferedTransformation &bt) +{ + byte b; + if (!bt.Peek(b)) + BERDecodeError(); + if (b == OBJECT_IDENTIFIER) + Initialize(OID(bt)); + else + { + BERSequenceDecoder seq(bt); + word32 version; + BERDecodeUnsigned(seq, version, INTEGER, 1, 1); // check version + EllipticCurve ec(seq); + Point G = ec.BERDecodePoint(seq); + Integer n(seq); + Integer k; + bool cofactorPresent = !seq.EndReached(); + if (cofactorPresent) + k.BERDecode(seq); + else + k = Integer::Zero(); + seq.MessageEnd(); + + Initialize(ec, G, n, k); + } +} + +template +void DL_GroupParameters_EC::DEREncode(BufferedTransformation &bt) const +{ + if (m_encodeAsOID && !m_oid.m_values.empty()) + m_oid.DEREncode(bt); + else + { + DERSequenceEncoder seq(bt); + DEREncodeUnsigned(seq, 1); // version + GetCurve().DEREncode(seq); + GetCurve().DEREncodePoint(seq, this->GetSubgroupGenerator(), m_compress); + m_n.DEREncode(seq); + if (m_k.NotZero()) + m_k.DEREncode(seq); + seq.MessageEnd(); + } +} + +template +Integer DL_GroupParameters_EC::GetCofactor() const +{ + if (!m_k) + { + Integer q = GetCurve().FieldSize(); + Integer qSqrt = q.SquareRoot(); + m_k = (q+2*qSqrt+1)/m_n; + } + + return m_k; +} + +template +Integer DL_GroupParameters_EC::ConvertElementToInteger(const Element &element) const +{ + return ConvertToInteger(element.x); +}; + +template +bool DL_GroupParameters_EC::ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const +{ + bool pass = GetCurve().ValidateParameters(rng, level); + + Integer q = GetCurve().FieldSize(); + pass = pass && m_n!=q; + + if (level >= 2) + { + Integer qSqrt = q.SquareRoot(); + pass = pass && m_n>4*qSqrt; + pass = pass && VerifyPrime(rng, m_n, level-2); + pass = pass && (m_k.IsZero() || m_k == (q+2*qSqrt+1)/m_n); + pass = pass && CheckMOVCondition(q, m_n); + } + + return pass; +} + +template +bool DL_GroupParameters_EC::ValidateElement(unsigned int level, const Element &g, const DL_FixedBasePrecomputation *gpc) const +{ + bool pass = !IsIdentity(g) && GetCurve().VerifyPoint(g); + if (level >= 1) + { + if (gpc) + pass = pass && gpc->Exponentiate(this->GetGroupPrecomputation(), Integer::One()) == g; + } + if (level >= 2 && pass) + { + const Integer &q = GetSubgroupOrder(); + Element gq = gpc ? gpc->Exponentiate(this->GetGroupPrecomputation(), q) : ExponentiateElement(g, q); + pass = pass && IsIdentity(gq); + } + return pass; +} + +template +void DL_GroupParameters_EC::SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const +{ + GetCurve().SimultaneousMultiply(results, base, exponents, exponentsCount); +} + +template +CPP_TYPENAME DL_GroupParameters_EC::Element DL_GroupParameters_EC::MultiplyElements(const Element &a, const Element &b) const +{ + return GetCurve().Add(a, b); +} + +template +CPP_TYPENAME DL_GroupParameters_EC::Element DL_GroupParameters_EC::CascadeExponentiate(const Element &element1, const Integer &exponent1, const Element &element2, const Integer &exponent2) const +{ + return GetCurve().CascadeMultiply(exponent1, element1, exponent2, element2); +} + +template +OID DL_GroupParameters_EC::GetAlgorithmID() const +{ + return ASN1::id_ecPublicKey(); +} + +// ****************************************************************** + +template +void DL_PublicKey_EC::BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size) +{ + typename EC::Point P; + if (!this->GetGroupParameters().GetCurve().DecodePoint(P, bt, size)) + BERDecodeError(); + SetPublicElement(P); +} + +template +void DL_PublicKey_EC::DEREncodePublicKey(BufferedTransformation &bt) const +{ + this->GetGroupParameters().GetCurve().EncodePoint(bt, this->GetPublicElement(), this->GetGroupParameters().GetPointCompression()); +} + +// ****************************************************************** + +template +void DL_PrivateKey_EC::BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size) +{ + BERSequenceDecoder seq(bt); + word32 version; + BERDecodeUnsigned(seq, version, INTEGER, 1, 1); // check version + + BERGeneralDecoder dec(seq, OCTET_STRING); + if (!dec.IsDefiniteLength()) + BERDecodeError(); + Integer x; + x.Decode(dec, (size_t)dec.RemainingLength()); + dec.MessageEnd(); + if (!parametersPresent && seq.PeekByte() != (CONTEXT_SPECIFIC | CONSTRUCTED | 0)) + BERDecodeError(); + if (!seq.EndReached() && seq.PeekByte() == (CONTEXT_SPECIFIC | CONSTRUCTED | 0)) + { + BERGeneralDecoder parameters(seq, CONTEXT_SPECIFIC | CONSTRUCTED | 0); + this->AccessGroupParameters().BERDecode(parameters); + parameters.MessageEnd(); + } + if (!seq.EndReached()) + { + // skip over the public element + SecByteBlock subjectPublicKey; + unsigned int unusedBits; + BERGeneralDecoder publicKey(seq, CONTEXT_SPECIFIC | CONSTRUCTED | 1); + BERDecodeBitString(publicKey, subjectPublicKey, unusedBits); + publicKey.MessageEnd(); + Element Q; + if (!(unusedBits == 0 && this->GetGroupParameters().GetCurve().DecodePoint(Q, subjectPublicKey, subjectPublicKey.size()))) + BERDecodeError(); + } + seq.MessageEnd(); + + this->SetPrivateExponent(x); +} + +template +void DL_PrivateKey_EC::DEREncodePrivateKey(BufferedTransformation &bt) const +{ + DERSequenceEncoder privateKey(bt); + DEREncodeUnsigned(privateKey, 1); // version + // SEC 1 ver 1.0 says privateKey (m_d) has the same length as order of the curve + // this will be changed to order of base point in a future version + this->GetPrivateExponent().DEREncodeAsOctetString(privateKey, this->GetGroupParameters().GetSubgroupOrder().ByteCount()); + privateKey.MessageEnd(); +} + +NAMESPACE_END + +#endif + +#endif diff --git a/CryptoPP/crypto/eccrypto.h b/CryptoPP/crypto/eccrypto.h new file mode 100644 index 0000000..e97b906 --- /dev/null +++ b/CryptoPP/crypto/eccrypto.h @@ -0,0 +1,280 @@ +#ifndef CRYPTOPP_ECCRYPTO_H +#define CRYPTOPP_ECCRYPTO_H + +/*! \file +*/ + +#include "pubkey.h" +#include "integer.h" +#include "asn.h" +#include "hmac.h" +#include "sha.h" +#include "gfpcrypt.h" +#include "dh.h" +#include "mqv.h" +#include "ecp.h" +#include "ec2n.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! Elliptic Curve Parameters +/*! This class corresponds to the ASN.1 sequence of the same name + in ANSI X9.62 (also SEC 1). +*/ +template +class DL_GroupParameters_EC : public DL_GroupParametersImpl > +{ + typedef DL_GroupParameters_EC ThisClass; + +public: + typedef EC EllipticCurve; + typedef typename EllipticCurve::Point Point; + typedef Point Element; + typedef IncompatibleCofactorMultiplication DefaultCofactorOption; + + DL_GroupParameters_EC() : m_compress(false), m_encodeAsOID(false) {} + DL_GroupParameters_EC(const OID &oid) + : m_compress(false), m_encodeAsOID(false) {Initialize(oid);} + DL_GroupParameters_EC(const EllipticCurve &ec, const Point &G, const Integer &n, const Integer &k = Integer::Zero()) + : m_compress(false), m_encodeAsOID(false) {Initialize(ec, G, n, k);} + DL_GroupParameters_EC(BufferedTransformation &bt) + : m_compress(false), m_encodeAsOID(false) {BERDecode(bt);} + + void Initialize(const EllipticCurve &ec, const Point &G, const Integer &n, const Integer &k = Integer::Zero()) + { + this->m_groupPrecomputation.SetCurve(ec); + SetSubgroupGenerator(G); + m_n = n; + m_k = k; + } + void Initialize(const OID &oid); + + // NameValuePairs + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; + void AssignFrom(const NameValuePairs &source); + + // GeneratibleCryptoMaterial interface + //! this implementation doesn't actually generate a curve, it just initializes the parameters with existing values + /*! parameters: (Curve, SubgroupGenerator, SubgroupOrder, Cofactor (optional)), or (GroupOID) */ + void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg); + + // DL_GroupParameters + const DL_FixedBasePrecomputation & GetBasePrecomputation() const {return this->m_gpc;} + DL_FixedBasePrecomputation & AccessBasePrecomputation() {return this->m_gpc;} + const Integer & GetSubgroupOrder() const {return m_n;} + Integer GetCofactor() const; + bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const; + bool ValidateElement(unsigned int level, const Element &element, const DL_FixedBasePrecomputation *precomp) const; + bool FastSubgroupCheckAvailable() const {return false;} + void EncodeElement(bool reversible, const Element &element, byte *encoded) const + { + if (reversible) + GetCurve().EncodePoint(encoded, element, m_compress); + else + element.x.Encode(encoded, GetEncodedElementSize(false)); + } + unsigned int GetEncodedElementSize(bool reversible) const + { + if (reversible) + return GetCurve().EncodedPointSize(m_compress); + else + return GetCurve().GetField().MaxElementByteLength(); + } + Element DecodeElement(const byte *encoded, bool checkForGroupMembership) const + { + Point result; + if (!GetCurve().DecodePoint(result, encoded, GetEncodedElementSize(true))) + throw DL_BadElement(); + if (checkForGroupMembership && !ValidateElement(1, result, NULL)) + throw DL_BadElement(); + return result; + } + Integer ConvertElementToInteger(const Element &element) const; + Integer GetMaxExponent() const {return GetSubgroupOrder()-1;} + bool IsIdentity(const Element &element) const {return element.identity;} + void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const; + static std::string CRYPTOPP_API StaticAlgorithmNamePrefix() {return "EC";} + + // ASN1Key + OID GetAlgorithmID() const; + + // used by MQV + Element MultiplyElements(const Element &a, const Element &b) const; + Element CascadeExponentiate(const Element &element1, const Integer &exponent1, const Element &element2, const Integer &exponent2) const; + + // non-inherited + + // enumerate OIDs for recommended parameters, use OID() to get first one + static OID CRYPTOPP_API GetNextRecommendedParametersOID(const OID &oid); + + void BERDecode(BufferedTransformation &bt); + void DEREncode(BufferedTransformation &bt) const; + + void SetPointCompression(bool compress) {m_compress = compress;} + bool GetPointCompression() const {return m_compress;} + + void SetEncodeAsOID(bool encodeAsOID) {m_encodeAsOID = encodeAsOID;} + bool GetEncodeAsOID() const {return m_encodeAsOID;} + + const EllipticCurve& GetCurve() const {return this->m_groupPrecomputation.GetCurve();} + + bool operator==(const ThisClass &rhs) const + {return this->m_groupPrecomputation.GetCurve() == rhs.m_groupPrecomputation.GetCurve() && this->m_gpc.GetBase(this->m_groupPrecomputation) == rhs.m_gpc.GetBase(rhs.m_groupPrecomputation);} + +#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY + const Point& GetBasePoint() const {return GetSubgroupGenerator();} + const Integer& GetBasePointOrder() const {return GetSubgroupOrder();} + void LoadRecommendedParameters(const OID &oid) {Initialize(oid);} +#endif + +protected: + unsigned int FieldElementLength() const {return GetCurve().GetField().MaxElementByteLength();} + unsigned int ExponentLength() const {return m_n.ByteCount();} + + OID m_oid; // set if parameters loaded from a recommended curve + Integer m_n; // order of base point + bool m_compress, m_encodeAsOID; + mutable Integer m_k; // cofactor +}; + +//! EC public key +template +class DL_PublicKey_EC : public DL_PublicKeyImpl > +{ +public: + typedef typename EC::Point Element; + + void Initialize(const DL_GroupParameters_EC ¶ms, const Element &Q) + {this->AccessGroupParameters() = params; SetPublicElement(Q);} + void Initialize(const EC &ec, const Element &G, const Integer &n, const Element &Q) + {this->AccessGroupParameters().Initialize(ec, G, n); SetPublicElement(Q);} + + // X509PublicKey + void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size); + void DEREncodePublicKey(BufferedTransformation &bt) const; +}; + +//! EC private key +template +class DL_PrivateKey_EC : public DL_PrivateKeyImpl > +{ +public: + typedef typename EC::Point Element; + + void Initialize(const DL_GroupParameters_EC ¶ms, const Integer &x) + {this->AccessGroupParameters() = params; this->SetPrivateExponent(x);} + void Initialize(const EC &ec, const Element &G, const Integer &n, const Integer &x) + {this->AccessGroupParameters().Initialize(ec, G, n); this->SetPrivateExponent(x);} + void Initialize(RandomNumberGenerator &rng, const DL_GroupParameters_EC ¶ms) + {GenerateRandom(rng, params);} + void Initialize(RandomNumberGenerator &rng, const EC &ec, const Element &G, const Integer &n) + {GenerateRandom(rng, DL_GroupParameters_EC(ec, G, n));} + + // PKCS8PrivateKey + void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size); + void DEREncodePrivateKey(BufferedTransformation &bt) const; +}; + +//! Elliptic Curve Diffie-Hellman, AKA ECDH +template ::DefaultCofactorOption> +struct ECDH +{ + typedef DH_Domain, COFACTOR_OPTION> Domain; +}; + +/// Elliptic Curve Menezes-Qu-Vanstone, AKA ECMQV +template ::DefaultCofactorOption> +struct ECMQV +{ + typedef MQV_Domain, COFACTOR_OPTION> Domain; +}; + +//! EC keys +template +struct DL_Keys_EC +{ + typedef DL_PublicKey_EC PublicKey; + typedef DL_PrivateKey_EC PrivateKey; +}; + +template +struct ECDSA; + +//! ECDSA keys +template +struct DL_Keys_ECDSA +{ + typedef DL_PublicKey_EC PublicKey; + typedef DL_PrivateKey_WithSignaturePairwiseConsistencyTest, ECDSA > PrivateKey; +}; + +//! ECDSA algorithm +template +class DL_Algorithm_ECDSA : public DL_Algorithm_GDSA +{ +public: + static const char * CRYPTOPP_API StaticAlgorithmName() {return "ECDSA";} +}; + +//! ECNR algorithm +template +class DL_Algorithm_ECNR : public DL_Algorithm_NR +{ +public: + static const char * CRYPTOPP_API StaticAlgorithmName() {return "ECNR";} +}; + +//! ECDSA +template +struct ECDSA : public DL_SS, DL_Algorithm_ECDSA, DL_SignatureMessageEncodingMethod_DSA, H> +{ +}; + +//! ECNR +template +struct ECNR : public DL_SS, DL_Algorithm_ECNR, DL_SignatureMessageEncodingMethod_NR, H> +{ +}; + +//! Elliptic Curve Integrated Encryption Scheme, AKA ECIES +/*! Default to (NoCofactorMultiplication and DHAES_MODE = false) for compatibilty with SEC1 and Crypto++ 4.2. + The combination of (IncompatibleCofactorMultiplication and DHAES_MODE = true) is recommended for best + efficiency and security. */ +template +struct ECIES + : public DL_ES< + DL_Keys_EC, + DL_KeyAgreementAlgorithm_DH, + DL_KeyDerivationAlgorithm_P1363 >, + DL_EncryptionAlgorithm_Xor, DHAES_MODE>, + ECIES > +{ + static std::string CRYPTOPP_API StaticAlgorithmName() {return "ECIES";} // TODO: fix this after name is standardized +}; + +NAMESPACE_END + +#ifdef CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES +#include "eccrypto.cpp" +#endif + +NAMESPACE_BEGIN(CryptoPP) + +CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupParameters_EC; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupParameters_EC; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKeyImpl >; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKeyImpl >; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKey_EC; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKey_EC; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKeyImpl >; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKeyImpl >; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_EC; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_EC; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_GDSA; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_GDSA; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_WithSignaturePairwiseConsistencyTest, ECDSA >; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_WithSignaturePairwiseConsistencyTest, ECDSA >; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/ecp.cpp b/CryptoPP/crypto/ecp.cpp new file mode 100644 index 0000000..35e264b --- /dev/null +++ b/CryptoPP/crypto/ecp.cpp @@ -0,0 +1,473 @@ +// ecp.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "ecp.h" +#include "asn.h" +#include "nbtheory.h" + +#include "algebra.cpp" + +NAMESPACE_BEGIN(CryptoPP) + +ANONYMOUS_NAMESPACE_BEGIN +static inline ECP::Point ToMontgomery(const ModularArithmetic &mr, const ECP::Point &P) +{ + return P.identity ? P : ECP::Point(mr.ConvertIn(P.x), mr.ConvertIn(P.y)); +} + +static inline ECP::Point FromMontgomery(const ModularArithmetic &mr, const ECP::Point &P) +{ + return P.identity ? P : ECP::Point(mr.ConvertOut(P.x), mr.ConvertOut(P.y)); +} +NAMESPACE_END + +ECP::ECP(const ECP &ecp, bool convertToMontgomeryRepresentation) +{ + if (convertToMontgomeryRepresentation && !ecp.GetField().IsMontgomeryRepresentation()) + { + m_fieldPtr.reset(new MontgomeryRepresentation(ecp.GetField().GetModulus())); + m_a = GetField().ConvertIn(ecp.m_a); + m_b = GetField().ConvertIn(ecp.m_b); + } + else + operator=(ecp); +} + +ECP::ECP(BufferedTransformation &bt) + : m_fieldPtr(new Field(bt)) +{ + BERSequenceDecoder seq(bt); + GetField().BERDecodeElement(seq, m_a); + GetField().BERDecodeElement(seq, m_b); + // skip optional seed + if (!seq.EndReached()) + { + SecByteBlock seed; + unsigned int unused; + BERDecodeBitString(seq, seed, unused); + } + seq.MessageEnd(); +} + +void ECP::DEREncode(BufferedTransformation &bt) const +{ + GetField().DEREncode(bt); + DERSequenceEncoder seq(bt); + GetField().DEREncodeElement(seq, m_a); + GetField().DEREncodeElement(seq, m_b); + seq.MessageEnd(); +} + +bool ECP::DecodePoint(ECP::Point &P, const byte *encodedPoint, size_t encodedPointLen) const +{ + StringStore store(encodedPoint, encodedPointLen); + return DecodePoint(P, store, encodedPointLen); +} + +bool ECP::DecodePoint(ECP::Point &P, BufferedTransformation &bt, size_t encodedPointLen) const +{ + byte type; + if (encodedPointLen < 1 || !bt.Get(type)) + return false; + + switch (type) + { + case 0: + P.identity = true; + return true; + case 2: + case 3: + { + if (encodedPointLen != EncodedPointSize(true)) + return false; + + Integer p = FieldSize(); + + P.identity = false; + P.x.Decode(bt, GetField().MaxElementByteLength()); + P.y = ((P.x*P.x+m_a)*P.x+m_b) % p; + + if (Jacobi(P.y, p) !=1) + return false; + + P.y = ModularSquareRoot(P.y, p); + + if ((type & 1) != P.y.GetBit(0)) + P.y = p-P.y; + + return true; + } + case 4: + { + if (encodedPointLen != EncodedPointSize(false)) + return false; + + unsigned int len = GetField().MaxElementByteLength(); + P.identity = false; + P.x.Decode(bt, len); + P.y.Decode(bt, len); + return true; + } + default: + return false; + } +} + +void ECP::EncodePoint(BufferedTransformation &bt, const Point &P, bool compressed) const +{ + if (P.identity) + NullStore().TransferTo(bt, EncodedPointSize(compressed)); + else if (compressed) + { + bt.Put(2 + P.y.GetBit(0)); + P.x.Encode(bt, GetField().MaxElementByteLength()); + } + else + { + unsigned int len = GetField().MaxElementByteLength(); + bt.Put(4); // uncompressed + P.x.Encode(bt, len); + P.y.Encode(bt, len); + } +} + +void ECP::EncodePoint(byte *encodedPoint, const Point &P, bool compressed) const +{ + ArraySink sink(encodedPoint, EncodedPointSize(compressed)); + EncodePoint(sink, P, compressed); + assert(sink.TotalPutLength() == EncodedPointSize(compressed)); +} + +ECP::Point ECP::BERDecodePoint(BufferedTransformation &bt) const +{ + SecByteBlock str; + BERDecodeOctetString(bt, str); + Point P; + if (!DecodePoint(P, str, str.size())) + BERDecodeError(); + return P; +} + +void ECP::DEREncodePoint(BufferedTransformation &bt, const Point &P, bool compressed) const +{ + SecByteBlock str(EncodedPointSize(compressed)); + EncodePoint(str, P, compressed); + DEREncodeOctetString(bt, str); +} + +bool ECP::ValidateParameters(RandomNumberGenerator &rng, unsigned int level) const +{ + Integer p = FieldSize(); + + bool pass = p.IsOdd(); + pass = pass && !m_a.IsNegative() && m_a

= 1) + pass = pass && ((4*m_a*m_a*m_a+27*m_b*m_b)%p).IsPositive(); + + if (level >= 2) + pass = pass && VerifyPrime(rng, p); + + return pass; +} + +bool ECP::VerifyPoint(const Point &P) const +{ + const FieldElement &x = P.x, &y = P.y; + Integer p = FieldSize(); + return P.identity || + (!x.IsNegative() && x

().Ref(); +} + +const ECP::Point& ECP::Inverse(const Point &P) const +{ + if (P.identity) + return P; + else + { + m_R.identity = false; + m_R.x = P.x; + m_R.y = GetField().Inverse(P.y); + return m_R; + } +} + +const ECP::Point& ECP::Add(const Point &P, const Point &Q) const +{ + if (P.identity) return Q; + if (Q.identity) return P; + if (GetField().Equal(P.x, Q.x)) + return GetField().Equal(P.y, Q.y) ? Double(P) : Identity(); + + FieldElement t = GetField().Subtract(Q.y, P.y); + t = GetField().Divide(t, GetField().Subtract(Q.x, P.x)); + FieldElement x = GetField().Subtract(GetField().Subtract(GetField().Square(t), P.x), Q.x); + m_R.y = GetField().Subtract(GetField().Multiply(t, GetField().Subtract(P.x, x)), P.y); + + m_R.x.swap(x); + m_R.identity = false; + return m_R; +} + +const ECP::Point& ECP::Double(const Point &P) const +{ + if (P.identity || P.y==GetField().Identity()) return Identity(); + + FieldElement t = GetField().Square(P.x); + t = GetField().Add(GetField().Add(GetField().Double(t), t), m_a); + t = GetField().Divide(t, GetField().Double(P.y)); + FieldElement x = GetField().Subtract(GetField().Subtract(GetField().Square(t), P.x), P.x); + m_R.y = GetField().Subtract(GetField().Multiply(t, GetField().Subtract(P.x, x)), P.y); + + m_R.x.swap(x); + m_R.identity = false; + return m_R; +} + +template void ParallelInvert(const AbstractRing &ring, Iterator begin, Iterator end) +{ + size_t n = end-begin; + if (n == 1) + *begin = ring.MultiplicativeInverse(*begin); + else if (n > 1) + { + std::vector vec((n+1)/2); + unsigned int i; + Iterator it; + + for (i=0, it=begin; i::iterator it) : it(it) {} + Integer& operator*() {return it->z;} + int operator-(ZIterator it2) {return int(it-it2.it);} + ZIterator operator+(int i) {return ZIterator(it+i);} + ZIterator& operator+=(int i) {it+=i; return *this;} + std::vector::iterator it; +}; + +ECP::Point ECP::ScalarMultiply(const Point &P, const Integer &k) const +{ + Element result; + if (k.BitCount() <= 5) + AbstractGroup::SimultaneousMultiply(&result, P, &k, 1); + else + ECP::SimultaneousMultiply(&result, P, &k, 1); + return result; +} + +void ECP::SimultaneousMultiply(ECP::Point *results, const ECP::Point &P, const Integer *expBegin, unsigned int expCount) const +{ + if (!GetField().IsMontgomeryRepresentation()) + { + ECP ecpmr(*this, true); + const ModularArithmetic &mr = ecpmr.GetField(); + ecpmr.SimultaneousMultiply(results, ToMontgomery(mr, P), expBegin, expCount); + for (unsigned int i=0; i bases; + std::vector exponents; + exponents.reserve(expCount); + std::vector > baseIndices(expCount); + std::vector > negateBase(expCount); + std::vector > exponentWindows(expCount); + unsigned int i; + + for (i=0; iNotNegative()); + exponents.push_back(WindowSlider(*expBegin++, InversionIsFast(), 5)); + exponents[i].FindNextWindow(); + } + + unsigned int expBitPosition = 0; + bool notDone = true; + + while (notDone) + { + notDone = false; + bool baseAdded = false; + for (i=0; i > finalCascade; + for (i=0; i::CascadeScalarMultiply(P, k1, Q, k2); +} + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/ecp.h b/CryptoPP/crypto/ecp.h new file mode 100644 index 0000000..07f906c --- /dev/null +++ b/CryptoPP/crypto/ecp.h @@ -0,0 +1,126 @@ +#ifndef CRYPTOPP_ECP_H +#define CRYPTOPP_ECP_H + +#include "modarith.h" +#include "eprecomp.h" +#include "smartptr.h" +#include "pubkey.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! Elliptical Curve Point +struct CRYPTOPP_DLL ECPPoint +{ + ECPPoint() : identity(true) {} + ECPPoint(const Integer &x, const Integer &y) + : identity(false), x(x), y(y) {} + + bool operator==(const ECPPoint &t) const + {return (identity && t.identity) || (!identity && !t.identity && x==t.x && y==t.y);} + bool operator< (const ECPPoint &t) const + {return identity ? !t.identity : (!t.identity && (x; + +//! Elliptic Curve over GF(p), where p is prime +class CRYPTOPP_DLL ECP : public AbstractGroup +{ +public: + typedef ModularArithmetic Field; + typedef Integer FieldElement; + typedef ECPPoint Point; + + ECP() {} + ECP(const ECP &ecp, bool convertToMontgomeryRepresentation = false); + ECP(const Integer &modulus, const FieldElement &a, const FieldElement &b) + : m_fieldPtr(new Field(modulus)), m_a(a.IsNegative() ? modulus+a : a), m_b(b) {} + // construct from BER encoded parameters + // this constructor will decode and extract the the fields fieldID and curve of the sequence ECParameters + ECP(BufferedTransformation &bt); + + // encode the fields fieldID and curve of the sequence ECParameters + void DEREncode(BufferedTransformation &bt) const; + + bool Equal(const Point &P, const Point &Q) const; + const Point& Identity() const; + const Point& Inverse(const Point &P) const; + bool InversionIsFast() const {return true;} + const Point& Add(const Point &P, const Point &Q) const; + const Point& Double(const Point &P) const; + Point ScalarMultiply(const Point &P, const Integer &k) const; + Point CascadeScalarMultiply(const Point &P, const Integer &k1, const Point &Q, const Integer &k2) const; + void SimultaneousMultiply(Point *results, const Point &base, const Integer *exponents, unsigned int exponentsCount) const; + + Point Multiply(const Integer &k, const Point &P) const + {return ScalarMultiply(P, k);} + Point CascadeMultiply(const Integer &k1, const Point &P, const Integer &k2, const Point &Q) const + {return CascadeScalarMultiply(P, k1, Q, k2);} + + bool ValidateParameters(RandomNumberGenerator &rng, unsigned int level=3) const; + bool VerifyPoint(const Point &P) const; + + unsigned int EncodedPointSize(bool compressed = false) const + {return 1 + (compressed?1:2)*GetField().MaxElementByteLength();} + // returns false if point is compressed and not valid (doesn't check if uncompressed) + bool DecodePoint(Point &P, BufferedTransformation &bt, size_t len) const; + bool DecodePoint(Point &P, const byte *encodedPoint, size_t len) const; + void EncodePoint(byte *encodedPoint, const Point &P, bool compressed) const; + void EncodePoint(BufferedTransformation &bt, const Point &P, bool compressed) const; + + Point BERDecodePoint(BufferedTransformation &bt) const; + void DEREncodePoint(BufferedTransformation &bt, const Point &P, bool compressed) const; + + Integer FieldSize() const {return GetField().GetModulus();} + const Field & GetField() const {return *m_fieldPtr;} + const FieldElement & GetA() const {return m_a;} + const FieldElement & GetB() const {return m_b;} + + bool operator==(const ECP &rhs) const + {return GetField() == rhs.GetField() && m_a == rhs.m_a && m_b == rhs.m_b;} + +private: + clonable_ptr m_fieldPtr; + FieldElement m_a, m_b; + mutable Point m_R; +}; + +CRYPTOPP_DLL_TEMPLATE_CLASS DL_FixedBasePrecomputationImpl; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupPrecomputation; + +template class EcPrecomputation; + +//! ECP precomputation +template<> class EcPrecomputation : public DL_GroupPrecomputation +{ +public: + typedef ECP EllipticCurve; + + // DL_GroupPrecomputation + bool NeedConversions() const {return true;} + Element ConvertIn(const Element &P) const + {return P.identity ? P : ECP::Point(m_ec->GetField().ConvertIn(P.x), m_ec->GetField().ConvertIn(P.y));}; + Element ConvertOut(const Element &P) const + {return P.identity ? P : ECP::Point(m_ec->GetField().ConvertOut(P.x), m_ec->GetField().ConvertOut(P.y));} + const AbstractGroup & GetGroup() const {return *m_ec;} + Element BERDecodeElement(BufferedTransformation &bt) const {return m_ec->BERDecodePoint(bt);} + void DEREncodeElement(BufferedTransformation &bt, const Element &v) const {m_ec->DEREncodePoint(bt, v, false);} + + // non-inherited + void SetCurve(const ECP &ec) + { + m_ec.reset(new ECP(ec, true)); + m_ecOriginal = ec; + } + const ECP & GetCurve() const {return *m_ecOriginal;} + +private: + value_ptr m_ec, m_ecOriginal; +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/elgamal.cpp b/CryptoPP/crypto/elgamal.cpp new file mode 100644 index 0000000..ff0a1dc --- /dev/null +++ b/CryptoPP/crypto/elgamal.cpp @@ -0,0 +1,17 @@ +// elgamal.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "elgamal.h" +#include "asn.h" +#include "nbtheory.h" + +NAMESPACE_BEGIN(CryptoPP) + +void ElGamal_TestInstantiations() +{ + ElGamalEncryptor test1(1, 1, 1); + ElGamalDecryptor test2(NullRNG(), 123); + ElGamalEncryptor test3(test2); +} + +NAMESPACE_END diff --git a/CryptoPP/crypto/elgamal.h b/CryptoPP/crypto/elgamal.h new file mode 100644 index 0000000..1c5d53b --- /dev/null +++ b/CryptoPP/crypto/elgamal.h @@ -0,0 +1,121 @@ +#ifndef CRYPTOPP_ELGAMAL_H +#define CRYPTOPP_ELGAMAL_H + +#include "modexppc.h" +#include "dsa.h" + +NAMESPACE_BEGIN(CryptoPP) + +class CRYPTOPP_NO_VTABLE ElGamalBase : public DL_KeyAgreementAlgorithm_DH, + public DL_KeyDerivationAlgorithm, + public DL_SymmetricEncryptionAlgorithm +{ +public: + void Derive(const DL_GroupParameters &groupParams, byte *derivedKey, size_t derivedLength, const Integer &agreedElement, const Integer &ephemeralPublicKey, const NameValuePairs &derivationParams) const + { + agreedElement.Encode(derivedKey, derivedLength); + } + + size_t GetSymmetricKeyLength(size_t plainTextLength) const + { + return GetGroupParameters().GetModulus().ByteCount(); + } + + size_t GetSymmetricCiphertextLength(size_t plainTextLength) const + { + unsigned int len = GetGroupParameters().GetModulus().ByteCount(); + if (plainTextLength <= GetMaxSymmetricPlaintextLength(len)) + return len; + else + return 0; + } + + size_t GetMaxSymmetricPlaintextLength(size_t cipherTextLength) const + { + unsigned int len = GetGroupParameters().GetModulus().ByteCount(); + if (cipherTextLength == len) + return STDMIN(255U, len-3); + else + return 0; + } + + void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plainText, size_t plainTextLength, byte *cipherText, const NameValuePairs ¶meters) const + { + const Integer &p = GetGroupParameters().GetModulus(); + unsigned int modulusLen = p.ByteCount(); + + SecByteBlock block(modulusLen-1); + rng.GenerateBlock(block, modulusLen-2-plainTextLength); + memcpy(block+modulusLen-2-plainTextLength, plainText, plainTextLength); + block[modulusLen-2] = (byte)plainTextLength; + + a_times_b_mod_c(Integer(key, modulusLen), Integer(block, modulusLen-1), p).Encode(cipherText, modulusLen); + } + + DecodingResult SymmetricDecrypt(const byte *key, const byte *cipherText, size_t cipherTextLength, byte *plainText, const NameValuePairs ¶meters) const + { + const Integer &p = GetGroupParameters().GetModulus(); + unsigned int modulusLen = p.ByteCount(); + + if (cipherTextLength != modulusLen) + return DecodingResult(); + + Integer m = a_times_b_mod_c(Integer(cipherText, modulusLen), Integer(key, modulusLen).InverseMod(p), p); + + m.Encode(plainText, 1); + unsigned int plainTextLength = plainText[0]; + if (plainTextLength > GetMaxSymmetricPlaintextLength(modulusLen)) + return DecodingResult(); + m >>= 8; + m.Encode(plainText, plainTextLength); + return DecodingResult(plainTextLength); + } + + virtual const DL_GroupParameters_GFP & GetGroupParameters() const =0; +}; + +template +class ElGamalObjectImpl : public DL_ObjectImplBase, public ElGamalBase +{ +public: + size_t FixedMaxPlaintextLength() const {return this->MaxPlaintextLength(FixedCiphertextLength());} + size_t FixedCiphertextLength() const {return this->CiphertextLength(0);} + + const DL_GroupParameters_GFP & GetGroupParameters() const {return this->GetKey().GetGroupParameters();} + + DecodingResult FixedLengthDecrypt(RandomNumberGenerator &rng, const byte *cipherText, byte *plainText) const + {return Decrypt(rng, cipherText, FixedCiphertextLength(), plainText);} + +protected: + const DL_KeyAgreementAlgorithm & GetKeyAgreementAlgorithm() const {return *this;} + const DL_KeyDerivationAlgorithm & GetKeyDerivationAlgorithm() const {return *this;} + const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const {return *this;} +}; + +struct ElGamalKeys +{ + typedef DL_CryptoKeys_GFP::GroupParameters GroupParameters; + typedef DL_PrivateKey_GFP_OldFormat PrivateKey; + typedef DL_PublicKey_GFP_OldFormat PublicKey; +}; + +//! ElGamal encryption scheme with non-standard padding +struct ElGamal +{ + typedef DL_CryptoSchemeOptions SchemeOptions; + + static const char * StaticAlgorithmName() {return "ElgamalEnc/Crypto++Padding";} + + typedef SchemeOptions::GroupParameters GroupParameters; + //! implements PK_Encryptor interface + typedef PK_FinalTemplate, SchemeOptions, SchemeOptions::PublicKey> > Encryptor; + //! implements PK_Decryptor interface + typedef PK_FinalTemplate, SchemeOptions, SchemeOptions::PrivateKey> > Decryptor; +}; + +typedef ElGamal::Encryptor ElGamalEncryptor; +typedef ElGamal::Decryptor ElGamalDecryptor; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/elgc1024.dat b/CryptoPP/crypto/elgc1024.dat new file mode 100644 index 0000000..37518b6 --- /dev/null +++ b/CryptoPP/crypto/elgc1024.dat @@ -0,0 +1 @@ +3082018E028181008B333697371663F8869E3EC80A414E46BBAFE41F6D40E754A01ADA60FE7D12ACD16DE311C4115293114F6B92A54195909276380F04BCD4ED5CD993ED7F516DF7A752B928E5035E0D3A1A979A1CDE8387734338793C02001D59B662D4FC8F2BF0EABB1F553F9F46F57E74BCABCBA4E458812DB601FCD04609D435317181236B9702010202818038FBC56751763146BC107ECC59E9BAD3852EBC38799B41B40EF5745810BCF9DCC6D569B7E61063EA358B0DF2A194910029B72A9CFD11AD240681D3F976EDCB18D79C0530AB2944DC1E314C2B520BE23066C802754C19BF2EC15DE0439E2663383CEA5163DC857B6A5F91079F54FB47C9B33F23A9EB6B3FCBA8581524B3EC5C75028181008B333697371663F8869E3EC80A414E46BBAFE41F6D40E754A01ADA60FE7D12ACD16DE311C4115293114F6B92A54195909276380F04BCD4ED5CD993ED7F516DF7A752B928E5035E0D3A1A979A1CDE8387734338793C02001D59B662D4FC8F2BF0EABB1F553F9F46F57E74BC7F3EC6725F2FC0A6155ADCA43CEE7319E623824852 \ No newline at end of file diff --git a/CryptoPP/crypto/emsa2.cpp b/CryptoPP/crypto/emsa2.cpp new file mode 100644 index 0000000..4397435 --- /dev/null +++ b/CryptoPP/crypto/emsa2.cpp @@ -0,0 +1,34 @@ +// emsa2.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "emsa2.h" + +#ifndef CRYPTOPP_IMPORTS + +NAMESPACE_BEGIN(CryptoPP) + +void EMSA2Pad::ComputeMessageRepresentative(RandomNumberGenerator &rng, + const byte *recoverableMessage, size_t recoverableMessageLength, + HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, + byte *representative, size_t representativeBitLength) const +{ + assert(representativeBitLength >= MinRepresentativeBitLength(hashIdentifier.second, hash.DigestSize())); + + if (representativeBitLength % 8 != 7) + throw PK_SignatureScheme::InvalidKeyLength("EMSA2: EMSA2 requires a key length that is a multiple of 8"); + + size_t digestSize = hash.DigestSize(); + size_t representativeByteLength = BitsToBytes(representativeBitLength); + + representative[0] = messageEmpty ? 0x4b : 0x6b; + memset(representative+1, 0xbb, representativeByteLength-digestSize-4); // pad with 0xbb + byte *afterP2 = representative+representativeByteLength-digestSize-3; + afterP2[0] = 0xba; + hash.Final(afterP2+1); + representative[representativeByteLength-2] = *hashIdentifier.first; + representative[representativeByteLength-1] = 0xcc; +} + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/emsa2.h b/CryptoPP/crypto/emsa2.h new file mode 100644 index 0000000..911bd97 --- /dev/null +++ b/CryptoPP/crypto/emsa2.h @@ -0,0 +1,86 @@ +#ifndef CRYPTOPP_EMSA2_H +#define CRYPTOPP_EMSA2_H + +/** \file + This file contains various padding schemes for public key algorithms. +*/ + +#include "cryptlib.h" +#include "pubkey.h" + +#ifdef CRYPTOPP_IS_DLL +#include "sha.h" +#endif + +NAMESPACE_BEGIN(CryptoPP) + +template class EMSA2HashId +{ +public: + static const byte id; +}; + +template +class EMSA2HashIdLookup : public BASE +{ +public: + struct HashIdentifierLookup + { + template struct HashIdentifierLookup2 + { + static HashIdentifier Lookup() + { + return HashIdentifier(&EMSA2HashId::id, 1); + } + }; + }; +}; + +// EMSA2HashId can be instantiated with the following classes. +class SHA1; +class RIPEMD160; +class RIPEMD128; +class SHA256; +class SHA384; +class SHA512; +class Whirlpool; +class SHA224; +// end of list + +#ifdef CRYPTOPP_IS_DLL +CRYPTOPP_DLL_TEMPLATE_CLASS EMSA2HashId; +CRYPTOPP_DLL_TEMPLATE_CLASS EMSA2HashId; +CRYPTOPP_DLL_TEMPLATE_CLASS EMSA2HashId; +CRYPTOPP_DLL_TEMPLATE_CLASS EMSA2HashId; +CRYPTOPP_DLL_TEMPLATE_CLASS EMSA2HashId; +#endif + +//! _ +class CRYPTOPP_DLL EMSA2Pad : public EMSA2HashIdLookup +{ +public: + static const char * CRYPTOPP_API StaticAlgorithmName() {return "EMSA2";} + + size_t MinRepresentativeBitLength(size_t hashIdentifierLength, size_t digestLength) const + {return 8*digestLength + 31;} + + void ComputeMessageRepresentative(RandomNumberGenerator &rng, + const byte *recoverableMessage, size_t recoverableMessageLength, + HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, + byte *representative, size_t representativeBitLength) const; +}; + +//! EMSA2, for use with RWSS and RSA_ISO +/*! Only the following hash functions are supported by this signature standard: + \dontinclude emsa2.h + \skip EMSA2HashId can be instantiated + \until end of list +*/ +struct P1363_EMSA2 : public SignatureStandard +{ + typedef EMSA2Pad SignatureMessageEncodingMethod; +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/eprecomp.cpp b/CryptoPP/crypto/eprecomp.cpp new file mode 100644 index 0000000..67a4ab6 --- /dev/null +++ b/CryptoPP/crypto/eprecomp.cpp @@ -0,0 +1,117 @@ +// eprecomp.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" + +// prevent Sun's CC compiler from including this file automatically +#if !defined(__SUNPRO_CC) || defined(CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES) + +#ifndef CRYPTOPP_IMPORTS + +#include "eprecomp.h" +#include "asn.h" + +NAMESPACE_BEGIN(CryptoPP) + +template void DL_FixedBasePrecomputationImpl::SetBase(const DL_GroupPrecomputation &group, const Element &i_base) +{ + m_base = group.NeedConversions() ? group.ConvertIn(i_base) : i_base; + + if (m_bases.empty() || !(m_base == m_bases[0])) + { + m_bases.resize(1); + m_bases[0] = m_base; + } + + if (group.NeedConversions()) + m_base = i_base; +} + +template void DL_FixedBasePrecomputationImpl::Precompute(const DL_GroupPrecomputation &group, unsigned int maxExpBits, unsigned int storage) +{ + assert(m_bases.size() > 0); + assert(storage <= maxExpBits); + + if (storage > 1) + { + m_windowSize = (maxExpBits+storage-1)/storage; + m_exponentBase = Integer::Power2(m_windowSize); + } + + m_bases.resize(storage); + for (unsigned i=1; i void DL_FixedBasePrecomputationImpl::Load(const DL_GroupPrecomputation &group, BufferedTransformation &bt) +{ + BERSequenceDecoder seq(bt); + word32 version; + BERDecodeUnsigned(seq, version, INTEGER, 1, 1); + m_exponentBase.BERDecode(seq); + m_windowSize = m_exponentBase.BitCount() - 1; + m_bases.clear(); + while (!seq.EndReached()) + m_bases.push_back(group.BERDecodeElement(seq)); + if (!m_bases.empty() && group.NeedConversions()) + m_base = group.ConvertOut(m_bases[0]); + seq.MessageEnd(); +} + +template void DL_FixedBasePrecomputationImpl::Save(const DL_GroupPrecomputation &group, BufferedTransformation &bt) const +{ + DERSequenceEncoder seq(bt); + DEREncodeUnsigned(seq, 1); // version + m_exponentBase.DEREncode(seq); + for (unsigned i=0; i void DL_FixedBasePrecomputationImpl::PrepareCascade(const DL_GroupPrecomputation &i_group, std::vector > &eb, const Integer &exponent) const +{ + const AbstractGroup &group = i_group.GetGroup(); + + Integer r, q, e = exponent; + bool fastNegate = group.InversionIsFast() && m_windowSize > 1; + unsigned int i; + + for (i=0; i+1(group.Inverse(m_bases[i]), m_exponentBase - r)); + } + else + eb.push_back(BaseAndExponent(m_bases[i], r)); + } + eb.push_back(BaseAndExponent(m_bases[i], e)); +} + +template T DL_FixedBasePrecomputationImpl::Exponentiate(const DL_GroupPrecomputation &group, const Integer &exponent) const +{ + std::vector > eb; // array of segments of the exponent and precalculated bases + eb.reserve(m_bases.size()); + PrepareCascade(group, eb, exponent); + return group.ConvertOut(GeneralCascadeMultiplication(group.GetGroup(), eb.begin(), eb.end())); +} + +template T + DL_FixedBasePrecomputationImpl::CascadeExponentiate(const DL_GroupPrecomputation &group, const Integer &exponent, + const DL_FixedBasePrecomputation &i_pc2, const Integer &exponent2) const +{ + std::vector > eb; // array of segments of the exponent and precalculated bases + const DL_FixedBasePrecomputationImpl &pc2 = static_cast &>(i_pc2); + eb.reserve(m_bases.size() + pc2.m_bases.size()); + PrepareCascade(group, eb, exponent); + pc2.PrepareCascade(group, eb, exponent2); + return group.ConvertOut(GeneralCascadeMultiplication(group.GetGroup(), eb.begin(), eb.end())); +} + +NAMESPACE_END + +#endif + +#endif diff --git a/CryptoPP/crypto/eprecomp.h b/CryptoPP/crypto/eprecomp.h new file mode 100644 index 0000000..ade6c34 --- /dev/null +++ b/CryptoPP/crypto/eprecomp.h @@ -0,0 +1,73 @@ +#ifndef CRYPTOPP_EPRECOMP_H +#define CRYPTOPP_EPRECOMP_H + +#include "integer.h" +#include "algebra.h" +#include + +NAMESPACE_BEGIN(CryptoPP) + +template +class DL_GroupPrecomputation +{ +public: + typedef T Element; + + virtual bool NeedConversions() const {return false;} + virtual Element ConvertIn(const Element &v) const {return v;} + virtual Element ConvertOut(const Element &v) const {return v;} + virtual const AbstractGroup & GetGroup() const =0; + virtual Element BERDecodeElement(BufferedTransformation &bt) const =0; + virtual void DEREncodeElement(BufferedTransformation &bt, const Element &P) const =0; +}; + +template +class DL_FixedBasePrecomputation +{ +public: + typedef T Element; + + virtual bool IsInitialized() const =0; + virtual void SetBase(const DL_GroupPrecomputation &group, const Element &base) =0; + virtual const Element & GetBase(const DL_GroupPrecomputation &group) const =0; + virtual void Precompute(const DL_GroupPrecomputation &group, unsigned int maxExpBits, unsigned int storage) =0; + virtual void Load(const DL_GroupPrecomputation &group, BufferedTransformation &storedPrecomputation) =0; + virtual void Save(const DL_GroupPrecomputation &group, BufferedTransformation &storedPrecomputation) const =0; + virtual Element Exponentiate(const DL_GroupPrecomputation &group, const Integer &exponent) const =0; + virtual Element CascadeExponentiate(const DL_GroupPrecomputation &group, const Integer &exponent, const DL_FixedBasePrecomputation &pc2, const Integer &exponent2) const =0; +}; + +template +class DL_FixedBasePrecomputationImpl : public DL_FixedBasePrecomputation +{ +public: + typedef T Element; + + // DL_FixedBasePrecomputation + bool IsInitialized() const + {return !m_bases.empty();} + void SetBase(const DL_GroupPrecomputation &group, const Element &base); + const Element & GetBase(const DL_GroupPrecomputation &group) const + {return group.NeedConversions() ? m_base : m_bases[0];} + void Precompute(const DL_GroupPrecomputation &group, unsigned int maxExpBits, unsigned int storage); + void Load(const DL_GroupPrecomputation &group, BufferedTransformation &storedPrecomputation); + void Save(const DL_GroupPrecomputation &group, BufferedTransformation &storedPrecomputation) const; + Element Exponentiate(const DL_GroupPrecomputation &group, const Integer &exponent) const; + Element CascadeExponentiate(const DL_GroupPrecomputation &group, const Integer &exponent, const DL_FixedBasePrecomputation &pc2, const Integer &exponent2) const; + +private: + void PrepareCascade(const DL_GroupPrecomputation &group, std::vector > &eb, const Integer &exponent) const; + + Element m_base; + unsigned int m_windowSize; + Integer m_exponentBase; // what base to represent the exponent in + std::vector m_bases; // precalculated bases +}; + +NAMESPACE_END + +#ifdef CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES +#include "eprecomp.cpp" +#endif + +#endif diff --git a/CryptoPP/crypto/esig1023.dat b/CryptoPP/crypto/esig1023.dat new file mode 100644 index 0000000..4e43ad4 --- /dev/null +++ b/CryptoPP/crypto/esig1023.dat @@ -0,0 +1 @@ +3081E00281807040653BA4FCD5C66E3318B31E82654C5A62957F68D2EE6AE10BD6678D7A14EEF8EBF0C85F28FE22056C12B2A2DD4E9C897EB2FF06D57DB03B872C049ED2806DC3E4D86F2947D134065AC642F233F95FBCB55C533274FA91FFDC0CEB9E71B8795B71A977C7956001FC19E28DE18A80B20E4AE8F775B952CEEA0DEFEAE8E93D7F020120022B1EC74E9FC5EEA090E8DDF4BDB64861C7DC3F8EC7E64286EC2FE39DA55B4763C582DB48146521BDEF0146D5022B1E559EB15755298408E4E4C6F4791BF075C7A8C9B3C7F5B7FA3E8C322BA0A160C09A9DB6BBC4974BE0F877 \ No newline at end of file diff --git a/CryptoPP/crypto/esig1536.dat b/CryptoPP/crypto/esig1536.dat new file mode 100644 index 0000000..8e10d13 --- /dev/null +++ b/CryptoPP/crypto/esig1536.dat @@ -0,0 +1 @@ +3082014D0281C100E2A6788AB3CC986AEC06C51690143D3677141645D0628165EE924B9AFB7E6EDD52D90145B2F6031522C7A6CEC05E358F42B7837DACEA589F868F8DCA1C0F5FD8E5EDB8BBBAFCFF6D64CFCFBE68F46FBA6EFF45BC9D0CBB4F7F6075F5FFC2049C2F304B51C417764E18D182926E02D4116CE5C5C010E3D0AA6872A49B0D1FF4B37D54689C31F5821D04E9D4DB34D7536EE7F88B8C481B0EC1F93193A0B70567E6FD76E9FAC4F67BB47DACD356D0C8015261E068DDF8C34C0CAFCF3FA775577FEB020120024100FAF0F292EE96D4F449024F86C0A104E0633C722586EC00AD33E0234629825D2081BA337597889CAC55DC6BEBDD8F13FE3AA2133D6371601A37D195DA7BC45EF3024100EBE16F88887A425AA08E271467CC2220DC44012AB24ED4FF3512A96E8CB600C8BBCB771459FF0EE63D4B6786952A83A7143A775073F0A1D69B6D0B5817755673 \ No newline at end of file diff --git a/CryptoPP/crypto/esig2046.dat b/CryptoPP/crypto/esig2046.dat new file mode 100644 index 0000000..1c31854 --- /dev/null +++ b/CryptoPP/crypto/esig2046.dat @@ -0,0 +1 @@ +308201B70282010028B1F9CDF87EF6D74F3AC2EA83C17CE376215FB2B3B4817145F1A137FB86B0F7BF0F9BA1BDCF7CC15DF1884DD1B150A983279B90F7A1E4392CB3C16390771DA5668E68621C3898DF66BD254F3787ECFB64B3435E707D5C237A6C09F407D8CD618CC3BBFBAB3DEBA38A0D1A88B2A4E09AE32FF2064EF1896348D5B83047EC2E079D85662EED4A66FBB9C159A617EE3C333BAED66989740F54C3CB336C0EF71130786E70648F2698F4F4192DA06C1578FDB065F8E320EFB63049E4BA664F215924B3E89F69131C5987F357C54593BE173A7AED2D37BE69F90CB574EF83AD49145EB15950FADE9E848DA83BC2CACBEDCAFC4A3B31BFFBBFC4DD03B8E47A218A51410201200256033F9C3F8BDDC021503A687BEC90438F38FF9C0E4C050DD95E46BACA370F478B843611A94BC37B5E838AABFD4ECCCE757BAC967DF8A7DD219B3A71A4DA64D54AB367622B7EB9B4282E898755F02036E91D2A12C81F41025603DB3DE2AE2B52889148C98D68F2B7606B0E5112E60E6A6FF5FD98E5D74143C000B43BEC77082F17C1EF4C82127010B12438D498AAFE8521E21EE6391627D464B54D1BE31F57FFF18C27EC38F08093EA65139A61A2C1 \ No newline at end of file diff --git a/CryptoPP/crypto/esign.cpp b/CryptoPP/crypto/esign.cpp new file mode 100644 index 0000000..39d80a6 --- /dev/null +++ b/CryptoPP/crypto/esign.cpp @@ -0,0 +1,210 @@ +// esign.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "esign.h" +#include "asn.h" +#include "modarith.h" +#include "nbtheory.h" +#include "sha.h" +#include "algparam.h" + +NAMESPACE_BEGIN(CryptoPP) + +void ESIGN_TestInstantiations() +{ + ESIGN::Verifier x1(1, 1); + ESIGN::Signer x2(NullRNG(), 1); + ESIGN::Verifier x3(x2); + ESIGN::Verifier x4(x2.GetKey()); + ESIGN::Verifier x5(x3); + ESIGN::Signer x6 = x2; + + x6 = x2; + x3 = ESIGN::Verifier(x2); + x4 = x2.GetKey(); +} + +void ESIGNFunction::BERDecode(BufferedTransformation &bt) +{ + BERSequenceDecoder seq(bt); + m_n.BERDecode(seq); + m_e.BERDecode(seq); + seq.MessageEnd(); +} + +void ESIGNFunction::DEREncode(BufferedTransformation &bt) const +{ + DERSequenceEncoder seq(bt); + m_n.DEREncode(seq); + m_e.DEREncode(seq); + seq.MessageEnd(); +} + +Integer ESIGNFunction::ApplyFunction(const Integer &x) const +{ + DoQuickSanityCheck(); + return STDMIN(a_exp_b_mod_c(x, m_e, m_n) >> (2*GetK()+2), MaxImage()); +} + +bool ESIGNFunction::Validate(RandomNumberGenerator &rng, unsigned int level) const +{ + bool pass = true; + pass = pass && m_n > Integer::One() && m_n.IsOdd(); + pass = pass && m_e >= 8 && m_e < m_n; + return pass; +} + +bool ESIGNFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const +{ + return GetValueHelper(this, name, valueType, pValue).Assignable() + CRYPTOPP_GET_FUNCTION_ENTRY(Modulus) + CRYPTOPP_GET_FUNCTION_ENTRY(PublicExponent) + ; +} + +void ESIGNFunction::AssignFrom(const NameValuePairs &source) +{ + AssignFromHelper(this, source) + CRYPTOPP_SET_FUNCTION_ENTRY(Modulus) + CRYPTOPP_SET_FUNCTION_ENTRY(PublicExponent) + ; +} + +// ***************************************************************************** + +void InvertibleESIGNFunction::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs ¶m) +{ + int modulusSize = 1023*2; + param.GetIntValue("ModulusSize", modulusSize) || param.GetIntValue("KeySize", modulusSize); + + if (modulusSize < 24) + throw InvalidArgument("InvertibleESIGNFunction: specified modulus size is too small"); + + if (modulusSize % 3 != 0) + throw InvalidArgument("InvertibleESIGNFunction: modulus size must be divisible by 3"); + + m_e = param.GetValueWithDefault("PublicExponent", Integer(32)); + + if (m_e < 8) + throw InvalidArgument("InvertibleESIGNFunction: public exponents less than 8 may not be secure"); + + // VC70 workaround: putting these after primeParam causes overlapped stack allocation + ConstByteArrayParameter seedParam; + SecByteBlock seed; + + const Integer minP = Integer(204) << (modulusSize/3-8); + const Integer maxP = Integer::Power2(modulusSize/3)-1; + const NameValuePairs &primeParam = MakeParameters("Min", minP)("Max", maxP)("RandomNumberType", Integer::PRIME); + + if (param.GetValue("Seed", seedParam)) + { + seed.resize(seedParam.size() + 4); + memcpy(seed + 4, seedParam.begin(), seedParam.size()); + + PutWord(false, BIG_ENDIAN_ORDER, seed, (word32)0); + m_p.GenerateRandom(rng, CombinedNameValuePairs(primeParam, MakeParameters("Seed", ConstByteArrayParameter(seed)))); + PutWord(false, BIG_ENDIAN_ORDER, seed, (word32)1); + m_q.GenerateRandom(rng, CombinedNameValuePairs(primeParam, MakeParameters("Seed", ConstByteArrayParameter(seed)))); + } + else + { + m_p.GenerateRandom(rng, primeParam); + m_q.GenerateRandom(rng, primeParam); + } + + m_n = m_p * m_p * m_q; + + assert(m_n.BitCount() == modulusSize); +} + +void InvertibleESIGNFunction::BERDecode(BufferedTransformation &bt) +{ + BERSequenceDecoder privateKey(bt); + m_n.BERDecode(privateKey); + m_e.BERDecode(privateKey); + m_p.BERDecode(privateKey); + m_q.BERDecode(privateKey); + privateKey.MessageEnd(); +} + +void InvertibleESIGNFunction::DEREncode(BufferedTransformation &bt) const +{ + DERSequenceEncoder privateKey(bt); + m_n.DEREncode(privateKey); + m_e.DEREncode(privateKey); + m_p.DEREncode(privateKey); + m_q.DEREncode(privateKey); + privateKey.MessageEnd(); +} + +Integer InvertibleESIGNFunction::CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const +{ + DoQuickSanityCheck(); + + Integer pq = m_p * m_q; + Integer p2 = m_p * m_p; + Integer r, z, re, a, w0, w1; + + do + { + r.Randomize(rng, Integer::Zero(), pq); + z = x << (2*GetK()+2); + re = a_exp_b_mod_c(r, m_e, m_n); + a = (z - re) % m_n; + Integer::Divide(w1, w0, a, pq); + if (w1.NotZero()) + { + ++w0; + w1 = pq - w1; + } + } + while ((w1 >> 2*GetK()+1).IsPositive()); + + ModularArithmetic modp(m_p); + Integer t = modp.Divide(w0 * r % m_p, m_e * re % m_p); + Integer s = r + t*pq; + assert(s < m_n); +/* + using namespace std; + cout << "f = " << x << endl; + cout << "r = " << r << endl; + cout << "z = " << z << endl; + cout << "a = " << a << endl; + cout << "w0 = " << w0 << endl; + cout << "w1 = " << w1 << endl; + cout << "t = " << t << endl; + cout << "s = " << s << endl; +*/ + return s; +} + +bool InvertibleESIGNFunction::Validate(RandomNumberGenerator &rng, unsigned int level) const +{ + bool pass = ESIGNFunction::Validate(rng, level); + pass = pass && m_p > Integer::One() && m_p.IsOdd() && m_p < m_n; + pass = pass && m_q > Integer::One() && m_q.IsOdd() && m_q < m_n; + pass = pass && m_p.BitCount() == m_q.BitCount(); + if (level >= 1) + pass = pass && m_p * m_p * m_q == m_n; + if (level >= 2) + pass = pass && VerifyPrime(rng, m_p, level-2) && VerifyPrime(rng, m_q, level-2); + return pass; +} + +bool InvertibleESIGNFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const +{ + return GetValueHelper(this, name, valueType, pValue).Assignable() + CRYPTOPP_GET_FUNCTION_ENTRY(Prime1) + CRYPTOPP_GET_FUNCTION_ENTRY(Prime2) + ; +} + +void InvertibleESIGNFunction::AssignFrom(const NameValuePairs &source) +{ + AssignFromHelper(this, source) + CRYPTOPP_SET_FUNCTION_ENTRY(Prime1) + CRYPTOPP_SET_FUNCTION_ENTRY(Prime2) + ; +} + +NAMESPACE_END diff --git a/CryptoPP/crypto/esign.h b/CryptoPP/crypto/esign.h new file mode 100644 index 0000000..058e414 --- /dev/null +++ b/CryptoPP/crypto/esign.h @@ -0,0 +1,128 @@ +#ifndef CRYPTOPP_ESIGN_H +#define CRYPTOPP_ESIGN_H + +/** \file + This file contains classes that implement the + ESIGN signature schemes as defined in IEEE P1363a. +*/ + +#include "pubkey.h" +#include "integer.h" +#include "asn.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! _ +class ESIGNFunction : public TrapdoorFunction, public ASN1CryptoMaterial +{ + typedef ESIGNFunction ThisClass; + +public: + void Initialize(const Integer &n, const Integer &e) + {m_n = n; m_e = e;} + + // PublicKey + void BERDecode(BufferedTransformation &bt); + void DEREncode(BufferedTransformation &bt) const; + + // CryptoMaterial + bool Validate(RandomNumberGenerator &rng, unsigned int level) const; + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; + void AssignFrom(const NameValuePairs &source); + + // TrapdoorFunction + Integer ApplyFunction(const Integer &x) const; + Integer PreimageBound() const {return m_n;} + Integer ImageBound() const {return Integer::Power2(GetK());} + + // non-derived + const Integer & GetModulus() const {return m_n;} + const Integer & GetPublicExponent() const {return m_e;} + + void SetModulus(const Integer &n) {m_n = n;} + void SetPublicExponent(const Integer &e) {m_e = e;} + +protected: + unsigned int GetK() const {return m_n.BitCount()/3-1;} + + Integer m_n, m_e; +}; + +//! _ +class InvertibleESIGNFunction : public ESIGNFunction, public RandomizedTrapdoorFunctionInverse, public PrivateKey +{ + typedef InvertibleESIGNFunction ThisClass; + +public: + void Initialize(const Integer &n, const Integer &e, const Integer &p, const Integer &q) + {m_n = n; m_e = e; m_p = p; m_q = q;} + // generate a random private key + void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits) + {GenerateRandomWithKeySize(rng, modulusBits);} + + void BERDecode(BufferedTransformation &bt); + void DEREncode(BufferedTransformation &bt) const; + + Integer CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const; + + // GeneratibleCryptoMaterial + bool Validate(RandomNumberGenerator &rng, unsigned int level) const; + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; + void AssignFrom(const NameValuePairs &source); + /*! parameters: (ModulusSize) */ + void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg); + + const Integer& GetPrime1() const {return m_p;} + const Integer& GetPrime2() const {return m_q;} + + void SetPrime1(const Integer &p) {m_p = p;} + void SetPrime2(const Integer &q) {m_q = q;} + +protected: + Integer m_p, m_q; +}; + +//! _ +template +class EMSA5Pad : public PK_DeterministicSignatureMessageEncodingMethod +{ +public: + static const char *StaticAlgorithmName() {return "EMSA5";} + + void ComputeMessageRepresentative(RandomNumberGenerator &rng, + const byte *recoverableMessage, size_t recoverableMessageLength, + HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, + byte *representative, size_t representativeBitLength) const + { + SecByteBlock digest(hash.DigestSize()); + hash.Final(digest); + size_t representativeByteLength = BitsToBytes(representativeBitLength); + T mgf; + mgf.GenerateAndMask(hash, representative, representativeByteLength, digest, digest.size(), false); + if (representativeBitLength % 8 != 0) + representative[0] = (byte)Crop(representative[0], representativeBitLength % 8); + } +}; + +//! EMSA5, for use with ESIGN +struct P1363_EMSA5 : public SignatureStandard +{ + typedef EMSA5Pad SignatureMessageEncodingMethod; +}; + +struct ESIGN_Keys +{ + static std::string StaticAlgorithmName() {return "ESIGN";} + typedef ESIGNFunction PublicKey; + typedef InvertibleESIGNFunction PrivateKey; +}; + +//! ESIGN, as defined in IEEE P1363a +template +struct ESIGN : public TF_SS +{ +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/factory.h b/CryptoPP/crypto/factory.h new file mode 100644 index 0000000..3c22c1b --- /dev/null +++ b/CryptoPP/crypto/factory.h @@ -0,0 +1,128 @@ +#ifndef CRYPTOPP_OBJFACT_H +#define CRYPTOPP_OBJFACT_H + +#include "cryptlib.h" +#include +#include + +NAMESPACE_BEGIN(CryptoPP) + +//! _ +template +class ObjectFactory +{ +public: + virtual AbstractClass * CreateObject() const =0; +}; + +//! _ +template +class DefaultObjectFactory : public ObjectFactory +{ +public: + AbstractClass * CreateObject() const + { + return new ConcreteClass; + } + +}; + +//! _ +template +class ObjectFactoryRegistry +{ +public: + class FactoryNotFound : public Exception + { + public: + FactoryNotFound(const char *name) : Exception(OTHER_ERROR, std::string("ObjectFactoryRegistry: could not find factory for algorithm ") + name) {} + }; + + ~ObjectFactoryRegistry() + { + for (CPP_TYPENAME Map::iterator i = m_map.begin(); i != m_map.end(); ++i) + { + delete (ObjectFactory *)i->second; + i->second = NULL; + } + } + + void RegisterFactory(const std::string &name, ObjectFactory *factory) + { + m_map[name] = factory; + } + + const ObjectFactory * GetFactory(const char *name) const + { + CPP_TYPENAME Map::const_iterator i = m_map.find(name); + return i == m_map.end() ? NULL : (ObjectFactory *)i->second; + } + + AbstractClass *CreateObject(const char *name) const + { + const ObjectFactory *factory = GetFactory(name); + if (!factory) + throw FactoryNotFound(name); + return factory->CreateObject(); + } + + // Return a vector containing the factory names. This is easier than returning an iterator. + // from Andrew Pitonyak + std::vector GetFactoryNames() const + { + std::vector names; + CPP_TYPENAME Map::const_iterator iter; + for (iter = m_map.begin(); iter != m_map.end(); ++iter) + names.push_back(iter->first); + return names; + } + + CRYPTOPP_NOINLINE static ObjectFactoryRegistry & Registry(CRYPTOPP_NOINLINE_DOTDOTDOT); + +private: + // use void * instead of ObjectFactory * to save code size + typedef std::map Map; + Map m_map; +}; + +template +ObjectFactoryRegistry & ObjectFactoryRegistry::Registry(CRYPTOPP_NOINLINE_DOTDOTDOT) +{ + static ObjectFactoryRegistry s_registry; + return s_registry; +} + +template +struct RegisterDefaultFactoryFor { +RegisterDefaultFactoryFor(const char *name=NULL) +{ + // BCB2006 workaround + std::string n = name ? std::string(name) : std::string(ConcreteClass::StaticAlgorithmName()); + ObjectFactoryRegistry::Registry(). + RegisterFactory(n, new DefaultObjectFactory); +}}; + +template +void RegisterAsymmetricCipherDefaultFactories(const char *name=NULL, SchemeClass *dummy=NULL) +{ + RegisterDefaultFactoryFor((const char *)name); + RegisterDefaultFactoryFor((const char *)name); +} + +template +void RegisterSignatureSchemeDefaultFactories(const char *name=NULL, SchemeClass *dummy=NULL) +{ + RegisterDefaultFactoryFor((const char *)name); + RegisterDefaultFactoryFor((const char *)name); +} + +template +void RegisterSymmetricCipherDefaultFactories(const char *name=NULL, SchemeClass *dummy=NULL) +{ + RegisterDefaultFactoryFor((const char *)name); + RegisterDefaultFactoryFor((const char *)name); +} + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/files.cpp b/CryptoPP/crypto/files.cpp new file mode 100644 index 0000000..61915d7 --- /dev/null +++ b/CryptoPP/crypto/files.cpp @@ -0,0 +1,212 @@ +// files.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "files.h" + +#include + +NAMESPACE_BEGIN(CryptoPP) + +using namespace std; + +void Files_TestInstantiations() +{ + FileStore f0; + FileSource f1; + FileSink f2; +} + +void FileStore::StoreInitialize(const NameValuePairs ¶meters) +{ + m_file.reset(new std::ifstream); + const char *fileName; + if (parameters.GetValue(Name::InputFileName(), fileName)) + { + ios::openmode binary = parameters.GetValueWithDefault(Name::InputBinaryMode(), true) ? ios::binary : ios::openmode(0); + m_file->open(fileName, ios::in | binary); + if (!*m_file) + throw OpenErr(fileName); + m_stream = m_file.get(); + } + else + { + m_stream = NULL; + parameters.GetValue(Name::InputStreamPointer(), m_stream); + } + m_waiting = false; +} + +lword FileStore::MaxRetrievable() const +{ + if (!m_stream) + return 0; + + streampos current = m_stream->tellg(); + streampos end = m_stream->seekg(0, ios::end).tellg(); + m_stream->seekg(current); + return end-current; +} + +size_t FileStore::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking) +{ + if (!m_stream) + { + transferBytes = 0; + return 0; + } + + lword size=transferBytes; + transferBytes = 0; + + if (m_waiting) + goto output; + + while (size && m_stream->good()) + { + { + size_t spaceSize = 1024; + m_space = HelpCreatePutSpace(target, channel, 1, UnsignedMin(size_t(0)-1, size), spaceSize); + + m_stream->read((char *)m_space, (unsigned int)STDMIN(size, (lword)spaceSize)); + } + m_len = m_stream->gcount(); + size_t blockedBytes; +output: + blockedBytes = target.ChannelPutModifiable2(channel, m_space, m_len, 0, blocking); + m_waiting = blockedBytes > 0; + if (m_waiting) + return blockedBytes; + size -= m_len; + transferBytes += m_len; + } + + if (!m_stream->good() && !m_stream->eof()) + throw ReadErr(); + + return 0; +} + +size_t FileStore::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end, const std::string &channel, bool blocking) const +{ + if (!m_stream) + return 0; + + if (begin == 0 && end == 1) + { + int result = m_stream->peek(); + if (result == char_traits::eof()) + return 0; + else + { + size_t blockedBytes = target.ChannelPut(channel, byte(result), blocking); + begin += 1-blockedBytes; + return blockedBytes; + } + } + + // TODO: figure out what happens on cin + streampos current = m_stream->tellg(); + streampos endPosition = m_stream->seekg(0, ios::end).tellg(); + streampos newPosition = current + (streamoff)begin; + + if (newPosition >= endPosition) + { + m_stream->seekg(current); + return 0; // don't try to seek beyond the end of file + } + m_stream->seekg(newPosition); + try + { + assert(!m_waiting); + lword copyMax = end-begin; + size_t blockedBytes = const_cast(this)->TransferTo2(target, copyMax, channel, blocking); + begin += copyMax; + if (blockedBytes) + { + const_cast(this)->m_waiting = false; + return blockedBytes; + } + } + catch(...) + { + m_stream->clear(); + m_stream->seekg(current); + throw; + } + m_stream->clear(); + m_stream->seekg(current); + + return 0; +} + +lword FileStore::Skip(lword skipMax) +{ + lword oldPos = m_stream->tellg(); + std::istream::off_type offset; + if (!SafeConvert(skipMax, offset)) + throw InvalidArgument("FileStore: maximum seek offset exceeded"); + m_stream->seekg(offset, ios::cur); + return (lword)m_stream->tellg() - oldPos; +} + +void FileSink::IsolatedInitialize(const NameValuePairs ¶meters) +{ + m_file.reset(new std::ofstream); + const char *fileName; + if (parameters.GetValue(Name::OutputFileName(), fileName)) + { + ios::openmode binary = parameters.GetValueWithDefault(Name::OutputBinaryMode(), true) ? ios::binary : ios::openmode(0); + m_file->open(fileName, ios::out | ios::trunc | binary); + if (!*m_file) + throw OpenErr(fileName); + m_stream = m_file.get(); + } + else + { + m_stream = NULL; + parameters.GetValue(Name::OutputStreamPointer(), m_stream); + } +} + +bool FileSink::IsolatedFlush(bool hardFlush, bool blocking) +{ + if (!m_stream) + throw Err("FileSink: output stream not opened"); + + m_stream->flush(); + if (!m_stream->good()) + throw WriteErr(); + + return false; +} + +size_t FileSink::Put2(const byte *inString, size_t length, int messageEnd, bool blocking) +{ + if (!m_stream) + throw Err("FileSink: output stream not opened"); + + while (length > 0) + { + std::streamsize size; + if (!SafeConvert(length, size)) + size = numeric_limits::max(); + m_stream->write((const char *)inString, size); + inString += size; + length -= size; + } + + if (messageEnd) + m_stream->flush(); + + if (!m_stream->good()) + throw WriteErr(); + + return 0; +} + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/files.h b/CryptoPP/crypto/files.h new file mode 100644 index 0000000..2e6fa87 --- /dev/null +++ b/CryptoPP/crypto/files.h @@ -0,0 +1,97 @@ +#ifndef CRYPTOPP_FILES_H +#define CRYPTOPP_FILES_H + +#include "cryptlib.h" +#include "filters.h" +#include "argnames.h" + +#include +#include + +NAMESPACE_BEGIN(CryptoPP) + +//! file-based implementation of Store interface +class CRYPTOPP_DLL FileStore : public Store, private FilterPutSpaceHelper, public NotCopyable +{ +public: + class Err : public Exception + { + public: + Err(const std::string &s) : Exception(IO_ERROR, s) {} + }; + class OpenErr : public Err {public: OpenErr(const std::string &filename) : Err("FileStore: error opening file for reading: " + filename) {}}; + class ReadErr : public Err {public: ReadErr() : Err("FileStore: error reading file") {}}; + + FileStore() : m_stream(NULL) {} + FileStore(std::istream &in) + {StoreInitialize(MakeParameters(Name::InputStreamPointer(), &in));} + FileStore(const char *filename) + {StoreInitialize(MakeParameters(Name::InputFileName(), filename));} + + std::istream* GetStream() {return m_stream;} + + lword MaxRetrievable() const; + size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=NULL_CHANNEL, bool blocking=true); + size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=NULL_CHANNEL, bool blocking=true) const; + lword Skip(lword skipMax=ULONG_MAX); + +private: + void StoreInitialize(const NameValuePairs ¶meters); + + member_ptr m_file; + std::istream *m_stream; + byte *m_space; + size_t m_len; + bool m_waiting; +}; + +//! file-based implementation of Source interface +class CRYPTOPP_DLL FileSource : public SourceTemplate +{ +public: + typedef FileStore::Err Err; + typedef FileStore::OpenErr OpenErr; + typedef FileStore::ReadErr ReadErr; + + FileSource(BufferedTransformation *attachment = NULL) + : SourceTemplate(attachment) {} + FileSource(std::istream &in, bool pumpAll, BufferedTransformation *attachment = NULL) + : SourceTemplate(attachment) {SourceInitialize(pumpAll, MakeParameters(Name::InputStreamPointer(), &in));} + FileSource(const char *filename, bool pumpAll, BufferedTransformation *attachment = NULL, bool binary=true) + : SourceTemplate(attachment) {SourceInitialize(pumpAll, MakeParameters(Name::InputFileName(), filename)(Name::InputBinaryMode(), binary));} + + std::istream* GetStream() {return m_store.GetStream();} +}; + +//! file-based implementation of Sink interface +class CRYPTOPP_DLL FileSink : public Sink, public NotCopyable +{ +public: + class Err : public Exception + { + public: + Err(const std::string &s) : Exception(IO_ERROR, s) {} + }; + class OpenErr : public Err {public: OpenErr(const std::string &filename) : Err("FileSink: error opening file for writing: " + filename) {}}; + class WriteErr : public Err {public: WriteErr() : Err("FileSink: error writing file") {}}; + + FileSink() : m_stream(NULL) {} + FileSink(std::ostream &out) + {IsolatedInitialize(MakeParameters(Name::OutputStreamPointer(), &out));} + FileSink(const char *filename, bool binary=true) + {IsolatedInitialize(MakeParameters(Name::OutputFileName(), filename)("OutputBinaryMode", binary));} + + std::ostream* GetStream() {return m_stream;} + + void IsolatedInitialize(const NameValuePairs ¶meters); + size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking); + bool IsolatedFlush(bool hardFlush, bool blocking); + +private: + member_ptr m_file; + std::ostream *m_stream; +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/filters.cpp b/CryptoPP/crypto/filters.cpp new file mode 100644 index 0000000..b3fbacf --- /dev/null +++ b/CryptoPP/crypto/filters.cpp @@ -0,0 +1,999 @@ +// filters.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "filters.h" +#include "mqueue.h" +#include "fltrimpl.h" +#include "argnames.h" +#include +#include + +NAMESPACE_BEGIN(CryptoPP) + +Filter::Filter(BufferedTransformation *attachment) + : m_attachment(attachment), m_continueAt(0) +{ +} + +BufferedTransformation * Filter::NewDefaultAttachment() const +{ + return new MessageQueue; +} + +BufferedTransformation * Filter::AttachedTransformation() +{ + if (m_attachment.get() == NULL) + m_attachment.reset(NewDefaultAttachment()); + return m_attachment.get(); +} + +const BufferedTransformation *Filter::AttachedTransformation() const +{ + if (m_attachment.get() == NULL) + const_cast(this)->m_attachment.reset(NewDefaultAttachment()); + return m_attachment.get(); +} + +void Filter::Detach(BufferedTransformation *newOut) +{ + m_attachment.reset(newOut); +} + +void Filter::Insert(Filter *filter) +{ + filter->m_attachment.reset(m_attachment.release()); + m_attachment.reset(filter); +} + +size_t Filter::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end, const std::string &channel, bool blocking) const +{ + return AttachedTransformation()->CopyRangeTo2(target, begin, end, channel, blocking); +} + +size_t Filter::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking) +{ + return AttachedTransformation()->TransferTo2(target, transferBytes, channel, blocking); +} + +void Filter::Initialize(const NameValuePairs ¶meters, int propagation) +{ + m_continueAt = 0; + IsolatedInitialize(parameters); + PropagateInitialize(parameters, propagation); +} + +bool Filter::Flush(bool hardFlush, int propagation, bool blocking) +{ + switch (m_continueAt) + { + case 0: + if (IsolatedFlush(hardFlush, blocking)) + return true; + case 1: + if (OutputFlush(1, hardFlush, propagation, blocking)) + return true; + } + return false; +} + +bool Filter::MessageSeriesEnd(int propagation, bool blocking) +{ + switch (m_continueAt) + { + case 0: + if (IsolatedMessageSeriesEnd(blocking)) + return true; + case 1: + if (ShouldPropagateMessageSeriesEnd() && OutputMessageSeriesEnd(1, propagation, blocking)) + return true; + } + return false; +} + +void Filter::PropagateInitialize(const NameValuePairs ¶meters, int propagation) +{ + if (propagation) + AttachedTransformation()->Initialize(parameters, propagation-1); +} + +size_t Filter::OutputModifiable(int outputSite, byte *inString, size_t length, int messageEnd, bool blocking, const std::string &channel) +{ + if (messageEnd) + messageEnd--; + size_t result = AttachedTransformation()->PutModifiable2(inString, length, messageEnd, blocking); + m_continueAt = result ? outputSite : 0; + return result; +} + +size_t Filter::Output(int outputSite, const byte *inString, size_t length, int messageEnd, bool blocking, const std::string &channel) +{ + if (messageEnd) + messageEnd--; + size_t result = AttachedTransformation()->Put2(inString, length, messageEnd, blocking); + m_continueAt = result ? outputSite : 0; + return result; +} + +bool Filter::OutputFlush(int outputSite, bool hardFlush, int propagation, bool blocking, const std::string &channel) +{ + if (propagation && AttachedTransformation()->ChannelFlush(channel, hardFlush, propagation-1, blocking)) + { + m_continueAt = outputSite; + return true; + } + m_continueAt = 0; + return false; +} + +bool Filter::OutputMessageSeriesEnd(int outputSite, int propagation, bool blocking, const std::string &channel) +{ + if (propagation && AttachedTransformation()->ChannelMessageSeriesEnd(channel, propagation-1, blocking)) + { + m_continueAt = outputSite; + return true; + } + m_continueAt = 0; + return false; +} + +// ************************************************************* + +void MeterFilter::ResetMeter() +{ + m_currentMessageBytes = m_totalBytes = m_currentSeriesMessages = m_totalMessages = m_totalMessageSeries = 0; + m_rangesToSkip.clear(); +} + +void MeterFilter::AddRangeToSkip(unsigned int message, lword position, lword size, bool sortNow) +{ + MessageRange r = {message, position, size}; + m_rangesToSkip.push_back(r); + if (sortNow) + std::sort(m_rangesToSkip.begin(), m_rangesToSkip.end()); +} + +size_t MeterFilter::PutMaybeModifiable(byte *begin, size_t length, int messageEnd, bool blocking, bool modifiable) +{ + if (!m_transparent) + return 0; + + size_t t; + FILTER_BEGIN; + + m_begin = begin; + m_length = length; + + while (m_length > 0 || messageEnd) + { + if (m_length > 0 && !m_rangesToSkip.empty() && m_rangesToSkip.front().message == m_totalMessages && m_currentMessageBytes + m_length > m_rangesToSkip.front().position) + { + FILTER_OUTPUT_MAYBE_MODIFIABLE(1, m_begin, t = (size_t)SaturatingSubtract(m_rangesToSkip.front().position, m_currentMessageBytes), false, modifiable); + + assert(t < m_length); + m_begin += t; + m_length -= t; + m_currentMessageBytes += t; + m_totalBytes += t; + + if (m_currentMessageBytes + m_length < m_rangesToSkip.front().position + m_rangesToSkip.front().size) + t = m_length; + else + { + t = (size_t)SaturatingSubtract(m_rangesToSkip.front().position + m_rangesToSkip.front().size, m_currentMessageBytes); + assert(t <= m_length); + m_rangesToSkip.pop_front(); + } + + m_begin += t; + m_length -= t; + m_currentMessageBytes += t; + m_totalBytes += t; + } + else + { + FILTER_OUTPUT_MAYBE_MODIFIABLE(2, m_begin, m_length, messageEnd, modifiable); + + m_currentMessageBytes += m_length; + m_totalBytes += m_length; + m_length = 0; + + if (messageEnd) + { + m_currentMessageBytes = 0; + m_currentSeriesMessages++; + m_totalMessages++; + messageEnd = false; + } + } + } + + FILTER_END_NO_MESSAGE_END; +} + +size_t MeterFilter::Put2(const byte *begin, size_t length, int messageEnd, bool blocking) +{ + return PutMaybeModifiable(const_cast(begin), length, messageEnd, blocking, false); +} + +size_t MeterFilter::PutModifiable2(byte *begin, size_t length, int messageEnd, bool blocking) +{ + return PutMaybeModifiable(begin, length, messageEnd, blocking, true); +} + +bool MeterFilter::IsolatedMessageSeriesEnd(bool blocking) +{ + m_currentMessageBytes = 0; + m_currentSeriesMessages = 0; + m_totalMessageSeries++; + return false; +} + +// ************************************************************* + +void FilterWithBufferedInput::BlockQueue::ResetQueue(size_t blockSize, size_t maxBlocks) +{ + m_buffer.New(blockSize * maxBlocks); + m_blockSize = blockSize; + m_maxBlocks = maxBlocks; + m_size = 0; + m_begin = m_buffer; +} + +byte *FilterWithBufferedInput::BlockQueue::GetBlock() +{ + if (m_size >= m_blockSize) + { + byte *ptr = m_begin; + if ((m_begin+=m_blockSize) == m_buffer.end()) + m_begin = m_buffer; + m_size -= m_blockSize; + return ptr; + } + else + return NULL; +} + +byte *FilterWithBufferedInput::BlockQueue::GetContigousBlocks(size_t &numberOfBytes) +{ + numberOfBytes = STDMIN(numberOfBytes, STDMIN(size_t(m_buffer.end()-m_begin), m_size)); + byte *ptr = m_begin; + m_begin += numberOfBytes; + m_size -= numberOfBytes; + if (m_size == 0 || m_begin == m_buffer.end()) + m_begin = m_buffer; + return ptr; +} + +size_t FilterWithBufferedInput::BlockQueue::GetAll(byte *outString) +{ + size_t size = m_size; + size_t numberOfBytes = m_maxBlocks*m_blockSize; + const byte *ptr = GetContigousBlocks(numberOfBytes); + memcpy(outString, ptr, numberOfBytes); + memcpy(outString+numberOfBytes, m_begin, m_size); + m_size = 0; + return size; +} + +void FilterWithBufferedInput::BlockQueue::Put(const byte *inString, size_t length) +{ + assert(m_size + length <= m_buffer.size()); + byte *end = (m_size < size_t(m_buffer.end()-m_begin)) ? m_begin + m_size : m_begin + m_size - m_buffer.size(); + size_t len = STDMIN(length, size_t(m_buffer.end()-end)); + memcpy(end, inString, len); + if (len < length) + memcpy(m_buffer, inString+len, length-len); + m_size += length; +} + +FilterWithBufferedInput::FilterWithBufferedInput(BufferedTransformation *attachment) + : Filter(attachment) +{ +} + +FilterWithBufferedInput::FilterWithBufferedInput(size_t firstSize, size_t blockSize, size_t lastSize, BufferedTransformation *attachment) + : Filter(attachment), m_firstSize(firstSize), m_blockSize(blockSize), m_lastSize(lastSize) + , m_firstInputDone(false) +{ + if (m_firstSize < 0 || m_blockSize < 1 || m_lastSize < 0) + throw InvalidArgument("FilterWithBufferedInput: invalid buffer size"); + + m_queue.ResetQueue(1, m_firstSize); +} + +void FilterWithBufferedInput::IsolatedInitialize(const NameValuePairs ¶meters) +{ + InitializeDerivedAndReturnNewSizes(parameters, m_firstSize, m_blockSize, m_lastSize); + if (m_firstSize < 0 || m_blockSize < 1 || m_lastSize < 0) + throw InvalidArgument("FilterWithBufferedInput: invalid buffer size"); + m_queue.ResetQueue(1, m_firstSize); + m_firstInputDone = false; +} + +bool FilterWithBufferedInput::IsolatedFlush(bool hardFlush, bool blocking) +{ + if (!blocking) + throw BlockingInputOnly("FilterWithBufferedInput"); + + if (hardFlush) + ForceNextPut(); + FlushDerived(); + + return false; +} + +size_t FilterWithBufferedInput::PutMaybeModifiable(byte *inString, size_t length, int messageEnd, bool blocking, bool modifiable) +{ + if (!blocking) + throw BlockingInputOnly("FilterWithBufferedInput"); + + if (length != 0) + { + size_t newLength = m_queue.CurrentSize() + length; + + if (!m_firstInputDone && newLength >= m_firstSize) + { + size_t len = m_firstSize - m_queue.CurrentSize(); + m_queue.Put(inString, len); + FirstPut(m_queue.GetContigousBlocks(m_firstSize)); + assert(m_queue.CurrentSize() == 0); + m_queue.ResetQueue(m_blockSize, (2*m_blockSize+m_lastSize-2)/m_blockSize); + + inString += len; + newLength -= m_firstSize; + m_firstInputDone = true; + } + + if (m_firstInputDone) + { + if (m_blockSize == 1) + { + while (newLength > m_lastSize && m_queue.CurrentSize() > 0) + { + size_t len = newLength - m_lastSize; + byte *ptr = m_queue.GetContigousBlocks(len); + NextPutModifiable(ptr, len); + newLength -= len; + } + + if (newLength > m_lastSize) + { + size_t len = newLength - m_lastSize; + NextPutMaybeModifiable(inString, len, modifiable); + inString += len; + newLength -= len; + } + } + else + { + while (newLength >= m_blockSize + m_lastSize && m_queue.CurrentSize() >= m_blockSize) + { + NextPutModifiable(m_queue.GetBlock(), m_blockSize); + newLength -= m_blockSize; + } + + if (newLength >= m_blockSize + m_lastSize && m_queue.CurrentSize() > 0) + { + assert(m_queue.CurrentSize() < m_blockSize); + size_t len = m_blockSize - m_queue.CurrentSize(); + m_queue.Put(inString, len); + inString += len; + NextPutModifiable(m_queue.GetBlock(), m_blockSize); + newLength -= m_blockSize; + } + + if (newLength >= m_blockSize + m_lastSize) + { + size_t len = RoundDownToMultipleOf(newLength - m_lastSize, m_blockSize); + NextPutMaybeModifiable(inString, len, modifiable); + inString += len; + newLength -= len; + } + } + } + + m_queue.Put(inString, newLength - m_queue.CurrentSize()); + } + + if (messageEnd) + { + if (!m_firstInputDone && m_firstSize==0) + FirstPut(NULL); + + SecByteBlock temp(m_queue.CurrentSize()); + m_queue.GetAll(temp); + LastPut(temp, temp.size()); + + m_firstInputDone = false; + m_queue.ResetQueue(1, m_firstSize); + + Output(1, NULL, 0, messageEnd, blocking); + } + return 0; +} + +void FilterWithBufferedInput::ForceNextPut() +{ + if (!m_firstInputDone) + return; + + if (m_blockSize > 1) + { + while (m_queue.CurrentSize() >= m_blockSize) + NextPutModifiable(m_queue.GetBlock(), m_blockSize); + } + else + { + size_t len; + while ((len = m_queue.CurrentSize()) > 0) + NextPutModifiable(m_queue.GetContigousBlocks(len), len); + } +} + +void FilterWithBufferedInput::NextPutMultiple(const byte *inString, size_t length) +{ + assert(m_blockSize > 1); // m_blockSize = 1 should always override this function + while (length > 0) + { + assert(length >= m_blockSize); + NextPutSingle(inString); + inString += m_blockSize; + length -= m_blockSize; + } +} + +// ************************************************************* + +void Redirector::Initialize(const NameValuePairs ¶meters, int propagation) +{ + m_target = parameters.GetValueWithDefault("RedirectionTargetPointer", (BufferedTransformation*)NULL); + m_behavior = parameters.GetIntValueWithDefault("RedirectionBehavior", PASS_EVERYTHING); + + if (m_target && GetPassSignals()) + m_target->Initialize(parameters, propagation); +} + +// ************************************************************* + +ProxyFilter::ProxyFilter(BufferedTransformation *filter, size_t firstSize, size_t lastSize, BufferedTransformation *attachment) + : FilterWithBufferedInput(firstSize, 1, lastSize, attachment), m_filter(filter) +{ + if (m_filter.get()) + m_filter->Attach(new OutputProxy(*this, false)); +} + +bool ProxyFilter::IsolatedFlush(bool hardFlush, bool blocking) +{ + return m_filter.get() ? m_filter->Flush(hardFlush, -1, blocking) : false; +} + +void ProxyFilter::SetFilter(Filter *filter) +{ + m_filter.reset(filter); + if (filter) + { + OutputProxy *proxy; + std::auto_ptr temp(proxy = new OutputProxy(*this, false)); + m_filter->TransferAllTo(*proxy); + m_filter->Attach(temp.release()); + } +} + +void ProxyFilter::NextPutMultiple(const byte *s, size_t len) +{ + if (m_filter.get()) + m_filter->Put(s, len); +} + +void ProxyFilter::NextPutModifiable(byte *s, size_t len) +{ + if (m_filter.get()) + m_filter->PutModifiable(s, len); +} + +// ************************************************************* + +void RandomNumberSink::IsolatedInitialize(const NameValuePairs ¶meters) +{ + parameters.GetRequiredParameter("RandomNumberSink", "RandomNumberGeneratorPointer", m_rng); +} + +size_t RandomNumberSink::Put2(const byte *begin, size_t length, int messageEnd, bool blocking) +{ + m_rng->IncorporateEntropy(begin, length); + return 0; +} + +size_t ArraySink::Put2(const byte *begin, size_t length, int messageEnd, bool blocking) +{ + if (m_buf+m_total != begin) + memcpy(m_buf+m_total, begin, STDMIN(length, SaturatingSubtract(m_size, m_total))); + m_total += length; + return 0; +} + +byte * ArraySink::CreatePutSpace(size_t &size) +{ + size = SaturatingSubtract(m_size, m_total); + return m_buf + m_total; +} + +void ArraySink::IsolatedInitialize(const NameValuePairs ¶meters) +{ + ByteArrayParameter array; + if (!parameters.GetValue(Name::OutputBuffer(), array)) + throw InvalidArgument("ArraySink: missing OutputBuffer argument"); + m_buf = array.begin(); + m_size = array.size(); + m_total = 0; +} + +size_t ArrayXorSink::Put2(const byte *begin, size_t length, int messageEnd, bool blocking) +{ + xorbuf(m_buf+m_total, begin, STDMIN(length, SaturatingSubtract(m_size, m_total))); + m_total += length; + return 0; +} + +// ************************************************************* + +size_t StreamTransformationFilter::LastBlockSize(StreamTransformation &c, BlockPaddingScheme padding) +{ + if (c.MinLastBlockSize() > 0) + return c.MinLastBlockSize(); + else if (c.MandatoryBlockSize() > 1 && !c.IsForwardTransformation() && padding != NO_PADDING && padding != ZEROS_PADDING) + return c.MandatoryBlockSize(); + else + return 0; +} + +StreamTransformationFilter::StreamTransformationFilter(StreamTransformation &c, BufferedTransformation *attachment, BlockPaddingScheme padding) + : FilterWithBufferedInput(0, c.MandatoryBlockSize(), LastBlockSize(c, padding), attachment) + , m_cipher(c) +{ + assert(c.MinLastBlockSize() == 0 || c.MinLastBlockSize() > c.MandatoryBlockSize()); + + bool isBlockCipher = (c.MandatoryBlockSize() > 1 && c.MinLastBlockSize() == 0); + + if (padding == DEFAULT_PADDING) + { + if (isBlockCipher) + m_padding = PKCS_PADDING; + else + m_padding = NO_PADDING; + } + else + m_padding = padding; + + if (!isBlockCipher && (m_padding == PKCS_PADDING || m_padding == ONE_AND_ZEROS_PADDING)) + throw InvalidArgument("StreamTransformationFilter: PKCS_PADDING and ONE_AND_ZEROS_PADDING cannot be used with " + c.AlgorithmName()); +} + +void StreamTransformationFilter::FirstPut(const byte *inString) +{ + m_optimalBufferSize = m_cipher.OptimalBlockSize(); + m_optimalBufferSize = (unsigned int)STDMAX(m_optimalBufferSize, RoundDownToMultipleOf(4096U, m_optimalBufferSize)); +} + +void StreamTransformationFilter::NextPutMultiple(const byte *inString, size_t length) +{ + if (!length) + return; + + size_t s = m_cipher.MandatoryBlockSize(); + + do + { + size_t len = m_optimalBufferSize; + byte *space = HelpCreatePutSpace(*AttachedTransformation(), NULL_CHANNEL, s, length, len); + if (len < length) + { + if (len == m_optimalBufferSize) + len -= m_cipher.GetOptimalBlockSizeUsed(); + len = RoundDownToMultipleOf(len, s); + } + else + len = length; + m_cipher.ProcessString(space, inString, len); + AttachedTransformation()->PutModifiable(space, len); + inString += len; + length -= len; + } + while (length > 0); +} + +void StreamTransformationFilter::NextPutModifiable(byte *inString, size_t length) +{ + m_cipher.ProcessString(inString, length); + AttachedTransformation()->PutModifiable(inString, length); +} + +void StreamTransformationFilter::LastPut(const byte *inString, size_t length) +{ + byte *space = NULL; + + switch (m_padding) + { + case NO_PADDING: + case ZEROS_PADDING: + if (length > 0) + { + size_t minLastBlockSize = m_cipher.MinLastBlockSize(); + bool isForwardTransformation = m_cipher.IsForwardTransformation(); + + if (isForwardTransformation && m_padding == ZEROS_PADDING && (minLastBlockSize == 0 || length < minLastBlockSize)) + { + // do padding + size_t blockSize = STDMAX(minLastBlockSize, (size_t)m_cipher.MandatoryBlockSize()); + space = HelpCreatePutSpace(*AttachedTransformation(), NULL_CHANNEL, blockSize); + memcpy(space, inString, length); + memset(space + length, 0, blockSize - length); + m_cipher.ProcessLastBlock(space, space, blockSize); + AttachedTransformation()->Put(space, blockSize); + } + else + { + if (minLastBlockSize == 0) + { + if (isForwardTransformation) + throw InvalidDataFormat("StreamTransformationFilter: plaintext length is not a multiple of block size and NO_PADDING is specified"); + else + throw InvalidCiphertext("StreamTransformationFilter: ciphertext length is not a multiple of block size"); + } + + space = HelpCreatePutSpace(*AttachedTransformation(), NULL_CHANNEL, length, m_optimalBufferSize); + m_cipher.ProcessLastBlock(space, inString, length); + AttachedTransformation()->Put(space, length); + } + } + break; + + case PKCS_PADDING: + case ONE_AND_ZEROS_PADDING: + unsigned int s; + s = m_cipher.MandatoryBlockSize(); + assert(s > 1); + space = HelpCreatePutSpace(*AttachedTransformation(), NULL_CHANNEL, s, m_optimalBufferSize); + if (m_cipher.IsForwardTransformation()) + { + assert(length < s); + memcpy(space, inString, length); + if (m_padding == PKCS_PADDING) + { + assert(s < 256); + byte pad = byte(s-length); + memset(space+length, pad, s-length); + } + else + { + space[length] = 0x80; + memset(space+length+1, 0, s-length-1); + } + m_cipher.ProcessData(space, space, s); + AttachedTransformation()->Put(space, s); + } + else + { + if (length != s) + throw InvalidCiphertext("StreamTransformationFilter: ciphertext length is not a multiple of block size"); + m_cipher.ProcessData(space, inString, s); + if (m_padding == PKCS_PADDING) + { + byte pad = space[s-1]; + if (pad < 1 || pad > s || std::find_if(space+s-pad, space+s, std::bind2nd(std::not_equal_to(), pad)) != space+s) + throw InvalidCiphertext("StreamTransformationFilter: invalid PKCS #7 block padding found"); + length = s-pad; + } + else + { + while (length > 1 && space[length-1] == 0) + --length; + if (space[--length] != 0x80) + throw InvalidCiphertext("StreamTransformationFilter: invalid ones-and-zeros padding found"); + } + AttachedTransformation()->Put(space, length); + } + break; + + default: + assert(false); + } +} + +// ************************************************************* + +void HashFilter::IsolatedInitialize(const NameValuePairs ¶meters) +{ + m_putMessage = parameters.GetValueWithDefault(Name::PutMessage(), false); + m_truncatedDigestSize = parameters.GetIntValueWithDefault(Name::TruncatedDigestSize(), -1); + m_hashModule.Restart(); +} + +size_t HashFilter::Put2(const byte *inString, size_t length, int messageEnd, bool blocking) +{ + FILTER_BEGIN; + m_hashModule.Update(inString, length); + if (m_putMessage) + FILTER_OUTPUT(1, inString, length, 0); + if (messageEnd) + { + { + size_t size; + m_digestSize = m_hashModule.DigestSize(); + if (m_truncatedDigestSize >= 0 && (unsigned int)m_truncatedDigestSize < m_digestSize) + m_digestSize = m_truncatedDigestSize; + m_space = HelpCreatePutSpace(*AttachedTransformation(), NULL_CHANNEL, m_digestSize, m_digestSize, size = m_digestSize); + m_hashModule.TruncatedFinal(m_space, m_digestSize); + } + FILTER_OUTPUT(2, m_space, m_digestSize, messageEnd); + } + FILTER_END_NO_MESSAGE_END; +} + +// ************************************************************* + +HashVerificationFilter::HashVerificationFilter(HashTransformation &hm, BufferedTransformation *attachment, word32 flags) + : FilterWithBufferedInput(attachment) + , m_hashModule(hm) +{ + IsolatedInitialize(MakeParameters(Name::HashVerificationFilterFlags(), flags)); +} + +void HashVerificationFilter::InitializeDerivedAndReturnNewSizes(const NameValuePairs ¶meters, size_t &firstSize, size_t &blockSize, size_t &lastSize) +{ + m_flags = parameters.GetValueWithDefault(Name::HashVerificationFilterFlags(), (word32)DEFAULT_FLAGS); + m_hashModule.Restart(); + size_t size = m_hashModule.DigestSize(); + m_verified = false; + firstSize = m_flags & HASH_AT_BEGIN ? size : 0; + blockSize = 1; + lastSize = m_flags & HASH_AT_BEGIN ? 0 : size; +} + +void HashVerificationFilter::FirstPut(const byte *inString) +{ + if (m_flags & HASH_AT_BEGIN) + { + m_expectedHash.New(m_hashModule.DigestSize()); + memcpy(m_expectedHash, inString, m_expectedHash.size()); + if (m_flags & PUT_HASH) + AttachedTransformation()->Put(inString, m_expectedHash.size()); + } +} + +void HashVerificationFilter::NextPutMultiple(const byte *inString, size_t length) +{ + m_hashModule.Update(inString, length); + if (m_flags & PUT_MESSAGE) + AttachedTransformation()->Put(inString, length); +} + +void HashVerificationFilter::LastPut(const byte *inString, size_t length) +{ + if (m_flags & HASH_AT_BEGIN) + { + assert(length == 0); + m_verified = m_hashModule.Verify(m_expectedHash); + } + else + { + m_verified = (length==m_hashModule.DigestSize() && m_hashModule.Verify(inString)); + if (m_flags & PUT_HASH) + AttachedTransformation()->Put(inString, length); + } + + if (m_flags & PUT_RESULT) + AttachedTransformation()->Put(m_verified); + + if ((m_flags & THROW_EXCEPTION) && !m_verified) + throw HashVerificationFailed(); +} + +// ************************************************************* + +void SignerFilter::IsolatedInitialize(const NameValuePairs ¶meters) +{ + m_putMessage = parameters.GetValueWithDefault(Name::PutMessage(), false); + m_messageAccumulator.reset(m_signer.NewSignatureAccumulator(m_rng)); +} + +size_t SignerFilter::Put2(const byte *inString, size_t length, int messageEnd, bool blocking) +{ + FILTER_BEGIN; + m_messageAccumulator->Update(inString, length); + if (m_putMessage) + FILTER_OUTPUT(1, inString, length, 0); + if (messageEnd) + { + m_buf.New(m_signer.SignatureLength()); + m_signer.Sign(m_rng, m_messageAccumulator.release(), m_buf); + FILTER_OUTPUT(2, m_buf, m_buf.size(), messageEnd); + m_messageAccumulator.reset(m_signer.NewSignatureAccumulator(m_rng)); + } + FILTER_END_NO_MESSAGE_END; +} + +SignatureVerificationFilter::SignatureVerificationFilter(const PK_Verifier &verifier, BufferedTransformation *attachment, word32 flags) + : FilterWithBufferedInput(attachment) + , m_verifier(verifier) +{ + IsolatedInitialize(MakeParameters(Name::SignatureVerificationFilterFlags(), flags)); +} + +void SignatureVerificationFilter::InitializeDerivedAndReturnNewSizes(const NameValuePairs ¶meters, size_t &firstSize, size_t &blockSize, size_t &lastSize) +{ + m_flags = parameters.GetValueWithDefault(Name::SignatureVerificationFilterFlags(), (word32)DEFAULT_FLAGS); + m_messageAccumulator.reset(m_verifier.NewVerificationAccumulator()); + size_t size = m_verifier.SignatureLength(); + assert(size != 0); // TODO: handle recoverable signature scheme + m_verified = false; + firstSize = m_flags & SIGNATURE_AT_BEGIN ? size : 0; + blockSize = 1; + lastSize = m_flags & SIGNATURE_AT_BEGIN ? 0 : size; +} + +void SignatureVerificationFilter::FirstPut(const byte *inString) +{ + if (m_flags & SIGNATURE_AT_BEGIN) + { + if (m_verifier.SignatureUpfront()) + m_verifier.InputSignature(*m_messageAccumulator, inString, m_verifier.SignatureLength()); + else + { + m_signature.New(m_verifier.SignatureLength()); + memcpy(m_signature, inString, m_signature.size()); + } + + if (m_flags & PUT_SIGNATURE) + AttachedTransformation()->Put(inString, m_signature.size()); + } + else + { + assert(!m_verifier.SignatureUpfront()); + } +} + +void SignatureVerificationFilter::NextPutMultiple(const byte *inString, size_t length) +{ + m_messageAccumulator->Update(inString, length); + if (m_flags & PUT_MESSAGE) + AttachedTransformation()->Put(inString, length); +} + +void SignatureVerificationFilter::LastPut(const byte *inString, size_t length) +{ + if (m_flags & SIGNATURE_AT_BEGIN) + { + assert(length == 0); + m_verifier.InputSignature(*m_messageAccumulator, m_signature, m_signature.size()); + m_verified = m_verifier.VerifyAndRestart(*m_messageAccumulator); + } + else + { + m_verifier.InputSignature(*m_messageAccumulator, inString, length); + m_verified = m_verifier.VerifyAndRestart(*m_messageAccumulator); + if (m_flags & PUT_SIGNATURE) + AttachedTransformation()->Put(inString, length); + } + + if (m_flags & PUT_RESULT) + AttachedTransformation()->Put(m_verified); + + if ((m_flags & THROW_EXCEPTION) && !m_verified) + throw SignatureVerificationFailed(); +} + +// ************************************************************* + +size_t Source::PumpAll2(bool blocking) +{ + unsigned int messageCount = UINT_MAX; + do { + RETURN_IF_NONZERO(PumpMessages2(messageCount, blocking)); + } while(messageCount == UINT_MAX); + + return 0; +} + +bool Store::GetNextMessage() +{ + if (!m_messageEnd && !AnyRetrievable()) + { + m_messageEnd=true; + return true; + } + else + return false; +} + +unsigned int Store::CopyMessagesTo(BufferedTransformation &target, unsigned int count, const std::string &channel) const +{ + if (m_messageEnd || count == 0) + return 0; + else + { + CopyTo(target, ULONG_MAX, channel); + if (GetAutoSignalPropagation()) + target.ChannelMessageEnd(channel, GetAutoSignalPropagation()-1); + return 1; + } +} + +void StringStore::StoreInitialize(const NameValuePairs ¶meters) +{ + ConstByteArrayParameter array; + if (!parameters.GetValue(Name::InputBuffer(), array)) + throw InvalidArgument("StringStore: missing InputBuffer argument"); + m_store = array.begin(); + m_length = array.size(); + m_count = 0; +} + +size_t StringStore::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking) +{ + lword position = 0; + size_t blockedBytes = CopyRangeTo2(target, position, transferBytes, channel, blocking); + m_count += (size_t)position; + transferBytes = position; + return blockedBytes; +} + +size_t StringStore::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end, const std::string &channel, bool blocking) const +{ + size_t i = UnsignedMin(m_length, m_count+begin); + size_t len = UnsignedMin(m_length-i, end-begin); + size_t blockedBytes = target.ChannelPut2(channel, m_store+i, len, 0, blocking); + if (!blockedBytes) + begin += len; + return blockedBytes; +} + +void RandomNumberStore::StoreInitialize(const NameValuePairs ¶meters) +{ + parameters.GetRequiredParameter("RandomNumberStore", "RandomNumberGeneratorPointer", m_rng); + int length; + parameters.GetRequiredIntParameter("RandomNumberStore", "RandomNumberStoreSize", length); + m_length = length; +} + +size_t RandomNumberStore::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking) +{ + if (!blocking) + throw NotImplemented("RandomNumberStore: nonblocking transfer is not implemented by this object"); + + transferBytes = UnsignedMin(transferBytes, m_length - m_count); + m_rng->GenerateIntoBufferedTransformation(target, channel, transferBytes); + m_count += transferBytes; + + return 0; +} + +size_t NullStore::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end, const std::string &channel, bool blocking) const +{ + static const byte nullBytes[128] = {0}; + while (begin < end) + { + size_t len = (size_t)STDMIN(end-begin, lword(128)); + size_t blockedBytes = target.ChannelPut2(channel, nullBytes, len, 0, blocking); + if (blockedBytes) + return blockedBytes; + begin += len; + } + return 0; +} + +size_t NullStore::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking) +{ + lword begin = 0; + size_t blockedBytes = NullStore::CopyRangeTo2(target, begin, transferBytes, channel, blocking); + transferBytes = begin; + m_size -= begin; + return blockedBytes; +} + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/filters.h b/CryptoPP/crypto/filters.h new file mode 100644 index 0000000..a49fb8d --- /dev/null +++ b/CryptoPP/crypto/filters.h @@ -0,0 +1,761 @@ +#ifndef CRYPTOPP_FILTERS_H +#define CRYPTOPP_FILTERS_H + +#include "simple.h" +#include "secblock.h" +#include "misc.h" +#include "smartptr.h" +#include "queue.h" +#include "algparam.h" +#include + +NAMESPACE_BEGIN(CryptoPP) + +/// provides an implementation of BufferedTransformation's attachment interface +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Filter : public BufferedTransformation, public NotCopyable +{ +public: + Filter(BufferedTransformation *attachment = NULL); + + bool Attachable() {return true;} + BufferedTransformation *AttachedTransformation(); + const BufferedTransformation *AttachedTransformation() const; + void Detach(BufferedTransformation *newAttachment = NULL); + + size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=NULL_CHANNEL, bool blocking=true); + size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=NULL_CHANNEL, bool blocking=true) const; + + void Initialize(const NameValuePairs ¶meters=g_nullNameValuePairs, int propagation=-1); + bool Flush(bool hardFlush, int propagation=-1, bool blocking=true); + bool MessageSeriesEnd(int propagation=-1, bool blocking=true); + +protected: + virtual BufferedTransformation * NewDefaultAttachment() const; + void Insert(Filter *nextFilter); // insert filter after this one + + virtual bool ShouldPropagateMessageEnd() const {return true;} + virtual bool ShouldPropagateMessageSeriesEnd() const {return true;} + + void PropagateInitialize(const NameValuePairs ¶meters, int propagation); + + size_t Output(int outputSite, const byte *inString, size_t length, int messageEnd, bool blocking, const std::string &channel=NULL_CHANNEL); + size_t OutputModifiable(int outputSite, byte *inString, size_t length, int messageEnd, bool blocking, const std::string &channel=NULL_CHANNEL); + bool OutputMessageEnd(int outputSite, int propagation, bool blocking, const std::string &channel=NULL_CHANNEL); + bool OutputFlush(int outputSite, bool hardFlush, int propagation, bool blocking, const std::string &channel=NULL_CHANNEL); + bool OutputMessageSeriesEnd(int outputSite, int propagation, bool blocking, const std::string &channel=NULL_CHANNEL); + +private: + member_ptr m_attachment; + +protected: + size_t m_inputPosition; + int m_continueAt; +}; + +struct CRYPTOPP_DLL FilterPutSpaceHelper +{ + // desiredSize is how much to ask target, bufferSize is how much to allocate in m_tempSpace + byte *HelpCreatePutSpace(BufferedTransformation &target, const std::string &channel, size_t minSize, size_t desiredSize, size_t &bufferSize) + { + assert(desiredSize >= minSize && bufferSize >= minSize); + if (m_tempSpace.size() < minSize) + { + byte *result = target.ChannelCreatePutSpace(channel, desiredSize); + if (desiredSize >= minSize) + { + bufferSize = desiredSize; + return result; + } + m_tempSpace.New(bufferSize); + } + + bufferSize = m_tempSpace.size(); + return m_tempSpace.begin(); + } + byte *HelpCreatePutSpace(BufferedTransformation &target, const std::string &channel, size_t minSize) + {return HelpCreatePutSpace(target, channel, minSize, minSize, minSize);} + byte *HelpCreatePutSpace(BufferedTransformation &target, const std::string &channel, size_t minSize, size_t bufferSize) + {return HelpCreatePutSpace(target, channel, minSize, minSize, bufferSize);} + SecByteBlock m_tempSpace; +}; + +//! measure how many byte and messages pass through, also serves as valve +class CRYPTOPP_DLL MeterFilter : public Bufferless +{ +public: + MeterFilter(BufferedTransformation *attachment=NULL, bool transparent=true) + : m_transparent(transparent) {Detach(attachment); ResetMeter();} + + void SetTransparent(bool transparent) {m_transparent = transparent;} + void AddRangeToSkip(unsigned int message, lword position, lword size, bool sortNow = true); + void ResetMeter(); + void IsolatedInitialize(const NameValuePairs ¶meters) {ResetMeter();} + + lword GetCurrentMessageBytes() const {return m_currentMessageBytes;} + lword GetTotalBytes() {return m_totalBytes;} + unsigned int GetCurrentSeriesMessages() {return m_currentSeriesMessages;} + unsigned int GetTotalMessages() {return m_totalMessages;} + unsigned int GetTotalMessageSeries() {return m_totalMessageSeries;} + + byte * CreatePutSpace(size_t &size) + {return AttachedTransformation()->CreatePutSpace(size);} + size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking); + size_t PutModifiable2(byte *inString, size_t length, int messageEnd, bool blocking); + bool IsolatedMessageSeriesEnd(bool blocking); + +private: + size_t PutMaybeModifiable(byte *inString, size_t length, int messageEnd, bool blocking, bool modifiable); + bool ShouldPropagateMessageEnd() const {return m_transparent;} + bool ShouldPropagateMessageSeriesEnd() const {return m_transparent;} + + struct MessageRange + { + inline bool operator<(const MessageRange &b) const // BCB2006 workaround: this has to be a member function + {return message < b.message || (message == b.message && position < b.position);} + unsigned int message; lword position; lword size; + }; + + bool m_transparent; + lword m_currentMessageBytes, m_totalBytes; + unsigned int m_currentSeriesMessages, m_totalMessages, m_totalMessageSeries; + std::deque m_rangesToSkip; + byte *m_begin; + size_t m_length; +}; + +//! _ +class CRYPTOPP_DLL TransparentFilter : public MeterFilter +{ +public: + TransparentFilter(BufferedTransformation *attachment=NULL) : MeterFilter(attachment, true) {} +}; + +//! _ +class CRYPTOPP_DLL OpaqueFilter : public MeterFilter +{ +public: + OpaqueFilter(BufferedTransformation *attachment=NULL) : MeterFilter(attachment, false) {} +}; + +/*! FilterWithBufferedInput divides up the input stream into + a first block, a number of middle blocks, and a last block. + First and last blocks are optional, and middle blocks may + be a stream instead (i.e. blockSize == 1). +*/ +class CRYPTOPP_DLL FilterWithBufferedInput : public Filter +{ +public: + FilterWithBufferedInput(BufferedTransformation *attachment); + //! firstSize and lastSize may be 0, blockSize must be at least 1 + FilterWithBufferedInput(size_t firstSize, size_t blockSize, size_t lastSize, BufferedTransformation *attachment); + + void IsolatedInitialize(const NameValuePairs ¶meters); + size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking) + { + return PutMaybeModifiable(const_cast(inString), length, messageEnd, blocking, false); + } + size_t PutModifiable2(byte *inString, size_t length, int messageEnd, bool blocking) + { + return PutMaybeModifiable(inString, length, messageEnd, blocking, true); + } + /*! calls ForceNextPut() if hardFlush is true */ + bool IsolatedFlush(bool hardFlush, bool blocking); + + /*! The input buffer may contain more than blockSize bytes if lastSize != 0. + ForceNextPut() forces a call to NextPut() if this is the case. + */ + void ForceNextPut(); + +protected: + bool DidFirstPut() {return m_firstInputDone;} + + virtual void InitializeDerivedAndReturnNewSizes(const NameValuePairs ¶meters, size_t &firstSize, size_t &blockSize, size_t &lastSize) + {InitializeDerived(parameters);} + virtual void InitializeDerived(const NameValuePairs ¶meters) {} + // FirstPut() is called if (firstSize != 0 and totalLength >= firstSize) + // or (firstSize == 0 and (totalLength > 0 or a MessageEnd() is received)) + virtual void FirstPut(const byte *inString) =0; + // NextPut() is called if totalLength >= firstSize+blockSize+lastSize + virtual void NextPutSingle(const byte *inString) {assert(false);} + // Same as NextPut() except length can be a multiple of blockSize + // Either NextPut() or NextPutMultiple() must be overriden + virtual void NextPutMultiple(const byte *inString, size_t length); + // Same as NextPutMultiple(), but inString can be modified + virtual void NextPutModifiable(byte *inString, size_t length) + {NextPutMultiple(inString, length);} + // LastPut() is always called + // if totalLength < firstSize then length == totalLength + // else if totalLength <= firstSize+lastSize then length == totalLength-firstSize + // else lastSize <= length < lastSize+blockSize + virtual void LastPut(const byte *inString, size_t length) =0; + virtual void FlushDerived() {} + +private: + size_t PutMaybeModifiable(byte *begin, size_t length, int messageEnd, bool blocking, bool modifiable); + void NextPutMaybeModifiable(byte *inString, size_t length, bool modifiable) + { + if (modifiable) NextPutModifiable(inString, length); + else NextPutMultiple(inString, length); + } + + // This function should no longer be used, put this here to cause a compiler error + // if someone tries to override NextPut(). + virtual int NextPut(const byte *inString, size_t length) {assert(false); return 0;} + + class BlockQueue + { + public: + void ResetQueue(size_t blockSize, size_t maxBlocks); + byte *GetBlock(); + byte *GetContigousBlocks(size_t &numberOfBytes); + size_t GetAll(byte *outString); + void Put(const byte *inString, size_t length); + size_t CurrentSize() const {return m_size;} + size_t MaxSize() const {return m_buffer.size();} + + private: + SecByteBlock m_buffer; + size_t m_blockSize, m_maxBlocks, m_size; + byte *m_begin; + }; + + size_t m_firstSize, m_blockSize, m_lastSize; + bool m_firstInputDone; + BlockQueue m_queue; +}; + +//! _ +class CRYPTOPP_DLL FilterWithInputQueue : public Filter +{ +public: + FilterWithInputQueue(BufferedTransformation *attachment=NULL) : Filter(attachment) {} + + size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking) + { + if (!blocking) + throw BlockingInputOnly("FilterWithInputQueue"); + + m_inQueue.Put(inString, length); + if (messageEnd) + { + IsolatedMessageEnd(blocking); + Output(0, NULL, 0, messageEnd, blocking); + } + return 0; + } + +protected: + virtual bool IsolatedMessageEnd(bool blocking) =0; + void IsolatedInitialize(const NameValuePairs ¶meters) {m_inQueue.Clear();} + + ByteQueue m_inQueue; +}; + +//! Filter Wrapper for StreamTransformation +class CRYPTOPP_DLL StreamTransformationFilter : public FilterWithBufferedInput, private FilterPutSpaceHelper +{ +public: + enum BlockPaddingScheme {NO_PADDING, ZEROS_PADDING, PKCS_PADDING, ONE_AND_ZEROS_PADDING, DEFAULT_PADDING}; + /*! DEFAULT_PADDING means PKCS_PADDING if c.MandatoryBlockSize() > 1 && c.MinLastBlockSize() == 0 (e.g. ECB or CBC mode), + otherwise NO_PADDING (OFB, CFB, CTR, CBC-CTS modes) */ + StreamTransformationFilter(StreamTransformation &c, BufferedTransformation *attachment = NULL, BlockPaddingScheme padding = DEFAULT_PADDING); + + void FirstPut(const byte *inString); + void NextPutMultiple(const byte *inString, size_t length); + void NextPutModifiable(byte *inString, size_t length); + void LastPut(const byte *inString, size_t length); +// byte * CreatePutSpace(size_t &size); + +protected: + static size_t LastBlockSize(StreamTransformation &c, BlockPaddingScheme padding); + + StreamTransformation &m_cipher; + BlockPaddingScheme m_padding; + unsigned int m_optimalBufferSize; +}; + +#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY +typedef StreamTransformationFilter StreamCipherFilter; +#endif + +//! Filter Wrapper for HashTransformation +class CRYPTOPP_DLL HashFilter : public Bufferless, private FilterPutSpaceHelper +{ +public: + HashFilter(HashTransformation &hm, BufferedTransformation *attachment = NULL, bool putMessage=false, int truncatedDigestSize=-1) + : m_hashModule(hm), m_putMessage(putMessage), m_truncatedDigestSize(truncatedDigestSize) {Detach(attachment);} + + std::string AlgorithmName() const {return m_hashModule.AlgorithmName();} + + void IsolatedInitialize(const NameValuePairs ¶meters); + size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking); + + byte * CreatePutSpace(size_t &size) {return m_hashModule.CreateUpdateSpace(size);} + +private: + HashTransformation &m_hashModule; + bool m_putMessage; + int m_truncatedDigestSize; + byte *m_space; + unsigned int m_digestSize; +}; + +//! Filter Wrapper for HashTransformation +class CRYPTOPP_DLL HashVerificationFilter : public FilterWithBufferedInput +{ +public: + class HashVerificationFailed : public Exception + { + public: + HashVerificationFailed() + : Exception(DATA_INTEGRITY_CHECK_FAILED, "HashVerifier: message hash not valid") {} + }; + + enum Flags {HASH_AT_BEGIN=1, PUT_MESSAGE=2, PUT_HASH=4, PUT_RESULT=8, THROW_EXCEPTION=16, DEFAULT_FLAGS = HASH_AT_BEGIN | PUT_RESULT}; + HashVerificationFilter(HashTransformation &hm, BufferedTransformation *attachment = NULL, word32 flags = DEFAULT_FLAGS); + + std::string AlgorithmName() const {return m_hashModule.AlgorithmName();} + + bool GetLastResult() const {return m_verified;} + +protected: + void InitializeDerivedAndReturnNewSizes(const NameValuePairs ¶meters, size_t &firstSize, size_t &blockSize, size_t &lastSize); + void FirstPut(const byte *inString); + void NextPutMultiple(const byte *inString, size_t length); + void LastPut(const byte *inString, size_t length); + +private: + static inline unsigned int FirstSize(word32 flags, HashTransformation &hm) {return flags & HASH_AT_BEGIN ? hm.DigestSize() : 0;} + static inline unsigned int LastSize(word32 flags, HashTransformation &hm) {return flags & HASH_AT_BEGIN ? 0 : hm.DigestSize();} + + HashTransformation &m_hashModule; + word32 m_flags; + SecByteBlock m_expectedHash; + bool m_verified; +}; + +typedef HashVerificationFilter HashVerifier; // for backwards compatibility + +//! Filter Wrapper for PK_Signer +class CRYPTOPP_DLL SignerFilter : public Unflushable +{ +public: + SignerFilter(RandomNumberGenerator &rng, const PK_Signer &signer, BufferedTransformation *attachment = NULL, bool putMessage=false) + : m_rng(rng), m_signer(signer), m_messageAccumulator(signer.NewSignatureAccumulator(rng)), m_putMessage(putMessage) {Detach(attachment);} + + std::string AlgorithmName() const {return m_signer.AlgorithmName();} + + void IsolatedInitialize(const NameValuePairs ¶meters); + size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking); + +private: + RandomNumberGenerator &m_rng; + const PK_Signer &m_signer; + member_ptr m_messageAccumulator; + bool m_putMessage; + SecByteBlock m_buf; +}; + +//! Filter Wrapper for PK_Verifier +class CRYPTOPP_DLL SignatureVerificationFilter : public FilterWithBufferedInput +{ +public: + class SignatureVerificationFailed : public Exception + { + public: + SignatureVerificationFailed() + : Exception(DATA_INTEGRITY_CHECK_FAILED, "VerifierFilter: digital signature not valid") {} + }; + + enum Flags {SIGNATURE_AT_BEGIN=1, PUT_MESSAGE=2, PUT_SIGNATURE=4, PUT_RESULT=8, THROW_EXCEPTION=16, DEFAULT_FLAGS = SIGNATURE_AT_BEGIN | PUT_RESULT}; + SignatureVerificationFilter(const PK_Verifier &verifier, BufferedTransformation *attachment = NULL, word32 flags = DEFAULT_FLAGS); + + std::string AlgorithmName() const {return m_verifier.AlgorithmName();} + + bool GetLastResult() const {return m_verified;} + +protected: + void InitializeDerivedAndReturnNewSizes(const NameValuePairs ¶meters, size_t &firstSize, size_t &blockSize, size_t &lastSize); + void FirstPut(const byte *inString); + void NextPutMultiple(const byte *inString, size_t length); + void LastPut(const byte *inString, size_t length); + +private: + const PK_Verifier &m_verifier; + member_ptr m_messageAccumulator; + word32 m_flags; + SecByteBlock m_signature; + bool m_verified; +}; + +typedef SignatureVerificationFilter VerifierFilter; // for backwards compatibility + +//! Redirect input to another BufferedTransformation without owning it +class CRYPTOPP_DLL Redirector : public CustomSignalPropagation +{ +public: + enum Behavior + { + DATA_ONLY = 0x00, + PASS_SIGNALS = 0x01, + PASS_WAIT_OBJECTS = 0x02, + PASS_EVERYTHING = PASS_SIGNALS | PASS_WAIT_OBJECTS + }; + + Redirector() : m_target(NULL), m_behavior(PASS_EVERYTHING) {} + Redirector(BufferedTransformation &target, Behavior behavior=PASS_EVERYTHING) + : m_target(&target), m_behavior(behavior) {} + + void Redirect(BufferedTransformation &target) {m_target = ⌖} + void StopRedirection() {m_target = NULL;} + + Behavior GetBehavior() {return (Behavior) m_behavior;} + void SetBehavior(Behavior behavior) {m_behavior=behavior;} + bool GetPassSignals() const {return (m_behavior & PASS_SIGNALS) != 0;} + void SetPassSignals(bool pass) { if (pass) m_behavior |= PASS_SIGNALS; else m_behavior &= ~(word32) PASS_SIGNALS; } + bool GetPassWaitObjects() const {return (m_behavior & PASS_WAIT_OBJECTS) != 0;} + void SetPassWaitObjects(bool pass) { if (pass) m_behavior |= PASS_WAIT_OBJECTS; else m_behavior &= ~(word32) PASS_WAIT_OBJECTS; } + + bool CanModifyInput() const + {return m_target ? m_target->CanModifyInput() : false;} + + void Initialize(const NameValuePairs ¶meters, int propagation); + byte * CreatePutSpace(size_t &size) + {return m_target ? m_target->CreatePutSpace(size) : (byte *)(size=0, NULL);} + size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking) + {return m_target ? m_target->Put2(begin, length, GetPassSignals() ? messageEnd : 0, blocking) : 0;} + bool Flush(bool hardFlush, int propagation=-1, bool blocking=true) + {return m_target && GetPassSignals() ? m_target->Flush(hardFlush, propagation, blocking) : false;} + bool MessageSeriesEnd(int propagation=-1, bool blocking=true) + {return m_target && GetPassSignals() ? m_target->MessageSeriesEnd(propagation, blocking) : false;} + + byte * ChannelCreatePutSpace(const std::string &channel, size_t &size) + {return m_target ? m_target->ChannelCreatePutSpace(channel, size) : (byte *)(size=0, NULL);} + size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking) + {return m_target ? m_target->ChannelPut2(channel, begin, length, GetPassSignals() ? messageEnd : 0, blocking) : 0;} + size_t ChannelPutModifiable2(const std::string &channel, byte *begin, size_t length, int messageEnd, bool blocking) + {return m_target ? m_target->ChannelPutModifiable2(channel, begin, length, GetPassSignals() ? messageEnd : 0, blocking) : 0;} + bool ChannelFlush(const std::string &channel, bool completeFlush, int propagation=-1, bool blocking=true) + {return m_target && GetPassSignals() ? m_target->ChannelFlush(channel, completeFlush, propagation, blocking) : false;} + bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true) + {return m_target && GetPassSignals() ? m_target->ChannelMessageSeriesEnd(channel, propagation, blocking) : false;} + + unsigned int GetMaxWaitObjectCount() const + { return m_target && GetPassWaitObjects() ? m_target->GetMaxWaitObjectCount() : 0; } + void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack) + { if (m_target && GetPassWaitObjects()) m_target->GetWaitObjects(container, callStack); } + +private: + BufferedTransformation *m_target; + word32 m_behavior; +}; + +// Used By ProxyFilter +class CRYPTOPP_DLL OutputProxy : public CustomSignalPropagation +{ +public: + OutputProxy(BufferedTransformation &owner, bool passSignal) : m_owner(owner), m_passSignal(passSignal) {} + + bool GetPassSignal() const {return m_passSignal;} + void SetPassSignal(bool passSignal) {m_passSignal = passSignal;} + + byte * CreatePutSpace(size_t &size) + {return m_owner.AttachedTransformation()->CreatePutSpace(size);} + size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking) + {return m_owner.AttachedTransformation()->Put2(begin, length, m_passSignal ? messageEnd : 0, blocking);} + size_t PutModifiable2(byte *begin, size_t length, int messageEnd, bool blocking) + {return m_owner.AttachedTransformation()->PutModifiable2(begin, length, m_passSignal ? messageEnd : 0, blocking);} + void Initialize(const NameValuePairs ¶meters=g_nullNameValuePairs, int propagation=-1) + {if (m_passSignal) m_owner.AttachedTransformation()->Initialize(parameters, propagation);} + bool Flush(bool hardFlush, int propagation=-1, bool blocking=true) + {return m_passSignal ? m_owner.AttachedTransformation()->Flush(hardFlush, propagation, blocking) : false;} + bool MessageSeriesEnd(int propagation=-1, bool blocking=true) + {return m_passSignal ? m_owner.AttachedTransformation()->MessageSeriesEnd(propagation, blocking) : false;} + + size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking) + {return m_owner.AttachedTransformation()->ChannelPut2(channel, begin, length, m_passSignal ? messageEnd : 0, blocking);} + size_t ChannelPutModifiable2(const std::string &channel, byte *begin, size_t length, int messageEnd, bool blocking) + {return m_owner.AttachedTransformation()->ChannelPutModifiable2(channel, begin, length, m_passSignal ? messageEnd : 0, blocking);} + bool ChannelFlush(const std::string &channel, bool completeFlush, int propagation=-1, bool blocking=true) + {return m_passSignal ? m_owner.AttachedTransformation()->ChannelFlush(channel, completeFlush, propagation, blocking) : false;} + bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true) + {return m_passSignal ? m_owner.AttachedTransformation()->ChannelMessageSeriesEnd(channel, propagation, blocking) : false;} + +private: + BufferedTransformation &m_owner; + bool m_passSignal; +}; + +//! Base class for Filter classes that are proxies for a chain of other filters. +class CRYPTOPP_DLL ProxyFilter : public FilterWithBufferedInput +{ +public: + ProxyFilter(BufferedTransformation *filter, size_t firstSize, size_t lastSize, BufferedTransformation *attachment); + + bool IsolatedFlush(bool hardFlush, bool blocking); + + void SetFilter(Filter *filter); + void NextPutMultiple(const byte *s, size_t len); + void NextPutModifiable(byte *inString, size_t length); + +protected: + member_ptr m_filter; +}; + +//! simple proxy filter that doesn't modify the underlying filter's input or output +class CRYPTOPP_DLL SimpleProxyFilter : public ProxyFilter +{ +public: + SimpleProxyFilter(BufferedTransformation *filter, BufferedTransformation *attachment) + : ProxyFilter(filter, 0, 0, attachment) {} + + void FirstPut(const byte *) {} + void LastPut(const byte *, size_t) {m_filter->MessageEnd();} +}; + +//! proxy for the filter created by PK_Encryptor::CreateEncryptionFilter +/*! This class is here just to provide symmetry with VerifierFilter. */ +class CRYPTOPP_DLL PK_EncryptorFilter : public SimpleProxyFilter +{ +public: + PK_EncryptorFilter(RandomNumberGenerator &rng, const PK_Encryptor &encryptor, BufferedTransformation *attachment = NULL) + : SimpleProxyFilter(encryptor.CreateEncryptionFilter(rng), attachment) {} +}; + +//! proxy for the filter created by PK_Decryptor::CreateDecryptionFilter +/*! This class is here just to provide symmetry with SignerFilter. */ +class CRYPTOPP_DLL PK_DecryptorFilter : public SimpleProxyFilter +{ +public: + PK_DecryptorFilter(RandomNumberGenerator &rng, const PK_Decryptor &decryptor, BufferedTransformation *attachment = NULL) + : SimpleProxyFilter(decryptor.CreateDecryptionFilter(rng), attachment) {} +}; + +//! Append input to a string object +template +class StringSinkTemplate : public Bufferless +{ +public: + // VC60 workaround: no T::char_type + typedef typename T::traits_type::char_type char_type; + + StringSinkTemplate(T &output) + : m_output(&output) {assert(sizeof(output[0])==1);} + + void IsolatedInitialize(const NameValuePairs ¶meters) + {if (!parameters.GetValue("OutputStringPointer", m_output)) throw InvalidArgument("StringSink: OutputStringPointer not specified");} + + size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking) + { + if (length > 0) + { + typename T::size_type size = m_output->size(); + if (length < size && size + length > m_output->capacity()) + m_output->reserve(2*size); + m_output->append((const char_type *)begin, (const char_type *)begin+length); + } + return 0; + } + +private: + T *m_output; +}; + +//! Append input to an std::string +CRYPTOPP_DLL_TEMPLATE_CLASS StringSinkTemplate; +typedef StringSinkTemplate StringSink; + +//! incorporates input into RNG as additional entropy +class RandomNumberSink : public Bufferless +{ +public: + RandomNumberSink() + : m_rng(NULL) {} + + RandomNumberSink(RandomNumberGenerator &rng) + : m_rng(&rng) {} + + void IsolatedInitialize(const NameValuePairs ¶meters); + size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking); + +private: + RandomNumberGenerator *m_rng; +}; + +//! Copy input to a memory buffer +class CRYPTOPP_DLL ArraySink : public Bufferless +{ +public: + ArraySink(const NameValuePairs ¶meters = g_nullNameValuePairs) {IsolatedInitialize(parameters);} + ArraySink(byte *buf, size_t size) : m_buf(buf), m_size(size), m_total(0) {} + + size_t AvailableSize() {return SaturatingSubtract(m_size, m_total);} + lword TotalPutLength() {return m_total;} + + void IsolatedInitialize(const NameValuePairs ¶meters); + byte * CreatePutSpace(size_t &size); + size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking); + +protected: + byte *m_buf; + size_t m_size; + lword m_total; +}; + +//! Xor input to a memory buffer +class CRYPTOPP_DLL ArrayXorSink : public ArraySink +{ +public: + ArrayXorSink(byte *buf, size_t size) + : ArraySink(buf, size) {} + + size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking); + byte * CreatePutSpace(size_t &size) {return BufferedTransformation::CreatePutSpace(size);} +}; + +//! string-based implementation of Store interface +class StringStore : public Store +{ +public: + StringStore(const char *string = NULL) + {StoreInitialize(MakeParameters("InputBuffer", ConstByteArrayParameter(string)));} + StringStore(const byte *string, size_t length) + {StoreInitialize(MakeParameters("InputBuffer", ConstByteArrayParameter(string, length)));} + template StringStore(const T &string) + {StoreInitialize(MakeParameters("InputBuffer", ConstByteArrayParameter(string)));} + + CRYPTOPP_DLL size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=NULL_CHANNEL, bool blocking=true); + CRYPTOPP_DLL size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=NULL_CHANNEL, bool blocking=true) const; + +private: + CRYPTOPP_DLL void StoreInitialize(const NameValuePairs ¶meters); + + const byte *m_store; + size_t m_length, m_count; +}; + +//! RNG-based implementation of Source interface +class CRYPTOPP_DLL RandomNumberStore : public Store +{ +public: + RandomNumberStore() + : m_rng(NULL), m_length(0), m_count(0) {} + + RandomNumberStore(RandomNumberGenerator &rng, lword length) + : m_rng(&rng), m_length(length), m_count(0) {} + + bool AnyRetrievable() const {return MaxRetrievable() != 0;} + lword MaxRetrievable() const {return m_length-m_count;} + + size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=NULL_CHANNEL, bool blocking=true); + size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=NULL_CHANNEL, bool blocking=true) const + { + throw NotImplemented("RandomNumberStore: CopyRangeTo2() is not supported by this store"); + } + +private: + void StoreInitialize(const NameValuePairs ¶meters); + + RandomNumberGenerator *m_rng; + lword m_length, m_count; +}; + +//! empty store +class CRYPTOPP_DLL NullStore : public Store +{ +public: + NullStore(lword size = ULONG_MAX) : m_size(size) {} + void StoreInitialize(const NameValuePairs ¶meters) {} + lword MaxRetrievable() const {return m_size;} + size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=NULL_CHANNEL, bool blocking=true); + size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=NULL_CHANNEL, bool blocking=true) const; + +private: + lword m_size; +}; + +//! A Filter that pumps data into its attachment as input +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Source : public InputRejecting +{ +public: + Source(BufferedTransformation *attachment = NULL) + {Source::Detach(attachment);} + + lword Pump(lword pumpMax=size_t(0)-1) + {Pump2(pumpMax); return pumpMax;} + unsigned int PumpMessages(unsigned int count=UINT_MAX) + {PumpMessages2(count); return count;} + void PumpAll() + {PumpAll2();} + virtual size_t Pump2(lword &byteCount, bool blocking=true) =0; + virtual size_t PumpMessages2(unsigned int &messageCount, bool blocking=true) =0; + virtual size_t PumpAll2(bool blocking=true); + virtual bool SourceExhausted() const =0; + +protected: + void SourceInitialize(bool pumpAll, const NameValuePairs ¶meters) + { + IsolatedInitialize(parameters); + if (pumpAll) + PumpAll(); + } +}; + +//! Turn a Store into a Source +template +class SourceTemplate : public Source +{ +public: + SourceTemplate(BufferedTransformation *attachment) + : Source(attachment) {} + void IsolatedInitialize(const NameValuePairs ¶meters) + {m_store.IsolatedInitialize(parameters);} + size_t Pump2(lword &byteCount, bool blocking=true) + {return m_store.TransferTo2(*AttachedTransformation(), byteCount, NULL_CHANNEL, blocking);} + size_t PumpMessages2(unsigned int &messageCount, bool blocking=true) + {return m_store.TransferMessagesTo2(*AttachedTransformation(), messageCount, NULL_CHANNEL, blocking);} + size_t PumpAll2(bool blocking=true) + {return m_store.TransferAllTo2(*AttachedTransformation(), NULL_CHANNEL, blocking);} + bool SourceExhausted() const + {return !m_store.AnyRetrievable() && !m_store.AnyMessages();} + void SetAutoSignalPropagation(int propagation) + {m_store.SetAutoSignalPropagation(propagation);} + int GetAutoSignalPropagation() const + {return m_store.GetAutoSignalPropagation();} + +protected: + T m_store; +}; + +//! string-based implementation of Source interface +class CRYPTOPP_DLL StringSource : public SourceTemplate +{ +public: + StringSource(BufferedTransformation *attachment = NULL) + : SourceTemplate(attachment) {} + //! zero terminated string as source + StringSource(const char *string, bool pumpAll, BufferedTransformation *attachment = NULL) + : SourceTemplate(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(string)));} + //! binary byte array as source + StringSource(const byte *string, size_t length, bool pumpAll, BufferedTransformation *attachment = NULL) + : SourceTemplate(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(string, length)));} + //! std::string as source + StringSource(const std::string &string, bool pumpAll, BufferedTransformation *attachment = NULL) + : SourceTemplate(attachment) {SourceInitialize(pumpAll, MakeParameters("InputBuffer", ConstByteArrayParameter(string)));} +}; + +//! use the third constructor for an array source +typedef StringSource ArraySource; + +//! RNG-based implementation of Source interface +class CRYPTOPP_DLL RandomNumberSource : public SourceTemplate +{ +public: + RandomNumberSource(RandomNumberGenerator &rng, int length, bool pumpAll, BufferedTransformation *attachment = NULL) + : SourceTemplate(attachment) + {SourceInitialize(pumpAll, MakeParameters("RandomNumberGeneratorPointer", &rng)("RandomNumberStoreSize", length));} +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/fips140.cpp b/CryptoPP/crypto/fips140.cpp new file mode 100644 index 0000000..87b4911 --- /dev/null +++ b/CryptoPP/crypto/fips140.cpp @@ -0,0 +1,84 @@ +// fips140.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "fips140.h" +#include "trdlocal.h" // needs to be included last for cygwin + +NAMESPACE_BEGIN(CryptoPP) + +// Define this to 1 to turn on FIPS 140-2 compliance features, including additional tests during +// startup, random number generation, and key generation. These tests may affect performance. +#ifndef CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 +#define CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 0 +#endif + +#if (CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 && !defined(THREADS_AVAILABLE)) +#error FIPS 140-2 compliance requires the availability of thread local storage. +#endif + +#if (CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 && !defined(OS_RNG_AVAILABLE)) +#error FIPS 140-2 compliance requires the availability of OS provided RNG. +#endif + +PowerUpSelfTestStatus g_powerUpSelfTestStatus = POWER_UP_SELF_TEST_NOT_DONE; + +bool FIPS_140_2_ComplianceEnabled() +{ + return CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2; +} + +void SimulatePowerUpSelfTestFailure() +{ + g_powerUpSelfTestStatus = POWER_UP_SELF_TEST_FAILED; +} + +PowerUpSelfTestStatus CRYPTOPP_API GetPowerUpSelfTestStatus() +{ + return g_powerUpSelfTestStatus; +} + +#if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 +ThreadLocalStorage & AccessPowerUpSelfTestInProgress() +{ + static ThreadLocalStorage selfTestInProgress; + return selfTestInProgress; +} +#endif + +bool PowerUpSelfTestInProgressOnThisThread() +{ +#if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 + return AccessPowerUpSelfTestInProgress().GetValue() != NULL; +#else + assert(false); // should not be called + return false; +#endif +} + +void SetPowerUpSelfTestInProgressOnThisThread(bool inProgress) +{ +#if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 + AccessPowerUpSelfTestInProgress().SetValue((void *)inProgress); +#endif +} + +void EncryptionPairwiseConsistencyTest_FIPS_140_Only(const PK_Encryptor &encryptor, const PK_Decryptor &decryptor) +{ +#if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 + EncryptionPairwiseConsistencyTest(encryptor, decryptor); +#endif +} + +void SignaturePairwiseConsistencyTest_FIPS_140_Only(const PK_Signer &signer, const PK_Verifier &verifier) +{ +#if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 + SignaturePairwiseConsistencyTest(signer, verifier); +#endif +} + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/fips140.h b/CryptoPP/crypto/fips140.h new file mode 100644 index 0000000..b580fe4 --- /dev/null +++ b/CryptoPP/crypto/fips140.h @@ -0,0 +1,59 @@ +#ifndef CRYPTOPP_FIPS140_H +#define CRYPTOPP_FIPS140_H + +/*! \file + FIPS 140 related functions and classes. +*/ + +#include "cryptlib.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! exception thrown when a crypto algorithm is used after a self test fails +class CRYPTOPP_DLL SelfTestFailure : public Exception +{ +public: + explicit SelfTestFailure(const std::string &s) : Exception(OTHER_ERROR, s) {} +}; + +//! returns whether FIPS 140-2 compliance features were enabled at compile time +CRYPTOPP_DLL bool CRYPTOPP_API FIPS_140_2_ComplianceEnabled(); + +//! enum values representing status of the power-up self test +enum PowerUpSelfTestStatus {POWER_UP_SELF_TEST_NOT_DONE, POWER_UP_SELF_TEST_FAILED, POWER_UP_SELF_TEST_PASSED}; + +//! perform the power-up self test, and set the self test status +CRYPTOPP_DLL void CRYPTOPP_API DoPowerUpSelfTest(const char *moduleFilename, const byte *expectedModuleMac); + +//! perform the power-up self test using the filename of this DLL and the embedded module MAC +CRYPTOPP_DLL void CRYPTOPP_API DoDllPowerUpSelfTest(); + +//! set the power-up self test status to POWER_UP_SELF_TEST_FAILED +CRYPTOPP_DLL void CRYPTOPP_API SimulatePowerUpSelfTestFailure(); + +//! return the current power-up self test status +CRYPTOPP_DLL PowerUpSelfTestStatus CRYPTOPP_API GetPowerUpSelfTestStatus(); + +typedef PowerUpSelfTestStatus (CRYPTOPP_API * PGetPowerUpSelfTestStatus)(); + +CRYPTOPP_DLL MessageAuthenticationCode * CRYPTOPP_API NewIntegrityCheckingMAC(); + +CRYPTOPP_DLL bool CRYPTOPP_API IntegrityCheckModule(const char *moduleFilename, const byte *expectedModuleMac, SecByteBlock *pActualMac = NULL, unsigned long *pMacFileLocation = NULL); + +// this is used by Algorithm constructor to allow Algorithm objects to be constructed for the self test +bool PowerUpSelfTestInProgressOnThisThread(); + +void SetPowerUpSelfTestInProgressOnThisThread(bool inProgress); + +void SignaturePairwiseConsistencyTest(const PK_Signer &signer, const PK_Verifier &verifier); +void EncryptionPairwiseConsistencyTest(const PK_Encryptor &encryptor, const PK_Decryptor &decryptor); + +void SignaturePairwiseConsistencyTest_FIPS_140_Only(const PK_Signer &signer, const PK_Verifier &verifier); +void EncryptionPairwiseConsistencyTest_FIPS_140_Only(const PK_Encryptor &encryptor, const PK_Decryptor &decryptor); + +#define CRYPTOPP_DUMMY_DLL_MAC "MAC_51f34b8db820ae8" + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/fipsalgt.cpp b/CryptoPP/crypto/fipsalgt.cpp new file mode 100644 index 0000000..5f33537 --- /dev/null +++ b/CryptoPP/crypto/fipsalgt.cpp @@ -0,0 +1,1290 @@ +// fipsalgt.cpp - written and placed in the public domain by Wei Dai + +// This file implements the various algorithm tests needed to pass FIPS 140 validation. +// They're preserved here (commented out) in case Crypto++ needs to be revalidated. + +#if 0 +#ifndef CRYPTOPP_IMPORTS +#define CRYPTOPP_DEFAULT_NO_DLL +#endif +#include "dll.h" +#include "oids.h" + +USING_NAMESPACE(CryptoPP) +USING_NAMESPACE(std) + +class LineBreakParser : public AutoSignaling > +{ +public: + LineBreakParser(BufferedTransformation *attachment=NULL, byte lineEnd='\n') + : m_lineEnd(lineEnd) {Detach(attachment);} + + size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking) + { + if (!blocking) + throw BlockingInputOnly("LineBreakParser"); + + unsigned int i, last = 0; + for (i=0; iPut2(begin+last, i-last, GetAutoSignalPropagation(), blocking); + last = i+1; + } + } + if (last != i) + AttachedTransformation()->Put2(begin+last, i-last, 0, blocking); + + if (messageEnd && GetAutoSignalPropagation()) + { + AttachedTransformation()->MessageEnd(GetAutoSignalPropagation()-1, blocking); + AttachedTransformation()->MessageSeriesEnd(GetAutoSignalPropagation()-1, blocking); + } + + return 0; + } + +private: + byte m_lineEnd; +}; + +class TestDataParser : public Unflushable +{ +public: + enum DataType {OTHER, COUNT, KEY_T, IV, INPUT, OUTPUT}; + + TestDataParser(std::string algorithm, std::string test, std::string mode, unsigned int feedbackSize, bool encrypt, BufferedTransformation *attachment) + : m_algorithm(algorithm), m_test(test), m_mode(mode), m_feedbackSize(feedbackSize) + , m_firstLine(true), m_blankLineTransition(0) + { + Detach(attachment); + + m_typeToName[COUNT] = "COUNT"; + + m_nameToType["COUNT"] = COUNT; + m_nameToType["KEY"] = KEY_T; + m_nameToType["KEYs"] = KEY_T; + m_nameToType["key"] = KEY_T; + m_nameToType["Key"] = KEY_T; + m_nameToType["IV"] = IV; + m_nameToType["IV1"] = IV; + m_nameToType["CV"] = IV; + m_nameToType["CV1"] = IV; + m_nameToType["IB"] = IV; + m_nameToType["TEXT"] = INPUT; + m_nameToType["RESULT"] = OUTPUT; + m_nameToType["Msg"] = INPUT; + m_nameToType["Seed"] = INPUT; + m_nameToType["V"] = INPUT; + m_nameToType["DT"] = IV; + SetEncrypt(encrypt); + + if (m_algorithm == "DSA" || m_algorithm == "ECDSA") + { + if (m_test == "PKV") + m_trigger = "Qy"; + else if (m_test == "KeyPair") + m_trigger = "N"; + else if (m_test == "SigGen") + m_trigger = "Msg"; + else if (m_test == "SigVer") + m_trigger = "S"; + else if (m_test == "PQGGen") + m_trigger = "N"; + else if (m_test == "PQGVer") + m_trigger = "H"; + } + else if (m_algorithm == "HMAC") + m_trigger = "Msg"; + else if (m_algorithm == "SHA") + m_trigger = (m_test == "MONTE") ? "Seed" : "Msg"; + else if (m_algorithm == "RNG") + m_trigger = "V"; + else if (m_algorithm == "RSA") + m_trigger = (m_test == "Ver") ? "S" : "Msg"; + } + + void SetEncrypt(bool encrypt) + { + m_encrypt = encrypt; + if (encrypt) + { + m_nameToType["PLAINTEXT"] = INPUT; + m_nameToType["CIPHERTEXT"] = OUTPUT; + m_nameToType["PT"] = INPUT; + m_nameToType["CT"] = OUTPUT; + } + else + { + m_nameToType["PLAINTEXT"] = OUTPUT; + m_nameToType["CIPHERTEXT"] = INPUT; + m_nameToType["PT"] = OUTPUT; + m_nameToType["CT"] = INPUT; + } + + if (m_algorithm == "AES" || m_algorithm == "TDES") + { + if (encrypt) + { + m_trigger = "PLAINTEXT"; + m_typeToName[OUTPUT] = "CIPHERTEXT"; + } + else + { + m_trigger = "CIPHERTEXT"; + m_typeToName[OUTPUT] = "PLAINTEXT"; + } + m_count = 0; + } + } + +protected: + void OutputData(std::string &output, const std::string &key, const std::string &data) + { + output += key; + output += "= "; + output += data; + output += "\n"; + } + + void OutputData(std::string &output, const std::string &key, int data) + { + OutputData(output, key, IntToString(data)); + } + + void OutputData(std::string &output, const std::string &key, const SecByteBlock &data) + { + output += key; + output += "= "; + HexEncoder(new StringSink(output), false).Put(data, data.size()); + output += "\n"; + } + + void OutputData(std::string &output, const std::string &key, const Integer &data, int size=-1) + { + SecByteBlock s(size < 0 ? data.MinEncodedSize() : size); + data.Encode(s, s.size()); + OutputData(output, key, s); + } + + void OutputData(std::string &output, const std::string &key, const PolynomialMod2 &data, int size=-1) + { + SecByteBlock s(size < 0 ? data.MinEncodedSize() : size); + data.Encode(s, s.size()); + OutputData(output, key, s); + } + + void OutputData(std::string &output, DataType t, const std::string &data) + { + if (m_algorithm == "SKIPJACK") + { + if (m_test == "KAT") + { + if (t == OUTPUT) + output = m_line + data + "\n"; + } + else + { + if (t != COUNT) + { + output += m_typeToName[t]; + output += "="; + } + output += data; + output += t == OUTPUT ? "\n" : " "; + } + } + else if (m_algorithm == "TDES" && t == KEY_T && m_typeToName[KEY_T].empty()) + { + output += "KEY1 = "; + output += data.substr(0, 16); + output += "\nKEY2 = "; + output += data.size() > 16 ? data.substr(16, 16) : data.substr(0, 16); + output += "\nKEY3 = "; + output += data.size() > 32 ? data.substr(32, 16) : data.substr(0, 16); + output += "\n"; + } + else + { + output += m_typeToName[t]; + output += " = "; + output += data; + output += "\n"; + } + } + + void OutputData(std::string &output, DataType t, int i) + { + OutputData(output, t, IntToString(i)); + } + + void OutputData(std::string &output, DataType t, const SecByteBlock &data) + { + std::string hexData; + StringSource(data.begin(), data.size(), true, new HexEncoder(new StringSink(hexData), false)); + OutputData(output, t, hexData); + } + + void OutputGivenData(std::string &output, DataType t, bool optional = false) + { + if (m_data.find(m_typeToName[t]) == m_data.end()) + { + if (optional) + return; + throw Exception(Exception::OTHER_ERROR, "TestDataParser: key not found: " + m_typeToName[t]); + } + + OutputData(output, t, m_data[m_typeToName[t]]); + } + + template + BlockCipher * NewBT(T *) + { + if (!m_encrypt && (m_mode == "ECB" || m_mode == "CBC")) + return new typename T::Decryption; + else + return new typename T::Encryption; + } + + template + SymmetricCipher * NewMode(T *, BlockCipher &bt, const byte *iv) + { + if (!m_encrypt) + return new typename T::Decryption(bt, iv, m_feedbackSize/8); + else + return new typename T::Encryption(bt, iv, m_feedbackSize/8); + } + + static inline void Xor(SecByteBlock &z, const SecByteBlock &x, const SecByteBlock &y) + { + assert(x.size() == y.size()); + z.resize(x.size()); + xorbuf(z, x, y, x.size()); + } + + SecByteBlock UpdateKey(SecByteBlock key, const SecByteBlock *text) + { + unsigned int innerCount = (m_algorithm == "AES") ? 1000 : 10000; + int keySize = key.size(), blockSize = text[0].size(); + SecByteBlock x(keySize); + for (int k=0; k + void EC_KeyPair(string &output, int n, const OID &oid) + { + DL_GroupParameters_EC params(oid); + for (int i=0; i priv; + DL_PublicKey_EC pub; + priv.Initialize(m_rng, params); + priv.MakePublicKey(pub); + + OutputData(output, "d ", priv.GetPrivateExponent()); + OutputData(output, "Qx ", pub.GetPublicElement().x, params.GetCurve().GetField().MaxElementByteLength()); + OutputData(output, "Qy ", pub.GetPublicElement().y, params.GetCurve().GetField().MaxElementByteLength()); + } + } + + template + void EC_SigGen(string &output, const OID &oid) + { + DL_GroupParameters_EC params(oid); + typename ECDSA::PrivateKey priv; + typename ECDSA::PublicKey pub; + priv.Initialize(m_rng, params); + priv.MakePublicKey(pub); + + typename ECDSA::Signer signer(priv); + SecByteBlock sig(signer.SignatureLength()); + StringSource(m_data["Msg"], true, new HexDecoder(new SignerFilter(m_rng, signer, new ArraySink(sig, sig.size())))); + SecByteBlock R(sig, sig.size()/2), S(sig+sig.size()/2, sig.size()/2); + + OutputData(output, "Qx ", pub.GetPublicElement().x, params.GetCurve().GetField().MaxElementByteLength()); + OutputData(output, "Qy ", pub.GetPublicElement().y, params.GetCurve().GetField().MaxElementByteLength()); + OutputData(output, "R ", R); + OutputData(output, "S ", S); + } + + template + void EC_SigVer(string &output, const OID &oid) + { + SecByteBlock x(DecodeHex(m_data["Qx"])); + SecByteBlock y(DecodeHex(m_data["Qy"])); + Integer r((m_data["R"]+"h").c_str()); + Integer s((m_data["S"]+"h").c_str()); + + typename EC::FieldElement Qx(x, x.size()); + typename EC::FieldElement Qy(y, y.size()); + typename EC::Element Q(Qx, Qy); + + DL_GroupParameters_EC params(oid); + typename ECDSA::PublicKey pub; + pub.Initialize(params, Q); + typename ECDSA::Verifier verifier(pub); + + SecByteBlock sig(verifier.SignatureLength()); + r.Encode(sig, sig.size()/2); + s.Encode(sig+sig.size()/2, sig.size()/2); + + SignatureVerificationFilter filter(verifier); + filter.Put(sig, sig.size()); + StringSource(m_data["Msg"], true, new HexDecoder(new Redirector(filter, Redirector::DATA_ONLY))); + filter.MessageEnd(); + byte b; + filter.Get(b); + OutputData(output, "Result ", b ? "P" : "F"); + } + + template + static bool EC_PKV(RandomNumberGenerator &rng, const SecByteBlock &x, const SecByteBlock &y, const OID &oid) + { + typename EC::FieldElement Qx(x, x.size()); + typename EC::FieldElement Qy(y, y.size()); + typename EC::Element Q(Qx, Qy); + + DL_GroupParameters_EC params(oid); + typename ECDSA::PublicKey pub; + pub.Initialize(params, Q); + return pub.Validate(rng, 3); + } + + template + Result * CreateRSA2(const std::string &standard) + { + if (typeid(Result) == typeid(PK_Verifier)) + { + if (standard == "R") + return (Result *) new typename RSASS_ISO::Verifier; + else if (standard == "P") + return (Result *) new typename RSASS::Verifier; + else if (standard == "1") + return (Result *) new typename RSASS::Verifier; + } + else if (typeid(Result) == typeid(PK_Signer)) + { + if (standard == "R") + return (Result *) new typename RSASS_ISO::Signer; + else if (standard == "P") + return (Result *) new typename RSASS::Signer; + else if (standard == "1") + return (Result *) new typename RSASS::Signer; + } + + return NULL; + } + + template + Result * CreateRSA(const std::string &standard, const std::string &hash) + { + if (hash == "1") + return CreateRSA2(standard); + else if (hash == "224") + return CreateRSA2(standard); + else if (hash == "256") + return CreateRSA2(standard); + else if (hash == "384") + return CreateRSA2(standard); + else if (hash == "512") + return CreateRSA2(standard); + else + return NULL; + } + + virtual void DoTest() + { + std::string output; + + if (m_algorithm == "DSA") + { + if (m_test == "KeyPair") + { + DL_GroupParameters_DSA pqg; + int modLen = atol(m_bracketString.substr(6).c_str()); + pqg.GenerateRandomWithKeySize(m_rng, modLen); + + OutputData(output, "P ", pqg.GetModulus()); + OutputData(output, "Q ", pqg.GetSubgroupOrder()); + OutputData(output, "G ", pqg.GetSubgroupGenerator()); + + int n = atol(m_data["N"].c_str()); + for (int i=0; iPut((byte *)output.data(), output.size()); + output.resize(0); + } + } + else if (m_test == "PQGGen") + { + int n = atol(m_data["N"].c_str()); + for (int i=0; iPut((byte *)output.data(), output.size()); + output.resize(0); + } + } + else if (m_test == "SigGen") + { + std::string &encodedKey = m_data["PrivKey"]; + int modLen = atol(m_bracketString.substr(6).c_str()); + DSA::PrivateKey priv; + + if (!encodedKey.empty()) + { + StringStore s(encodedKey); + priv.BERDecode(s); + if (priv.GetGroupParameters().GetModulus().BitCount() != modLen) + encodedKey.clear(); + } + + if (encodedKey.empty()) + { + priv.Initialize(m_rng, modLen); + StringSink s(encodedKey); + priv.DEREncode(s); + OutputData(output, "P ", priv.GetGroupParameters().GetModulus()); + OutputData(output, "Q ", priv.GetGroupParameters().GetSubgroupOrder()); + OutputData(output, "G ", priv.GetGroupParameters().GetSubgroupGenerator()); + } + + DSA::Signer signer(priv); + DSA::Verifier pub(signer); + OutputData(output, "Msg ", m_data["Msg"]); + OutputData(output, "Y ", pub.GetKey().GetPublicElement()); + + SecByteBlock sig(signer.SignatureLength()); + StringSource(m_data["Msg"], true, new HexDecoder(new SignerFilter(m_rng, signer, new ArraySink(sig, sig.size())))); + SecByteBlock R(sig, sig.size()/2), S(sig+sig.size()/2, sig.size()/2); + OutputData(output, "R ", R); + OutputData(output, "S ", S); + AttachedTransformation()->Put((byte *)output.data(), output.size()); + output.resize(0); + } + else if (m_test == "SigVer") + { + Integer p((m_data["P"] + "h").c_str()); + Integer q((m_data["Q"] + "h").c_str()); + Integer g((m_data["G"] + "h").c_str()); + Integer y((m_data["Y"] + "h").c_str()); + DSA::Verifier verifier(p, q, g, y); + + HexDecoder filter(new SignatureVerificationFilter(verifier)); + StringSource(m_data["R"], true, new Redirector(filter, Redirector::DATA_ONLY)); + StringSource(m_data["S"], true, new Redirector(filter, Redirector::DATA_ONLY)); + StringSource(m_data["Msg"], true, new Redirector(filter, Redirector::DATA_ONLY)); + filter.MessageEnd(); + byte b; + filter.Get(b); + OutputData(output, "Result ", b ? "P" : "F"); + AttachedTransformation()->Put((byte *)output.data(), output.size()); + output.resize(0); + } + else if (m_test == "PQGVer") + { + Integer p((m_data["P"] + "h").c_str()); + Integer q((m_data["Q"] + "h").c_str()); + Integer g((m_data["G"] + "h").c_str()); + Integer h((m_data["H"] + "h").c_str()); + int c = atol(m_data["c"].c_str()); + SecByteBlock seed(m_data["Seed"].size()/2); + StringSource(m_data["Seed"], true, new HexDecoder(new ArraySink(seed, seed.size()))); + + Integer p1, q1; + bool result = DSA::GeneratePrimes(seed, seed.size()*8, c, p1, 1024, q1, true); + result = result && (p1 == p && q1 == q); + result = result && g == a_exp_b_mod_c(h, (p-1)/q, p); + + OutputData(output, "Result ", result ? "P" : "F"); + AttachedTransformation()->Put((byte *)output.data(), output.size()); + output.resize(0); + } + + return; + } + + if (m_algorithm == "ECDSA") + { + std::map name2oid; + name2oid["P-192"] = ASN1::secp192r1(); + name2oid["P-224"] = ASN1::secp224r1(); + name2oid["P-256"] = ASN1::secp256r1(); + name2oid["P-384"] = ASN1::secp384r1(); + name2oid["P-521"] = ASN1::secp521r1(); + name2oid["K-163"] = ASN1::sect163k1(); + name2oid["K-233"] = ASN1::sect233k1(); + name2oid["K-283"] = ASN1::sect283k1(); + name2oid["K-409"] = ASN1::sect409k1(); + name2oid["K-571"] = ASN1::sect571k1(); + name2oid["B-163"] = ASN1::sect163r2(); + name2oid["B-233"] = ASN1::sect233r1(); + name2oid["B-283"] = ASN1::sect283r1(); + name2oid["B-409"] = ASN1::sect409r1(); + name2oid["B-571"] = ASN1::sect571r1(); + + if (m_test == "PKV") + { + bool pass; + if (m_bracketString[0] == 'P') + pass = EC_PKV(m_rng, DecodeHex(m_data["Qx"]), DecodeHex(m_data["Qy"]), name2oid[m_bracketString]); + else + pass = EC_PKV(m_rng, DecodeHex(m_data["Qx"]), DecodeHex(m_data["Qy"]), name2oid[m_bracketString]); + + OutputData(output, "Result ", pass ? "P" : "F"); + } + else if (m_test == "KeyPair") + { + if (m_bracketString[0] == 'P') + EC_KeyPair(output, atol(m_data["N"].c_str()), name2oid[m_bracketString]); + else + EC_KeyPair(output, atol(m_data["N"].c_str()), name2oid[m_bracketString]); + } + else if (m_test == "SigGen") + { + if (m_bracketString[0] == 'P') + EC_SigGen(output, name2oid[m_bracketString]); + else + EC_SigGen(output, name2oid[m_bracketString]); + } + else if (m_test == "SigVer") + { + if (m_bracketString[0] == 'P') + EC_SigVer(output, name2oid[m_bracketString]); + else + EC_SigVer(output, name2oid[m_bracketString]); + } + + AttachedTransformation()->Put((byte *)output.data(), output.size()); + output.resize(0); + return; + } + + if (m_algorithm == "RSA") + { + std::string shaAlg = m_data["SHAAlg"].substr(3); + + if (m_test == "Ver") + { + Integer n((m_data["n"] + "h").c_str()); + Integer e((m_data["e"] + "h").c_str()); + RSA::PublicKey pub; + pub.Initialize(n, e); + + member_ptr pV(CreateRSA(m_mode, shaAlg)); + pV->AccessMaterial().AssignFrom(pub); + + HexDecoder filter(new SignatureVerificationFilter(*pV)); + for (unsigned int i=m_data["S"].size(); iSignatureLength()*2; i++) + filter.Put('0'); + StringSource(m_data["S"], true, new Redirector(filter, Redirector::DATA_ONLY)); + StringSource(m_data["Msg"], true, new Redirector(filter, Redirector::DATA_ONLY)); + filter.MessageEnd(); + byte b; + filter.Get(b); + OutputData(output, "Result ", b ? "P" : "F"); + } + else + { + assert(m_test == "Gen"); + int modLen = atol(m_bracketString.substr(6).c_str()); + std::string &encodedKey = m_data["PrivKey"]; + RSA::PrivateKey priv; + + if (!encodedKey.empty()) + { + StringStore s(encodedKey); + priv.BERDecode(s); + if (priv.GetModulus().BitCount() != modLen) + encodedKey.clear(); + } + + if (encodedKey.empty()) + { + priv.Initialize(m_rng, modLen); + StringSink s(encodedKey); + priv.DEREncode(s); + OutputData(output, "n ", priv.GetModulus()); + OutputData(output, "e ", priv.GetPublicExponent(), modLen/8); + } + + member_ptr pS(CreateRSA(m_mode, shaAlg)); + pS->AccessMaterial().AssignFrom(priv); + + SecByteBlock sig(pS->SignatureLength()); + StringSource(m_data["Msg"], true, new HexDecoder(new SignerFilter(m_rng, *pS, new ArraySink(sig, sig.size())))); + OutputData(output, "SHAAlg ", m_data["SHAAlg"]); + OutputData(output, "Msg ", m_data["Msg"]); + OutputData(output, "S ", sig); + } + + AttachedTransformation()->Put((byte *)output.data(), output.size()); + output.resize(0); + return; + } + + if (m_algorithm == "SHA") + { + member_ptr pHF; + + if (m_mode == "1") + pHF.reset(new SHA1); + else if (m_mode == "224") + pHF.reset(new SHA224); + else if (m_mode == "256") + pHF.reset(new SHA256); + else if (m_mode == "384") + pHF.reset(new SHA384); + else if (m_mode == "512") + pHF.reset(new SHA512); + + if (m_test == "MONTE") + { + SecByteBlock seed = m_data2[INPUT]; + SecByteBlock MD[1003]; + int i,j; + + for (j=0; j<100; j++) + { + MD[0] = MD[1] = MD[2] = seed; + for (i=3; i<1003; i++) + { + SecByteBlock Mi = MD[i-3] + MD[i-2] + MD[i-1]; + MD[i].resize(pHF->DigestSize()); + pHF->CalculateDigest(MD[i], Mi, Mi.size()); + } + seed = MD[1002]; + OutputData(output, "COUNT ", j); + OutputData(output, "MD ", seed); + AttachedTransformation()->Put((byte *)output.data(), output.size()); + output.resize(0); + } + } + else + { + SecByteBlock tag(pHF->DigestSize()); + SecByteBlock &msg(m_data2[INPUT]); + int len = atol(m_data["Len"].c_str()); + StringSource(msg.begin(), len/8, true, new HashFilter(*pHF, new ArraySink(tag, tag.size()))); + OutputData(output, "MD ", tag); + AttachedTransformation()->Put((byte *)output.data(), output.size()); + output.resize(0); + } + return; + } + + SecByteBlock &key = m_data2[KEY_T]; + + if (m_algorithm == "TDES") + { + if (!m_data["KEY1"].empty()) + { + const std::string keys[3] = {m_data["KEY1"], m_data["KEY2"], m_data["KEY3"]}; + key.resize(24); + HexDecoder hexDec(new ArraySink(key, key.size())); + for (int i=0; i<3; i++) + hexDec.Put((byte *)keys[i].data(), keys[i].size()); + + if (keys[0] == keys[2]) + { + if (keys[0] == keys[1]) + key.resize(8); + else + key.resize(16); + } + else + key.resize(24); + } + } + + if (m_algorithm == "RNG") + { + key.resize(24); + StringSource(m_data["Key1"] + m_data["Key2"] + m_data["Key3"], true, new HexDecoder(new ArraySink(key, key.size()))); + + SecByteBlock seed(m_data2[INPUT]), dt(m_data2[IV]), r(8); + X917RNG rng(new DES_EDE3::Encryption(key, key.size()), seed, dt); + + if (m_test == "MCT") + { + for (int i=0; i<10000; i++) + rng.GenerateBlock(r, r.size()); + } + else + { + rng.GenerateBlock(r, r.size()); + } + + OutputData(output, "R ", r); + AttachedTransformation()->Put((byte *)output.data(), output.size()); + output.resize(0); + return; + } + + if (m_algorithm == "HMAC") + { + member_ptr pMAC; + + if (m_bracketString == "L=20") + pMAC.reset(new HMAC); + else if (m_bracketString == "L=28") + pMAC.reset(new HMAC); + else if (m_bracketString == "L=32") + pMAC.reset(new HMAC); + else if (m_bracketString == "L=48") + pMAC.reset(new HMAC); + else if (m_bracketString == "L=64") + pMAC.reset(new HMAC); + else + throw Exception(Exception::OTHER_ERROR, "TestDataParser: unexpected HMAC bracket string: " + m_bracketString); + + pMAC->SetKey(key, key.size()); + int Tlen = atol(m_data["Tlen"].c_str()); + SecByteBlock tag(Tlen); + StringSource(m_data["Msg"], true, new HexDecoder(new HashFilter(*pMAC, new ArraySink(tag, Tlen), false, Tlen))); + OutputData(output, "Mac ", tag); + AttachedTransformation()->Put((byte *)output.data(), output.size()); + output.resize(0); + return; + } + + member_ptr pBT; + if (m_algorithm == "DES") + pBT.reset(NewBT((DES*)0)); + else if (m_algorithm == "TDES") + { + if (key.size() == 8) + pBT.reset(NewBT((DES*)0)); + else if (key.size() == 16) + pBT.reset(NewBT((DES_EDE2*)0)); + else + pBT.reset(NewBT((DES_EDE3*)0)); + } + else if (m_algorithm == "SKIPJACK") + pBT.reset(NewBT((SKIPJACK*)0)); + else if (m_algorithm == "AES") + pBT.reset(NewBT((AES*)0)); + else + throw Exception(Exception::OTHER_ERROR, "TestDataParser: unexpected algorithm: " + m_algorithm); + + if (!pBT->IsValidKeyLength(key.size())) + key.CleanNew(pBT->DefaultKeyLength()); // for Scbcvrct + pBT->SetKey(key.data(), key.size()); + + SecByteBlock &iv = m_data2[IV]; + if (iv.empty()) + iv.CleanNew(pBT->BlockSize()); + + member_ptr pCipher; + unsigned int K = m_feedbackSize; + + if (m_mode == "ECB") + pCipher.reset(NewMode((ECB_Mode_ExternalCipher*)0, *pBT, iv)); + else if (m_mode == "CBC") + pCipher.reset(NewMode((CBC_Mode_ExternalCipher*)0, *pBT, iv)); + else if (m_mode == "CFB") + pCipher.reset(NewMode((CFB_Mode_ExternalCipher*)0, *pBT, iv)); + else if (m_mode == "OFB") + pCipher.reset(NewMode((OFB_Mode_ExternalCipher*)0, *pBT, iv)); + else + throw Exception(Exception::OTHER_ERROR, "TestDataParser: unexpected mode: " + m_mode); + + bool encrypt = m_encrypt; + + if (m_test == "MONTE") + { + SecByteBlock KEY[401]; + KEY[0] = key; + int keySize = key.size(); + int blockSize = pBT->BlockSize(); + + std::vector IB(10001), OB(10001), PT(10001), CT(10001), RESULT(10001), TXT(10001), CV(10001); + PT[0] = GetData("PLAINTEXT"); + CT[0] = GetData("CIPHERTEXT"); + CV[0] = IB[0] = iv; + TXT[0] = GetData("TEXT"); + + int outerCount = (m_algorithm == "AES") ? 100 : 400; + int innerCount = (m_algorithm == "AES") ? 1000 : 10000; + + for (int i=0; iSetKey(KEY[i], keySize); + + for (int j=0; jProcessBlock(IB[j], CT[j]); + PT[j+1] = CT[j]; + } + else + { + IB[j] = CT[j]; + PT[j].resize(blockSize); + pBT->ProcessBlock(IB[j], PT[j]); + CT[j+1] = PT[j]; + } + } + else if (m_mode == "OFB") + { + OB[j].resize(blockSize); + pBT->ProcessBlock(IB[j], OB[j]); + Xor(RESULT[j], OB[j], TXT[j]); + TXT[j+1] = IB[j]; + IB[j+1] = OB[j]; + } + else if (m_mode == "CBC") + { + if (encrypt) + { + Xor(IB[j], PT[j], CV[j]); + CT[j].resize(blockSize); + pBT->ProcessBlock(IB[j], CT[j]); + PT[j+1] = CV[j]; + CV[j+1] = CT[j]; + } + else + { + IB[j] = CT[j]; + OB[j].resize(blockSize); + pBT->ProcessBlock(IB[j], OB[j]); + Xor(PT[j], OB[j], CV[j]); + CV[j+1] = CT[j]; + CT[j+1] = PT[j]; + } + } + else if (m_mode == "CFB") + { + if (encrypt) + { + OB[j].resize(blockSize); + pBT->ProcessBlock(IB[j], OB[j]); + AssignLeftMostBits(CT[j], OB[j], K); + Xor(CT[j], CT[j], PT[j]); + AssignLeftMostBits(PT[j+1], IB[j], K); + IB[j+1].resize(blockSize); + memcpy(IB[j+1], IB[j]+K/8, blockSize-K/8); + memcpy(IB[j+1]+blockSize-K/8, CT[j], K/8); + } + else + { + OB[j].resize(blockSize); + pBT->ProcessBlock(IB[j], OB[j]); + AssignLeftMostBits(PT[j], OB[j], K); + Xor(PT[j], PT[j], CT[j]); + IB[j+1].resize(blockSize); + memcpy(IB[j+1], IB[j]+K/8, blockSize-K/8); + memcpy(IB[j+1]+blockSize-K/8, CT[j], K/8); + AssignLeftMostBits(CT[j+1], OB[j], K); + } + } + else + throw Exception(Exception::OTHER_ERROR, "TestDataParser: unexpected mode: " + m_mode); + } + + OutputData(output, COUNT, IntToString(i)); + OutputData(output, KEY_T, KEY[i]); + if (m_mode == "CBC") + OutputData(output, IV, CV[0]); + if (m_mode == "OFB" || m_mode == "CFB") + OutputData(output, IV, IB[0]); + if (m_mode == "ECB" || m_mode == "CBC" || m_mode == "CFB") + { + if (encrypt) + { + OutputData(output, INPUT, PT[0]); + OutputData(output, OUTPUT, CT[innerCount-1]); + KEY[i+1] = UpdateKey(KEY[i], &CT[0]); + } + else + { + OutputData(output, INPUT, CT[0]); + OutputData(output, OUTPUT, PT[innerCount-1]); + KEY[i+1] = UpdateKey(KEY[i], &PT[0]); + } + PT[0] = PT[innerCount]; + IB[0] = IB[innerCount]; + CV[0] = CV[innerCount]; + CT[0] = CT[innerCount]; + } + else if (m_mode == "OFB") + { + OutputData(output, INPUT, TXT[0]); + OutputData(output, OUTPUT, RESULT[innerCount-1]); + KEY[i+1] = UpdateKey(KEY[i], &RESULT[0]); + Xor(TXT[0], TXT[0], IB[innerCount-1]); + IB[0] = OB[innerCount-1]; + } + output += "\n"; + AttachedTransformation()->Put((byte *)output.data(), output.size()); + output.resize(0); + } + } + else if (m_test == "MCT") + { + SecByteBlock KEY[101]; + KEY[0] = key; + int keySize = key.size(); + int blockSize = pBT->BlockSize(); + + SecByteBlock ivs[101], inputs[1001], outputs[1001]; + ivs[0] = iv; + inputs[0] = m_data2[INPUT]; + + for (int i=0; i<100; i++) + { + pCipher->SetKey(KEY[i], keySize, MakeParameters(Name::IV(), (const byte *)ivs[i])(Name::FeedbackSize(), (int)K/8, false)); + + for (int j=0; j<1000; j++) + { + outputs[j] = inputs[j]; + pCipher->ProcessString(outputs[j], outputs[j].size()); + if (K==8 && m_mode == "CFB") + { + if (j<16) + inputs[j+1].Assign(ivs[i]+j, 1); + else + inputs[j+1] = outputs[j-16]; + } + else if (m_mode == "ECB") + inputs[j+1] = outputs[j]; + else if (j == 0) + inputs[j+1] = ivs[i]; + else + inputs[j+1] = outputs[j-1]; + } + + if (m_algorithm == "AES") + OutputData(output, COUNT, m_count++); + OutputData(output, KEY_T, KEY[i]); + if (m_mode != "ECB") + OutputData(output, IV, ivs[i]); + OutputData(output, INPUT, inputs[0]); + OutputData(output, OUTPUT, outputs[999]); + output += "\n"; + AttachedTransformation()->Put((byte *)output.data(), output.size()); + output.resize(0); + + KEY[i+1] = UpdateKey(KEY[i], outputs); + ivs[i+1].CleanNew(pCipher->IVSize()); + ivs[i+1] = UpdateKey(ivs[i+1], outputs); + if (K==8 && m_mode == "CFB") + inputs[0] = outputs[999-16]; + else if (m_mode == "ECB") + inputs[0] = outputs[999]; + else + inputs[0] = outputs[998]; + } + } + else + { + assert(m_test == "KAT"); + + SecByteBlock &input = m_data2[INPUT]; + SecByteBlock result(input.size()); + member_ptr pFilter(new StreamTransformationFilter(*pCipher, new ArraySink(result, result.size()), StreamTransformationFilter::NO_PADDING)); + StringSource(input.data(), input.size(), true, pFilter.release()); + + OutputGivenData(output, COUNT, true); + OutputData(output, KEY_T, key); + OutputGivenData(output, IV, true); + OutputGivenData(output, INPUT); + OutputData(output, OUTPUT, result); + output += "\n"; + AttachedTransformation()->Put((byte *)output.data(), output.size()); + } + } + + std::vector Tokenize(const std::string &line) + { + std::vector result; + std::string s; + for (unsigned int i=0; i") + { + assert(m_test == "sha"); + m_bracketString = m_line.substr(2, m_line.size()-4); + m_line = m_line.substr(0, 13) + "Hashes") + copyLine = true; + + if (m_line == "Put((byte *)m_line.data(), m_line.size(), blocking); + return false; + } + + std::vector tokens = Tokenize(m_line); + + if (m_algorithm == "DSA" && m_test == "sha") + { + for (unsigned int i = 0; i < tokens.size(); i++) + { + if (tokens[i] == "^") + DoTest(); + else if (tokens[i] != "") + m_compactString.push_back(atol(tokens[i].c_str())); + } + } + else + { + if (!m_line.empty() && ((m_algorithm == "RSA" && m_test != "Gen") || m_algorithm == "RNG" || m_algorithm == "HMAC" || m_algorithm == "SHA" || (m_algorithm == "ECDSA" && m_test != "KeyPair") || (m_algorithm == "DSA" && (m_test == "PQGVer" || m_test == "SigVer")))) + { + // copy input to output + std::string output = m_line + '\n'; + AttachedTransformation()->Put((byte *)output.data(), output.size()); + } + + for (unsigned int i = 0; i < tokens.size(); i++) + { + if (m_firstLine && m_algorithm != "DSA") + { + if (tokens[i] == "Encrypt" || tokens[i] == "OFB") + SetEncrypt(true); + else if (tokens[i] == "Decrypt") + SetEncrypt(false); + else if (tokens[i] == "Modes") + m_test = "MONTE"; + } + else + { + if (tokens[i] != "=") + continue; + + if (i == 0) + throw Exception(Exception::OTHER_ERROR, "TestDataParser: unexpected data: " + m_line); + + const std::string &key = tokens[i-1]; + std::string &data = m_data[key]; + data = (tokens.size() > i+1) ? tokens[i+1] : ""; + DataType t = m_nameToType[key]; + m_typeToName[t] = key; + m_data2[t] = DecodeHex(data); + + if (key == m_trigger || (t == OUTPUT && !m_data2[INPUT].empty() && !isspace(m_line[0]))) + DoTest(); + } + } + } + + m_firstLine = false; + + return false; + } + + inline const SecByteBlock & GetData(const std::string &key) + { + return m_data2[m_nameToType[key]]; + } + + static SecByteBlock DecodeHex(const std::string &data) + { + SecByteBlock data2(data.size() / 2); + StringSource(data, true, new HexDecoder(new ArraySink(data2, data2.size()))); + return data2; + } + + std::string m_algorithm, m_test, m_mode, m_line, m_bracketString, m_trigger; + unsigned int m_feedbackSize, m_blankLineTransition; + bool m_encrypt, m_firstLine; + + typedef std::map NameToTypeMap; + NameToTypeMap m_nameToType; + typedef std::map TypeToNameMap; + TypeToNameMap m_typeToName; + + typedef std::map Map; + Map m_data; // raw data + typedef std::map Map2; + Map2 m_data2; + int m_count; + + AutoSeededX917RNG m_rng; + std::vector m_compactString; +}; + +int FIPS_140_AlgorithmTest(int argc, char **argv) +{ + argc--; + argv++; + + std::string algorithm = argv[1]; + std::string pathname = argv[2]; + unsigned int i = pathname.find_last_of("\\/"); + std::string filename = pathname.substr(i == std::string::npos ? 0 : i+1); + std::string dirname = pathname.substr(0, i); + + if (algorithm == "auto") + { + string algTable[] = {"AES", "ECDSA", "DSA", "HMAC", "RNG", "RSA", "TDES", "SKIPJACK", "SHA"}; // order is important here + for (i=0; i 3) + { + std::string outDir = argv[3]; + + if (outDir == "auto") + { + if (dirname.substr(dirname.size()-3) == "req") + outDir = dirname.substr(0, dirname.size()-3) + "resp"; + } + + if (*outDir.rbegin() != '\\' && *outDir.rbegin() != '/') + outDir += '/'; + std::string outPathname = outDir + filename.substr(0, filename.size() - 3) + "rsp"; + pSink = new FileSink(outPathname.c_str(), false); + } + else + pSink = new FileSink(cout); + + FileSource(pathname.c_str(), true, new LineBreakParser(new TestDataParser(algorithm, test, mode, feedbackSize, encrypt, pSink)), false); + } + catch (...) + { + cout << "file: " << filename << endl; + throw; + } + return 0; +} + +extern int (*AdhocTest)(int argc, char *argv[]); +static int s_i = (AdhocTest = &FIPS_140_AlgorithmTest, 0); +#endif diff --git a/CryptoPP/crypto/fipstest.cpp b/CryptoPP/crypto/fipstest.cpp new file mode 100644 index 0000000..f1a8b8e --- /dev/null +++ b/CryptoPP/crypto/fipstest.cpp @@ -0,0 +1,616 @@ +// fipstest.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#define CRYPTOPP_DEFAULT_NO_DLL +#include "dll.h" + +#ifdef CRYPTOPP_WIN32_AVAILABLE +#define _WIN32_WINNT 0x0400 +#include + +#if defined(_MSC_VER) && _MSC_VER >= 1400 +#ifdef _M_IX86 +#define _CRT_DEBUGGER_HOOK _crt_debugger_hook +#else +#define _CRT_DEBUGGER_HOOK __crt_debugger_hook +#endif +extern "C" {_CRTIMP void __cdecl _CRT_DEBUGGER_HOOK(int);} +#endif +#endif + +#include + +NAMESPACE_BEGIN(CryptoPP) + +extern PowerUpSelfTestStatus g_powerUpSelfTestStatus; +SecByteBlock g_actualMac; +unsigned long g_macFileLocation = 0; + +// use a random dummy string here, to be searched/replaced later with the real MAC +static const byte s_moduleMac[CryptoPP::HMAC::DIGESTSIZE] = CRYPTOPP_DUMMY_DLL_MAC; +CRYPTOPP_COMPILE_ASSERT(sizeof(s_moduleMac) == CryptoPP::SHA1::DIGESTSIZE); + +#ifdef CRYPTOPP_WIN32_AVAILABLE +static HMODULE s_hModule = NULL; +#endif + +const byte * CRYPTOPP_API GetActualMacAndLocation(unsigned int &macSize, unsigned int &fileLocation) +{ + macSize = (unsigned int)g_actualMac.size(); + fileLocation = g_macFileLocation; + return g_actualMac; +} + +void KnownAnswerTest(RandomNumberGenerator &rng, const char *output) +{ + EqualityComparisonFilter comparison; + + RandomNumberStore(rng, strlen(output)/2).TransferAllTo(comparison, "0"); + StringSource(output, true, new HexDecoder(new ChannelSwitch(comparison, "1"))); + + comparison.ChannelMessageSeriesEnd("0"); + comparison.ChannelMessageSeriesEnd("1"); +} + +template +void X917RNG_KnownAnswerTest( + const char *key, + const char *seed, + const char *deterministicTimeVector, + const char *output, + CIPHER *dummy = NULL) +{ +#ifdef OS_RNG_AVAILABLE + std::string decodedKey, decodedSeed, decodedDeterministicTimeVector; + StringSource(key, true, new HexDecoder(new StringSink(decodedKey))); + StringSource(seed, true, new HexDecoder(new StringSink(decodedSeed))); + StringSource(deterministicTimeVector, true, new HexDecoder(new StringSink(decodedDeterministicTimeVector))); + + AutoSeededX917RNG rng; + rng.Reseed((const byte *)decodedKey.data(), decodedKey.size(), (const byte *)decodedSeed.data(), (const byte *)decodedDeterministicTimeVector.data()); + KnownAnswerTest(rng, output); +#else + throw 0; +#endif +} + +void KnownAnswerTest(StreamTransformation &encryption, StreamTransformation &decryption, const char *plaintext, const char *ciphertext) +{ + EqualityComparisonFilter comparison; + + StringSource(plaintext, true, new HexDecoder(new StreamTransformationFilter(encryption, new ChannelSwitch(comparison, "0"), StreamTransformationFilter::NO_PADDING))); + StringSource(ciphertext, true, new HexDecoder(new ChannelSwitch(comparison, "1"))); + + StringSource(ciphertext, true, new HexDecoder(new StreamTransformationFilter(decryption, new ChannelSwitch(comparison, "0"), StreamTransformationFilter::NO_PADDING))); + StringSource(plaintext, true, new HexDecoder(new ChannelSwitch(comparison, "1"))); + + comparison.ChannelMessageSeriesEnd("0"); + comparison.ChannelMessageSeriesEnd("1"); +} + +template +void SymmetricEncryptionKnownAnswerTest( + const char *key, + const char *hexIV, + const char *plaintext, + const char *ecb, + const char *cbc, + const char *cfb, + const char *ofb, + const char *ctr, + CIPHER *dummy = NULL) +{ + std::string decodedKey; + StringSource(key, true, new HexDecoder(new StringSink(decodedKey))); + + typename CIPHER::Encryption encryption((const byte *)decodedKey.data(), decodedKey.size()); + typename CIPHER::Decryption decryption((const byte *)decodedKey.data(), decodedKey.size()); + + SecByteBlock iv(encryption.BlockSize()); + StringSource(hexIV, true, new HexDecoder(new ArraySink(iv, iv.size()))); + + if (ecb) + KnownAnswerTest(ECB_Mode_ExternalCipher::Encryption(encryption).Ref(), ECB_Mode_ExternalCipher::Decryption(decryption).Ref(), plaintext, ecb); + if (cbc) + KnownAnswerTest(CBC_Mode_ExternalCipher::Encryption(encryption, iv).Ref(), CBC_Mode_ExternalCipher::Decryption(decryption, iv).Ref(), plaintext, cbc); + if (cfb) + KnownAnswerTest(CFB_Mode_ExternalCipher::Encryption(encryption, iv).Ref(), CFB_Mode_ExternalCipher::Decryption(encryption, iv).Ref(), plaintext, cfb); + if (ofb) + KnownAnswerTest(OFB_Mode_ExternalCipher::Encryption(encryption, iv).Ref(), OFB_Mode_ExternalCipher::Decryption(encryption, iv).Ref(), plaintext, ofb); + if (ctr) + KnownAnswerTest(CTR_Mode_ExternalCipher::Encryption(encryption, iv).Ref(), CTR_Mode_ExternalCipher::Decryption(encryption, iv).Ref(), plaintext, ctr); +} + +void KnownAnswerTest(HashTransformation &hash, const char *message, const char *digest) +{ + EqualityComparisonFilter comparison; + StringSource(digest, true, new HexDecoder(new ChannelSwitch(comparison, "1"))); + StringSource(message, true, new HashFilter(hash, new ChannelSwitch(comparison, "0"))); + + comparison.ChannelMessageSeriesEnd("0"); + comparison.ChannelMessageSeriesEnd("1"); +} + +template +void SecureHashKnownAnswerTest(const char *message, const char *digest, HASH *dummy = NULL) +{ + HASH hash; + KnownAnswerTest(hash, message, digest); +} + +template +void MAC_KnownAnswerTest(const char *key, const char *message, const char *digest, MAC *dummy = NULL) +{ + std::string decodedKey; + StringSource(key, true, new HexDecoder(new StringSink(decodedKey))); + + MAC mac((const byte *)decodedKey.data(), decodedKey.size()); + KnownAnswerTest(mac, message, digest); +} + +template +void SignatureKnownAnswerTest(const char *key, const char *message, const char *signature, SCHEME *dummy = NULL) +{ +#ifdef OS_RNG_AVAILABLE + DefaultAutoSeededRNG rng; +#else + RandomNumberGenerator &rng = NullRNG(); +#endif + + typename SCHEME::Signer signer(StringSource(key, true, new HexDecoder).Ref()); + typename SCHEME::Verifier verifier(signer); + + EqualityComparisonFilter comparison; + + StringSource(message, true, new SignerFilter(rng, signer, new ChannelSwitch(comparison, "0"))); + StringSource(signature, true, new HexDecoder(new ChannelSwitch(comparison, "1"))); + + comparison.ChannelMessageSeriesEnd("0"); + comparison.ChannelMessageSeriesEnd("1"); + + VerifierFilter verifierFilter(verifier, NULL, VerifierFilter::SIGNATURE_AT_BEGIN | VerifierFilter::THROW_EXCEPTION); + StringSource(signature, true, new HexDecoder(new Redirector(verifierFilter, Redirector::DATA_ONLY))); + StringSource(message, true, new Redirector(verifierFilter)); +} + +void EncryptionPairwiseConsistencyTest(const PK_Encryptor &encryptor, const PK_Decryptor &decryptor) +{ + try + { +#ifdef OS_RNG_AVAILABLE + DefaultAutoSeededRNG rng; +#else + RandomNumberGenerator &rng = NullRNG(); +#endif + const char *testMessage ="test message"; + std::string ciphertext, decrypted; + + StringSource( + testMessage, + true, + new PK_EncryptorFilter( + rng, + encryptor, + new StringSink(ciphertext))); + + if (ciphertext == testMessage) + throw 0; + + StringSource( + ciphertext, + true, + new PK_DecryptorFilter( + rng, + decryptor, + new StringSink(decrypted))); + + if (decrypted != testMessage) + throw 0; + } + catch (...) + { + throw SelfTestFailure(encryptor.AlgorithmName() + ": pairwise consistency test failed"); + } +} + +void SignaturePairwiseConsistencyTest(const PK_Signer &signer, const PK_Verifier &verifier) +{ + try + { +#ifdef OS_RNG_AVAILABLE + DefaultAutoSeededRNG rng; +#else + RandomNumberGenerator &rng = NullRNG(); +#endif + + StringSource( + "test message", + true, + new SignerFilter( + rng, + signer, + new VerifierFilter(verifier, NULL, VerifierFilter::THROW_EXCEPTION), + true)); + } + catch (...) + { + throw SelfTestFailure(signer.AlgorithmName() + ": pairwise consistency test failed"); + } +} + +template +void SignaturePairwiseConsistencyTest(const char *key, SCHEME *dummy = NULL) +{ + typename SCHEME::Signer signer(StringSource(key, true, new HexDecoder).Ref()); + typename SCHEME::Verifier verifier(signer); + + SignaturePairwiseConsistencyTest(signer, verifier); +} + +MessageAuthenticationCode * NewIntegrityCheckingMAC() +{ + byte key[] = {0x47, 0x1E, 0x33, 0x96, 0x65, 0xB1, 0x6A, 0xED, 0x0B, 0xF8, 0x6B, 0xFD, 0x01, 0x65, 0x05, 0xCC}; + return new HMAC(key, sizeof(key)); +} + +bool IntegrityCheckModule(const char *moduleFilename, const byte *expectedModuleMac, SecByteBlock *pActualMac, unsigned long *pMacFileLocation) +{ + std::auto_ptr mac(NewIntegrityCheckingMAC()); + unsigned int macSize = mac->DigestSize(); + + SecByteBlock tempMac; + SecByteBlock &actualMac = pActualMac ? *pActualMac : tempMac; + actualMac.resize(macSize); + + unsigned long tempLocation; + unsigned long &macFileLocation = pMacFileLocation ? *pMacFileLocation : tempLocation; + macFileLocation = 0; + + MeterFilter verifier(new HashFilter(*mac, new ArraySink(actualMac, actualMac.size()))); +// MeterFilter verifier(new FileSink("c:\\dt.tmp")); + std::ifstream moduleStream; + +#ifdef CRYPTOPP_WIN32_AVAILABLE + HMODULE h; + { + char moduleFilenameBuf[MAX_PATH] = ""; + if (moduleFilename == NULL) + { +#if (_MSC_VER >= 1400 && !defined(_STLPORT_VERSION)) // ifstream doesn't support wide filename on other compilers + wchar_t wideModuleFilename[MAX_PATH]; + if (GetModuleFileNameW(s_hModule, wideModuleFilename, MAX_PATH) > 0) + { + moduleStream.open(wideModuleFilename, std::ios::in | std::ios::binary); + h = GetModuleHandleW(wideModuleFilename); + } + else +#endif + { + GetModuleFileNameA(s_hModule, moduleFilenameBuf, MAX_PATH); + moduleFilename = moduleFilenameBuf; + } + } +#endif + if (moduleFilename != NULL) + { + moduleStream.open(moduleFilename, std::ios::in | std::ios::binary); +#ifdef CRYPTOPP_WIN32_AVAILABLE + h = GetModuleHandleA(moduleFilename); + moduleFilename = NULL; + } +#endif + } + + if (!moduleStream) + { +#ifdef CRYPTOPP_WIN32_AVAILABLE + OutputDebugString("Crypto++ DLL integrity check failed. Cannot open file for reading."); +#endif + return false; + } + FileStore file(moduleStream); + +#ifdef CRYPTOPP_WIN32_AVAILABLE + // try to hash from memory first + const byte *memBase = (const byte *)h; + const IMAGE_DOS_HEADER *ph = (IMAGE_DOS_HEADER *)memBase; + const IMAGE_NT_HEADERS *phnt = (IMAGE_NT_HEADERS *)(memBase + ph->e_lfanew); + const IMAGE_SECTION_HEADER *phs = IMAGE_FIRST_SECTION(phnt); + DWORD nSections = phnt->FileHeader.NumberOfSections; + size_t currentFilePos = 0; + + size_t checksumPos = (byte *)&phnt->OptionalHeader.CheckSum - memBase; + size_t checksumSize = sizeof(phnt->OptionalHeader.CheckSum); + size_t certificateTableDirectoryPos = (byte *)&phnt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY] - memBase; + size_t certificateTableDirectorySize = sizeof(phnt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY]); + size_t certificateTablePos = phnt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress; + size_t certificateTableSize = phnt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].Size; + + verifier.AddRangeToSkip(0, checksumPos, checksumSize); + verifier.AddRangeToSkip(0, certificateTableDirectoryPos, certificateTableDirectorySize); + verifier.AddRangeToSkip(0, certificateTablePos, certificateTableSize); + + while (nSections--) + { + switch (phs->Characteristics) + { + default: + break; + case IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ: + case IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ: + unsigned int sectionSize = STDMIN(phs->SizeOfRawData, phs->Misc.VirtualSize); + const byte *sectionMemStart = memBase + phs->VirtualAddress; + unsigned int sectionFileStart = phs->PointerToRawData; + size_t subSectionStart = 0, nextSubSectionStart; + + do + { + const byte *subSectionMemStart = sectionMemStart + subSectionStart; + size_t subSectionFileStart = sectionFileStart + subSectionStart; + size_t subSectionSize = sectionSize - subSectionStart; + nextSubSectionStart = 0; + + unsigned int entriesToReadFromDisk[] = {IMAGE_DIRECTORY_ENTRY_IMPORT, IMAGE_DIRECTORY_ENTRY_IAT}; + for (unsigned int i=0; iOptionalHeader.DataDirectory[entriesToReadFromDisk[i]]; + const byte *entryMemStart = memBase + entry.VirtualAddress; + if (subSectionMemStart <= entryMemStart && entryMemStart < subSectionMemStart + subSectionSize) + { + subSectionSize = entryMemStart - subSectionMemStart; + nextSubSectionStart = entryMemStart - sectionMemStart + entry.Size; + } + } + +#if defined(_MSC_VER) && _MSC_VER >= 1400 + // first byte of _CRT_DEBUGGER_HOOK gets modified in memory by the debugger invisibly, so read it from file + if (IsDebuggerPresent()) + { + if (subSectionMemStart <= (byte *)&_CRT_DEBUGGER_HOOK && (byte *)&_CRT_DEBUGGER_HOOK < subSectionMemStart + subSectionSize) + { + subSectionSize = (byte *)&_CRT_DEBUGGER_HOOK - subSectionMemStart; + nextSubSectionStart = (byte *)&_CRT_DEBUGGER_HOOK - sectionMemStart + 1; + } + } +#endif + + if (subSectionMemStart <= expectedModuleMac && expectedModuleMac < subSectionMemStart + subSectionSize) + { + // found stored MAC + macFileLocation = (unsigned long)(subSectionFileStart + (expectedModuleMac - subSectionMemStart)); + verifier.AddRangeToSkip(0, macFileLocation, macSize); + } + + file.TransferTo(verifier, subSectionFileStart - currentFilePos); + verifier.Put(subSectionMemStart, subSectionSize); + file.Skip(subSectionSize); + currentFilePos = subSectionFileStart + subSectionSize; + subSectionStart = nextSubSectionStart; + } while (nextSubSectionStart != 0); + } + phs++; + } +#endif + file.TransferAllTo(verifier); + +#ifdef CRYPTOPP_WIN32_AVAILABLE + // if that fails (could be caused by debug breakpoints or DLL base relocation modifying image in memory), + // hash from disk instead + if (memcmp(expectedModuleMac, actualMac, macSize) != 0) + { + OutputDebugString("In memory integrity check failed. This may be caused by debug breakpoints or DLL relocation.\n"); + moduleStream.clear(); + moduleStream.seekg(0); + verifier.Initialize(MakeParameters(Name::OutputBuffer(), ByteArrayParameter(actualMac, (unsigned int)actualMac.size()))); +// verifier.Initialize(MakeParameters(Name::OutputFileName(), (const char *)"c:\\dt2.tmp")); + verifier.AddRangeToSkip(0, checksumPos, checksumSize); + verifier.AddRangeToSkip(0, certificateTableDirectoryPos, certificateTableDirectorySize); + verifier.AddRangeToSkip(0, certificateTablePos, certificateTableSize); + verifier.AddRangeToSkip(0, macFileLocation, macSize); + FileStore(moduleStream).TransferAllTo(verifier); + } +#endif + + if (memcmp(expectedModuleMac, actualMac, macSize) == 0) + return true; + +#ifdef CRYPTOPP_WIN32_AVAILABLE + std::string hexMac; + HexEncoder(new StringSink(hexMac)).PutMessageEnd(actualMac, actualMac.size()); + OutputDebugString((("Crypto++ DLL integrity check failed. Actual MAC is: " + hexMac) + "\n").c_str()); +#endif + return false; +} + +void DoPowerUpSelfTest(const char *moduleFilename, const byte *expectedModuleMac) +{ + g_powerUpSelfTestStatus = POWER_UP_SELF_TEST_NOT_DONE; + SetPowerUpSelfTestInProgressOnThisThread(true); + + try + { + if (FIPS_140_2_ComplianceEnabled() || expectedModuleMac != NULL) + { + if (!IntegrityCheckModule(moduleFilename, expectedModuleMac, &g_actualMac, &g_macFileLocation)) + throw 0; // throw here so we break in the debugger, this will be caught right away + } + + // algorithm tests + + X917RNG_KnownAnswerTest( + "2b7e151628aed2a6abf7158809cf4f3c", // key + "000102030405060708090a0b0c0d0e0f", // seed + "00000000000000000000000000000001", // time vector + "D176EDD27493B0395F4D10546232B0693DC7061C03C3A554F09CECF6F6B46D945A"); // output + + SymmetricEncryptionKnownAnswerTest( + "385D7189A5C3D485E1370AA5D408082B5CCCCB5E19F2D90E", + "C141B5FCCD28DC8A", + "6E1BD7C6120947A464A6AAB293A0F89A563D8D40D3461B68", + "64EAAD4ACBB9CEAD6C7615E7C7E4792FE587D91F20C7D2F4", + "6235A461AFD312973E3B4F7AA7D23E34E03371F8E8C376C9", + "E26BA806A59B0330DE40CA38E77A3E494BE2B212F6DD624B", + "E26BA806A59B03307DE2BCC25A08BA40A8BA335F5D604C62", + "E26BA806A59B03303C62C2EFF32D3ACDD5D5F35EBCC53371"); + + SymmetricEncryptionKnownAnswerTest( + "1555E5531C3A169B2D65", + "6EC9795701F49864", + "00AFA48E9621E52E8CBDA312660184EDDB1F33D9DACDA8DA", + "DBEC73562EFCAEB56204EB8AE9557EBF77473FBB52D17CD1", + "0C7B0B74E21F99B8F2C8DF37879F6C044967F42A796DCA8B", + "79FDDA9724E36CC2E023E9A5C717A8A8A7FDA465CADCBF63", + "79FDDA9724E36CC26CACBD83C1ABC06EAF5B249BE5B1E040", + "79FDDA9724E36CC211B0AEC607B95A96BCDA318440B82F49"); + + SymmetricEncryptionKnownAnswerTest( + "2b7e151628aed2a6abf7158809cf4f3c", + "000102030405060708090a0b0c0d0e0f", + "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710", // plaintext + "3ad77bb40d7a3660a89ecaf32466ef97f5d3d58503b9699de785895a96fdbaaf43b1cd7f598ece23881b00e3ed0306887b0c785e27e8ad3f8223207104725dd4", // ecb + "7649abac8119b246cee98e9b12e9197d5086cb9b507219ee95db113a917678b273bed6b8e3c1743b7116e69e222295163ff1caa1681fac09120eca307586e1a7", // cbc + "3b3fd92eb72dad20333449f8e83cfb4ac8a64537a0b3a93fcde3cdad9f1ce58b26751f67a3cbb140b1808cf187a4f4dfc04b05357c5d1c0eeac4c66f9ff7f2e6", // cfb + "3b3fd92eb72dad20333449f8e83cfb4a7789508d16918f03f53c52dac54ed8259740051e9c5fecf64344f7a82260edcc304c6528f659c77866a510d9c1d6ae5e", // ofb + NULL); + + SymmetricEncryptionKnownAnswerTest( + "2b7e151628aed2a6abf7158809cf4f3c", + "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", + "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710", + NULL, + NULL, + NULL, + NULL, + "874d6191b620e3261bef6864990db6ce9806f66b7970fdff8617187bb9fffdff5ae4df3edbd5d35e5b4f09020db03eab1e031dda2fbe03d1792170a0f3009cee"); // ctr + + + SecureHashKnownAnswerTest( + "abc", + "A9993E364706816ABA3E25717850C26C9CD0D89D"); + + SecureHashKnownAnswerTest( + "abc", + "23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7"); + + SecureHashKnownAnswerTest( + "abc", + "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"); + +#ifdef WORD64_AVAILABLE + SecureHashKnownAnswerTest( + "abc", + "cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7"); + + SecureHashKnownAnswerTest( + "abc", + "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"); +#endif + + MAC_KnownAnswerTest >( + "303132333435363738393a3b3c3d3e3f40414243", + "Sample #2", + "0922d3405faa3d194f82a45830737d5cc6c75d24"); + + const char *keyRSA1 = + "30820150020100300d06092a864886f70d01010105000482013a3082013602010002400a66791dc6988168de7ab77419bb7fb0" + "c001c62710270075142942e19a8d8c51d053b3e3782a1de5dc5af4ebe99468170114a1dfe67cdc9a9af55d655620bbab0203010001" + "02400123c5b61ba36edb1d3679904199a89ea80c09b9122e1400c09adcf7784676d01d23356a7d44d6bd8bd50e94bfc723fa" + "87d8862b75177691c11d757692df8881022033d48445c859e52340de704bcdda065fbb4058d740bd1d67d29e9c146c11cf61" + "0220335e8408866b0fd38dc7002d3f972c67389a65d5d8306566d5c4f2a5aa52628b0220045ec90071525325d3d46db79695e9af" + "acc4523964360e02b119baa366316241022015eb327360c7b60d12e5e2d16bdcd97981d17fba6b70db13b20b436e24eada590220" + "2ca6366d72781dfa24d34a9a24cbc2ae927a9958af426563ff63fb11658a461d"; + + const char *keyRSA2 = + "30820273020100300D06092A864886F70D01010105000482025D3082025902010002818100D40AF9" + "A2B713034249E5780056D70FC7DE75D76E44565AA6A6B8ED9646F3C19F9E254D72D7DE6E49DB2264" + "0C1D05AB9E2A5F901D8F3FE1F7AE02CEE2ECCE54A40ABAE55A004692752E70725AEEE7CDEA67628A" + "82A9239B4AB660C2BC56D9F01E90CBAAB9BF0FC8E17173CEFC5709A29391A7DDF3E0B758691AAF30" + "725B292F4F020111027F18C0BA087D082C45D75D3594E0767E4820818EB35612B80CEAB8C880ACA5" + "44B6876DFFEF85A576C0D45B551AFAA1FD63209CD745DF75C5A0F0B580296EA466CD0338207E4752" + "FF4E7DB724D8AE18CE5CF4153BB94C27869FBB50E64F02546E4B02997A0B8623E64017CC770759C6" + "695DB649EEFD829D688D441BCC4E7348F1024100EF86DD7AF3F32CDE8A9F6564E43A559A0C9F8BAD" + "36CC25330548B347AC158A345631FA90F7B873C36EFFAE2F7823227A3F580B5DD18304D5932751E7" + "43E9234F024100E2A039854B55688740E32A51DF4AF88613D91A371CF8DDD95D780A89D7CF2119A9" + "54F1AC0F3DCDB2F6959926E6D9D37D8BC07A4C634DE6F16315BD5F0DAC340102407ECEEDB9903572" + "1B76909F174BA6698DCA72953D957B22C0A871C8531EDE3A1BB52984A719BC010D1CA57A555DB83F" + "6DE54CBAB932AEC652F38D497A6F3F30CF024100854F30E4FF232E6DADB2CD99926855F484255AB7" + "01FBCDCB27EC426F33A7046972AA700ADBCA008763DF87440F52F4E070531AC385B55AAC1C2AE7DD" + "8F9278F1024100C313F4AF9E4A9DE1253C21080CE524251560C111550772FD08690F13FBE658342E" + "BD2D41C9DCB12374E871B1839E26CAE252E1AE3DAAD5F1EE1F42B4D0EE7581"; + + SignatureKnownAnswerTest >( + keyRSA1, + "Everyone gets Friday off.", + "0610761F95FFD1B8F29DA34212947EC2AA0E358866A722F03CC3C41487ADC604A48FF54F5C6BEDB9FB7BD59F82D6E55D8F3174BA361B2214B2D74E8825E04E81"); + + SignatureKnownAnswerTest >( + keyRSA2, + "test", + "32F6BA41C8930DE71EE67F2627172CC539EDE04267FDE03AC295E3C50311F26C3B275D3AF513AC96" + "8EE493BAB7DA3A754661D1A7C4A0D1A2B7EE8B313AACD8CB8BFBC5C15EFB0EF15C86A9334A1E87AD" + "291EB961B5CA0E84930429B28780816AA94F96FC2367B71E2D2E4866FA966795B147F00600E5207E" + "2F189C883B37477C"); + + SignaturePairwiseConsistencyTest( + "3082014A0201003082012B06072A8648CE3804013082011E02818100F468699A6F6EBCC0120D3B34C8E007F125EC7D81F763B8D0F33869AE3BD6B9F2ECCC7DF34DF84C0307449E9B85D30D57194BCCEB310F48141914DD13A077AAF9B624A6CBE666BBA1D7EBEA95B5BA6F54417FD5D4E4220C601E071D316A24EA814E8B0122DBF47EE8AEEFD319EBB01DD95683F10DBB4FEB023F8262A07EAEB7FD02150082AD4E034DA6EEACDFDAE68C36F2BAD614F9E53B02818071AAF73361A26081529F7D84078ADAFCA48E031DB54AD57FB1A833ADBD8672328AABAA0C756247998D7A5B10DACA359D231332CE8120B483A784FE07D46EEBFF0D7D374A10691F78653E6DC29E27CCB1B174923960DFE5B959B919B2C3816C19251832AFD8E35D810E598F82877ABF7D40A041565168BD7F0E21E3FE2A8D8C1C0416021426EBA66E846E755169F84A1DA981D86502405DDF"); + + SignaturePairwiseConsistencyTest >( + "302D020100301006072A8648CE3D020106052B8104000404163014020101040F0070337065E1E196980A9D00E37211"); + + SignaturePairwiseConsistencyTest >( + "3039020100301306072A8648CE3D020106082A8648CE3D030101041F301D02010104182BB8A13C8B867010BD9471D9E81FDB01ABD0538C64D6249A"); + + SignaturePairwiseConsistencyTest >(keyRSA1); + } + catch (...) + { + g_powerUpSelfTestStatus = POWER_UP_SELF_TEST_FAILED; + goto done; + } + + g_powerUpSelfTestStatus = POWER_UP_SELF_TEST_PASSED; + +done: + SetPowerUpSelfTestInProgressOnThisThread(false); + return; +} + +#ifdef CRYPTOPP_WIN32_AVAILABLE + +void DoDllPowerUpSelfTest() +{ + CryptoPP::DoPowerUpSelfTest(NULL, s_moduleMac); +} + +#else + +void DoDllPowerUpSelfTest() +{ + throw NotImplemented("DoDllPowerUpSelfTest() only available on Windows"); +} + +#endif // #ifdef CRYPTOPP_WIN32_AVAILABLE + +NAMESPACE_END + +#ifdef CRYPTOPP_WIN32_AVAILABLE + +// DllMain needs to be in the global namespace +BOOL APIENTRY DllMain(HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved) +{ + if (ul_reason_for_call == DLL_PROCESS_ATTACH) + { + CryptoPP::s_hModule = (HMODULE)hModule; + CryptoPP::DoDllPowerUpSelfTest(); + } + return TRUE; +} + +#endif // #ifdef CRYPTOPP_WIN32_AVAILABLE + +#endif // #ifndef CRYPTOPP_IMPORTS diff --git a/CryptoPP/crypto/fltrimpl.h b/CryptoPP/crypto/fltrimpl.h new file mode 100644 index 0000000..62f7604 --- /dev/null +++ b/CryptoPP/crypto/fltrimpl.h @@ -0,0 +1,64 @@ +#ifndef CRYPTOPP_FLTRIMPL_H +#define CRYPTOPP_FLTRIMPL_H + +#define FILTER_BEGIN \ + switch (m_continueAt) \ + { \ + case 0: \ + m_inputPosition = 0; + +#define FILTER_END_NO_MESSAGE_END_NO_RETURN \ + break; \ + default: \ + assert(false); \ + } + +#define FILTER_END_NO_MESSAGE_END \ + FILTER_END_NO_MESSAGE_END_NO_RETURN \ + return 0; + +/* +#define FILTER_END \ + case -1: \ + if (messageEnd && Output(-1, NULL, 0, messageEnd, blocking)) \ + return 1; \ + FILTER_END_NO_MESSAGE_END +*/ + +#define FILTER_OUTPUT2(site, statement, output, length, messageEnd) \ + {\ + case site: \ + statement; \ + if (Output(site, output, length, messageEnd, blocking)) \ + return STDMAX(size_t(1), length-m_inputPosition);\ + } + +#define FILTER_OUTPUT(site, output, length, messageEnd) \ + FILTER_OUTPUT2(site, 0, output, length, messageEnd) + +#define FILTER_OUTPUT_BYTE(site, output) \ + FILTER_OUTPUT(site, &(const byte &)(byte)output, 1, 0) + +#define FILTER_OUTPUT2_MODIFIABLE(site, statement, output, length, messageEnd) \ + {\ + case site: \ + statement; \ + if (OutputModifiable(site, output, length, messageEnd, blocking)) \ + return STDMAX(size_t(1), length-m_inputPosition);\ + } + +#define FILTER_OUTPUT_MODIFIABLE(site, output, length, messageEnd) \ + FILTER_OUTPUT2_MODIFIABLE(site, 0, output, length, messageEnd) + +#define FILTER_OUTPUT2_MAYBE_MODIFIABLE(site, statement, output, length, messageEnd, modifiable) \ + {\ + case site: \ + statement; \ + if (modifiable ? OutputModifiable(site, output, length, messageEnd, blocking) : Output(site, output, length, messageEnd, blocking)) \ + return STDMAX(size_t(1), length-m_inputPosition);\ + } + +#define FILTER_OUTPUT_MAYBE_MODIFIABLE(site, output, length, messageEnd, modifiable) \ + FILTER_OUTPUT2_MAYBE_MODIFIABLE(site, 0, output, length, messageEnd, modifiable) + +#endif diff --git a/CryptoPP/crypto/gf256.cpp b/CryptoPP/crypto/gf256.cpp new file mode 100644 index 0000000..3649f75 --- /dev/null +++ b/CryptoPP/crypto/gf256.cpp @@ -0,0 +1,34 @@ +// gf256.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "gf256.h" + +NAMESPACE_BEGIN(CryptoPP) + +GF256::Element GF256::Multiply(Element a, Element b) const +{ + word result = 0, t = b; + + for (unsigned int i=0; i<8; i++) + { + result <<= 1; + if (result & 0x100) + result ^= m_modulus; + + t <<= 1; + if (t & 0x100) + result ^= a; + } + + return (GF256::Element) result; +} + +GF256::Element GF256::MultiplicativeInverse(Element a) const +{ + Element result = a; + for (int i=1; i<7; i++) + result = Multiply(Square(result), a); + return Square(result); +} + +NAMESPACE_END diff --git a/CryptoPP/crypto/gf256.h b/CryptoPP/crypto/gf256.h new file mode 100644 index 0000000..24a86f5 --- /dev/null +++ b/CryptoPP/crypto/gf256.h @@ -0,0 +1,66 @@ +#ifndef CRYPTOPP_GF256_H +#define CRYPTOPP_GF256_H + +#include "cryptlib.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! GF(256) with polynomial basis +class GF256 +{ +public: + typedef byte Element; + typedef int RandomizationParameter; + + GF256(byte modulus) : m_modulus(modulus) {} + + Element RandomElement(RandomNumberGenerator &rng, int ignored = 0) const + {return rng.GenerateByte();} + + bool Equal(Element a, Element b) const + {return a==b;} + + Element Zero() const + {return 0;} + + Element Add(Element a, Element b) const + {return a^b;} + + Element& Accumulate(Element &a, Element b) const + {return a^=b;} + + Element Inverse(Element a) const + {return a;} + + Element Subtract(Element a, Element b) const + {return a^b;} + + Element& Reduce(Element &a, Element b) const + {return a^=b;} + + Element Double(Element a) const + {return 0;} + + Element One() const + {return 1;} + + Element Multiply(Element a, Element b) const; + + Element Square(Element a) const + {return Multiply(a, a);} + + bool IsUnit(Element a) const + {return a != 0;} + + Element MultiplicativeInverse(Element a) const; + + Element Divide(Element a, Element b) const + {return Multiply(a, MultiplicativeInverse(b));} + +private: + word m_modulus; +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/gf2_32.cpp b/CryptoPP/crypto/gf2_32.cpp new file mode 100644 index 0000000..929dac0 --- /dev/null +++ b/CryptoPP/crypto/gf2_32.cpp @@ -0,0 +1,99 @@ +// gf2_32.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "misc.h" +#include "gf2_32.h" + +NAMESPACE_BEGIN(CryptoPP) + +GF2_32::Element GF2_32::Multiply(Element a, Element b) const +{ + word32 table[4]; + table[0] = 0; + table[1] = m_modulus; + if (a & 0x80000000) + { + table[2] = m_modulus ^ (a<<1); + table[3] = a<<1; + } + else + { + table[2] = a<<1; + table[3] = m_modulus ^ (a<<1); + } + +#if CRYPTOPP_FAST_ROTATE(32) + b = rotrFixed(b, 30U); + word32 result = table[b&2]; + + for (int i=29; i>=0; --i) + { + b = rotlFixed(b, 1U); + result = (result<<1) ^ table[(b&2) + (result>>31)]; + } + + return (b&1) ? result ^ a : result; +#else + word32 result = table[(b>>30) & 2]; + + for (int i=29; i>=0; --i) + result = (result<<1) ^ table[((b>>i)&2) + (result>>31)]; + + return (b&1) ? result ^ a : result; +#endif +} + +GF2_32::Element GF2_32::MultiplicativeInverse(Element a) const +{ + if (a <= 1) // 1 is a special case + return a; + + // warning - don't try to adapt this algorithm for another situation + word32 g0=m_modulus, g1=a, g2=a; + word32 v0=0, v1=1, v2=1; + + assert(g1); + + while (!(g2 & 0x80000000)) + { + g2 <<= 1; + v2 <<= 1; + } + + g2 <<= 1; + v2 <<= 1; + + g0 ^= g2; + v0 ^= v2; + + while (g0 != 1) + { + if (g1 < g0 || ((g0^g1) < g0 && (g0^g1) < g1)) + { + assert(BitPrecision(g1) <= BitPrecision(g0)); + g2 = g1; + v2 = v1; + } + else + { + assert(BitPrecision(g1) > BitPrecision(g0)); + g2 = g0; g0 = g1; g1 = g2; + v2 = v0; v0 = v1; v1 = v2; + } + + while ((g0^g2) >= g2) + { + assert(BitPrecision(g0) > BitPrecision(g2)); + g2 <<= 1; + v2 <<= 1; + } + + assert(BitPrecision(g0) == BitPrecision(g2)); + g0 ^= g2; + v0 ^= v2; + } + + return v0; +} + +NAMESPACE_END diff --git a/CryptoPP/crypto/gf2_32.h b/CryptoPP/crypto/gf2_32.h new file mode 100644 index 0000000..d2eecf1 --- /dev/null +++ b/CryptoPP/crypto/gf2_32.h @@ -0,0 +1,66 @@ +#ifndef CRYPTOPP_GF2_32_H +#define CRYPTOPP_GF2_32_H + +#include "cryptlib.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! GF(2^32) with polynomial basis +class GF2_32 +{ +public: + typedef word32 Element; + typedef int RandomizationParameter; + + GF2_32(word32 modulus=0x0000008D) : m_modulus(modulus) {} + + Element RandomElement(RandomNumberGenerator &rng, int ignored = 0) const + {return rng.GenerateWord32();} + + bool Equal(Element a, Element b) const + {return a==b;} + + Element Identity() const + {return 0;} + + Element Add(Element a, Element b) const + {return a^b;} + + Element& Accumulate(Element &a, Element b) const + {return a^=b;} + + Element Inverse(Element a) const + {return a;} + + Element Subtract(Element a, Element b) const + {return a^b;} + + Element& Reduce(Element &a, Element b) const + {return a^=b;} + + Element Double(Element a) const + {return 0;} + + Element MultiplicativeIdentity() const + {return 1;} + + Element Multiply(Element a, Element b) const; + + Element Square(Element a) const + {return Multiply(a, a);} + + bool IsUnit(Element a) const + {return a != 0;} + + Element MultiplicativeInverse(Element a) const; + + Element Divide(Element a, Element b) const + {return Multiply(a, MultiplicativeInverse(b));} + +private: + word32 m_modulus; +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/gf2n.cpp b/CryptoPP/crypto/gf2n.cpp new file mode 100644 index 0000000..463db0f --- /dev/null +++ b/CryptoPP/crypto/gf2n.cpp @@ -0,0 +1,879 @@ +// gf2n.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "gf2n.h" +#include "algebra.h" +#include "words.h" +#include "randpool.h" +#include "asn.h" +#include "oids.h" + +#include + +NAMESPACE_BEGIN(CryptoPP) + +PolynomialMod2::PolynomialMod2() +{ +} + +PolynomialMod2::PolynomialMod2(word value, size_t bitLength) + : reg(BitsToWords(bitLength)) +{ + assert(value==0 || reg.size()>0); + + if (reg.size() > 0) + { + reg[0] = value; + SetWords(reg+1, 0, reg.size()-1); + } +} + +PolynomialMod2::PolynomialMod2(const PolynomialMod2& t) + : reg(t.reg.size()) +{ + CopyWords(reg, t.reg, reg.size()); +} + +void PolynomialMod2::Randomize(RandomNumberGenerator &rng, size_t nbits) +{ + const size_t nbytes = nbits/8 + 1; + SecByteBlock buf(nbytes); + rng.GenerateBlock(buf, nbytes); + buf[0] = (byte)Crop(buf[0], nbits % 8); + Decode(buf, nbytes); +} + +PolynomialMod2 PolynomialMod2::AllOnes(size_t bitLength) +{ + PolynomialMod2 result((word)0, bitLength); + SetWords(result.reg, ~(word)0, result.reg.size()); + if (bitLength%WORD_BITS) + result.reg[result.reg.size()-1] = (word)Crop(result.reg[result.reg.size()-1], bitLength%WORD_BITS); + return result; +} + +void PolynomialMod2::SetBit(size_t n, int value) +{ + if (value) + { + reg.CleanGrow(n/WORD_BITS + 1); + reg[n/WORD_BITS] |= (word(1) << (n%WORD_BITS)); + } + else + { + if (n/WORD_BITS < reg.size()) + reg[n/WORD_BITS] &= ~(word(1) << (n%WORD_BITS)); + } +} + +byte PolynomialMod2::GetByte(size_t n) const +{ + if (n/WORD_SIZE >= reg.size()) + return 0; + else + return byte(reg[n/WORD_SIZE] >> ((n%WORD_SIZE)*8)); +} + +void PolynomialMod2::SetByte(size_t n, byte value) +{ + reg.CleanGrow(BytesToWords(n+1)); + reg[n/WORD_SIZE] &= ~(word(0xff) << 8*(n%WORD_SIZE)); + reg[n/WORD_SIZE] |= (word(value) << 8*(n%WORD_SIZE)); +} + +PolynomialMod2 PolynomialMod2::Monomial(size_t i) +{ + PolynomialMod2 r((word)0, i+1); + r.SetBit(i); + return r; +} + +PolynomialMod2 PolynomialMod2::Trinomial(size_t t0, size_t t1, size_t t2) +{ + PolynomialMod2 r((word)0, t0+1); + r.SetBit(t0); + r.SetBit(t1); + r.SetBit(t2); + return r; +} + +PolynomialMod2 PolynomialMod2::Pentanomial(size_t t0, size_t t1, size_t t2, size_t t3, size_t t4) +{ + PolynomialMod2 r((word)0, t0+1); + r.SetBit(t0); + r.SetBit(t1); + r.SetBit(t2); + r.SetBit(t3); + r.SetBit(t4); + return r; +} + +template +struct NewPolynomialMod2 +{ + PolynomialMod2 * operator()() const + { + return new PolynomialMod2(i); + } +}; + +const PolynomialMod2 &PolynomialMod2::Zero() +{ + return Singleton().Ref(); +} + +const PolynomialMod2 &PolynomialMod2::One() +{ + return Singleton >().Ref(); +} + +void PolynomialMod2::Decode(const byte *input, size_t inputLen) +{ + StringStore store(input, inputLen); + Decode(store, inputLen); +} + +void PolynomialMod2::Encode(byte *output, size_t outputLen) const +{ + ArraySink sink(output, outputLen); + Encode(sink, outputLen); +} + +void PolynomialMod2::Decode(BufferedTransformation &bt, size_t inputLen) +{ + reg.CleanNew(BytesToWords(inputLen)); + + for (size_t i=inputLen; i > 0; i--) + { + byte b; + bt.Get(b); + reg[(i-1)/WORD_SIZE] |= word(b) << ((i-1)%WORD_SIZE)*8; + } +} + +void PolynomialMod2::Encode(BufferedTransformation &bt, size_t outputLen) const +{ + for (size_t i=outputLen; i > 0; i--) + bt.Put(GetByte(i-1)); +} + +void PolynomialMod2::DEREncodeAsOctetString(BufferedTransformation &bt, size_t length) const +{ + DERGeneralEncoder enc(bt, OCTET_STRING); + Encode(enc, length); + enc.MessageEnd(); +} + +void PolynomialMod2::BERDecodeAsOctetString(BufferedTransformation &bt, size_t length) +{ + BERGeneralDecoder dec(bt, OCTET_STRING); + if (!dec.IsDefiniteLength() || dec.RemainingLength() != length) + BERDecodeError(); + Decode(dec, length); + dec.MessageEnd(); +} + +unsigned int PolynomialMod2::WordCount() const +{ + return (unsigned int)CountWords(reg, reg.size()); +} + +unsigned int PolynomialMod2::ByteCount() const +{ + unsigned wordCount = WordCount(); + if (wordCount) + return (wordCount-1)*WORD_SIZE + BytePrecision(reg[wordCount-1]); + else + return 0; +} + +unsigned int PolynomialMod2::BitCount() const +{ + unsigned wordCount = WordCount(); + if (wordCount) + return (wordCount-1)*WORD_BITS + BitPrecision(reg[wordCount-1]); + else + return 0; +} + +unsigned int PolynomialMod2::Parity() const +{ + unsigned i; + word temp=0; + for (i=0; i= reg.size()) + { + PolynomialMod2 result((word)0, b.reg.size()*WORD_BITS); + XorWords(result.reg, reg, b.reg, reg.size()); + CopyWords(result.reg+reg.size(), b.reg+reg.size(), b.reg.size()-reg.size()); + return result; + } + else + { + PolynomialMod2 result((word)0, reg.size()*WORD_BITS); + XorWords(result.reg, reg, b.reg, b.reg.size()); + CopyWords(result.reg+b.reg.size(), reg+b.reg.size(), reg.size()-b.reg.size()); + return result; + } +} + +PolynomialMod2 PolynomialMod2::And(const PolynomialMod2 &b) const +{ + PolynomialMod2 result((word)0, WORD_BITS*STDMIN(reg.size(), b.reg.size())); + AndWords(result.reg, reg, b.reg, result.reg.size()); + return result; +} + +PolynomialMod2 PolynomialMod2::Times(const PolynomialMod2 &b) const +{ + PolynomialMod2 result((word)0, BitCount() + b.BitCount()); + + for (int i=b.Degree(); i>=0; i--) + { + result <<= 1; + if (b[i]) + XorWords(result.reg, reg, reg.size()); + } + return result; +} + +PolynomialMod2 PolynomialMod2::Squared() const +{ + static const word map[16] = {0, 1, 4, 5, 16, 17, 20, 21, 64, 65, 68, 69, 80, 81, 84, 85}; + + PolynomialMod2 result((word)0, 2*reg.size()*WORD_BITS); + + for (unsigned i=0; i> (j/2)) % 16] << j; + + for (j=0; j> (j/2 + WORD_BITS/2)) % 16] << j; + } + + return result; +} + +void PolynomialMod2::Divide(PolynomialMod2 &remainder, PolynomialMod2 "ient, + const PolynomialMod2 ÷nd, const PolynomialMod2 &divisor) +{ + if (!divisor) + throw PolynomialMod2::DivideByZero(); + + int degree = divisor.Degree(); + remainder.reg.CleanNew(BitsToWords(degree+1)); + if (dividend.BitCount() >= divisor.BitCount()) + quotient.reg.CleanNew(BitsToWords(dividend.BitCount() - divisor.BitCount() + 1)); + else + quotient.reg.CleanNew(0); + + for (int i=dividend.Degree(); i>=0; i--) + { + remainder <<= 1; + remainder.reg[0] |= dividend[i]; + if (remainder[degree]) + { + remainder -= divisor; + quotient.SetBit(i); + } + } +} + +PolynomialMod2 PolynomialMod2::DividedBy(const PolynomialMod2 &b) const +{ + PolynomialMod2 remainder, quotient; + PolynomialMod2::Divide(remainder, quotient, *this, b); + return quotient; +} + +PolynomialMod2 PolynomialMod2::Modulo(const PolynomialMod2 &b) const +{ + PolynomialMod2 remainder, quotient; + PolynomialMod2::Divide(remainder, quotient, *this, b); + return remainder; +} + +PolynomialMod2& PolynomialMod2::operator<<=(unsigned int n) +{ + if (!reg.size()) + return *this; + + int i; + word u; + word carry=0; + word *r=reg; + + if (n==1) // special case code for most frequent case + { + i = (int)reg.size(); + while (i--) + { + u = *r; + *r = (u << 1) | carry; + carry = u >> (WORD_BITS-1); + r++; + } + + if (carry) + { + reg.Grow(reg.size()+1); + reg[reg.size()-1] = carry; + } + + return *this; + } + + int shiftWords = n / WORD_BITS; + int shiftBits = n % WORD_BITS; + + if (shiftBits) + { + i = (int)reg.size(); + while (i--) + { + u = *r; + *r = (u << shiftBits) | carry; + carry = u >> (WORD_BITS-shiftBits); + r++; + } + } + + if (carry) + { + reg.Grow(reg.size()+shiftWords+1); + reg[reg.size()-1] = carry; + } + else + reg.Grow(reg.size()+shiftWords); + + if (shiftWords) + { + for (i = (int)reg.size()-1; i>=shiftWords; i--) + reg[i] = reg[i-shiftWords]; + for (; i>=0; i--) + reg[i] = 0; + } + + return *this; +} + +PolynomialMod2& PolynomialMod2::operator>>=(unsigned int n) +{ + if (!reg.size()) + return *this; + + int shiftWords = n / WORD_BITS; + int shiftBits = n % WORD_BITS; + + size_t i; + word u; + word carry=0; + word *r=reg+reg.size()-1; + + if (shiftBits) + { + i = reg.size(); + while (i--) + { + u = *r; + *r = (u >> shiftBits) | carry; + carry = u << (WORD_BITS-shiftBits); + r--; + } + } + + if (shiftWords) + { + for (i=0; i>(unsigned int n) const +{ + PolynomialMod2 result(*this); + return result>>=n; +} + +bool PolynomialMod2::operator!() const +{ + for (unsigned i=0; i s(a.BitCount()/bits+1); + unsigned i; + const char vec[]="0123456789ABCDEF"; + + for (i=0; i*bits < a.BitCount(); i++) + { + int digit=0; + for (int j=0; j().Gcd(a, b); +} + +PolynomialMod2 PolynomialMod2::InverseMod(const PolynomialMod2 &modulus) const +{ + typedef EuclideanDomainOf Domain; + return QuotientRing(Domain(), modulus).MultiplicativeInverse(*this); +} + +bool PolynomialMod2::IsIrreducible() const +{ + signed int d = Degree(); + if (d <= 0) + return false; + + PolynomialMod2 t(2), u(t); + for (int i=1; i<=d/2; i++) + { + u = u.Squared()%(*this); + if (!Gcd(u+t, *this).IsUnit()) + return false; + } + return true; +} + +// ******************************************************** + +GF2NP::GF2NP(const PolynomialMod2 &modulus) + : QuotientRing >(EuclideanDomainOf(), modulus), m(modulus.Degree()) +{ +} + +GF2NP::Element GF2NP::SquareRoot(const Element &a) const +{ + Element r = a; + for (unsigned int i=1; i t1 && t1 > t2 && t2==0); +} + +const GF2NT::Element& GF2NT::MultiplicativeInverse(const Element &a) const +{ + if (t0-t1 < WORD_BITS) + return GF2NP::MultiplicativeInverse(a); + + SecWordBlock T(m_modulus.reg.size() * 4); + word *b = T; + word *c = T+m_modulus.reg.size(); + word *f = T+2*m_modulus.reg.size(); + word *g = T+3*m_modulus.reg.size(); + size_t bcLen=1, fgLen=m_modulus.reg.size(); + unsigned int k=0; + + SetWords(T, 0, 3*m_modulus.reg.size()); + b[0]=1; + assert(a.reg.size() <= m_modulus.reg.size()); + CopyWords(f, a.reg, a.reg.size()); + CopyWords(g, m_modulus.reg, m_modulus.reg.size()); + + while (1) + { + word t=f[0]; + while (!t) + { + ShiftWordsRightByWords(f, fgLen, 1); + if (c[bcLen-1]) + bcLen++; + assert(bcLen <= m_modulus.reg.size()); + ShiftWordsLeftByWords(c, bcLen, 1); + k+=WORD_BITS; + t=f[0]; + } + + unsigned int i=0; + while (t%2 == 0) + { + t>>=1; + i++; + } + k+=i; + + if (t==1 && CountWords(f, fgLen)==1) + break; + + if (i==1) + { + ShiftWordsRightByBits(f, fgLen, 1); + t=ShiftWordsLeftByBits(c, bcLen, 1); + } + else + { + ShiftWordsRightByBits(f, fgLen, i); + t=ShiftWordsLeftByBits(c, bcLen, i); + } + if (t) + { + c[bcLen] = t; + bcLen++; + assert(bcLen <= m_modulus.reg.size()); + } + + if (f[fgLen-1]==0 && g[fgLen-1]==0) + fgLen--; + + if (f[fgLen-1] < g[fgLen-1]) + { + std::swap(f, g); + std::swap(b, c); + } + + XorWords(f, g, fgLen); + XorWords(b, c, bcLen); + } + + while (k >= WORD_BITS) + { + word temp = b[0]; + // right shift b + for (unsigned i=0; i+1> j) & 1) << (t1 + j); + else + b[t1/WORD_BITS-1] ^= temp << t1%WORD_BITS; + + if (t1 % WORD_BITS) + b[t1/WORD_BITS] ^= temp >> (WORD_BITS - t1%WORD_BITS); + + if (t0%WORD_BITS) + { + b[t0/WORD_BITS-1] ^= temp << t0%WORD_BITS; + b[t0/WORD_BITS] ^= temp >> (WORD_BITS - t0%WORD_BITS); + } + else + b[t0/WORD_BITS-1] ^= temp; + + k -= WORD_BITS; + } + + if (k) + { + word temp = b[0] << (WORD_BITS - k); + ShiftWordsRightByBits(b, BitsToWords(m), k); + + if (t1 < WORD_BITS) + for (unsigned int j=0; j> j) & 1) << (t1 + j); + else + b[t1/WORD_BITS-1] ^= temp << t1%WORD_BITS; + + if (t1 % WORD_BITS) + b[t1/WORD_BITS] ^= temp >> (WORD_BITS - t1%WORD_BITS); + + if (t0%WORD_BITS) + { + b[t0/WORD_BITS-1] ^= temp << t0%WORD_BITS; + b[t0/WORD_BITS] ^= temp >> (WORD_BITS - t0%WORD_BITS); + } + else + b[t0/WORD_BITS-1] ^= temp; + } + + CopyWords(result.reg.begin(), b, result.reg.size()); + return result; +} + +const GF2NT::Element& GF2NT::Multiply(const Element &a, const Element &b) const +{ + size_t aSize = STDMIN(a.reg.size(), result.reg.size()); + Element r((word)0, m); + + for (int i=m-1; i>=0; i--) + { + if (r[m-1]) + { + ShiftWordsLeftByBits(r.reg.begin(), r.reg.size(), 1); + XorWords(r.reg.begin(), m_modulus.reg, r.reg.size()); + } + else + ShiftWordsLeftByBits(r.reg.begin(), r.reg.size(), 1); + + if (b[i]) + XorWords(r.reg.begin(), a.reg, aSize); + } + + if (m%WORD_BITS) + r.reg.begin()[r.reg.size()-1] = (word)Crop(r.reg[r.reg.size()-1], m%WORD_BITS); + + CopyWords(result.reg.begin(), r.reg.begin(), result.reg.size()); + return result; +} + +const GF2NT::Element& GF2NT::Reduced(const Element &a) const +{ + if (t0-t1 < WORD_BITS) + return m_domain.Mod(a, m_modulus); + + SecWordBlock b(a.reg); + + size_t i; + for (i=b.size()-1; i>=BitsToWords(t0); i--) + { + word temp = b[i]; + + if (t0%WORD_BITS) + { + b[i-t0/WORD_BITS] ^= temp >> t0%WORD_BITS; + b[i-t0/WORD_BITS-1] ^= temp << (WORD_BITS - t0%WORD_BITS); + } + else + b[i-t0/WORD_BITS] ^= temp; + + if ((t0-t1)%WORD_BITS) + { + b[i-(t0-t1)/WORD_BITS] ^= temp >> (t0-t1)%WORD_BITS; + b[i-(t0-t1)/WORD_BITS-1] ^= temp << (WORD_BITS - (t0-t1)%WORD_BITS); + } + else + b[i-(t0-t1)/WORD_BITS] ^= temp; + } + + if (i==BitsToWords(t0)-1 && t0%WORD_BITS) + { + word mask = ((word)1<<(t0%WORD_BITS))-1; + word temp = b[i] & ~mask; + b[i] &= mask; + + b[i-t0/WORD_BITS] ^= temp >> t0%WORD_BITS; + + if ((t0-t1)%WORD_BITS) + { + b[i-(t0-t1)/WORD_BITS] ^= temp >> (t0-t1)%WORD_BITS; + if ((t0-t1)%WORD_BITS > t0%WORD_BITS) + b[i-(t0-t1)/WORD_BITS-1] ^= temp << (WORD_BITS - (t0-t1)%WORD_BITS); + else + assert(temp << (WORD_BITS - (t0-t1)%WORD_BITS) == 0); + } + else + b[i-(t0-t1)/WORD_BITS] ^= temp; + } + + SetWords(result.reg.begin(), 0, result.reg.size()); + CopyWords(result.reg.begin(), b, STDMIN(b.size(), result.reg.size())); + return result; +} + +void GF2NP::DEREncodeElement(BufferedTransformation &out, const Element &a) const +{ + a.DEREncodeAsOctetString(out, MaxElementByteLength()); +} + +void GF2NP::BERDecodeElement(BufferedTransformation &in, Element &a) const +{ + a.BERDecodeAsOctetString(in, MaxElementByteLength()); +} + +void GF2NT::DEREncode(BufferedTransformation &bt) const +{ + DERSequenceEncoder seq(bt); + ASN1::characteristic_two_field().DEREncode(seq); + DERSequenceEncoder parameters(seq); + DEREncodeUnsigned(parameters, m); + ASN1::tpBasis().DEREncode(parameters); + DEREncodeUnsigned(parameters, t1); + parameters.MessageEnd(); + seq.MessageEnd(); +} + +void GF2NPP::DEREncode(BufferedTransformation &bt) const +{ + DERSequenceEncoder seq(bt); + ASN1::characteristic_two_field().DEREncode(seq); + DERSequenceEncoder parameters(seq); + DEREncodeUnsigned(parameters, m); + ASN1::ppBasis().DEREncode(parameters); + DERSequenceEncoder pentanomial(parameters); + DEREncodeUnsigned(pentanomial, t3); + DEREncodeUnsigned(pentanomial, t2); + DEREncodeUnsigned(pentanomial, t1); + pentanomial.MessageEnd(); + parameters.MessageEnd(); + seq.MessageEnd(); +} + +GF2NP * BERDecodeGF2NP(BufferedTransformation &bt) +{ + // VC60 workaround: auto_ptr lacks reset() + member_ptr result; + + BERSequenceDecoder seq(bt); + if (OID(seq) != ASN1::characteristic_two_field()) + BERDecodeError(); + BERSequenceDecoder parameters(seq); + unsigned int m; + BERDecodeUnsigned(parameters, m); + OID oid(parameters); + if (oid == ASN1::tpBasis()) + { + unsigned int t1; + BERDecodeUnsigned(parameters, t1); + result.reset(new GF2NT(m, t1, 0)); + } + else if (oid == ASN1::ppBasis()) + { + unsigned int t1, t2, t3; + BERSequenceDecoder pentanomial(parameters); + BERDecodeUnsigned(pentanomial, t3); + BERDecodeUnsigned(pentanomial, t2); + BERDecodeUnsigned(pentanomial, t1); + pentanomial.MessageEnd(); + result.reset(new GF2NPP(m, t3, t2, t1, 0)); + } + else + { + BERDecodeError(); + return NULL; + } + parameters.MessageEnd(); + seq.MessageEnd(); + + return result.release(); +} + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/gf2n.h b/CryptoPP/crypto/gf2n.h new file mode 100644 index 0000000..c450050 --- /dev/null +++ b/CryptoPP/crypto/gf2n.h @@ -0,0 +1,367 @@ +#ifndef CRYPTOPP_GF2N_H +#define CRYPTOPP_GF2N_H + +/*! \file */ + +#include "cryptlib.h" +#include "secblock.h" +#include "misc.h" +#include "algebra.h" + +#include + +NAMESPACE_BEGIN(CryptoPP) + +//! Polynomial with Coefficients in GF(2) +/*! \nosubgrouping */ +class CRYPTOPP_DLL PolynomialMod2 +{ +public: + //! \name ENUMS, EXCEPTIONS, and TYPEDEFS + //@{ + //! divide by zero exception + class DivideByZero : public Exception + { + public: + DivideByZero() : Exception(OTHER_ERROR, "PolynomialMod2: division by zero") {} + }; + + typedef unsigned int RandomizationParameter; + //@} + + //! \name CREATORS + //@{ + //! creates the zero polynomial + PolynomialMod2(); + //! copy constructor + PolynomialMod2(const PolynomialMod2& t); + + //! convert from word + /*! value should be encoded with the least significant bit as coefficient to x^0 + and most significant bit as coefficient to x^(WORD_BITS-1) + bitLength denotes how much memory to allocate initially + */ + PolynomialMod2(word value, size_t bitLength=WORD_BITS); + + //! convert from big-endian byte array + PolynomialMod2(const byte *encodedPoly, size_t byteCount) + {Decode(encodedPoly, byteCount);} + + //! convert from big-endian form stored in a BufferedTransformation + PolynomialMod2(BufferedTransformation &encodedPoly, size_t byteCount) + {Decode(encodedPoly, byteCount);} + + //! create a random polynomial uniformly distributed over all polynomials with degree less than bitcount + PolynomialMod2(RandomNumberGenerator &rng, size_t bitcount) + {Randomize(rng, bitcount);} + + //! return x^i + static PolynomialMod2 CRYPTOPP_API Monomial(size_t i); + //! return x^t0 + x^t1 + x^t2 + static PolynomialMod2 CRYPTOPP_API Trinomial(size_t t0, size_t t1, size_t t2); + //! return x^t0 + x^t1 + x^t2 + x^t3 + x^t4 + static PolynomialMod2 CRYPTOPP_API Pentanomial(size_t t0, size_t t1, size_t t2, size_t t3, size_t t4); + //! return x^(n-1) + ... + x + 1 + static PolynomialMod2 CRYPTOPP_API AllOnes(size_t n); + + //! + static const PolynomialMod2 & CRYPTOPP_API Zero(); + //! + static const PolynomialMod2 & CRYPTOPP_API One(); + //@} + + //! \name ENCODE/DECODE + //@{ + //! minimum number of bytes to encode this polynomial + /*! MinEncodedSize of 0 is 1 */ + unsigned int MinEncodedSize() const {return STDMAX(1U, ByteCount());} + + //! encode in big-endian format + /*! if outputLen < MinEncodedSize, the most significant bytes will be dropped + if outputLen > MinEncodedSize, the most significant bytes will be padded + */ + void Encode(byte *output, size_t outputLen) const; + //! + void Encode(BufferedTransformation &bt, size_t outputLen) const; + + //! + void Decode(const byte *input, size_t inputLen); + //! + //* Precondition: bt.MaxRetrievable() >= inputLen + void Decode(BufferedTransformation &bt, size_t inputLen); + + //! encode value as big-endian octet string + void DEREncodeAsOctetString(BufferedTransformation &bt, size_t length) const; + //! decode value as big-endian octet string + void BERDecodeAsOctetString(BufferedTransformation &bt, size_t length); + //@} + + //! \name ACCESSORS + //@{ + //! number of significant bits = Degree() + 1 + unsigned int BitCount() const; + //! number of significant bytes = ceiling(BitCount()/8) + unsigned int ByteCount() const; + //! number of significant words = ceiling(ByteCount()/sizeof(word)) + unsigned int WordCount() const; + + //! return the n-th bit, n=0 being the least significant bit + bool GetBit(size_t n) const {return GetCoefficient(n)!=0;} + //! return the n-th byte + byte GetByte(size_t n) const; + + //! the zero polynomial will return a degree of -1 + signed int Degree() const {return BitCount()-1;} + //! degree + 1 + unsigned int CoefficientCount() const {return BitCount();} + //! return coefficient for x^i + int GetCoefficient(size_t i) const + {return (i/WORD_BITS < reg.size()) ? int(reg[i/WORD_BITS] >> (i % WORD_BITS)) & 1 : 0;} + //! return coefficient for x^i + int operator[](unsigned int i) const {return GetCoefficient(i);} + + //! + bool IsZero() const {return !*this;} + //! + bool Equals(const PolynomialMod2 &rhs) const; + //@} + + //! \name MANIPULATORS + //@{ + //! + PolynomialMod2& operator=(const PolynomialMod2& t); + //! + PolynomialMod2& operator&=(const PolynomialMod2& t); + //! + PolynomialMod2& operator^=(const PolynomialMod2& t); + //! + PolynomialMod2& operator+=(const PolynomialMod2& t) {return *this ^= t;} + //! + PolynomialMod2& operator-=(const PolynomialMod2& t) {return *this ^= t;} + //! + PolynomialMod2& operator*=(const PolynomialMod2& t); + //! + PolynomialMod2& operator/=(const PolynomialMod2& t); + //! + PolynomialMod2& operator%=(const PolynomialMod2& t); + //! + PolynomialMod2& operator<<=(unsigned int); + //! + PolynomialMod2& operator>>=(unsigned int); + + //! + void Randomize(RandomNumberGenerator &rng, size_t bitcount); + + //! + void SetBit(size_t i, int value = 1); + //! set the n-th byte to value + void SetByte(size_t n, byte value); + + //! + void SetCoefficient(size_t i, int value) {SetBit(i, value);} + + //! + void swap(PolynomialMod2 &a) {reg.swap(a.reg);} + //@} + + //! \name UNARY OPERATORS + //@{ + //! + bool operator!() const; + //! + PolynomialMod2 operator+() const {return *this;} + //! + PolynomialMod2 operator-() const {return *this;} + //@} + + //! \name BINARY OPERATORS + //@{ + //! + PolynomialMod2 And(const PolynomialMod2 &b) const; + //! + PolynomialMod2 Xor(const PolynomialMod2 &b) const; + //! + PolynomialMod2 Plus(const PolynomialMod2 &b) const {return Xor(b);} + //! + PolynomialMod2 Minus(const PolynomialMod2 &b) const {return Xor(b);} + //! + PolynomialMod2 Times(const PolynomialMod2 &b) const; + //! + PolynomialMod2 DividedBy(const PolynomialMod2 &b) const; + //! + PolynomialMod2 Modulo(const PolynomialMod2 &b) const; + + //! + PolynomialMod2 operator>>(unsigned int n) const; + //! + PolynomialMod2 operator<<(unsigned int n) const; + //@} + + //! \name OTHER ARITHMETIC FUNCTIONS + //@{ + //! sum modulo 2 of all coefficients + unsigned int Parity() const; + + //! check for irreducibility + bool IsIrreducible() const; + + //! is always zero since we're working modulo 2 + PolynomialMod2 Doubled() const {return Zero();} + //! + PolynomialMod2 Squared() const; + + //! only 1 is a unit + bool IsUnit() const {return Equals(One());} + //! return inverse if *this is a unit, otherwise return 0 + PolynomialMod2 MultiplicativeInverse() const {return IsUnit() ? One() : Zero();} + + //! greatest common divisor + static PolynomialMod2 CRYPTOPP_API Gcd(const PolynomialMod2 &a, const PolynomialMod2 &n); + //! calculate multiplicative inverse of *this mod n + PolynomialMod2 InverseMod(const PolynomialMod2 &) const; + + //! calculate r and q such that (a == d*q + r) && (deg(r) < deg(d)) + static void CRYPTOPP_API Divide(PolynomialMod2 &r, PolynomialMod2 &q, const PolynomialMod2 &a, const PolynomialMod2 &d); + //@} + + //! \name INPUT/OUTPUT + //@{ + //! + friend std::ostream& operator<<(std::ostream& out, const PolynomialMod2 &a); + //@} + +private: + friend class GF2NT; + + SecWordBlock reg; +}; + +//! +inline bool operator==(const CryptoPP::PolynomialMod2 &a, const CryptoPP::PolynomialMod2 &b) +{return a.Equals(b);} +//! +inline bool operator!=(const CryptoPP::PolynomialMod2 &a, const CryptoPP::PolynomialMod2 &b) +{return !(a==b);} +//! compares degree +inline bool operator> (const CryptoPP::PolynomialMod2 &a, const CryptoPP::PolynomialMod2 &b) +{return a.Degree() > b.Degree();} +//! compares degree +inline bool operator>=(const CryptoPP::PolynomialMod2 &a, const CryptoPP::PolynomialMod2 &b) +{return a.Degree() >= b.Degree();} +//! compares degree +inline bool operator< (const CryptoPP::PolynomialMod2 &a, const CryptoPP::PolynomialMod2 &b) +{return a.Degree() < b.Degree();} +//! compares degree +inline bool operator<=(const CryptoPP::PolynomialMod2 &a, const CryptoPP::PolynomialMod2 &b) +{return a.Degree() <= b.Degree();} +//! +inline CryptoPP::PolynomialMod2 operator&(const CryptoPP::PolynomialMod2 &a, const CryptoPP::PolynomialMod2 &b) {return a.And(b);} +//! +inline CryptoPP::PolynomialMod2 operator^(const CryptoPP::PolynomialMod2 &a, const CryptoPP::PolynomialMod2 &b) {return a.Xor(b);} +//! +inline CryptoPP::PolynomialMod2 operator+(const CryptoPP::PolynomialMod2 &a, const CryptoPP::PolynomialMod2 &b) {return a.Plus(b);} +//! +inline CryptoPP::PolynomialMod2 operator-(const CryptoPP::PolynomialMod2 &a, const CryptoPP::PolynomialMod2 &b) {return a.Minus(b);} +//! +inline CryptoPP::PolynomialMod2 operator*(const CryptoPP::PolynomialMod2 &a, const CryptoPP::PolynomialMod2 &b) {return a.Times(b);} +//! +inline CryptoPP::PolynomialMod2 operator/(const CryptoPP::PolynomialMod2 &a, const CryptoPP::PolynomialMod2 &b) {return a.DividedBy(b);} +//! +inline CryptoPP::PolynomialMod2 operator%(const CryptoPP::PolynomialMod2 &a, const CryptoPP::PolynomialMod2 &b) {return a.Modulo(b);} + +// CodeWarrior 8 workaround: put these template instantiations after overloaded operator declarations, +// but before the use of QuotientRing > for VC .NET 2003 +CRYPTOPP_DLL_TEMPLATE_CLASS AbstractGroup; +CRYPTOPP_DLL_TEMPLATE_CLASS AbstractRing; +CRYPTOPP_DLL_TEMPLATE_CLASS AbstractEuclideanDomain; +CRYPTOPP_DLL_TEMPLATE_CLASS EuclideanDomainOf; +CRYPTOPP_DLL_TEMPLATE_CLASS QuotientRing >; + +//! GF(2^n) with Polynomial Basis +class CRYPTOPP_DLL GF2NP : public QuotientRing > +{ +public: + GF2NP(const PolynomialMod2 &modulus); + + virtual GF2NP * Clone() const {return new GF2NP(*this);} + virtual void DEREncode(BufferedTransformation &bt) const + {assert(false);} // no ASN.1 syntax yet for general polynomial basis + + void DEREncodeElement(BufferedTransformation &out, const Element &a) const; + void BERDecodeElement(BufferedTransformation &in, Element &a) const; + + bool Equal(const Element &a, const Element &b) const + {assert(a.Degree() < m_modulus.Degree() && b.Degree() < m_modulus.Degree()); return a.Equals(b);} + + bool IsUnit(const Element &a) const + {assert(a.Degree() < m_modulus.Degree()); return !!a;} + + unsigned int MaxElementBitLength() const + {return m;} + + unsigned int MaxElementByteLength() const + {return (unsigned int)BitsToBytes(MaxElementBitLength());} + + Element SquareRoot(const Element &a) const; + + Element HalfTrace(const Element &a) const; + + // returns z such that z^2 + z == a + Element SolveQuadraticEquation(const Element &a) const; + +protected: + unsigned int m; +}; + +//! GF(2^n) with Trinomial Basis +class CRYPTOPP_DLL GF2NT : public GF2NP +{ +public: + // polynomial modulus = x^t0 + x^t1 + x^t2, t0 > t1 > t2 + GF2NT(unsigned int t0, unsigned int t1, unsigned int t2); + + GF2NP * Clone() const {return new GF2NT(*this);} + void DEREncode(BufferedTransformation &bt) const; + + const Element& Multiply(const Element &a, const Element &b) const; + + const Element& Square(const Element &a) const + {return Reduced(a.Squared());} + + const Element& MultiplicativeInverse(const Element &a) const; + +private: + const Element& Reduced(const Element &a) const; + + unsigned int t0, t1; + mutable PolynomialMod2 result; +}; + +//! GF(2^n) with Pentanomial Basis +class CRYPTOPP_DLL GF2NPP : public GF2NP +{ +public: + // polynomial modulus = x^t0 + x^t1 + x^t2 + x^t3 + x^t4, t0 > t1 > t2 > t3 > t4 + GF2NPP(unsigned int t0, unsigned int t1, unsigned int t2, unsigned int t3, unsigned int t4) + : GF2NP(PolynomialMod2::Pentanomial(t0, t1, t2, t3, t4)), t0(t0), t1(t1), t2(t2), t3(t3) {} + + GF2NP * Clone() const {return new GF2NPP(*this);} + void DEREncode(BufferedTransformation &bt) const; + +private: + unsigned int t0, t1, t2, t3; +}; + +// construct new GF2NP from the ASN.1 sequence Characteristic-two +CRYPTOPP_DLL GF2NP * CRYPTOPP_API BERDecodeGF2NP(BufferedTransformation &bt); + +NAMESPACE_END + +NAMESPACE_BEGIN(std) +template<> inline void swap(CryptoPP::PolynomialMod2 &a, CryptoPP::PolynomialMod2 &b) +{ + a.swap(b); +} +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/gfpcrypt.cpp b/CryptoPP/crypto/gfpcrypt.cpp new file mode 100644 index 0000000..0a0ffe9 --- /dev/null +++ b/CryptoPP/crypto/gfpcrypt.cpp @@ -0,0 +1,275 @@ +// dsa.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "gfpcrypt.h" +#include "asn.h" +#include "oids.h" +#include "nbtheory.h" + +NAMESPACE_BEGIN(CryptoPP) + +void TestInstantiations_gfpcrypt() +{ + GDSA::Signer test; + GDSA::Verifier test1; + DSA::Signer test5(NullRNG(), 100); + DSA::Signer test2(test5); + NR::Signer test3; + NR::Verifier test4; + DLIES<>::Encryptor test6; + DLIES<>::Decryptor test7; +} + +void DL_GroupParameters_DSA::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg) +{ + Integer p, q, g; + + if (alg.GetValue("Modulus", p) && alg.GetValue("SubgroupGenerator", g)) + { + q = alg.GetValueWithDefault("SubgroupOrder", ComputeGroupOrder(p)/2); + } + else + { + int modulusSize = 1024; + alg.GetIntValue("ModulusSize", modulusSize) || alg.GetIntValue("KeySize", modulusSize); + + if (!DSA::IsValidPrimeLength(modulusSize)) + throw InvalidArgument("DSA: not a valid prime length"); + + SecByteBlock seed(SHA::DIGESTSIZE); + Integer h; + int c; + + do + { + rng.GenerateBlock(seed, SHA::DIGESTSIZE); + } while (!DSA::GeneratePrimes(seed, SHA::DIGESTSIZE*8, c, p, modulusSize, q)); + + do + { + h.Randomize(rng, 2, p-2); + g = a_exp_b_mod_c(h, (p-1)/q, p); + } while (g <= 1); + } + + Initialize(p, q, g); +} + +bool DL_GroupParameters_DSA::ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const +{ + bool pass = DL_GroupParameters_GFP::ValidateGroup(rng, level); + pass = pass && DSA::IsValidPrimeLength(GetModulus().BitCount()); + pass = pass && GetSubgroupOrder().BitCount() == 160; + return pass; +} + +void DL_SignatureMessageEncodingMethod_DSA::ComputeMessageRepresentative(RandomNumberGenerator &rng, + const byte *recoverableMessage, size_t recoverableMessageLength, + HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, + byte *representative, size_t representativeBitLength) const +{ + assert(recoverableMessageLength == 0); + assert(hashIdentifier.second == 0); + const size_t representativeByteLength = BitsToBytes(representativeBitLength); + const size_t digestSize = hash.DigestSize(); + const size_t paddingLength = SaturatingSubtract(representativeByteLength, digestSize); + + memset(representative, 0, paddingLength); + hash.TruncatedFinal(representative+paddingLength, STDMIN(representativeByteLength, digestSize)); + + if (digestSize*8 > representativeBitLength) + { + Integer h(representative, representativeByteLength); + h >>= representativeByteLength*8 - representativeBitLength; + h.Encode(representative, representativeByteLength); + } +} + +void DL_SignatureMessageEncodingMethod_NR::ComputeMessageRepresentative(RandomNumberGenerator &rng, + const byte *recoverableMessage, size_t recoverableMessageLength, + HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, + byte *representative, size_t representativeBitLength) const +{ + assert(recoverableMessageLength == 0); + assert(hashIdentifier.second == 0); + const size_t representativeByteLength = BitsToBytes(representativeBitLength); + const size_t digestSize = hash.DigestSize(); + const size_t paddingLength = SaturatingSubtract(representativeByteLength, digestSize); + + memset(representative, 0, paddingLength); + hash.TruncatedFinal(representative+paddingLength, STDMIN(representativeByteLength, digestSize)); + + if (digestSize*8 >= representativeBitLength) + { + Integer h(representative, representativeByteLength); + h >>= representativeByteLength*8 - representativeBitLength + 1; + h.Encode(representative, representativeByteLength); + } +} + +bool DL_GroupParameters_IntegerBased::ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const +{ + const Integer &p = GetModulus(), &q = GetSubgroupOrder(); + + bool pass = true; + pass = pass && p > Integer::One() && p.IsOdd(); + pass = pass && q > Integer::One() && q.IsOdd(); + + if (level >= 1) + pass = pass && GetCofactor() > Integer::One() && GetGroupOrder() % q == Integer::Zero(); + if (level >= 2) + pass = pass && VerifyPrime(rng, q, level-2) && VerifyPrime(rng, p, level-2); + + return pass; +} + +bool DL_GroupParameters_IntegerBased::ValidateElement(unsigned int level, const Integer &g, const DL_FixedBasePrecomputation *gpc) const +{ + const Integer &p = GetModulus(), &q = GetSubgroupOrder(); + + bool pass = true; + pass = pass && GetFieldType() == 1 ? g.IsPositive() : g.NotNegative(); + pass = pass && g < p && !IsIdentity(g); + + if (level >= 1) + { + if (gpc) + pass = pass && gpc->Exponentiate(GetGroupPrecomputation(), Integer::One()) == g; + } + if (level >= 2) + { + if (GetFieldType() == 2) + pass = pass && Jacobi(g*g-4, p)==-1; + + // verifying that Lucas((p+1)/2, w, p)==2 is omitted because it's too costly + // and at most 1 bit is leaked if it's false + bool fullValidate = (GetFieldType() == 2 && level >= 3) || !FastSubgroupCheckAvailable(); + + if (fullValidate && pass) + { + Integer gp = gpc ? gpc->Exponentiate(GetGroupPrecomputation(), q) : ExponentiateElement(g, q); + pass = pass && IsIdentity(gp); + } + else if (GetFieldType() == 1) + pass = pass && Jacobi(g, p) == 1; + } + + return pass; +} + +void DL_GroupParameters_IntegerBased::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg) +{ + Integer p, q, g; + + if (alg.GetValue("Modulus", p) && alg.GetValue("SubgroupGenerator", g)) + { + q = alg.GetValueWithDefault("SubgroupOrder", ComputeGroupOrder(p)/2); + } + else + { + int modulusSize, subgroupOrderSize; + + if (!alg.GetIntValue("ModulusSize", modulusSize)) + modulusSize = alg.GetIntValueWithDefault("KeySize", 2048); + + if (!alg.GetIntValue("SubgroupOrderSize", subgroupOrderSize)) + subgroupOrderSize = GetDefaultSubgroupOrderSize(modulusSize); + + PrimeAndGenerator pg; + pg.Generate(GetFieldType() == 1 ? 1 : -1, rng, modulusSize, subgroupOrderSize); + p = pg.Prime(); + q = pg.SubPrime(); + g = pg.Generator(); + } + + Initialize(p, q, g); +} + +Integer DL_GroupParameters_IntegerBased::DecodeElement(const byte *encoded, bool checkForGroupMembership) const +{ + Integer g(encoded, GetModulus().ByteCount()); + if (!ValidateElement(1, g, NULL)) + throw DL_BadElement(); + return g; +} + +void DL_GroupParameters_IntegerBased::BERDecode(BufferedTransformation &bt) +{ + BERSequenceDecoder parameters(bt); + Integer p(parameters); + Integer q(parameters); + Integer g; + if (parameters.EndReached()) + { + g = q; + q = ComputeGroupOrder(p) / 2; + } + else + g.BERDecode(parameters); + parameters.MessageEnd(); + + SetModulusAndSubgroupGenerator(p, g); + SetSubgroupOrder(q); +} + +void DL_GroupParameters_IntegerBased::DEREncode(BufferedTransformation &bt) const +{ + DERSequenceEncoder parameters(bt); + GetModulus().DEREncode(parameters); + m_q.DEREncode(parameters); + GetSubgroupGenerator().DEREncode(parameters); + parameters.MessageEnd(); +} + +bool DL_GroupParameters_IntegerBased::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const +{ + return GetValueHelper >(this, name, valueType, pValue) + CRYPTOPP_GET_FUNCTION_ENTRY(Modulus); +} + +void DL_GroupParameters_IntegerBased::AssignFrom(const NameValuePairs &source) +{ + AssignFromHelper(this, source) + CRYPTOPP_SET_FUNCTION_ENTRY2(Modulus, SubgroupGenerator) + CRYPTOPP_SET_FUNCTION_ENTRY(SubgroupOrder) + ; +} + +OID DL_GroupParameters_IntegerBased::GetAlgorithmID() const +{ + return ASN1::id_dsa(); +} + +void DL_GroupParameters_GFP::SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const +{ + ModularArithmetic ma(GetModulus()); + ma.SimultaneousExponentiate(results, base, exponents, exponentsCount); +} + +DL_GroupParameters_GFP::Element DL_GroupParameters_GFP::MultiplyElements(const Element &a, const Element &b) const +{ + return a_times_b_mod_c(a, b, GetModulus()); +} + +DL_GroupParameters_GFP::Element DL_GroupParameters_GFP::CascadeExponentiate(const Element &element1, const Integer &exponent1, const Element &element2, const Integer &exponent2) const +{ + ModularArithmetic ma(GetModulus()); + return ma.CascadeExponentiate(element1, exponent1, element2, exponent2); +} + +Integer DL_GroupParameters_IntegerBased::GetMaxExponent() const +{ + return STDMIN(GetSubgroupOrder()-1, Integer::Power2(2*DiscreteLogWorkFactor(GetFieldType()*GetModulus().BitCount()))); +} + +unsigned int DL_GroupParameters_IntegerBased::GetDefaultSubgroupOrderSize(unsigned int modulusSize) const +{ + return 2*DiscreteLogWorkFactor(GetFieldType()*modulusSize); +} + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/gfpcrypt.h b/CryptoPP/crypto/gfpcrypt.h new file mode 100644 index 0000000..6e73d47 --- /dev/null +++ b/CryptoPP/crypto/gfpcrypt.h @@ -0,0 +1,536 @@ +#ifndef CRYPTOPP_GFPCRYPT_H +#define CRYPTOPP_GFPCRYPT_H + +/** \file + Implementation of schemes based on DL over GF(p) +*/ + +#include "pubkey.h" +#include "modexppc.h" +#include "sha.h" +#include "algparam.h" +#include "asn.h" +#include "smartptr.h" +#include "hmac.h" + +#include + +NAMESPACE_BEGIN(CryptoPP) + +CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupParameters; + +//! _ +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE DL_GroupParameters_IntegerBased : public ASN1CryptoMaterial > +{ + typedef DL_GroupParameters_IntegerBased ThisClass; + +public: + void Initialize(const DL_GroupParameters_IntegerBased ¶ms) + {Initialize(params.GetModulus(), params.GetSubgroupOrder(), params.GetSubgroupGenerator());} + void Initialize(RandomNumberGenerator &rng, unsigned int pbits) + {GenerateRandom(rng, MakeParameters("ModulusSize", (int)pbits));} + void Initialize(const Integer &p, const Integer &g) + {SetModulusAndSubgroupGenerator(p, g); SetSubgroupOrder(ComputeGroupOrder(p)/2);} + void Initialize(const Integer &p, const Integer &q, const Integer &g) + {SetModulusAndSubgroupGenerator(p, g); SetSubgroupOrder(q);} + + // ASN1Object interface + void BERDecode(BufferedTransformation &bt); + void DEREncode(BufferedTransformation &bt) const; + + // GeneratibleCryptoMaterial interface + /*! parameters: (ModulusSize, SubgroupOrderSize (optional)) */ + void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg); + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; + void AssignFrom(const NameValuePairs &source); + + // DL_GroupParameters + const Integer & GetSubgroupOrder() const {return m_q;} + Integer GetGroupOrder() const {return GetFieldType() == 1 ? GetModulus()-Integer::One() : GetModulus()+Integer::One();} + bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const; + bool ValidateElement(unsigned int level, const Integer &element, const DL_FixedBasePrecomputation *precomp) const; + bool FastSubgroupCheckAvailable() const {return GetCofactor() == 2;} + void EncodeElement(bool reversible, const Element &element, byte *encoded) const + {element.Encode(encoded, GetModulus().ByteCount());} + unsigned int GetEncodedElementSize(bool reversible) const {return GetModulus().ByteCount();} + Integer DecodeElement(const byte *encoded, bool checkForGroupMembership) const; + Integer ConvertElementToInteger(const Element &element) const + {return element;} + Integer GetMaxExponent() const; + static std::string CRYPTOPP_API StaticAlgorithmNamePrefix() {return "";} + + OID GetAlgorithmID() const; + + virtual const Integer & GetModulus() const =0; + virtual void SetModulusAndSubgroupGenerator(const Integer &p, const Integer &g) =0; + + void SetSubgroupOrder(const Integer &q) + {m_q = q; ParametersChanged();} + +protected: + Integer ComputeGroupOrder(const Integer &modulus) const + {return modulus-(GetFieldType() == 1 ? 1 : -1);} + + // GF(p) = 1, GF(p^2) = 2 + virtual int GetFieldType() const =0; + virtual unsigned int GetDefaultSubgroupOrderSize(unsigned int modulusSize) const; + +private: + Integer m_q; +}; + +//! _ +template > +class CRYPTOPP_NO_VTABLE DL_GroupParameters_IntegerBasedImpl : public DL_GroupParametersImpl +{ + typedef DL_GroupParameters_IntegerBasedImpl ThisClass; + +public: + typedef typename GROUP_PRECOMP::Element Element; + + // GeneratibleCryptoMaterial interface + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const + {return GetValueHelper(this, name, valueType, pValue).Assignable();} + + void AssignFrom(const NameValuePairs &source) + {AssignFromHelper(this, source);} + + // DL_GroupParameters + const DL_FixedBasePrecomputation & GetBasePrecomputation() const {return this->m_gpc;} + DL_FixedBasePrecomputation & AccessBasePrecomputation() {return this->m_gpc;} + + // IntegerGroupParameters + const Integer & GetModulus() const {return this->m_groupPrecomputation.GetModulus();} + const Integer & GetGenerator() const {return this->m_gpc.GetBase(this->GetGroupPrecomputation());} + + void SetModulusAndSubgroupGenerator(const Integer &p, const Integer &g) // these have to be set together + {this->m_groupPrecomputation.SetModulus(p); this->m_gpc.SetBase(this->GetGroupPrecomputation(), g); this->ParametersChanged();} + + // non-inherited + bool operator==(const DL_GroupParameters_IntegerBasedImpl &rhs) const + {return GetModulus() == rhs.GetModulus() && GetGenerator() == rhs.GetGenerator() && this->GetSubgroupOrder() == rhs.GetSubgroupOrder();} + bool operator!=(const DL_GroupParameters_IntegerBasedImpl &rhs) const + {return !operator==(rhs);} +}; + +CRYPTOPP_DLL_TEMPLATE_CLASS DL_GroupParameters_IntegerBasedImpl; + +//! GF(p) group parameters +class CRYPTOPP_DLL DL_GroupParameters_GFP : public DL_GroupParameters_IntegerBasedImpl +{ +public: + // DL_GroupParameters + bool IsIdentity(const Integer &element) const {return element == Integer::One();} + void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const; + + // NameValuePairs interface + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const + { + return GetValueHelper(this, name, valueType, pValue).Assignable(); + } + + // used by MQV + Element MultiplyElements(const Element &a, const Element &b) const; + Element CascadeExponentiate(const Element &element1, const Integer &exponent1, const Element &element2, const Integer &exponent2) const; + +protected: + int GetFieldType() const {return 1;} +}; + +//! GF(p) group parameters that default to same primes +class CRYPTOPP_DLL DL_GroupParameters_GFP_DefaultSafePrime : public DL_GroupParameters_GFP +{ +public: + typedef NoCofactorMultiplication DefaultCofactorOption; + +protected: + unsigned int GetDefaultSubgroupOrderSize(unsigned int modulusSize) const {return modulusSize-1;} +}; + +//! GDSA algorithm +template +class DL_Algorithm_GDSA : public DL_ElgamalLikeSignatureAlgorithm +{ +public: + static const char * CRYPTOPP_API StaticAlgorithmName() {return "DSA-1363";} + + void Sign(const DL_GroupParameters ¶ms, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const + { + const Integer &q = params.GetSubgroupOrder(); + r %= q; + Integer kInv = k.InverseMod(q); + s = (kInv * (x*r + e)) % q; + assert(!!r && !!s); + } + + bool Verify(const DL_GroupParameters ¶ms, const DL_PublicKey &publicKey, const Integer &e, const Integer &r, const Integer &s) const + { + const Integer &q = params.GetSubgroupOrder(); + if (r>=q || r<1 || s>=q || s<1) + return false; + + Integer w = s.InverseMod(q); + Integer u1 = (e * w) % q; + Integer u2 = (r * w) % q; + // verify r == (g^u1 * y^u2 mod p) mod q + return r == params.ConvertElementToInteger(publicKey.CascadeExponentiateBaseAndPublicElement(u1, u2)) % q; + } +}; + +CRYPTOPP_DLL_TEMPLATE_CLASS DL_Algorithm_GDSA; + +//! NR algorithm +template +class DL_Algorithm_NR : public DL_ElgamalLikeSignatureAlgorithm +{ +public: + static const char * CRYPTOPP_API StaticAlgorithmName() {return "NR";} + + void Sign(const DL_GroupParameters ¶ms, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const + { + const Integer &q = params.GetSubgroupOrder(); + r = (r + e) % q; + s = (k - x*r) % q; + assert(!!r); + } + + bool Verify(const DL_GroupParameters ¶ms, const DL_PublicKey &publicKey, const Integer &e, const Integer &r, const Integer &s) const + { + const Integer &q = params.GetSubgroupOrder(); + if (r>=q || r<1 || s>=q) + return false; + + // check r == (m_g^s * m_y^r + m) mod m_q + return r == (params.ConvertElementToInteger(publicKey.CascadeExponentiateBaseAndPublicElement(s, r)) + e) % q; + } +}; + +/*! DSA public key format is defined in 7.3.3 of RFC 2459. The + private key format is defined in 12.9 of PKCS #11 v2.10. */ +template +class DL_PublicKey_GFP : public DL_PublicKeyImpl +{ +public: + void Initialize(const DL_GroupParameters_IntegerBased ¶ms, const Integer &y) + {this->AccessGroupParameters().Initialize(params); this->SetPublicElement(y);} + void Initialize(const Integer &p, const Integer &g, const Integer &y) + {this->AccessGroupParameters().Initialize(p, g); this->SetPublicElement(y);} + void Initialize(const Integer &p, const Integer &q, const Integer &g, const Integer &y) + {this->AccessGroupParameters().Initialize(p, q, g); this->SetPublicElement(y);} + + // X509PublicKey + void BERDecodePublicKey(BufferedTransformation &bt, bool, size_t) + {this->SetPublicElement(Integer(bt));} + void DEREncodePublicKey(BufferedTransformation &bt) const + {this->GetPublicElement().DEREncode(bt);} +}; + +//! DL private key (in GF(p) groups) +template +class DL_PrivateKey_GFP : public DL_PrivateKeyImpl +{ +public: + void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits) + {this->GenerateRandomWithKeySize(rng, modulusBits);} + void Initialize(RandomNumberGenerator &rng, const Integer &p, const Integer &g) + {this->GenerateRandom(rng, MakeParameters("Modulus", p)("SubgroupGenerator", g));} + void Initialize(RandomNumberGenerator &rng, const Integer &p, const Integer &q, const Integer &g) + {this->GenerateRandom(rng, MakeParameters("Modulus", p)("SubgroupOrder", q)("SubgroupGenerator", g));} + void Initialize(const DL_GroupParameters_IntegerBased ¶ms, const Integer &x) + {this->AccessGroupParameters().Initialize(params); this->SetPrivateExponent(x);} + void Initialize(const Integer &p, const Integer &g, const Integer &x) + {this->AccessGroupParameters().Initialize(p, g); this->SetPrivateExponent(x);} + void Initialize(const Integer &p, const Integer &q, const Integer &g, const Integer &x) + {this->AccessGroupParameters().Initialize(p, q, g); this->SetPrivateExponent(x);} +}; + +//! DL signing/verification keys (in GF(p) groups) +struct DL_SignatureKeys_GFP +{ + typedef DL_GroupParameters_GFP GroupParameters; + typedef DL_PublicKey_GFP PublicKey; + typedef DL_PrivateKey_GFP PrivateKey; +}; + +//! DL encryption/decryption keys (in GF(p) groups) +struct DL_CryptoKeys_GFP +{ + typedef DL_GroupParameters_GFP_DefaultSafePrime GroupParameters; + typedef DL_PublicKey_GFP PublicKey; + typedef DL_PrivateKey_GFP PrivateKey; +}; + +//! provided for backwards compatibility, this class uses the old non-standard Crypto++ key format +template +class DL_PublicKey_GFP_OldFormat : public BASE +{ +public: + void BERDecode(BufferedTransformation &bt) + { + BERSequenceDecoder seq(bt); + Integer v1(seq); + Integer v2(seq); + Integer v3(seq); + + if (seq.EndReached()) + { + this->AccessGroupParameters().Initialize(v1, v1/2, v2); + this->SetPublicElement(v3); + } + else + { + Integer v4(seq); + this->AccessGroupParameters().Initialize(v1, v2, v3); + this->SetPublicElement(v4); + } + + seq.MessageEnd(); + } + + void DEREncode(BufferedTransformation &bt) const + { + DERSequenceEncoder seq(bt); + this->GetGroupParameters().GetModulus().DEREncode(seq); + if (this->GetGroupParameters().GetCofactor() != 2) + this->GetGroupParameters().GetSubgroupOrder().DEREncode(seq); + this->GetGroupParameters().GetGenerator().DEREncode(seq); + this->GetPublicElement().DEREncode(seq); + seq.MessageEnd(); + } +}; + +//! provided for backwards compatibility, this class uses the old non-standard Crypto++ key format +template +class DL_PrivateKey_GFP_OldFormat : public BASE +{ +public: + void BERDecode(BufferedTransformation &bt) + { + BERSequenceDecoder seq(bt); + Integer v1(seq); + Integer v2(seq); + Integer v3(seq); + Integer v4(seq); + + if (seq.EndReached()) + { + this->AccessGroupParameters().Initialize(v1, v1/2, v2); + this->SetPrivateExponent(v4 % (v1/2)); // some old keys may have x >= q + } + else + { + Integer v5(seq); + this->AccessGroupParameters().Initialize(v1, v2, v3); + this->SetPrivateExponent(v5); + } + + seq.MessageEnd(); + } + + void DEREncode(BufferedTransformation &bt) const + { + DERSequenceEncoder seq(bt); + this->GetGroupParameters().GetModulus().DEREncode(seq); + if (this->GetGroupParameters().GetCofactor() != 2) + this->GetGroupParameters().GetSubgroupOrder().DEREncode(seq); + this->GetGroupParameters().GetGenerator().DEREncode(seq); + this->GetGroupParameters().ExponentiateBase(this->GetPrivateExponent()).DEREncode(seq); + this->GetPrivateExponent().DEREncode(seq); + seq.MessageEnd(); + } +}; + +//! DSA-1363 +template +struct GDSA : public DL_SS< + DL_SignatureKeys_GFP, + DL_Algorithm_GDSA, + DL_SignatureMessageEncodingMethod_DSA, + H> +{ +}; + +//! NR +template +struct NR : public DL_SS< + DL_SignatureKeys_GFP, + DL_Algorithm_NR, + DL_SignatureMessageEncodingMethod_NR, + H> +{ +}; + +//! DSA group parameters, these are GF(p) group parameters that are allowed by the DSA standard +class CRYPTOPP_DLL DL_GroupParameters_DSA : public DL_GroupParameters_GFP +{ +public: + /*! also checks that the lengths of p and q are allowed by the DSA standard */ + bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const; + /*! parameters: (ModulusSize), or (Modulus, SubgroupOrder, SubgroupGenerator) */ + /*! ModulusSize must be between DSA::MIN_PRIME_LENGTH and DSA::MAX_PRIME_LENGTH, and divisible by DSA::PRIME_LENGTH_MULTIPLE */ + void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg); +}; + +struct DSA; + +//! DSA keys +struct DL_Keys_DSA +{ + typedef DL_PublicKey_GFP PublicKey; + typedef DL_PrivateKey_WithSignaturePairwiseConsistencyTest, DSA> PrivateKey; +}; + +//! DSA +struct CRYPTOPP_DLL DSA : public DL_SS< + DL_Keys_DSA, + DL_Algorithm_GDSA, + DL_SignatureMessageEncodingMethod_DSA, + SHA, + DSA> +{ + static const char * CRYPTOPP_API StaticAlgorithmName() {return "DSA";} + + //! Generate DSA primes according to NIST standard + /*! Both seedLength and primeLength are in bits, but seedLength should + be a multiple of 8. + If useInputCounterValue == true, the counter parameter is taken as input, otherwise it's used for output + */ + static bool CRYPTOPP_API GeneratePrimes(const byte *seed, unsigned int seedLength, int &counter, + Integer &p, unsigned int primeLength, Integer &q, bool useInputCounterValue = false); + + static bool CRYPTOPP_API IsValidPrimeLength(unsigned int pbits) + {return pbits >= MIN_PRIME_LENGTH && pbits <= MAX_PRIME_LENGTH && pbits % PRIME_LENGTH_MULTIPLE == 0;} + + //! FIPS 186-2 Change Notice 1 changed the minimum modulus length to 1024 + enum { +#if (DSA_1024_BIT_MODULUS_ONLY) + MIN_PRIME_LENGTH = 1024, +#else + MIN_PRIME_LENGTH = 512, +#endif + MAX_PRIME_LENGTH = 1024, PRIME_LENGTH_MULTIPLE = 64}; +}; + +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PublicKey_GFP; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_GFP; +CRYPTOPP_DLL_TEMPLATE_CLASS DL_PrivateKey_WithSignaturePairwiseConsistencyTest, DSA>; + +//! the XOR encryption method, for use with DL-based cryptosystems +template +class DL_EncryptionAlgorithm_Xor : public DL_SymmetricEncryptionAlgorithm +{ +public: + bool ParameterSupported(const char *name) const {return strcmp(name, Name::EncodingParameters()) == 0;} + size_t GetSymmetricKeyLength(size_t plaintextLength) const + {return plaintextLength + MAC::DEFAULT_KEYLENGTH;} + size_t GetSymmetricCiphertextLength(size_t plaintextLength) const + {return plaintextLength + MAC::DIGESTSIZE;} + size_t GetMaxSymmetricPlaintextLength(size_t ciphertextLength) const + {return (unsigned int)SaturatingSubtract(ciphertextLength, (unsigned int)MAC::DIGESTSIZE);} + void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs ¶meters) const + { + const byte *cipherKey, *macKey; + if (DHAES_MODE) + { + macKey = key; + cipherKey = key + MAC::DEFAULT_KEYLENGTH; + } + else + { + cipherKey = key; + macKey = key + plaintextLength; + } + + ConstByteArrayParameter encodingParameters; + parameters.GetValue(Name::EncodingParameters(), encodingParameters); + + xorbuf(ciphertext, plaintext, cipherKey, plaintextLength); + MAC mac(macKey); + mac.Update(ciphertext, plaintextLength); + mac.Update(encodingParameters.begin(), encodingParameters.size()); + if (DHAES_MODE) + { + byte L[8] = {0,0,0,0}; + PutWord(false, BIG_ENDIAN_ORDER, L+4, word32(encodingParameters.size())); + mac.Update(L, 8); + } + mac.Final(ciphertext + plaintextLength); + } + DecodingResult SymmetricDecrypt(const byte *key, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs ¶meters) const + { + size_t plaintextLength = GetMaxSymmetricPlaintextLength(ciphertextLength); + const byte *cipherKey, *macKey; + if (DHAES_MODE) + { + macKey = key; + cipherKey = key + MAC::DEFAULT_KEYLENGTH; + } + else + { + cipherKey = key; + macKey = key + plaintextLength; + } + + ConstByteArrayParameter encodingParameters; + parameters.GetValue(Name::EncodingParameters(), encodingParameters); + + MAC mac(macKey); + mac.Update(ciphertext, plaintextLength); + mac.Update(encodingParameters.begin(), encodingParameters.size()); + if (DHAES_MODE) + { + byte L[8] = {0,0,0,0}; + PutWord(false, BIG_ENDIAN_ORDER, L+4, word32(encodingParameters.size())); + mac.Update(L, 8); + } + if (!mac.Verify(ciphertext + plaintextLength)) + return DecodingResult(); + + xorbuf(plaintext, ciphertext, cipherKey, plaintextLength); + return DecodingResult(plaintextLength); + } +}; + +//! _ +template +class DL_KeyDerivationAlgorithm_P1363 : public DL_KeyDerivationAlgorithm +{ +public: + bool ParameterSupported(const char *name) const {return strcmp(name, Name::KeyDerivationParameters()) == 0;} + void Derive(const DL_GroupParameters ¶ms, byte *derivedKey, size_t derivedLength, const T &agreedElement, const T &ephemeralPublicKey, const NameValuePairs ¶meters) const + { + SecByteBlock agreedSecret; + if (DHAES_MODE) + { + agreedSecret.New(params.GetEncodedElementSize(true) + params.GetEncodedElementSize(false)); + params.EncodeElement(true, ephemeralPublicKey, agreedSecret); + params.EncodeElement(false, agreedElement, agreedSecret + params.GetEncodedElementSize(true)); + } + else + { + agreedSecret.New(params.GetEncodedElementSize(false)); + params.EncodeElement(false, agreedElement, agreedSecret); + } + + ConstByteArrayParameter derivationParameters; + parameters.GetValue(Name::KeyDerivationParameters(), derivationParameters); + KDF::DeriveKey(derivedKey, derivedLength, agreedSecret, agreedSecret.size(), derivationParameters.begin(), derivationParameters.size()); + } +}; + +//! Discrete Log Integrated Encryption Scheme, AKA DLIES +template +struct DLIES + : public DL_ES< + DL_CryptoKeys_GFP, + DL_KeyAgreementAlgorithm_DH, + DL_KeyDerivationAlgorithm_P1363 >, + DL_EncryptionAlgorithm_Xor, DHAES_MODE>, + DLIES<> > +{ + static std::string CRYPTOPP_API StaticAlgorithmName() {return "DLIES";} // TODO: fix this after name is standardized +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/gost.cpp b/CryptoPP/crypto/gost.cpp new file mode 100644 index 0000000..4318b3d --- /dev/null +++ b/CryptoPP/crypto/gost.cpp @@ -0,0 +1,123 @@ +#include "pch.h" +#include "gost.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +// these are the S-boxes given in Applied Cryptography 2nd Ed., p. 333 +const byte GOST::Base::sBox[8][16]={ + {4, 10, 9, 2, 13, 8, 0, 14, 6, 11, 1, 12, 7, 15, 5, 3}, + {14, 11, 4, 12, 6, 13, 15, 10, 2, 3, 8, 1, 0, 7, 5, 9}, + {5, 8, 1, 13, 10, 3, 4, 2, 14, 15, 12, 7, 6, 0, 9, 11}, + {7, 13, 10, 1, 0, 8, 9, 15, 14, 4, 6, 12, 11, 2, 5, 3}, + {6, 12, 7, 1, 5, 15, 13, 8, 4, 10, 9, 14, 0, 3, 11, 2}, + {4, 11, 10, 0, 7, 2, 1, 13, 3, 6, 8, 5, 9, 12, 15, 14}, + {13, 11, 4, 1, 3, 15, 5, 9, 0, 10, 14, 7, 6, 8, 2, 12}, + {1, 15, 13, 0, 5, 7, 10, 4, 9, 2, 3, 14, 6, 11, 8, 12}}; + +/* // these are the S-boxes given in the GOST source code listing in Applied + // Cryptography 2nd Ed., p. 644. they appear to be from the DES S-boxes + {13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7 }, + { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 }, + {12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11 }, + { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9 }, + { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15 }, + {10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 }, + {15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10 }, + {14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 }}; +*/ + +bool GOST::Base::sTableCalculated = false; +word32 GOST::Base::sTable[4][256]; + +void GOST::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs &) +{ + AssertValidKeyLength(length); + + PrecalculateSTable(); + + GetUserKey(LITTLE_ENDIAN_ORDER, key.begin(), 8, userKey, KEYLENGTH); +} + +void GOST::Base::PrecalculateSTable() +{ + if (!sTableCalculated) + { + for (unsigned i = 0; i < 4; i++) + for (unsigned j = 0; j < 256; j++) + { + word32 temp = sBox[2*i][j%16] | (sBox[2*i+1][j/16] << 4); + sTable[i][j] = rotlMod(temp, 11+8*i); + } + + sTableCalculated=true; + } +} + +#define f(x) ( t=x, \ + sTable[3][GETBYTE(t, 3)] ^ sTable[2][GETBYTE(t, 2)] \ + ^ sTable[1][GETBYTE(t, 1)] ^ sTable[0][GETBYTE(t, 0)] ) + +typedef BlockGetAndPut Block; + +void GOST::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word32 n1, n2, t; + + Block::Get(inBlock)(n1)(n2); + + for (unsigned int i=0; i<3; i++) + { + n2 ^= f(n1+key[0]); + n1 ^= f(n2+key[1]); + n2 ^= f(n1+key[2]); + n1 ^= f(n2+key[3]); + n2 ^= f(n1+key[4]); + n1 ^= f(n2+key[5]); + n2 ^= f(n1+key[6]); + n1 ^= f(n2+key[7]); + } + + n2 ^= f(n1+key[7]); + n1 ^= f(n2+key[6]); + n2 ^= f(n1+key[5]); + n1 ^= f(n2+key[4]); + n2 ^= f(n1+key[3]); + n1 ^= f(n2+key[2]); + n2 ^= f(n1+key[1]); + n1 ^= f(n2+key[0]); + + Block::Put(xorBlock, outBlock)(n2)(n1); +} + +void GOST::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word32 n1, n2, t; + + Block::Get(inBlock)(n1)(n2); + + n2 ^= f(n1+key[0]); + n1 ^= f(n2+key[1]); + n2 ^= f(n1+key[2]); + n1 ^= f(n2+key[3]); + n2 ^= f(n1+key[4]); + n1 ^= f(n2+key[5]); + n2 ^= f(n1+key[6]); + n1 ^= f(n2+key[7]); + + for (unsigned int i=0; i<3; i++) + { + n2 ^= f(n1+key[7]); + n1 ^= f(n2+key[6]); + n2 ^= f(n1+key[5]); + n1 ^= f(n2+key[4]); + n2 ^= f(n1+key[3]); + n1 ^= f(n2+key[2]); + n2 ^= f(n1+key[1]); + n1 ^= f(n2+key[0]); + } + + Block::Put(xorBlock, outBlock)(n2)(n1); +} + +NAMESPACE_END diff --git a/CryptoPP/crypto/gost.h b/CryptoPP/crypto/gost.h new file mode 100644 index 0000000..a919120 --- /dev/null +++ b/CryptoPP/crypto/gost.h @@ -0,0 +1,58 @@ +#ifndef CRYPTOPP_GOST_H +#define CRYPTOPP_GOST_H + +/** \file +*/ + +#include "seckey.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! _ +struct GOST_Info : public FixedBlockSize<8>, public FixedKeyLength<32> +{ + static const char *StaticAlgorithmName() {return "GOST";} +}; + +/// GOST +class GOST : public GOST_Info, public BlockCipherDocumentation +{ + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + public: + void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); + + protected: + static void PrecalculateSTable(); + + static const byte sBox[8][16]; + static bool sTableCalculated; + static word32 sTable[4][256]; + + FixedSizeSecBlock key; + }; + + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef GOST::Encryption GOSTEncryption; +typedef GOST::Decryption GOSTDecryption; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/gostval.dat b/CryptoPP/crypto/gostval.dat new file mode 100644 index 0000000..d81d03b --- /dev/null +++ b/CryptoPP/crypto/gostval.dat @@ -0,0 +1,23 @@ +BE5EC2006CFF9DCF52354959F1FF0CBFE95061B5A648C10387069C25997C0672 +0DF82802B741A292 07F9027DF7F7DF89 + +B385272AC8D72A5A8B344BC80363AC4D09BF58F41F540624CBCB8FDCF55307D7 +1354EE9C0A11CD4C 4FB50536F960A7B1 + +AEE02F609A35660E4097E546FD3026B032CD107C7D459977ADF489BEF2652262 +6693D492C4B0CC39 670034AC0FA811B5 + +320E9D8422165D58911DFC7D8BBB1F81B0ECD924023BF94D9DF7DCF7801240E0 +99E2D13080928D79 8118FF9D3B3CFE7D + +C9F703BBBFC63691BFA3B7B87EA8FD5E8E8EF384EF733F1A61AEF68C8FFA265F +D1E787749C72814C A083826A790D3E0C + +728FEE32F04B4C654AD7F607D71C660C2C2670D7C999713233149A1C0C17A1F0 +D4C05323A4F7A7B5 4D1F2E6B0D9DE2CE + +35FC96402209500FCFDEF5352D1ABB038FE33FC0D9D58512E56370B22BAA133B +8742D9A05F6A3AF6 2F3BB84879D11E52 + +D416F630BE65B7FE150656183370E07018234EE5DA3D89C4CE9152A03E5BFB77 +F86506DA04E41CB8 96F0A5C77A04F5CE diff --git a/CryptoPP/crypto/gzip.cpp b/CryptoPP/crypto/gzip.cpp new file mode 100644 index 0000000..c9f7558 --- /dev/null +++ b/CryptoPP/crypto/gzip.cpp @@ -0,0 +1,99 @@ +// gzip.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "gzip.h" + +NAMESPACE_BEGIN(CryptoPP) + +void Gzip::WritePrestreamHeader() +{ + m_totalLen = 0; + m_crc.Restart(); + + AttachedTransformation()->Put(MAGIC1); + AttachedTransformation()->Put(MAGIC2); + AttachedTransformation()->Put(DEFLATED); + AttachedTransformation()->Put(0); // general flag + AttachedTransformation()->PutWord32(0); // time stamp + byte extra = (GetDeflateLevel() == 1) ? FAST : ((GetDeflateLevel() == 9) ? SLOW : 0); + AttachedTransformation()->Put(extra); + AttachedTransformation()->Put(GZIP_OS_CODE); +} + +void Gzip::ProcessUncompressedData(const byte *inString, size_t length) +{ + m_crc.Update(inString, length); + m_totalLen += (word32)length; +} + +void Gzip::WritePoststreamTail() +{ + SecByteBlock crc(4); + m_crc.Final(crc); + AttachedTransformation()->Put(crc, 4); + AttachedTransformation()->PutWord32(m_totalLen, LITTLE_ENDIAN_ORDER); +} + +// ************************************************************* + +Gunzip::Gunzip(BufferedTransformation *attachment, bool repeat, int propagation) + : Inflator(attachment, repeat, propagation) +{ +} + +void Gunzip::ProcessPrestreamHeader() +{ + m_length = 0; + m_crc.Restart(); + + byte buf[6]; + byte b, flags; + + if (m_inQueue.Get(buf, 2)!=2) throw HeaderErr(); + if (buf[0] != MAGIC1 || buf[1] != MAGIC2) throw HeaderErr(); + if (!m_inQueue.Skip(1)) throw HeaderErr(); // skip extra flags + if (!m_inQueue.Get(flags)) throw HeaderErr(); + if (flags & (ENCRYPTED | CONTINUED)) throw HeaderErr(); + if (m_inQueue.Skip(6)!=6) throw HeaderErr(); // Skip file time, extra flags and OS type + + if (flags & EXTRA_FIELDS) // skip extra fields + { + word16 length; + if (m_inQueue.GetWord16(length, LITTLE_ENDIAN_ORDER) != 2) throw HeaderErr(); + if (m_inQueue.Skip(length)!=length) throw HeaderErr(); + } + + if (flags & FILENAME) // skip filename + do + if(!m_inQueue.Get(b)) throw HeaderErr(); + while (b); + + if (flags & COMMENTS) // skip comments + do + if(!m_inQueue.Get(b)) throw HeaderErr(); + while (b); +} + +void Gunzip::ProcessDecompressedData(const byte *inString, size_t length) +{ + AttachedTransformation()->Put(inString, length); + m_crc.Update(inString, length); + m_length += (word32)length; +} + +void Gunzip::ProcessPoststreamTail() +{ + SecByteBlock crc(4); + if (m_inQueue.Get(crc, 4) != 4) + throw TailErr(); + if (!m_crc.Verify(crc)) + throw CrcErr(); + + word32 lengthCheck; + if (m_inQueue.GetWord32(lengthCheck, LITTLE_ENDIAN_ORDER) != 4) + throw TailErr(); + if (lengthCheck != m_length) + throw LengthErr(); +} + +NAMESPACE_END diff --git a/CryptoPP/crypto/gzip.h b/CryptoPP/crypto/gzip.h new file mode 100644 index 0000000..b96fc1e --- /dev/null +++ b/CryptoPP/crypto/gzip.h @@ -0,0 +1,65 @@ +#ifndef CRYPTOPP_GZIP_H +#define CRYPTOPP_GZIP_H + +#include "zdeflate.h" +#include "zinflate.h" +#include "crc.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// GZIP Compression (RFC 1952) +class Gzip : public Deflator +{ +public: + Gzip(BufferedTransformation *attachment=NULL, unsigned int deflateLevel=DEFAULT_DEFLATE_LEVEL, unsigned int log2WindowSize=DEFAULT_LOG2_WINDOW_SIZE, bool detectUncompressible=true) + : Deflator(attachment, deflateLevel, log2WindowSize, detectUncompressible) {} + Gzip(const NameValuePairs ¶meters, BufferedTransformation *attachment=NULL) + : Deflator(parameters, attachment) {} + +protected: + enum {MAGIC1=0x1f, MAGIC2=0x8b, // flags for the header + DEFLATED=8, FAST=4, SLOW=2}; + + void WritePrestreamHeader(); + void ProcessUncompressedData(const byte *string, size_t length); + void WritePoststreamTail(); + + word32 m_totalLen; + CRC32 m_crc; +}; + +/// GZIP Decompression (RFC 1952) +class Gunzip : public Inflator +{ +public: + typedef Inflator::Err Err; + class HeaderErr : public Err {public: HeaderErr() : Err(INVALID_DATA_FORMAT, "Gunzip: header decoding error") {}}; + class TailErr : public Err {public: TailErr() : Err(INVALID_DATA_FORMAT, "Gunzip: tail too short") {}}; + class CrcErr : public Err {public: CrcErr() : Err(DATA_INTEGRITY_CHECK_FAILED, "Gunzip: CRC check error") {}}; + class LengthErr : public Err {public: LengthErr() : Err(DATA_INTEGRITY_CHECK_FAILED, "Gunzip: length check error") {}}; + + /*! \param repeat decompress multiple compressed streams in series + \param autoSignalPropagation 0 to turn off MessageEnd signal + */ + Gunzip(BufferedTransformation *attachment = NULL, bool repeat = false, int autoSignalPropagation = -1); + +protected: + enum {MAGIC1=0x1f, MAGIC2=0x8b, // flags for the header + DEFLATED=8}; + + enum FLAG_MASKS { + CONTINUED=2, EXTRA_FIELDS=4, FILENAME=8, COMMENTS=16, ENCRYPTED=32}; + + unsigned int MaxPrestreamHeaderSize() const {return 1024;} + void ProcessPrestreamHeader(); + void ProcessDecompressedData(const byte *string, size_t length); + unsigned int MaxPoststreamTailSize() const {return 8;} + void ProcessPoststreamTail(); + + word32 m_length; + CRC32 m_crc; +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/haval.cpp b/CryptoPP/crypto/haval.cpp new file mode 100644 index 0000000..d98d38e --- /dev/null +++ b/CryptoPP/crypto/haval.cpp @@ -0,0 +1,276 @@ +// haval.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "haval.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +HAVAL::HAVAL(unsigned int digestSize, unsigned int pass) + : digestSize(digestSize), pass(pass) +{ + SetStateSize(DIGESTSIZE); + + if (!(digestSize >= 16 && digestSize <= 32 && digestSize%4==0)) + throw InvalidArgument("HAVAL: invalid digest size"); + + if (!(pass >= 3 && pass <= 5)) + throw InvalidArgument("HAVAL: invalid number of passes"); + + Init(); +} + +void HAVAL::Init() +{ + m_digest[0] = 0x243F6A88; + m_digest[1] = 0x85A308D3; + m_digest[2] = 0x13198A2E; + m_digest[3] = 0x03707344; + m_digest[4] = 0xA4093822; + m_digest[5] = 0x299F31D0; + m_digest[6] = 0x082EFA98; + m_digest[7] = 0xEC4E6C89; +} + +void HAVAL::HashEndianCorrectedBlock(const word32 *in) +{ + if (pass==3) + HAVAL3::Transform(m_digest, in); + else if (pass==4) + HAVAL4::Transform(m_digest, in); + else + HAVAL5::Transform(m_digest, in); +} + +void HAVAL::TruncatedFinal(byte *hash, size_t size) +{ + ThrowIfInvalidTruncatedSize(size); + + PadLastBlock(118, 1); // first byte of padding for HAVAL is 1 instead of 0x80 + CorrectEndianess(m_data, m_data, 120); + + m_data[29] &= 0xffff; + m_data[29] |= ((word32)digestSize<<25) | ((word32)pass<<19) | ((word32)HAVAL_VERSION<<16); + m_data[30] = GetBitCountLo(); + m_data[31] = GetBitCountHi(); + + HashEndianCorrectedBlock(m_data); + Tailor(digestSize*8); + CorrectEndianess(m_digest, m_digest, digestSize); + memcpy(hash, m_digest, size); + + Restart(); // reinit for next use +} + +#define ROTR(x, y) rotrFixed(x, y##u) + +// fold digest down to desired size +void HAVAL::Tailor(unsigned int bitlen) +{ +#define EB(a, b, c) (m_digest[a] & (((~(word32)0) << b) & ((~(word32)0) >> (8*sizeof(word32)-b-c)))) +#define S(a, b) (a > b ? a - b : 32 + a - b) +#define T128(a, b, c, d, e) ROTR(EB(7, b, S(a,b)) | EB(6, c, S(b,c)) | EB(5, d, S(c,d)) | EB(4, e, S(d,e)), e) +#define T160(a, b, c, d) ROTR(EB(7, b, S(a,b)) | EB(6, c, S(b,c)) | EB(5, d, S(c,d)), d) +#define T192(a, b, c) ROTR(EB(7, b, S(a,b)) | EB(6, c, S(b,c)), c) +#define T224(a, b) ROTR(EB(7, b, S(a,b)), b) + + switch (bitlen) + { + case 128: + m_digest[0] += T128(8, 0, 24, 16, 8); + m_digest[1] += T128(16, 8, 0, 24, 16); + m_digest[2] += T128(24, 16, 8, 0, 24); + m_digest[3] += T128(0, 24, 16, 8, 0); + break; + + case 160: + m_digest[0] += T160(6, 0, 25, 19); + m_digest[1] += T160(12, 6, 0, 25); + m_digest[2] += T160(19, 12, 6, 0); + m_digest[3] += T160(25, 19, 12, 6); + m_digest[4] += T160(0, 25, 19, 12); + break; + + case 192: + m_digest[0] += T192(5, 0, 26); + m_digest[1] += T192(10, 5, 0); + m_digest[2] += T192(16, 10, 5); + m_digest[3] += T192(21, 16, 10); + m_digest[4] += T192(26, 21, 16); + m_digest[5] += T192(0, 26, 21); + break; + + case 224: + m_digest[0] += T224(0, 27); + m_digest[1] += T224(27, 22); + m_digest[2] += T224(22, 18); + m_digest[3] += T224(18, 13); + m_digest[4] += T224(13, 9); + m_digest[5] += T224(9, 4); + m_digest[6] += T224(4, 0); + break; + + case 256: + break; + + default: + assert(false); + } +} + +/* Nonlinear F functions */ + +/* #define F1(X6, X5, X4, X3, X2, X1, X0) \ + ((X1) & (X4) ^ (X2) & (X5) ^ (X3) & (X6) ^ (X0) & (X1) ^ (X0))*/ +#define F1(X6, X5, X4, X3, X2, X1, X0) \ + (((X1) & ((X4) ^ (X0))) ^ ((X2) & (X5)) ^ ((X3) & (X6)) ^ (X0)) + +/* #define F2(X6, X5, X4, X3, X2, X1, X0) \ + ((X1) & (X2) & (X3) ^ (X2) & (X4) & (X5) ^ \ + (X1) & (X2) ^ (X1) & (X4) ^ (X2) & (X6) ^ (X3) & (X5) ^ \ + (X4) & (X5) ^ (X0) & (X2) ^ (X0))*/ +#define F2(X6, X5, X4, X3, X2, X1, X0) \ + (((X2) & (((X1) & (~(X3))) ^ ((X4) & (X5)) ^ (X6) ^ (X0))) ^ \ + (((X4) & ((X1) ^ (X5))) ^ ((X3) & (X5)) ^ (X0))) + +/* #define F3(X6, X5, X4, X3, X2, X1, X0) \ + ((X1) & (X2) & (X3) ^ (X1) & (X4) ^ (X2) & (X5) ^ (X3) & (X6) ^ (X0) & +(X3) ^ (X0))*/ +#define F3(X6, X5, X4, X3, X2, X1, X0) \ + (((X3) & (((X1) & (X2)) ^ (X6) ^ (X0))) ^ ((X1) & (X4)) ^ \ + ((X2) & (X5)) ^ (X0)) + +/* #define F4(X6, X5, X4, X3, X2, X1, X0) \ + ((X1) & (X2) & (X3) ^ (X2) & (X4) & (X5) ^ (X3) & (X4) & (X6) ^ \ + (X1) & (X4) ^ (X2) & (X6) ^ (X3) & (X4) ^ (X3) & (X5) ^ \ + (X3) & (X6) ^ (X4) & (X5) ^ (X4) & (X6) ^ (X0) & (X4) ^(X0))*/ +#define F4(X6, X5, X4, X3, X2, X1, X0) \ + (((X4) & (((~(X2)) & (X5)) ^ ((X3) | (X6)) ^ (X1) ^ (X0))) ^ \ + ((X3) & (((X1) & (X2)) ^ (X5) ^ (X6))) ^ ((X2) & (X6)) ^ (X0)) + +/* #define F5(X6, X5, X4, X3, X2, X1, X0) \ + ((X1) & (X4) ^ (X2) & (X5) ^ (X3) & (X6) ^ \ + (X0) & (X1) & (X2) & (X3) ^ (X0) & (X5) ^ (X0))*/ +#define F5(X6, X5, X4, X3, X2, X1, X0) \ + (((X1) & ((X4) ^ ((X0) & (X2) & (X3)))) ^ \ + (((X2) ^ (X0)) & (X5)) ^ ((X3) & (X6)) ^ (X0)) + +#define p31(x) (x==0 ? 1 : (x==1 ? 0 : (x==2 ? 3 : (x==3 ? 5 : (x==4 ? 6 : (x==5 ? 2 : (x==6 ? 4 : 7))))))) +#define p41(x) (x==0 ? 2 : (x==1 ? 6 : (x==2 ? 1 : (x==3 ? 4 : (x==4 ? 5 : (x==5 ? 3 : (x==6 ? 0 : 7))))))) +#define p51(x) (x==0 ? 3 : (x==1 ? 4 : (x==2 ? 1 : (x==3 ? 0 : (x==4 ? 5 : (x==5 ? 2 : (x==6 ? 6 : 7))))))) +#define p32(x) (x==0 ? 4 : (x==1 ? 2 : (x==2 ? 1 : (x==3 ? 0 : (x==4 ? 5 : (x==5 ? 3 : (x==6 ? 6 : 7))))))) +#define p42(x) (x==0 ? 3 : (x==1 ? 5 : (x==2 ? 2 : (x==3 ? 0 : (x==4 ? 1 : (x==5 ? 6 : (x==6 ? 4 : 7))))))) +#define p52(x) (x==0 ? 6 : (x==1 ? 2 : (x==2 ? 1 : (x==3 ? 0 : (x==4 ? 3 : (x==5 ? 4 : (x==6 ? 5 : 7))))))) +#define p33(x) (x==0 ? 6 : (x==1 ? 1 : (x==2 ? 2 : (x==3 ? 3 : (x==4 ? 4 : (x==5 ? 5 : (x==6 ? 0 : 7))))))) +#define p43(x) (x==0 ? 1 : (x==1 ? 4 : (x==2 ? 3 : (x==3 ? 6 : (x==4 ? 0 : (x==5 ? 2 : (x==6 ? 5 : 7))))))) +#define p53(x) (x==0 ? 2 : (x==1 ? 6 : (x==2 ? 0 : (x==3 ? 4 : (x==4 ? 3 : (x==5 ? 1 : (x==6 ? 5 : 7))))))) +#define p44(x) (x==0 ? 6 : (x==1 ? 4 : (x==2 ? 0 : (x==3 ? 5 : (x==4 ? 2 : (x==5 ? 1 : (x==6 ? 3 : 7))))))) +#define p54(x) (x==0 ? 1 : (x==1 ? 5 : (x==2 ? 3 : (x==3 ? 2 : (x==4 ? 0 : (x==5 ? 4 : (x==6 ? 6 : 7))))))) +#define p55(x) (x==0 ? 2 : (x==1 ? 5 : (x==2 ? 0 : (x==3 ? 6 : (x==4 ? 4 : (x==5 ? 3 : (x==6 ? 1 : 7))))))) + +#define t(b,p,x,j) ((b&&((p(x)+8-j)%8<(8-j)))?E:T)[(p(x)+8-j)%8] + +#define FF(b, e, F, p, j, w, c) \ + T[7-j] = rotrFixed(F(t(b,p,0,j), t(b,p,1,j), t(b,p,2,j), t(b,p,3,j), t(b,p,4,j), t(b,p,5,j), t(b,p,6,j)), 7U) + rotrFixed(t(b,p,7,j), 11U) + w + c; \ + if (e) E[7-j] += T[7-j]; + +#ifdef CRYPTOPP_DOXYGEN_PROCESSING +// Doxygen can't handle these macros +#define Round1(t) +#define Round(t, n) +#else +#define Round1(t) \ + for (i=0; i<4; i++) \ + { \ + FF(i==0, 0, F1, p##t##1, 0, W[8*i+0], 0); \ + FF(i==0, 0, F1, p##t##1, 1, W[8*i+1], 0); \ + FF(i==0, 0, F1, p##t##1, 2, W[8*i+2], 0); \ + FF(i==0, 0, F1, p##t##1, 3, W[8*i+3], 0); \ + FF(i==0, 0, F1, p##t##1, 4, W[8*i+4], 0); \ + FF(i==0, 0, F1, p##t##1, 5, W[8*i+5], 0); \ + FF(i==0, 0, F1, p##t##1, 6, W[8*i+6], 0); \ + FF(i==0, 0, F1, p##t##1, 7, W[8*i+7], 0); \ + } +#define Round(t, n) \ + for (i=0; i<4; i++) \ + { \ + FF(0, t==n && i==3, F##n, p##t##n, 0, W[wi##n[8*i+0]], mc##n[8*i+0]); \ + FF(0, t==n && i==3, F##n, p##t##n, 1, W[wi##n[8*i+1]], mc##n[8*i+1]); \ + FF(0, t==n && i==3, F##n, p##t##n, 2, W[wi##n[8*i+2]], mc##n[8*i+2]); \ + FF(0, t==n && i==3, F##n, p##t##n, 3, W[wi##n[8*i+3]], mc##n[8*i+3]); \ + FF(0, t==n && i==3, F##n, p##t##n, 4, W[wi##n[8*i+4]], mc##n[8*i+4]); \ + FF(0, t==n && i==3, F##n, p##t##n, 5, W[wi##n[8*i+5]], mc##n[8*i+5]); \ + FF(0, t==n && i==3, F##n, p##t##n, 6, W[wi##n[8*i+6]], mc##n[8*i+6]); \ + FF(0, t==n && i==3, F##n, p##t##n, 7, W[wi##n[8*i+7]], mc##n[8*i+7]); \ + } +#endif + +const unsigned int HAVAL::wi2[32] = { 5,14,26,18,11,28, 7,16, 0,23,20,22, 1,10, 4, 8,30, 3,21, 9,17,24,29, 6,19,12,15,13, 2,25,31,27}; +const unsigned int HAVAL::wi3[32] = {19, 9, 4,20,28,17, 8,22,29,14,25,12,24,30,16,26,31,15, 7, 3, 1, 0,18,27,13, 6,21,10,23,11, 5, 2}; +const unsigned int HAVAL::wi4[32] = {24, 4, 0,14, 2, 7,28,23,26, 6,30,20,18,25,19, 3,22,11,31,21, 8,27,12, 9, 1,29, 5,15,17,10,16,13}; +const unsigned int HAVAL::wi5[32] = {27, 3,21,26,17,11,20,29,19, 0,12, 7,13, 8,31,10, 5, 9,14,30,18, 6,28,24, 2,23,16,22, 4, 1,25,15}; + +const word32 HAVAL::mc2[32] = { + 0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C, 0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917 +, 0x9216D5D9, 0x8979FB1B, 0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7, 0xB8E1AFED, 0x6A267E96 +, 0xBA7C9045, 0xF12C7F99, 0x24A19947, 0xB3916CF7, 0x0801F2E2, 0x858EFC16, 0x636920D8, 0x71574E69 +, 0xA458FEA3, 0xF4933D7E, 0x0D95748F, 0x728EB658, 0x718BCD58, 0x82154AEE, 0x7B54A41D, 0xC25A59B5}; + +const word32 HAVAL::mc3[32] = { +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}; + +const word32 HAVAL::mc4[32] = { +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}; + +const word32 HAVAL::mc5[32] = { +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}; + +void HAVAL3::Transform(word32 *E, const word32 *W) +{ + word32 T[8]; + unsigned int i; + + Round1(3); + Round(3, 2); + Round(3, 3); + + memset(T, 0, sizeof(T)); +} + +void HAVAL4::Transform(word32 *E, const word32 *W) +{ + word32 T[8]; + unsigned int i; + + Round1(4); + Round(4, 2); + Round(4, 3); + Round(4, 4); + + memset(T, 0, sizeof(T)); +} + +void HAVAL5::Transform(word32 *E, const word32 *W) +{ + word32 T[8]; + unsigned int i; + + Round1(5); + Round(5, 2); + Round(5, 3); + Round(5, 4); + Round(5, 5); + + memset(T, 0, sizeof(T)); +} + +NAMESPACE_END diff --git a/CryptoPP/crypto/haval.h b/CryptoPP/crypto/haval.h new file mode 100644 index 0000000..4cd6db3 --- /dev/null +++ b/CryptoPP/crypto/haval.h @@ -0,0 +1,63 @@ +#ifndef CRYPTOPP_HAVAL_H +#define CRYPTOPP_HAVAL_H + +#include "iterhash.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// HAVAL +/*! \warning HAVAL with 128-bit or 160-bit output is considered insecure, and should not be used + unless you absolutely need it for compatibility. */ +class HAVAL : public IteratedHash +{ +public: + enum {HAVAL_VERSION = 1}; + CRYPTOPP_CONSTANT(DIGESTSIZE = 32) + + /// digestSize can be 16, 20, 24, 28, or 32 (Default=32)
+ /// pass can be 3, 4 or 5 (Default=3) + HAVAL(unsigned int digestSize=DIGESTSIZE, unsigned int passes=3); + void TruncatedFinal(byte *hash, size_t size); + unsigned int DigestSize() const {return digestSize;} + + static const char * StaticAlgorithmName() {return "HAVAL";} + std::string AlgorithmName() const {return std::string("HAVAL(") + IntToString(digestSize) + "," + IntToString(pass) + ")";} + +protected: + static const unsigned int wi2[32], wi3[32], wi4[32], wi5[32]; + static const word32 mc2[32], mc3[32], mc4[32], mc5[32]; + + void Init(); + void Tailor(unsigned int FPTLEN); + void HashEndianCorrectedBlock(const word32 *in); + + const unsigned int digestSize, pass; +}; + +/// HAVAL with 3 passes +class HAVAL3 : public HAVAL +{ +public: + HAVAL3(unsigned int digestSize=DIGESTSIZE) : HAVAL(digestSize, 3) {} + static void Transform(word32 *buf, const word32 *in); +}; + +/// HAVAL with 4 passes +class HAVAL4 : public HAVAL +{ +public: + HAVAL4(unsigned int digestSize=DIGESTSIZE) : HAVAL(digestSize, 4) {} + static void Transform(word32 *buf, const word32 *in); +}; + +/// HAVAL with 5 passes +class HAVAL5 : public HAVAL +{ +public: + HAVAL5(unsigned int digestSize=DIGESTSIZE) : HAVAL(digestSize, 5) {} + static void Transform(word32 *buf, const word32 *in); +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/havalcer.dat b/CryptoPP/crypto/havalcer.dat new file mode 100644 index 0000000..e0ab403 --- /dev/null +++ b/CryptoPP/crypto/havalcer.dat @@ -0,0 +1,23 @@ +3 128 + +1BDC556B29AD02EC09AF8C66477F2A87 + +3 160 +a +5E1610FCED1D3ADB0BB18E92AC2B11F0BD99D8ED + +4 192 +HAVAL +74AA31182FF09BCCE453A7F71B5A7C5E80872FA90CD93AE4 + +4 224 +0123456789 +144CB2DE11F05DF7C356282A3B485796DA653F6B702868C7DCF4AE76 + +5 256 +abcdefghijklmnopqrstuvwxyz +1A1DC8099BDAA7F35B4DA4E805F1A28FEE909D8DEE920198185CBCAED8A10A8D + +5 256 +ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 +C5647FC6C1877FFF96742F27E9266B6874894F41A08F5913033D9D532AEDDB39 diff --git a/CryptoPP/crypto/hex.cpp b/CryptoPP/crypto/hex.cpp new file mode 100644 index 0000000..df4fc2e --- /dev/null +++ b/CryptoPP/crypto/hex.cpp @@ -0,0 +1,44 @@ +// hex.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "hex.h" + +NAMESPACE_BEGIN(CryptoPP) + +static const byte s_vecUpper[] = "0123456789ABCDEF"; +static const byte s_vecLower[] = "0123456789abcdef"; + +void HexEncoder::IsolatedInitialize(const NameValuePairs ¶meters) +{ + bool uppercase = parameters.GetValueWithDefault(Name::Uppercase(), true); + m_filter->Initialize(CombinedNameValuePairs( + parameters, + MakeParameters(Name::EncodingLookupArray(), uppercase ? &s_vecUpper[0] : &s_vecLower[0], false)(Name::Log2Base(), 4, true))); +} + +void HexDecoder::IsolatedInitialize(const NameValuePairs ¶meters) +{ + BaseN_Decoder::IsolatedInitialize(CombinedNameValuePairs( + parameters, + MakeParameters(Name::DecodingLookupArray(), GetDefaultDecodingLookupArray(), false)(Name::Log2Base(), 4, true))); +} + +const int *HexDecoder::GetDefaultDecodingLookupArray() +{ + static bool s_initialized = false; + static int s_array[256]; + + if (!s_initialized) + { + InitializeDecodingLookupArray(s_array, s_vecUpper, 16, true); + s_initialized = true; + } + return s_array; +} + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/hex.h b/CryptoPP/crypto/hex.h new file mode 100644 index 0000000..b19592c --- /dev/null +++ b/CryptoPP/crypto/hex.h @@ -0,0 +1,36 @@ +#ifndef CRYPTOPP_HEX_H +#define CRYPTOPP_HEX_H + +#include "basecode.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! Converts given data to base 16 +class CRYPTOPP_DLL HexEncoder : public SimpleProxyFilter +{ +public: + HexEncoder(BufferedTransformation *attachment = NULL, bool uppercase = true, int outputGroupSize = 0, const std::string &separator = ":", const std::string &terminator = "") + : SimpleProxyFilter(new BaseN_Encoder(new Grouper), attachment) + { + IsolatedInitialize(MakeParameters(Name::Uppercase(), uppercase)(Name::GroupSize(), outputGroupSize)(Name::Separator(), ConstByteArrayParameter(separator))(Name::Terminator(), ConstByteArrayParameter(terminator))); + } + + void IsolatedInitialize(const NameValuePairs ¶meters); +}; + +//! Decode base 16 data back to bytes +class CRYPTOPP_DLL HexDecoder : public BaseN_Decoder +{ +public: + HexDecoder(BufferedTransformation *attachment = NULL) + : BaseN_Decoder(GetDefaultDecodingLookupArray(), 4, attachment) {} + + void IsolatedInitialize(const NameValuePairs ¶meters); + +private: + static const int * CRYPTOPP_API GetDefaultDecodingLookupArray(); +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/hmac.cpp b/CryptoPP/crypto/hmac.cpp new file mode 100644 index 0000000..a25eb74 --- /dev/null +++ b/CryptoPP/crypto/hmac.cpp @@ -0,0 +1,86 @@ +// hmac.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "hmac.h" + +NAMESPACE_BEGIN(CryptoPP) + +void HMAC_Base::UncheckedSetKey(const byte *userKey, unsigned int keylength, const NameValuePairs &) +{ + AssertValidKeyLength(keylength); + + Restart(); + + HashTransformation &hash = AccessHash(); + unsigned int blockSize = hash.BlockSize(); + + if (!blockSize) + throw InvalidArgument("HMAC: can only be used with a block-based hash function"); + + m_buf.resize(2*AccessHash().BlockSize() + AccessHash().DigestSize()); + + if (keylength <= blockSize) + memcpy(AccessIpad(), userKey, keylength); + else + { + AccessHash().CalculateDigest(AccessIpad(), userKey, keylength); + keylength = hash.DigestSize(); + } + + assert(keylength <= blockSize); + memset(AccessIpad()+keylength, 0, blockSize-keylength); + + for (unsigned int i=0; i, public MessageAuthenticationCode +{ +public: + HMAC_Base() : m_innerHashKeyed(false) {} + void UncheckedSetKey(const byte *userKey, unsigned int keylength, const NameValuePairs ¶ms); + + void Restart(); + void Update(const byte *input, size_t length); + void TruncatedFinal(byte *mac, size_t size); + unsigned int OptimalBlockSize() const {return const_cast(this)->AccessHash().OptimalBlockSize();} + unsigned int DigestSize() const {return const_cast(this)->AccessHash().DigestSize();} + +protected: + virtual HashTransformation & AccessHash() =0; + byte * AccessIpad() {return m_buf;} + byte * AccessOpad() {return m_buf + AccessHash().BlockSize();} + byte * AccessInnerHash() {return m_buf + 2*AccessHash().BlockSize();} + +private: + void KeyInnerHash(); + + SecByteBlock m_buf; + bool m_innerHashKeyed; +}; + +//! HMAC +/*! HMAC(K, text) = H(K XOR opad, H(K XOR ipad, text)) */ +template +class HMAC : public MessageAuthenticationCodeImpl > +{ +public: + CRYPTOPP_CONSTANT(DIGESTSIZE=T::DIGESTSIZE) + CRYPTOPP_CONSTANT(BLOCKSIZE=T::BLOCKSIZE) + + HMAC() {} + HMAC(const byte *key, size_t length=HMAC_Base::DEFAULT_KEYLENGTH) + {this->SetKey(key, length);} + + static std::string StaticAlgorithmName() {return std::string("HMAC(") + T::StaticAlgorithmName() + ")";} + std::string AlgorithmName() const {return std::string("HMAC(") + m_hash.AlgorithmName() + ")";} + +private: + HashTransformation & AccessHash() {return m_hash;} + + T m_hash; +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/hrtimer.cpp b/CryptoPP/crypto/hrtimer.cpp new file mode 100644 index 0000000..4a1cc79 --- /dev/null +++ b/CryptoPP/crypto/hrtimer.cpp @@ -0,0 +1,139 @@ +// hrtimer.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "hrtimer.h" +#include "misc.h" +#include // for NULL +#include + +#if defined(CRYPTOPP_WIN32_AVAILABLE) +#include +#elif defined(CRYPTOPP_UNIX_AVAILABLE) +#include +#include +#include +#endif + +#include + +NAMESPACE_BEGIN(CryptoPP) + +#ifndef CRYPTOPP_IMPORTS + +double TimerBase::ConvertTo(TimerWord t, Unit unit) +{ + static unsigned long unitsPerSecondTable[] = {1, 1000, 1000*1000, 1000*1000*1000}; + + assert(unit < sizeof(unitsPerSecondTable) / sizeof(unitsPerSecondTable[0])); + return (double)CRYPTOPP_VC6_INT64 t * unitsPerSecondTable[unit] / CRYPTOPP_VC6_INT64 TicksPerSecond(); +} + +void TimerBase::StartTimer() +{ + m_last = m_start = GetCurrentTimerValue(); + m_started = true; +} + +double TimerBase::ElapsedTimeAsDouble() +{ + if (m_stuckAtZero) + return 0; + + if (m_started) + { + TimerWord now = GetCurrentTimerValue(); + if (m_last < now) // protect against OS bugs where time goes backwards + m_last = now; + return ConvertTo(m_last - m_start, m_timerUnit); + } + + StartTimer(); + return 0; +} + +unsigned long TimerBase::ElapsedTime() +{ + double elapsed = ElapsedTimeAsDouble(); + assert(elapsed <= ULONG_MAX); + return (unsigned long)elapsed; +} + +TimerWord Timer::GetCurrentTimerValue() +{ +#if defined(CRYPTOPP_WIN32_AVAILABLE) + LARGE_INTEGER now; + if (!QueryPerformanceCounter(&now)) + throw Exception(Exception::OTHER_ERROR, "Timer: QueryPerformanceCounter failed with error " + IntToString(GetLastError())); + return now.QuadPart; +#elif defined(CRYPTOPP_UNIX_AVAILABLE) + timeval now; + gettimeofday(&now, NULL); + return (TimerWord)now.tv_sec * 1000000 + now.tv_usec; +#else + clock_t now; + return clock(); +#endif +} + +TimerWord Timer::TicksPerSecond() +{ +#if defined(CRYPTOPP_WIN32_AVAILABLE) + static LARGE_INTEGER freq = {0}; + if (freq.QuadPart == 0) + { + if (!QueryPerformanceFrequency(&freq)) + throw Exception(Exception::OTHER_ERROR, "Timer: QueryPerformanceFrequency failed with error " + IntToString(GetLastError())); + } + return freq.QuadPart; +#elif defined(CRYPTOPP_UNIX_AVAILABLE) + return 1000000; +#else + return CLOCKS_PER_SEC; +#endif +} + +#endif // #ifndef CRYPTOPP_IMPORTS + +TimerWord ThreadUserTimer::GetCurrentTimerValue() +{ +#if defined(CRYPTOPP_WIN32_AVAILABLE) + static bool getCurrentThreadImplemented = true; + if (getCurrentThreadImplemented) + { + FILETIME now, ignored; + if (!GetThreadTimes(GetCurrentThread(), &ignored, &ignored, &ignored, &now)) + { + DWORD lastError = GetLastError(); + if (lastError == ERROR_CALL_NOT_IMPLEMENTED) + { + getCurrentThreadImplemented = false; + goto GetCurrentThreadNotImplemented; + } + throw Exception(Exception::OTHER_ERROR, "ThreadUserTimer: GetThreadTimes failed with error " + IntToString(lastError)); + } + return now.dwLowDateTime + ((TimerWord)now.dwHighDateTime << 32); + } +GetCurrentThreadNotImplemented: + return (TimerWord)clock() * (10*1000*1000 / CLOCKS_PER_SEC); +#elif defined(CRYPTOPP_UNIX_AVAILABLE) + tms now; + times(&now); + return now.tms_utime; +#else + return clock(); +#endif +} + +TimerWord ThreadUserTimer::TicksPerSecond() +{ +#if defined(CRYPTOPP_WIN32_AVAILABLE) + return 10*1000*1000; +#elif defined(CRYPTOPP_UNIX_AVAILABLE) + static const long ticksPerSecond = sysconf(_SC_CLK_TCK); + return ticksPerSecond; +#else + return CLOCKS_PER_SEC; +#endif +} + +NAMESPACE_END diff --git a/CryptoPP/crypto/hrtimer.h b/CryptoPP/crypto/hrtimer.h new file mode 100644 index 0000000..de8835f --- /dev/null +++ b/CryptoPP/crypto/hrtimer.h @@ -0,0 +1,65 @@ +#ifndef CRYPTOPP_HRTIMER_H +#define CRYPTOPP_HRTIMER_H + +#include "config.h" +#ifndef HIGHRES_TIMER_AVAILABLE +#include +#endif + +NAMESPACE_BEGIN(CryptoPP) + +#ifdef HIGHRES_TIMER_AVAILABLE + #ifdef WORD64_AVAILABLE + typedef word64 TimerWord; + #else + typedef word32 TimerWord; + #endif +#else + typedef clock_t TimerWord; +#endif + +//! _ +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TimerBase +{ +public: + enum Unit {SECONDS = 0, MILLISECONDS, MICROSECONDS, NANOSECONDS}; + TimerBase(Unit unit, bool stuckAtZero) : m_timerUnit(unit), m_stuckAtZero(stuckAtZero), m_started(false) {} + + virtual TimerWord GetCurrentTimerValue() =0; // GetCurrentTime is a macro in MSVC 6.0 + virtual TimerWord TicksPerSecond() =0; // this is not the resolution, just a conversion factor into seconds + + void StartTimer(); + double ElapsedTimeAsDouble(); + unsigned long ElapsedTime(); + +private: + double ConvertTo(TimerWord t, Unit unit); + + Unit m_timerUnit; // HPUX workaround: m_unit is a system macro on HPUX + bool m_stuckAtZero, m_started; + TimerWord m_start, m_last; +}; + +//! measure CPU time spent executing instructions of this thread (if supported by OS) +/*! /note This only works correctly on Windows NT or later. On Unix it reports process time, and others wall clock time. +*/ +class ThreadUserTimer : public TimerBase +{ +public: + ThreadUserTimer(Unit unit = TimerBase::SECONDS, bool stuckAtZero = false) : TimerBase(unit, stuckAtZero) {} + TimerWord GetCurrentTimerValue(); + TimerWord TicksPerSecond(); +}; + +//! high resolution timer +class CRYPTOPP_DLL Timer : public TimerBase +{ +public: + Timer(Unit unit = TimerBase::SECONDS, bool stuckAtZero = false) : TimerBase(unit, stuckAtZero) {} + TimerWord GetCurrentTimerValue(); + TimerWord TicksPerSecond(); +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/ida.cpp b/CryptoPP/crypto/ida.cpp new file mode 100644 index 0000000..aae18f2 --- /dev/null +++ b/CryptoPP/crypto/ida.cpp @@ -0,0 +1,421 @@ +// ida.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "ida.h" + +#include "algebra.h" +#include "gf2_32.h" +#include "polynomi.h" +#include + +#include "polynomi.cpp" + +ANONYMOUS_NAMESPACE_BEGIN +static const CryptoPP::GF2_32 field; +NAMESPACE_END + +using namespace std; + +NAMESPACE_BEGIN(CryptoPP) + +void RawIDA::IsolatedInitialize(const NameValuePairs ¶meters) +{ + if (!parameters.GetIntValue("RecoveryThreshold", m_threshold)) + throw InvalidArgument("RawIDA: missing RecoveryThreshold argument"); + + if (m_threshold <= 0) + throw InvalidArgument("RawIDA: RecoveryThreshold must be greater than 0"); + + m_lastMapPosition = m_inputChannelMap.end(); + m_channelsReady = 0; + m_channelsFinished = 0; + m_w.New(m_threshold); + m_y.New(m_threshold); + m_inputQueues.reserve(m_threshold); + + m_outputChannelIds.clear(); + m_outputChannelIdStrings.clear(); + m_outputQueues.clear(); + + word32 outputChannelID; + if (parameters.GetValue("OutputChannelID", outputChannelID)) + AddOutputChannel(outputChannelID); + else + { + int nShares = parameters.GetIntValueWithDefault("NumberOfShares", m_threshold); + for (int i=0; ifirst == channelId) + goto skipFind; + ++m_lastMapPosition; + if (m_lastMapPosition != m_inputChannelMap.end() && m_lastMapPosition->first == channelId) + goto skipFind; + } + m_lastMapPosition = m_inputChannelMap.find(channelId); + +skipFind: + if (m_lastMapPosition == m_inputChannelMap.end()) + { + if (m_inputChannelIds.size() == m_threshold) + return m_threshold; + + m_lastMapPosition = m_inputChannelMap.insert(InputChannelMap::value_type(channelId, (unsigned int)m_inputChannelIds.size())).first; + m_inputQueues.push_back(MessageQueue()); + m_inputChannelIds.push_back(channelId); + + if (m_inputChannelIds.size() == m_threshold) + PrepareInterpolation(); + } + return m_lastMapPosition->second; +} + +unsigned int RawIDA::LookupInputChannel(word32 channelId) const +{ + map::const_iterator it = m_inputChannelMap.find(channelId); + if (it == m_inputChannelMap.end()) + return m_threshold; + else + return it->second; +} + +void RawIDA::ChannelData(word32 channelId, const byte *inString, size_t length, bool messageEnd) +{ + int i = InsertInputChannel(channelId); + if (i < m_threshold) + { + lword size = m_inputQueues[i].MaxRetrievable(); + m_inputQueues[i].Put(inString, length); + if (size < 4 && size + length >= 4) + { + m_channelsReady++; + if (m_channelsReady == m_threshold) + ProcessInputQueues(); + } + + if (messageEnd) + { + m_inputQueues[i].MessageEnd(); + if (m_inputQueues[i].NumberOfMessages() == 1) + { + m_channelsFinished++; + if (m_channelsFinished == m_threshold) + { + m_channelsReady = 0; + for (i=0; i= m_v.size()) + { + m_v.resize(i+1); + m_outputToInput.resize(i+1); + } + + m_outputToInput[i] = LookupInputChannel(m_outputChannelIds[i]); + if (m_outputToInput[i] == m_threshold && i * m_threshold <= 1000*1000) + { + m_v[i].resize(m_threshold); + PrepareBulkPolynomialInterpolationAt(field, m_v[i].begin(), m_outputChannelIds[i], &(m_inputChannelIds[0]), m_w.begin(), m_threshold); + } +} + +void RawIDA::AddOutputChannel(word32 channelId) +{ + m_outputChannelIds.push_back(channelId); + m_outputChannelIdStrings.push_back(WordToString(channelId)); + m_outputQueues.push_back(ByteQueue()); + if (m_inputChannelIds.size() == m_threshold) + ComputeV((unsigned int)m_outputChannelIds.size() - 1); +} + +void RawIDA::PrepareInterpolation() +{ + assert(m_inputChannelIds.size() == m_threshold); + PrepareBulkPolynomialInterpolation(field, m_w.begin(), &(m_inputChannelIds[0]), m_threshold); + for (unsigned int i=0; i 0 : m_channelsReady == m_threshold) + { + m_channelsReady = 0; + for (i=0; i 0 || queue.MaxRetrievable() >= 4; + } + + for (i=0; (unsigned int)i 0 && m_outputQueues[0].AnyRetrievable()) + FlushOutputQueues(); + + if (finished) + { + OutputMessageEnds(); + + m_channelsReady = 0; + m_channelsFinished = 0; + m_v.clear(); + + vector inputQueues; + vector inputChannelIds; + + inputQueues.swap(m_inputQueues); + inputChannelIds.swap(m_inputChannelIds); + m_inputChannelMap.clear(); + m_lastMapPosition = m_inputChannelMap.end(); + + for (i=0; iChannelMessageEnd(m_outputChannelIdStrings[i], GetAutoSignalPropagation()-1); + } +} + +// **************************************************************** + +void SecretSharing::IsolatedInitialize(const NameValuePairs ¶meters) +{ + m_pad = parameters.GetValueWithDefault("AddPadding", true); + m_ida.IsolatedInitialize(parameters); +} + +size_t SecretSharing::Put2(const byte *begin, size_t length, int messageEnd, bool blocking) +{ + if (!blocking) + throw BlockingInputOnly("SecretSharing"); + + SecByteBlock buf(UnsignedMin(256, length)); + unsigned int threshold = m_ida.GetThreshold(); + while (length > 0) + { + size_t len = STDMIN(length, buf.size()); + m_ida.ChannelData(0xffffffff, begin, len, false); + for (unsigned int i=0; i 0) + SecretSharing::Put(0); + } + m_ida.ChannelData(0xffffffff, NULL, 0, true); + for (unsigned int i=0; iMessageEnd(GetAutoSignalPropagation()-1); +} + +// **************************************************************** + +void InformationDispersal::IsolatedInitialize(const NameValuePairs ¶meters) +{ + m_nextChannel = 0; + m_pad = parameters.GetValueWithDefault("AddPadding", true); + m_ida.IsolatedInitialize(parameters); +} + +size_t InformationDispersal::Put2(const byte *begin, size_t length, int messageEnd, bool blocking) +{ + if (!blocking) + throw BlockingInputOnly("InformationDispersal"); + + while (length--) + { + m_ida.ChannelData(m_nextChannel, begin, 1, false); + begin++; + m_nextChannel++; + if (m_nextChannel == m_ida.GetThreshold()) + m_nextChannel = 0; + } + + if (messageEnd) + { + m_ida.SetAutoSignalPropagation(messageEnd-1); + if (m_pad) + InformationDispersal::Put(1); + for (word32 i=0; iMessageEnd(GetAutoSignalPropagation()-1); +} + +size_t PaddingRemover::Put2(const byte *begin, size_t length, int messageEnd, bool blocking) +{ + if (!blocking) + throw BlockingInputOnly("PaddingRemover"); + + const byte *const end = begin + length; + + if (m_possiblePadding) + { + size_t len = find_if(begin, end, bind2nd(not_equal_to(), 0)) - begin; + m_zeroCount += len; + begin += len; + if (begin == end) + return 0; + + AttachedTransformation()->Put(1); + while (m_zeroCount--) + AttachedTransformation()->Put(0); + AttachedTransformation()->Put(*begin++); + m_possiblePadding = false; + } + +#if defined(_MSC_VER) && !defined(__MWERKS__) && (_MSC_VER <= 1300) + // VC60 and VC7 workaround: built-in reverse_iterator has two template parameters, Dinkumware only has one + typedef reverse_bidirectional_iterator RevIt; +#elif defined(_RWSTD_NO_CLASS_PARTIAL_SPEC) + typedef reverse_iterator RevIt; +#else + typedef reverse_iterator RevIt; +#endif + const byte *x = find_if(RevIt(end), RevIt(begin), bind2nd(not_equal_to(), 0)).base(); + if (x != begin && *(x-1) == 1) + { + AttachedTransformation()->Put(begin, x-begin-1); + m_possiblePadding = true; + m_zeroCount = end - x; + } + else + AttachedTransformation()->Put(begin, end-begin); + + if (messageEnd) + { + m_possiblePadding = false; + Output(0, begin, length, messageEnd, blocking); + } + return 0; +} + +NAMESPACE_END diff --git a/CryptoPP/crypto/ida.h b/CryptoPP/crypto/ida.h new file mode 100644 index 0000000..8171637 --- /dev/null +++ b/CryptoPP/crypto/ida.h @@ -0,0 +1,152 @@ +#ifndef CRYPTOPP_IDA_H +#define CRYPTOPP_IDA_H + +#include "mqueue.h" +#include "filters.h" +#include "channels.h" +#include +#include + +NAMESPACE_BEGIN(CryptoPP) + +/// base class for secret sharing and information dispersal +class RawIDA : public AutoSignaling > > +{ +public: + RawIDA(BufferedTransformation *attachment=NULL) + {Detach(attachment);} + + unsigned int GetThreshold() const {return m_threshold;} + void AddOutputChannel(word32 channelId); + void ChannelData(word32 channelId, const byte *inString, size_t length, bool messageEnd); + lword InputBuffered(word32 channelId) const; + + void IsolatedInitialize(const NameValuePairs ¶meters=g_nullNameValuePairs); + size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking) + { + if (!blocking) + throw BlockingInputOnly("RawIDA"); + ChannelData(StringToWord(channel), begin, length, messageEnd != 0); + return 0; + } + +protected: + virtual void FlushOutputQueues(); + virtual void OutputMessageEnds(); + + unsigned int InsertInputChannel(word32 channelId); + unsigned int LookupInputChannel(word32 channelId) const; + void ComputeV(unsigned int); + void PrepareInterpolation(); + void ProcessInputQueues(); + + typedef std::map InputChannelMap; + InputChannelMap m_inputChannelMap; + InputChannelMap::iterator m_lastMapPosition; + std::vector m_inputQueues; + std::vector m_inputChannelIds, m_outputChannelIds, m_outputToInput; + std::vector m_outputChannelIdStrings; + std::vector m_outputQueues; + int m_threshold; + unsigned int m_channelsReady, m_channelsFinished; + std::vector > m_v; + SecBlock m_u, m_w, m_y; +}; + +/// a variant of Shamir's Secret Sharing Algorithm +class SecretSharing : public CustomFlushPropagation +{ +public: + SecretSharing(RandomNumberGenerator &rng, int threshold, int nShares, BufferedTransformation *attachment=NULL, bool addPadding=true) + : m_rng(rng), m_ida(new OutputProxy(*this, true)) + { + Detach(attachment); + IsolatedInitialize(MakeParameters("RecoveryThreshold", threshold)("NumberOfShares", nShares)("AddPadding", addPadding)); + } + + void IsolatedInitialize(const NameValuePairs ¶meters=g_nullNameValuePairs); + size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking); + bool Flush(bool hardFlush, int propagation=-1, bool blocking=true) {return m_ida.Flush(hardFlush, propagation, blocking);} + +protected: + RandomNumberGenerator &m_rng; + RawIDA m_ida; + bool m_pad; +}; + +/// a variant of Shamir's Secret Sharing Algorithm +class SecretRecovery : public RawIDA +{ +public: + SecretRecovery(int threshold, BufferedTransformation *attachment=NULL, bool removePadding=true) + : RawIDA(attachment) + {IsolatedInitialize(MakeParameters("RecoveryThreshold", threshold)("RemovePadding", removePadding));} + + void IsolatedInitialize(const NameValuePairs ¶meters=g_nullNameValuePairs); + +protected: + void FlushOutputQueues(); + void OutputMessageEnds(); + + bool m_pad; +}; + +/// a variant of Rabin's Information Dispersal Algorithm +class InformationDispersal : public CustomFlushPropagation +{ +public: + InformationDispersal(int threshold, int nShares, BufferedTransformation *attachment=NULL, bool addPadding=true) + : m_ida(new OutputProxy(*this, true)) + { + Detach(attachment); + IsolatedInitialize(MakeParameters("RecoveryThreshold", threshold)("NumberOfShares", nShares)("AddPadding", addPadding)); + } + + void IsolatedInitialize(const NameValuePairs ¶meters=g_nullNameValuePairs); + size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking); + bool Flush(bool hardFlush, int propagation=-1, bool blocking=true) {return m_ida.Flush(hardFlush, propagation, blocking);} + +protected: + RawIDA m_ida; + bool m_pad; + unsigned int m_nextChannel; +}; + +/// a variant of Rabin's Information Dispersal Algorithm +class InformationRecovery : public RawIDA +{ +public: + InformationRecovery(int threshold, BufferedTransformation *attachment=NULL, bool removePadding=true) + : RawIDA(attachment) + {IsolatedInitialize(MakeParameters("RecoveryThreshold", threshold)("RemovePadding", removePadding));} + + void IsolatedInitialize(const NameValuePairs ¶meters=g_nullNameValuePairs); + +protected: + void FlushOutputQueues(); + void OutputMessageEnds(); + + bool m_pad; + ByteQueue m_queue; +}; + +class PaddingRemover : public Unflushable +{ +public: + PaddingRemover(BufferedTransformation *attachment=NULL) + : m_possiblePadding(false) {Detach(attachment);} + + void IsolatedInitialize(const NameValuePairs ¶meters) {m_possiblePadding = false;} + size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking); + + // GetPossiblePadding() == false at the end of a message indicates incorrect padding + bool GetPossiblePadding() const {return m_possiblePadding;} + +private: + bool m_possiblePadding; + lword m_zeroCount; +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/idea.cpp b/CryptoPP/crypto/idea.cpp new file mode 100644 index 0000000..19e9330 --- /dev/null +++ b/CryptoPP/crypto/idea.cpp @@ -0,0 +1,192 @@ +// idea.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "idea.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +static const int IDEA_KEYLEN=(6*IDEA::ROUNDS+4); // key schedule length in # of word16s + +#define low16(x) ((x)&0xffff) // compiler should be able to optimize this away if word is 16 bits +#define high16(x) ((x)>>16) + +CRYPTOPP_COMPILE_ASSERT(sizeof(IDEA::Word) >= 2); + +// should use an inline function but macros are still faster in MSVC 4.0 +#define DirectMUL(a,b) \ +{ \ + assert(b <= 0xffff); \ + \ + word32 p=(word32)low16(a)*b; \ + \ + if (p) \ + { \ + p = low16(p) - high16(p); \ + a = (IDEA::Word)p - (IDEA::Word)high16(p); \ + } \ + else \ + a = 1-a-b; \ +} + +#ifdef IDEA_LARGECACHE +bool IDEA::Base::tablesBuilt = false; +word16 IDEA::Base::log[0x10000]; +word16 IDEA::Base::antilog[0x10000]; + +void IDEA::Base::BuildLogTables() +{ + if (tablesBuilt) + return; + else + { + tablesBuilt = true; + + IDEA::Word x=1; + word32 i; + + for (i=0; i<0x10000; i++) + { + antilog[i] = (word16)x; + DirectMUL(x, 3); + } + + for (i=0; i<0x10000; i++) + log[antilog[i]] = (word16)i; + } +} + +void IDEA::Base::LookupKeyLogs() +{ + IDEA::Word* Z=key; + int r=ROUNDS; + do + { + Z[0] = log[Z[0]]; + Z[3] = log[Z[3]]; + Z[4] = log[Z[4]]; + Z[5] = log[Z[5]]; + Z+=6; + } while (--r); + Z[0] = log[Z[0]]; + Z[3] = log[Z[3]]; +} + +inline void IDEA::Base::LookupMUL(IDEA::Word &a, IDEA::Word b) +{ + a = antilog[low16(log[low16(a)]+b)]; +} +#endif // IDEA_LARGECACHE + +void IDEA::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs &) +{ + AssertValidKeyLength(length); + +#ifdef IDEA_LARGECACHE + BuildLogTables(); +#endif + + EnKey(userKey); + + if (!IsForwardTransformation()) + DeKey(); + +#ifdef IDEA_LARGECACHE + LookupKeyLogs(); +#endif +} + +void IDEA::Base::EnKey (const byte *userKey) +{ + unsigned int i; + + for (i=0; i<8; i++) + m_key[i] = ((IDEA::Word)userKey[2*i]<<8) | userKey[2*i+1]; + + for (; i> 7)); + } +} + +static IDEA::Word MulInv(IDEA::Word x) +{ + IDEA::Word y=x; + for (unsigned i=0; i<15; i++) + { + DirectMUL(y,low16(y)); + DirectMUL(y,x); + } + return low16(y); +} + +static inline IDEA::Word AddInv(IDEA::Word x) +{ + return low16(0-x); +} + +void IDEA::Base::DeKey() +{ + FixedSizeSecBlock tempkey; + unsigned int i; + + for (i=0; i0)]); + tempkey[i*6+2] = AddInv(m_key[(ROUNDS-i)*6+2-(i>0)]); + tempkey[i*6+3] = MulInv(m_key[(ROUNDS-i)*6+3]); + tempkey[i*6+4] = m_key[(ROUNDS-1-i)*6+4]; + tempkey[i*6+5] = m_key[(ROUNDS-1-i)*6+5]; + } + + tempkey[i*6+0] = MulInv(m_key[(ROUNDS-i)*6+0]); + tempkey[i*6+1] = AddInv(m_key[(ROUNDS-i)*6+1]); + tempkey[i*6+2] = AddInv(m_key[(ROUNDS-i)*6+2]); + tempkey[i*6+3] = MulInv(m_key[(ROUNDS-i)*6+3]); + + m_key = tempkey; +} + +#ifdef IDEA_LARGECACHE +#define MUL(a,b) LookupMUL(a,b) +#else +#define MUL(a,b) DirectMUL(a,b) +#endif + +void IDEA::Base::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + typedef BlockGetAndPut Block; + + const IDEA::Word *key = m_key; + IDEA::Word x0,x1,x2,x3,t0,t1; + Block::Get(inBlock)(x0)(x1)(x2)(x3); + + for (unsigned int i=0; i, public FixedKeyLength<16>, public FixedRounds<8> +{ + static const char *StaticAlgorithmName() {return "IDEA";} +}; + +/// IDEA +class IDEA : public IDEA_Info, public BlockCipherDocumentation +{ +public: // made public for internal purposes +#ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE + typedef word Word; +#else + typedef hword Word; +#endif + +private: + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + public: + unsigned int GetAlignment() const {return 2;} + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + + void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); + + private: + void EnKey(const byte *); + void DeKey(); + FixedSizeSecBlock m_key; + + #ifdef IDEA_LARGECACHE + static inline void LookupMUL(word &a, word b); + void LookupKeyLogs(); + static void BuildLogTables(); + static bool tablesBuilt; + static word16 log[0x10000], antilog[0x10000]; + #endif + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef IDEA::Encryption IDEAEncryption; +typedef IDEA::Decryption IDEADecryption; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/ideaval.dat b/CryptoPP/crypto/ideaval.dat new file mode 100644 index 0000000..4c96d33 --- /dev/null +++ b/CryptoPP/crypto/ideaval.dat @@ -0,0 +1,11 @@ +00010002000300040005000600070008 0000000100020003 11FBED2B01986DE5 +00010002000300040005000600070008 0102030405060708 540E5FEA18C2F8B1 +00010002000300040005000600070008 0019324B647D96AF 9F0A0AB6E10CED78 +00010002000300040005000600070008 F5202D5B9C671B08 CF18FD7355E2C5C5 +00010002000300040005000600070008 FAE6D2BEAA96826E 85DF52005608193D +00010002000300040005000600070008 0A141E28323C4650 2F7DE750212FB734 +00010002000300040005000600070008 050A0F14191E2328 7B7314925DE59C09 +0005000A000F00140019001E00230028 0102030405060708 3EC04780BEFF6E20 +3A984E2000195DB32EE501C8C47CEA60 0102030405060708 97BCD8200780DA86 +006400C8012C019001F4025802BC0320 05320A6414C819FA 65BE87E7A2538AED +9D4075C103BC322AFB03E7BE6AB30006 0808080808080808 F5DB1AC45E5EF9F9 diff --git a/CryptoPP/crypto/integer.cpp b/CryptoPP/crypto/integer.cpp new file mode 100644 index 0000000..fe87a95 --- /dev/null +++ b/CryptoPP/crypto/integer.cpp @@ -0,0 +1,4237 @@ +// integer.cpp - written and placed in the public domain by Wei Dai +// contains public domain code contributed by Alister Lee and Leonard Janke + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "integer.h" +#include "modarith.h" +#include "nbtheory.h" +#include "asn.h" +#include "oids.h" +#include "words.h" +#include "algparam.h" +#include "pubkey.h" // for P1363_KDF2 +#include "sha.h" +#include "cpu.h" + +#include + +#if _MSC_VER >= 1400 + #include +#endif + +#ifdef __DECCXX + #include +#endif + +#ifdef CRYPTOPP_MSVC6_NO_PP + #pragma message("You do not seem to have the Visual C++ Processor Pack installed, so use of SSE2 instructions will be disabled.") +#endif + +#define CRYPTOPP_INTEGER_SSE2 (CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86) + +NAMESPACE_BEGIN(CryptoPP) + +bool AssignIntToInteger(const std::type_info &valueType, void *pInteger, const void *pInt) +{ + if (valueType != typeid(Integer)) + return false; + *reinterpret_cast(pInteger) = *reinterpret_cast(pInt); + return true; +} + +inline static int Compare(const word *A, const word *B, size_t N) +{ + while (N--) + if (A[N] > B[N]) + return 1; + else if (A[N] < B[N]) + return -1; + + return 0; +} + +inline static int Increment(word *A, size_t N, word B=1) +{ + assert(N); + word t = A[0]; + A[0] = t+B; + if (A[0] >= t) + return 0; + for (unsigned i=1; i>(WORD_BITS-1)); d##0 = 2*d##0 + (c>>(WORD_BITS-1)); c *= 2; + #endif + #ifndef Acc2WordsBy2 + #define Acc2WordsBy2(a, b) a##0 += b##0; a##1 += a##0 < b##0; a##1 += b##1; + #endif + #define AddWithCarry(u, a, b) {word t = a+b; u##0 = t + u##1; u##1 = (ta) + (u##0>t);} + #define GetCarry(u) u##1 + #define GetBorrow(u) u##1 +#else + #define Declare2Words(x) dword x; + #if _MSC_VER >= 1400 && !defined(__INTEL_COMPILER) + #define MultiplyWords(p, a, b) p = __emulu(a, b); + #else + #define MultiplyWords(p, a, b) p = (dword)a*b; + #endif + #define AssignWord(a, b) a = b; + #define Add2WordsBy1(a, b, c) a = b + c; + #define Acc2WordsBy2(a, b) a += b; + #define LowWord(a) word(a) + #define HighWord(a) word(a>>WORD_BITS) + #define Double3Words(c, d) d = 2*d + (c>>(WORD_BITS-1)); c *= 2; + #define AddWithCarry(u, a, b) u = dword(a) + b + GetCarry(u); + #define SubtractWithBorrow(u, a, b) u = dword(a) - b - GetBorrow(u); + #define GetCarry(u) HighWord(u) + #define GetBorrow(u) word(u>>(WORD_BITS*2-1)) +#endif +#ifndef MulAcc + #define MulAcc(c, d, a, b) MultiplyWords(p, a, b); Acc2WordsBy1(p, c); c = LowWord(p); Acc2WordsBy1(d, HighWord(p)); +#endif +#ifndef Acc2WordsBy1 + #define Acc2WordsBy1(a, b) Add2WordsBy1(a, a, b) +#endif +#ifndef Acc3WordsBy2 + #define Acc3WordsBy2(c, d, e) Acc2WordsBy1(e, c); c = LowWord(e); Add2WordsBy1(e, d, HighWord(e)); +#endif + +class DWord +{ +public: + DWord() {} + +#ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE + explicit DWord(word low) + { + m_whole = low; + } +#else + explicit DWord(word low) + { + m_halfs.low = low; + m_halfs.high = 0; + } +#endif + + DWord(word low, word high) + { + m_halfs.low = low; + m_halfs.high = high; + } + + static DWord Multiply(word a, word b) + { + DWord r; + #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE + r.m_whole = (dword)a * b; + #elif defined(__x86_64__) + asm ("mulq %3" : "=a"(r.m_halfs.low), "=d"(r.m_halfs.high) : "a"(a), "g"(b) : "cc"); + #else + r.m_halfs.low = _umul128(a, b, &r.m_halfs.high); + #endif + return r; + } + + static DWord MultiplyAndAdd(word a, word b, word c) + { + DWord r = Multiply(a, b); + return r += c; + } + + DWord & operator+=(word a) + { + #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE + m_whole = m_whole + a; + #else + m_halfs.low += a; + m_halfs.high += (m_halfs.low < a); + #endif + return *this; + } + + DWord operator+(word a) + { + DWord r; + #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE + r.m_whole = m_whole + a; + #else + r.m_halfs.low = m_halfs.low + a; + r.m_halfs.high = m_halfs.high + (r.m_halfs.low < a); + #endif + return r; + } + + DWord operator-(DWord a) + { + DWord r; + #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE + r.m_whole = m_whole - a.m_whole; + #else + r.m_halfs.low = m_halfs.low - a.m_halfs.low; + r.m_halfs.high = m_halfs.high - a.m_halfs.high - (r.m_halfs.low > m_halfs.low); + #endif + return r; + } + + DWord operator-(word a) + { + DWord r; + #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE + r.m_whole = m_whole - a; + #else + r.m_halfs.low = m_halfs.low - a; + r.m_halfs.high = m_halfs.high - (r.m_halfs.low > m_halfs.low); + #endif + return r; + } + + // returns quotient, which must fit in a word + word operator/(word divisor); + + word operator%(word a); + + bool operator!() const + { + #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE + return !m_whole; + #else + return !m_halfs.high && !m_halfs.low; + #endif + } + + word GetLowHalf() const {return m_halfs.low;} + word GetHighHalf() const {return m_halfs.high;} + word GetHighHalfAsBorrow() const {return 0-m_halfs.high;} + +private: + union + { + #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE + dword m_whole; + #endif + struct + { + #ifdef IS_LITTLE_ENDIAN + word low; + word high; + #else + word high; + word low; + #endif + } m_halfs; + }; +}; + +class Word +{ +public: + Word() {} + + Word(word value) + { + m_whole = value; + } + + Word(hword low, hword high) + { + m_whole = low | (word(high) << (WORD_BITS/2)); + } + + static Word Multiply(hword a, hword b) + { + Word r; + r.m_whole = (word)a * b; + return r; + } + + Word operator-(Word a) + { + Word r; + r.m_whole = m_whole - a.m_whole; + return r; + } + + Word operator-(hword a) + { + Word r; + r.m_whole = m_whole - a; + return r; + } + + // returns quotient, which must fit in a word + hword operator/(hword divisor) + { + return hword(m_whole / divisor); + } + + bool operator!() const + { + return !m_whole; + } + + word GetWhole() const {return m_whole;} + hword GetLowHalf() const {return hword(m_whole);} + hword GetHighHalf() const {return hword(m_whole>>(WORD_BITS/2));} + hword GetHighHalfAsBorrow() const {return 0-hword(m_whole>>(WORD_BITS/2));} + +private: + word m_whole; +}; + +// do a 3 word by 2 word divide, returns quotient and leaves remainder in A +template +S DivideThreeWordsByTwo(S *A, S B0, S B1, D *dummy=NULL) +{ + // assert {A[2],A[1]} < {B1,B0}, so quotient can fit in a S + assert(A[2] < B1 || (A[2]==B1 && A[1] < B0)); + + // estimate the quotient: do a 2 S by 1 S divide + S Q; + if (S(B1+1) == 0) + Q = A[2]; + else + Q = D(A[1], A[2]) / S(B1+1); + + // now subtract Q*B from A + D p = D::Multiply(B0, Q); + D u = (D) A[0] - p.GetLowHalf(); + A[0] = u.GetLowHalf(); + u = (D) A[1] - p.GetHighHalf() - u.GetHighHalfAsBorrow() - D::Multiply(B1, Q); + A[1] = u.GetLowHalf(); + A[2] += u.GetHighHalf(); + + // Q <= actual quotient, so fix it + while (A[2] || A[1] > B1 || (A[1]==B1 && A[0]>=B0)) + { + u = (D) A[0] - B0; + A[0] = u.GetLowHalf(); + u = (D) A[1] - B1 - u.GetHighHalfAsBorrow(); + A[1] = u.GetLowHalf(); + A[2] += u.GetHighHalf(); + Q++; + assert(Q); // shouldn't overflow + } + + return Q; +} + +// do a 4 word by 2 word divide, returns 2 word quotient in Q0 and Q1 +template +inline D DivideFourWordsByTwo(S *T, const D &Al, const D &Ah, const D &B) +{ + if (!B) // if divisor is 0, we assume divisor==2**(2*WORD_BITS) + return D(Ah.GetLowHalf(), Ah.GetHighHalf()); + else + { + S Q[2]; + T[0] = Al.GetLowHalf(); + T[1] = Al.GetHighHalf(); + T[2] = Ah.GetLowHalf(); + T[3] = Ah.GetHighHalf(); + Q[1] = DivideThreeWordsByTwo(T+1, B.GetLowHalf(), B.GetHighHalf()); + Q[0] = DivideThreeWordsByTwo(T, B.GetLowHalf(), B.GetHighHalf()); + return D(Q[0], Q[1]); + } +} + +// returns quotient, which must fit in a word +inline word DWord::operator/(word a) +{ + #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE + return word(m_whole / a); + #else + hword r[4]; + return DivideFourWordsByTwo(r, m_halfs.low, m_halfs.high, a).GetWhole(); + #endif +} + +inline word DWord::operator%(word a) +{ + #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE + return word(m_whole % a); + #else + if (a < (word(1) << (WORD_BITS/2))) + { + hword h = hword(a); + word r = m_halfs.high % h; + r = ((m_halfs.low >> (WORD_BITS/2)) + (r << (WORD_BITS/2))) % h; + return hword((hword(m_halfs.low) + (r << (WORD_BITS/2))) % h); + } + else + { + hword r[4]; + DivideFourWordsByTwo(r, m_halfs.low, m_halfs.high, a); + return Word(r[0], r[1]).GetWhole(); + } + #endif +} + +// ******************************************************** + +// use some tricks to share assembly code between MSVC and GCC +#if defined(__GNUC__) + #define AddPrologue \ + int result; \ + __asm__ __volatile__ \ + ( \ + ".intel_syntax noprefix;" + #define AddEpilogue \ + ".att_syntax prefix;" \ + : "=a" (result)\ + : "d" (C), "a" (A), "D" (B), "c" (N) \ + : "%esi", "memory", "cc" \ + );\ + return result; + #define MulPrologue \ + __asm__ __volatile__ \ + ( \ + ".intel_syntax noprefix;" \ + AS1( push ebx) \ + AS2( mov ebx, edx) + #define MulEpilogue \ + AS1( pop ebx) \ + ".att_syntax prefix;" \ + : \ + : "d" (s_maskLow16), "c" (C), "a" (A), "D" (B) \ + : "%esi", "memory", "cc" \ + ); + #define SquPrologue MulPrologue + #define SquEpilogue \ + AS1( pop ebx) \ + ".att_syntax prefix;" \ + : \ + : "d" (s_maskLow16), "c" (C), "a" (A) \ + : "%esi", "%edi", "memory", "cc" \ + ); + #define TopPrologue MulPrologue + #define TopEpilogue \ + AS1( pop ebx) \ + ".att_syntax prefix;" \ + : \ + : "d" (s_maskLow16), "c" (C), "a" (A), "D" (B), "S" (L) \ + : "memory", "cc" \ + ); +#else + #define AddPrologue \ + __asm push edi \ + __asm push esi \ + __asm mov eax, [esp+12] \ + __asm mov edi, [esp+16] + #define AddEpilogue \ + __asm pop esi \ + __asm pop edi \ + __asm ret 8 +#if _MSC_VER < 1300 + #define SaveEBX __asm push ebx + #define RestoreEBX __asm pop ebx +#else + #define SaveEBX + #define RestoreEBX +#endif + #define SquPrologue \ + AS2( mov eax, A) \ + AS2( mov ecx, C) \ + SaveEBX \ + AS2( lea ebx, s_maskLow16) + #define MulPrologue \ + AS2( mov eax, A) \ + AS2( mov edi, B) \ + AS2( mov ecx, C) \ + SaveEBX \ + AS2( lea ebx, s_maskLow16) + #define TopPrologue \ + AS2( mov eax, A) \ + AS2( mov edi, B) \ + AS2( mov ecx, C) \ + AS2( mov esi, L) \ + SaveEBX \ + AS2( lea ebx, s_maskLow16) + #define SquEpilogue RestoreEBX + #define MulEpilogue RestoreEBX + #define TopEpilogue RestoreEBX +#endif + +#ifdef CRYPTOPP_X64_MASM_AVAILABLE +extern "C" { +int Baseline_Add(size_t N, word *C, const word *A, const word *B); +int Baseline_Sub(size_t N, word *C, const word *A, const word *B); +} +#elif defined(CRYPTOPP_X64_ASM_AVAILABLE) && defined(__GNUC__) +int Baseline_Add(size_t N, word *C, const word *A, const word *B) +{ + word result; + __asm__ __volatile__ + ( + ".intel_syntax;" + AS1( neg %1) + ASJ( jz, 1, f) + AS2( mov %0,[%3+8*%1]) + AS2( add %0,[%4+8*%1]) + AS2( mov [%2+8*%1],%0) + ASL(0) + AS2( mov %0,[%3+8*%1+8]) + AS2( adc %0,[%4+8*%1+8]) + AS2( mov [%2+8*%1+8],%0) + AS2( lea %1,[%1+2]) + ASJ( jrcxz, 1, f) + AS2( mov %0,[%3+8*%1]) + AS2( adc %0,[%4+8*%1]) + AS2( mov [%2+8*%1],%0) + ASJ( jmp, 0, b) + ASL(1) + AS2( mov %0, 0) + AS2( adc %0, %0) + ".att_syntax;" + : "=&r" (result) + : "c" (N), "r" (C+N), "r" (A+N), "r" (B+N) + : "memory", "cc" + ); + return (int)result; +} + +int Baseline_Sub(size_t N, word *C, const word *A, const word *B) +{ + word result; + __asm__ __volatile__ + ( + ".intel_syntax;" + AS1( neg %1) + ASJ( jz, 1, f) + AS2( mov %0,[%3+8*%1]) + AS2( sub %0,[%4+8*%1]) + AS2( mov [%2+8*%1],%0) + ASL(0) + AS2( mov %0,[%3+8*%1+8]) + AS2( sbb %0,[%4+8*%1+8]) + AS2( mov [%2+8*%1+8],%0) + AS2( lea %1,[%1+2]) + ASJ( jrcxz, 1, f) + AS2( mov %0,[%3+8*%1]) + AS2( sbb %0,[%4+8*%1]) + AS2( mov [%2+8*%1],%0) + ASJ( jmp, 0, b) + ASL(1) + AS2( mov %0, 0) + AS2( adc %0, %0) + ".att_syntax;" + : "=&r" (result) + : "c" (N), "r" (C+N), "r" (A+N), "r" (B+N) + : "memory", "cc" + ); + return (int)result; +} +#elif defined(CRYPTOPP_X86_ASM_AVAILABLE) && CRYPTOPP_BOOL_X86 +CRYPTOPP_NAKED int CRYPTOPP_FASTCALL Baseline_Add(size_t N, word *C, const word *A, const word *B) +{ + AddPrologue + + // now: eax = A, edi = B, edx = C, ecx = N + AS2( lea eax, [eax+4*ecx]) + AS2( lea edi, [edi+4*ecx]) + AS2( lea edx, [edx+4*ecx]) + + AS1( neg ecx) // ecx is negative index + AS2( test ecx, 2) // this clears carry flag + ASJ( jz, 0, f) + AS2( sub ecx, 2) + ASJ( jmp, 1, f) + + ASL(0) + ASJ( jecxz, 2, f) // loop until ecx overflows and becomes zero + AS2( mov esi,[eax+4*ecx]) + AS2( adc esi,[edi+4*ecx]) + AS2( mov [edx+4*ecx],esi) + AS2( mov esi,[eax+4*ecx+4]) + AS2( adc esi,[edi+4*ecx+4]) + AS2( mov [edx+4*ecx+4],esi) + ASL(1) + AS2( mov esi,[eax+4*ecx+8]) + AS2( adc esi,[edi+4*ecx+8]) + AS2( mov [edx+4*ecx+8],esi) + AS2( mov esi,[eax+4*ecx+12]) + AS2( adc esi,[edi+4*ecx+12]) + AS2( mov [edx+4*ecx+12],esi) + + AS2( lea ecx,[ecx+4]) // advance index, avoid inc which causes slowdown on Intel Core 2 + ASJ( jmp, 0, b) + + ASL(2) + AS2( mov eax, 0) + AS1( setc al) // store carry into eax (return result register) + + AddEpilogue +} + +CRYPTOPP_NAKED int CRYPTOPP_FASTCALL Baseline_Sub(size_t N, word *C, const word *A, const word *B) +{ + AddPrologue + + // now: eax = A, edi = B, edx = C, ecx = N + AS2( lea eax, [eax+4*ecx]) + AS2( lea edi, [edi+4*ecx]) + AS2( lea edx, [edx+4*ecx]) + + AS1( neg ecx) // ecx is negative index + AS2( test ecx, 2) // this clears carry flag + ASJ( jz, 0, f) + AS2( sub ecx, 2) + ASJ( jmp, 1, f) + + ASL(0) + ASJ( jecxz, 2, f) // loop until ecx overflows and becomes zero + AS2( mov esi,[eax+4*ecx]) + AS2( sbb esi,[edi+4*ecx]) + AS2( mov [edx+4*ecx],esi) + AS2( mov esi,[eax+4*ecx+4]) + AS2( sbb esi,[edi+4*ecx+4]) + AS2( mov [edx+4*ecx+4],esi) + ASL(1) + AS2( mov esi,[eax+4*ecx+8]) + AS2( sbb esi,[edi+4*ecx+8]) + AS2( mov [edx+4*ecx+8],esi) + AS2( mov esi,[eax+4*ecx+12]) + AS2( sbb esi,[edi+4*ecx+12]) + AS2( mov [edx+4*ecx+12],esi) + + AS2( lea ecx,[ecx+4]) // advance index, avoid inc which causes slowdown on Intel Core 2 + ASJ( jmp, 0, b) + + ASL(2) + AS2( mov eax, 0) + AS1( setc al) // store carry into eax (return result register) + + AddEpilogue +} + +#if CRYPTOPP_INTEGER_SSE2 +CRYPTOPP_NAKED int CRYPTOPP_FASTCALL SSE2_Add(size_t N, word *C, const word *A, const word *B) +{ + AddPrologue + + // now: eax = A, edi = B, edx = C, ecx = N + AS2( lea eax, [eax+4*ecx]) + AS2( lea edi, [edi+4*ecx]) + AS2( lea edx, [edx+4*ecx]) + + AS1( neg ecx) // ecx is negative index + AS2( pxor mm2, mm2) + ASJ( jz, 2, f) + AS2( test ecx, 2) // this clears carry flag + ASJ( jz, 0, f) + AS2( sub ecx, 2) + ASJ( jmp, 1, f) + + ASL(0) + AS2( movd mm0, DWORD PTR [eax+4*ecx]) + AS2( movd mm1, DWORD PTR [edi+4*ecx]) + AS2( paddq mm0, mm1) + AS2( paddq mm2, mm0) + AS2( movd DWORD PTR [edx+4*ecx], mm2) + AS2( psrlq mm2, 32) + + AS2( movd mm0, DWORD PTR [eax+4*ecx+4]) + AS2( movd mm1, DWORD PTR [edi+4*ecx+4]) + AS2( paddq mm0, mm1) + AS2( paddq mm2, mm0) + AS2( movd DWORD PTR [edx+4*ecx+4], mm2) + AS2( psrlq mm2, 32) + + ASL(1) + AS2( movd mm0, DWORD PTR [eax+4*ecx+8]) + AS2( movd mm1, DWORD PTR [edi+4*ecx+8]) + AS2( paddq mm0, mm1) + AS2( paddq mm2, mm0) + AS2( movd DWORD PTR [edx+4*ecx+8], mm2) + AS2( psrlq mm2, 32) + + AS2( movd mm0, DWORD PTR [eax+4*ecx+12]) + AS2( movd mm1, DWORD PTR [edi+4*ecx+12]) + AS2( paddq mm0, mm1) + AS2( paddq mm2, mm0) + AS2( movd DWORD PTR [edx+4*ecx+12], mm2) + AS2( psrlq mm2, 32) + + AS2( add ecx, 4) + ASJ( jnz, 0, b) + + ASL(2) + AS2( movd eax, mm2) + AS1( emms) + + AddEpilogue +} +CRYPTOPP_NAKED int CRYPTOPP_FASTCALL SSE2_Sub(size_t N, word *C, const word *A, const word *B) +{ + AddPrologue + + // now: eax = A, edi = B, edx = C, ecx = N + AS2( lea eax, [eax+4*ecx]) + AS2( lea edi, [edi+4*ecx]) + AS2( lea edx, [edx+4*ecx]) + + AS1( neg ecx) // ecx is negative index + AS2( pxor mm2, mm2) + ASJ( jz, 2, f) + AS2( test ecx, 2) // this clears carry flag + ASJ( jz, 0, f) + AS2( sub ecx, 2) + ASJ( jmp, 1, f) + + ASL(0) + AS2( movd mm0, DWORD PTR [eax+4*ecx]) + AS2( movd mm1, DWORD PTR [edi+4*ecx]) + AS2( psubq mm0, mm1) + AS2( psubq mm0, mm2) + AS2( movd DWORD PTR [edx+4*ecx], mm0) + AS2( psrlq mm0, 63) + + AS2( movd mm2, DWORD PTR [eax+4*ecx+4]) + AS2( movd mm1, DWORD PTR [edi+4*ecx+4]) + AS2( psubq mm2, mm1) + AS2( psubq mm2, mm0) + AS2( movd DWORD PTR [edx+4*ecx+4], mm2) + AS2( psrlq mm2, 63) + + ASL(1) + AS2( movd mm0, DWORD PTR [eax+4*ecx+8]) + AS2( movd mm1, DWORD PTR [edi+4*ecx+8]) + AS2( psubq mm0, mm1) + AS2( psubq mm0, mm2) + AS2( movd DWORD PTR [edx+4*ecx+8], mm0) + AS2( psrlq mm0, 63) + + AS2( movd mm2, DWORD PTR [eax+4*ecx+12]) + AS2( movd mm1, DWORD PTR [edi+4*ecx+12]) + AS2( psubq mm2, mm1) + AS2( psubq mm2, mm0) + AS2( movd DWORD PTR [edx+4*ecx+12], mm2) + AS2( psrlq mm2, 63) + + AS2( add ecx, 4) + ASJ( jnz, 0, b) + + ASL(2) + AS2( movd eax, mm2) + AS1( emms) + + AddEpilogue +} +#endif // #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE +#else +int CRYPTOPP_FASTCALL Baseline_Add(size_t N, word *C, const word *A, const word *B) +{ + assert (N%2 == 0); + + Declare2Words(u); + AssignWord(u, 0); + for (size_t i=0; i=2 && N%2==0); + + if (N <= s_recursionLimit) + s_pMul[N/4](R, A, B); + else + { + const size_t N2 = N/2; + + size_t AN2 = Compare(A0, A1, N2) > 0 ? 0 : N2; + Subtract(R0, A + AN2, A + (N2 ^ AN2), N2); + + size_t BN2 = Compare(B0, B1, N2) > 0 ? 0 : N2; + Subtract(R1, B + BN2, B + (N2 ^ BN2), N2); + + RecursiveMultiply(R2, T2, A1, B1, N2); + RecursiveMultiply(T0, T2, R0, R1, N2); + RecursiveMultiply(R0, T2, A0, B0, N2); + + // now T[01] holds (A1-A0)*(B0-B1), R[01] holds A0*B0, R[23] holds A1*B1 + + int c2 = Add(R2, R2, R1, N2); + int c3 = c2; + c2 += Add(R1, R2, R0, N2); + c3 += Add(R2, R2, R3, N2); + + if (AN2 == BN2) + c3 -= Subtract(R1, R1, T0, N); + else + c3 += Add(R1, R1, T0, N); + + c3 += Increment(R2, N2, c2); + assert (c3 >= 0 && c3 <= 2); + Increment(R3, N2, c3); + } +} + +// R[2*N] - result = A*A +// T[2*N] - temporary work space +// A[N] --- number to be squared + +void RecursiveSquare(word *R, word *T, const word *A, size_t N) +{ + assert(N && N%2==0); + + if (N <= s_recursionLimit) + s_pSqu[N/4](R, A); + else + { + const size_t N2 = N/2; + + RecursiveSquare(R0, T2, A0, N2); + RecursiveSquare(R2, T2, A1, N2); + RecursiveMultiply(T0, T2, A0, A1, N2); + + int carry = Add(R1, R1, T0, N); + carry += Add(R1, R1, T0, N); + Increment(R3, N2, carry); + } +} + +// R[N] - bottom half of A*B +// T[3*N/2] - temporary work space +// A[N] - multiplier +// B[N] - multiplicant + +void RecursiveMultiplyBottom(word *R, word *T, const word *A, const word *B, size_t N) +{ + assert(N>=2 && N%2==0); + + if (N <= s_recursionLimit) + s_pBot[N/4](R, A, B); + else + { + const size_t N2 = N/2; + + RecursiveMultiply(R, T, A0, B0, N2); + RecursiveMultiplyBottom(T0, T1, A1, B0, N2); + Add(R1, R1, T0, N2); + RecursiveMultiplyBottom(T0, T1, A0, B1, N2); + Add(R1, R1, T0, N2); + } +} + +// R[N] --- upper half of A*B +// T[2*N] - temporary work space +// L[N] --- lower half of A*B +// A[N] --- multiplier +// B[N] --- multiplicant + +void MultiplyTop(word *R, word *T, const word *L, const word *A, const word *B, size_t N) +{ + assert(N>=2 && N%2==0); + + if (N <= s_recursionLimit) + s_pTop[N/4](R, A, B, L[N-1]); + else + { + const size_t N2 = N/2; + + size_t AN2 = Compare(A0, A1, N2) > 0 ? 0 : N2; + Subtract(R0, A + AN2, A + (N2 ^ AN2), N2); + + size_t BN2 = Compare(B0, B1, N2) > 0 ? 0 : N2; + Subtract(R1, B + BN2, B + (N2 ^ BN2), N2); + + RecursiveMultiply(T0, T2, R0, R1, N2); + RecursiveMultiply(R0, T2, A1, B1, N2); + + // now T[01] holds (A1-A0)*(B0-B1) = A1*B0+A0*B1-A1*B1-A0*B0, R[01] holds A1*B1 + + int t, c3; + int c2 = Subtract(T2, L+N2, L, N2); + + if (AN2 == BN2) + { + c2 -= Add(T2, T2, T0, N2); + t = (Compare(T2, R0, N2) == -1); + c3 = t - Subtract(T2, T2, T1, N2); + } + else + { + c2 += Subtract(T2, T2, T0, N2); + t = (Compare(T2, R0, N2) == -1); + c3 = t + Add(T2, T2, T1, N2); + } + + c2 += t; + if (c2 >= 0) + c3 += Increment(T2, N2, c2); + else + c3 -= Decrement(T2, N2, -c2); + c3 += Add(R0, T2, R1, N2); + + assert (c3 >= 0 && c3 <= 2); + Increment(R1, N2, c3); + } +} + +inline void Multiply(word *R, word *T, const word *A, const word *B, size_t N) +{ + RecursiveMultiply(R, T, A, B, N); +} + +inline void Square(word *R, word *T, const word *A, size_t N) +{ + RecursiveSquare(R, T, A, N); +} + +inline void MultiplyBottom(word *R, word *T, const word *A, const word *B, size_t N) +{ + RecursiveMultiplyBottom(R, T, A, B, N); +} + +// R[NA+NB] - result = A*B +// T[NA+NB] - temporary work space +// A[NA] ---- multiplier +// B[NB] ---- multiplicant + +void AsymmetricMultiply(word *R, word *T, const word *A, size_t NA, const word *B, size_t NB) +{ + if (NA == NB) + { + if (A == B) + Square(R, T, A, NA); + else + Multiply(R, T, A, B, NA); + + return; + } + + if (NA > NB) + { + std::swap(A, B); + std::swap(NA, NB); + } + + assert(NB % NA == 0); + + if (NA==2 && !A[1]) + { + switch (A[0]) + { + case 0: + SetWords(R, 0, NB+2); + return; + case 1: + CopyWords(R, B, NB); + R[NB] = R[NB+1] = 0; + return; + default: + R[NB] = LinearMultiply(R, B, A[0], NB); + R[NB+1] = 0; + return; + } + } + + size_t i; + if ((NB/NA)%2 == 0) + { + Multiply(R, T, A, B, NA); + CopyWords(T+2*NA, R+NA, NA); + + for (i=2*NA; i=4); + +#define M0 M +#define M1 (M+N2) +#define V0 V +#define V1 (V+N2) + +#define X0 X +#define X1 (X+N2) +#define X2 (X+N) +#define X3 (X+N+N2) + + const size_t N2 = N/2; + Multiply(T0, T2, V0, X3, N2); + int c2 = Add(T0, T0, X0, N); + MultiplyBottom(T3, T2, T0, U, N2); + MultiplyTop(T2, R, T0, T3, M0, N2); + c2 -= Subtract(T2, T1, T2, N2); + Multiply(T0, R, T3, M1, N2); + c2 -= Subtract(T0, T2, T0, N2); + int c3 = -(int)Subtract(T1, X2, T1, N2); + Multiply(R0, T2, V1, X3, N2); + c3 += Add(R, R, T, N); + + if (c2>0) + c3 += Increment(R1, N2); + else if (c2<0) + c3 -= Decrement(R1, N2, -c2); + + assert(c3>=-1 && c3<=1); + if (c3>0) + Subtract(R, R, M, N); + else if (c3<0) + Add(R, R, M, N); + +#undef M0 +#undef M1 +#undef V0 +#undef V1 + +#undef X0 +#undef X1 +#undef X2 +#undef X3 +} + +#undef A0 +#undef A1 +#undef B0 +#undef B1 + +#undef T0 +#undef T1 +#undef T2 +#undef T3 + +#undef R0 +#undef R1 +#undef R2 +#undef R3 + +/* +// do a 3 word by 2 word divide, returns quotient and leaves remainder in A +static word SubatomicDivide(word *A, word B0, word B1) +{ + // assert {A[2],A[1]} < {B1,B0}, so quotient can fit in a word + assert(A[2] < B1 || (A[2]==B1 && A[1] < B0)); + + // estimate the quotient: do a 2 word by 1 word divide + word Q; + if (B1+1 == 0) + Q = A[2]; + else + Q = DWord(A[1], A[2]).DividedBy(B1+1); + + // now subtract Q*B from A + DWord p = DWord::Multiply(B0, Q); + DWord u = (DWord) A[0] - p.GetLowHalf(); + A[0] = u.GetLowHalf(); + u = (DWord) A[1] - p.GetHighHalf() - u.GetHighHalfAsBorrow() - DWord::Multiply(B1, Q); + A[1] = u.GetLowHalf(); + A[2] += u.GetHighHalf(); + + // Q <= actual quotient, so fix it + while (A[2] || A[1] > B1 || (A[1]==B1 && A[0]>=B0)) + { + u = (DWord) A[0] - B0; + A[0] = u.GetLowHalf(); + u = (DWord) A[1] - B1 - u.GetHighHalfAsBorrow(); + A[1] = u.GetLowHalf(); + A[2] += u.GetHighHalf(); + Q++; + assert(Q); // shouldn't overflow + } + + return Q; +} + +// do a 4 word by 2 word divide, returns 2 word quotient in Q0 and Q1 +static inline void AtomicDivide(word *Q, const word *A, const word *B) +{ + if (!B[0] && !B[1]) // if divisor is 0, we assume divisor==2**(2*WORD_BITS) + { + Q[0] = A[2]; + Q[1] = A[3]; + } + else + { + word T[4]; + T[0] = A[0]; T[1] = A[1]; T[2] = A[2]; T[3] = A[3]; + Q[1] = SubatomicDivide(T+1, B[0], B[1]); + Q[0] = SubatomicDivide(T, B[0], B[1]); + +#ifndef NDEBUG + // multiply quotient and divisor and add remainder, make sure it equals dividend + assert(!T[2] && !T[3] && (T[1] < B[1] || (T[1]==B[1] && T[0](T, DWord(A[0], A[1]), DWord(A[2], A[3]), DWord(B[0], B[1])); + Q[0] = q.GetLowHalf(); + Q[1] = q.GetHighHalf(); + +#ifndef NDEBUG + if (B[0] || B[1]) + { + // multiply quotient and divisor and add remainder, make sure it equals dividend + assert(!T[2] && !T[3] && (T[1] < B[1] || (T[1]==B[1] && T[0]= 0) + { + R[N] -= Subtract(R, R, B, N); + Q[1] += (++Q[0]==0); + assert(Q[0] || Q[1]); // no overflow + } +} + +// R[NB] -------- remainder = A%B +// Q[NA-NB+2] --- quotient = A/B +// T[NA+3*(NB+2)] - temp work space +// A[NA] -------- dividend +// B[NB] -------- divisor + +void Divide(word *R, word *Q, word *T, const word *A, size_t NA, const word *B, size_t NB) +{ + assert(NA && NB && NA%2==0 && NB%2==0); + assert(B[NB-1] || B[NB-2]); + assert(NB <= NA); + + // set up temporary work space + word *const TA=T; + word *const TB=T+NA+2; + word *const TP=T+NA+2+NB; + + // copy B into TB and normalize it so that TB has highest bit set to 1 + unsigned shiftWords = (B[NB-1]==0); + TB[0] = TB[NB-1] = 0; + CopyWords(TB+shiftWords, B, NB-shiftWords); + unsigned shiftBits = WORD_BITS - BitPrecision(TB[NB-1]); + assert(shiftBits < WORD_BITS); + ShiftWordsLeftByBits(TB, NB, shiftBits); + + // copy A into TA and normalize it + TA[0] = TA[NA] = TA[NA+1] = 0; + CopyWords(TA+shiftWords, A, NA); + ShiftWordsLeftByBits(TA, NA+2, shiftBits); + + if (TA[NA+1]==0 && TA[NA] <= 1) + { + Q[NA-NB+1] = Q[NA-NB] = 0; + while (TA[NA] || Compare(TA+NA-NB, TB, NB) >= 0) + { + TA[NA] -= Subtract(TA+NA-NB, TA+NA-NB, TB, NB); + ++Q[NA-NB]; + } + } + else + { + NA+=2; + assert(Compare(TA+NA-NB, TB, NB) < 0); + } + + word BT[2]; + BT[0] = TB[NB-2] + 1; + BT[1] = TB[NB-1] + (BT[0]==0); + + // start reducing TA mod TB, 2 words at a time + for (size_t i=NA-2; i>=NB; i-=2) + { + AtomicDivide(Q+i-NB, TA+i-2, BT); + CorrectQuotientEstimate(TA+i-NB, TP, Q+i-NB, TB, NB); + } + + // copy TA into R, and denormalize it + CopyWords(R, TA+shiftWords, NB); + ShiftWordsRightByBits(R, NB, shiftBits); +} + +static inline size_t EvenWordCount(const word *X, size_t N) +{ + while (N && X[N-2]==0 && X[N-1]==0) + N-=2; + return N; +} + +// return k +// R[N] --- result = A^(-1) * 2^k mod M +// T[4*N] - temporary work space +// A[NA] -- number to take inverse of +// M[N] --- modulus + +unsigned int AlmostInverse(word *R, word *T, const word *A, size_t NA, const word *M, size_t N) +{ + assert(NA<=N && N && N%2==0); + + word *b = T; + word *c = T+N; + word *f = T+2*N; + word *g = T+3*N; + size_t bcLen=2, fgLen=EvenWordCount(M, N); + unsigned int k=0, s=0; + + SetWords(T, 0, 3*N); + b[0]=1; + CopyWords(f, A, NA); + CopyWords(g, M, N); + + while (1) + { + word t=f[0]; + while (!t) + { + if (EvenWordCount(f, fgLen)==0) + { + SetWords(R, 0, N); + return 0; + } + + ShiftWordsRightByWords(f, fgLen, 1); + if (c[bcLen-1]) bcLen+=2; + assert(bcLen <= N); + ShiftWordsLeftByWords(c, bcLen, 1); + k+=WORD_BITS; + t=f[0]; + } + + unsigned int i=0; + while (t%2 == 0) + { + t>>=1; + i++; + } + k+=i; + + if (t==1 && f[1]==0 && EvenWordCount(f, fgLen)==2) + { + if (s%2==0) + CopyWords(R, b, N); + else + Subtract(R, M, b, N); + return k; + } + + ShiftWordsRightByBits(f, fgLen, i); + t=ShiftWordsLeftByBits(c, bcLen, i); + if (t) + { + c[bcLen] = t; + bcLen+=2; + assert(bcLen <= N); + } + + if (f[fgLen-2]==0 && g[fgLen-2]==0 && f[fgLen-1]==0 && g[fgLen-1]==0) + fgLen-=2; + + if (Compare(f, g, fgLen)==-1) + { + std::swap(f, g); + std::swap(b, c); + s++; + } + + Subtract(f, f, g, fgLen); + + if (Add(b, b, c, bcLen)) + { + b[bcLen] = 1; + bcLen+=2; + assert(bcLen <= N); + } + } +} + +// R[N] - result = A/(2^k) mod M +// A[N] - input +// M[N] - modulus + +void DivideByPower2Mod(word *R, const word *A, size_t k, const word *M, size_t N) +{ + CopyWords(R, A, N); + + while (k--) + { + if (R[0]%2==0) + ShiftWordsRightByBits(R, N, 1); + else + { + word carry = Add(R, R, M, N); + ShiftWordsRightByBits(R, N, 1); + R[N-1] += carry<<(WORD_BITS-1); + } + } +} + +// R[N] - result = A*(2^k) mod M +// A[N] - input +// M[N] - modulus + +void MultiplyByPower2Mod(word *R, const word *A, size_t k, const word *M, size_t N) +{ + CopyWords(R, A, N); + + while (k--) + if (ShiftWordsLeftByBits(R, N, 1) || Compare(R, M, N)>=0) + Subtract(R, R, M, N); +} + +// ****************************************************************** + +InitializeInteger::InitializeInteger() +{ + if (!g_pAssignIntToInteger) + { + SetFunctionPointers(); + g_pAssignIntToInteger = AssignIntToInteger; + } +} + +static const unsigned int RoundupSizeTable[] = {2, 2, 2, 4, 4, 8, 8, 8, 8}; + +static inline size_t RoundupSize(size_t n) +{ + if (n<=8) + return RoundupSizeTable[n]; + else if (n<=16) + return 16; + else if (n<=32) + return 32; + else if (n<=64) + return 64; + else return size_t(1) << BitPrecision(n-1); +} + +Integer::Integer() + : reg(2), sign(POSITIVE) +{ + reg[0] = reg[1] = 0; +} + +Integer::Integer(const Integer& t) + : reg(RoundupSize(t.WordCount())), sign(t.sign) +{ + CopyWords(reg, t.reg, reg.size()); +} + +Integer::Integer(Sign s, lword value) + : reg(2), sign(s) +{ + reg[0] = word(value); + reg[1] = word(SafeRightShift(value)); +} + +Integer::Integer(signed long value) + : reg(2) +{ + if (value >= 0) + sign = POSITIVE; + else + { + sign = NEGATIVE; + value = -value; + } + reg[0] = word(value); + reg[1] = word(SafeRightShift((unsigned long)value)); +} + +Integer::Integer(Sign s, word high, word low) + : reg(2), sign(s) +{ + reg[0] = low; + reg[1] = high; +} + +bool Integer::IsConvertableToLong() const +{ + if (ByteCount() > sizeof(long)) + return false; + + unsigned long value = (unsigned long)reg[0]; + value += SafeLeftShift((unsigned long)reg[1]); + + if (sign==POSITIVE) + return (signed long)value >= 0; + else + return -(signed long)value < 0; +} + +signed long Integer::ConvertToLong() const +{ + assert(IsConvertableToLong()); + + unsigned long value = (unsigned long)reg[0]; + value += SafeLeftShift((unsigned long)reg[1]); + return sign==POSITIVE ? value : -(signed long)value; +} + +Integer::Integer(BufferedTransformation &encodedInteger, size_t byteCount, Signedness s) +{ + Decode(encodedInteger, byteCount, s); +} + +Integer::Integer(const byte *encodedInteger, size_t byteCount, Signedness s) +{ + Decode(encodedInteger, byteCount, s); +} + +Integer::Integer(BufferedTransformation &bt) +{ + BERDecode(bt); +} + +Integer::Integer(RandomNumberGenerator &rng, size_t bitcount) +{ + Randomize(rng, bitcount); +} + +Integer::Integer(RandomNumberGenerator &rng, const Integer &min, const Integer &max, RandomNumberType rnType, const Integer &equiv, const Integer &mod) +{ + if (!Randomize(rng, min, max, rnType, equiv, mod)) + throw Integer::RandomNumberNotFound(); +} + +Integer Integer::Power2(size_t e) +{ + Integer r((word)0, BitsToWords(e+1)); + r.SetBit(e); + return r; +} + +template +struct NewInteger +{ + Integer * operator()() const + { + return new Integer(i); + } +}; + +const Integer &Integer::Zero() +{ + return Singleton().Ref(); +} + +const Integer &Integer::One() +{ + return Singleton >().Ref(); +} + +const Integer &Integer::Two() +{ + return Singleton >().Ref(); +} + +bool Integer::operator!() const +{ + return IsNegative() ? false : (reg[0]==0 && WordCount()==0); +} + +Integer& Integer::operator=(const Integer& t) +{ + if (this != &t) + { + if (reg.size() != t.reg.size() || t.reg[t.reg.size()/2] == 0) + reg.New(RoundupSize(t.WordCount())); + CopyWords(reg, t.reg, reg.size()); + sign = t.sign; + } + return *this; +} + +bool Integer::GetBit(size_t n) const +{ + if (n/WORD_BITS >= reg.size()) + return 0; + else + return bool((reg[n/WORD_BITS] >> (n % WORD_BITS)) & 1); +} + +void Integer::SetBit(size_t n, bool value) +{ + if (value) + { + reg.CleanGrow(RoundupSize(BitsToWords(n+1))); + reg[n/WORD_BITS] |= (word(1) << (n%WORD_BITS)); + } + else + { + if (n/WORD_BITS < reg.size()) + reg[n/WORD_BITS] &= ~(word(1) << (n%WORD_BITS)); + } +} + +byte Integer::GetByte(size_t n) const +{ + if (n/WORD_SIZE >= reg.size()) + return 0; + else + return byte(reg[n/WORD_SIZE] >> ((n%WORD_SIZE)*8)); +} + +void Integer::SetByte(size_t n, byte value) +{ + reg.CleanGrow(RoundupSize(BytesToWords(n+1))); + reg[n/WORD_SIZE] &= ~(word(0xff) << 8*(n%WORD_SIZE)); + reg[n/WORD_SIZE] |= (word(value) << 8*(n%WORD_SIZE)); +} + +lword Integer::GetBits(size_t i, size_t n) const +{ + lword v = 0; + assert(n <= sizeof(v)*8); + for (unsigned int j=0; j +static Integer StringToInteger(const T *str) +{ + int radix; + // GCC workaround + // std::char_traits::length() not defined in GCC 3.2 and STLport 4.5.3 + unsigned int length; + for (length = 0; str[length] != 0; length++) {} + + Integer v; + + if (length == 0) + return v; + + switch (str[length-1]) + { + case 'h': + case 'H': + radix=16; + break; + case 'o': + case 'O': + radix=8; + break; + case 'b': + case 'B': + radix=2; + break; + default: + radix=10; + } + + if (length > 2 && str[0] == '0' && str[1] == 'x') + radix = 16; + + for (unsigned i=0; i= '0' && str[i] <= '9') + digit = str[i] - '0'; + else if (str[i] >= 'A' && str[i] <= 'F') + digit = str[i] - 'A' + 10; + else if (str[i] >= 'a' && str[i] <= 'f') + digit = str[i] - 'a' + 10; + else + digit = radix; + + if (digit < radix) + { + v *= radix; + v += digit; + } + } + + if (str[0] == '-') + v.Negate(); + + return v; +} + +Integer::Integer(const char *str) + : reg(2), sign(POSITIVE) +{ + *this = StringToInteger(str); +} + +Integer::Integer(const wchar_t *str) + : reg(2), sign(POSITIVE) +{ + *this = StringToInteger(str); +} + +unsigned int Integer::WordCount() const +{ + return (unsigned int)CountWords(reg, reg.size()); +} + +unsigned int Integer::ByteCount() const +{ + unsigned wordCount = WordCount(); + if (wordCount) + return (wordCount-1)*WORD_SIZE + BytePrecision(reg[wordCount-1]); + else + return 0; +} + +unsigned int Integer::BitCount() const +{ + unsigned wordCount = WordCount(); + if (wordCount) + return (wordCount-1)*WORD_BITS + BitPrecision(reg[wordCount-1]); + else + return 0; +} + +void Integer::Decode(const byte *input, size_t inputLen, Signedness s) +{ + StringStore store(input, inputLen); + Decode(store, inputLen, s); +} + +void Integer::Decode(BufferedTransformation &bt, size_t inputLen, Signedness s) +{ + assert(bt.MaxRetrievable() >= inputLen); + + byte b; + bt.Peek(b); + sign = ((s==SIGNED) && (b & 0x80)) ? NEGATIVE : POSITIVE; + + while (inputLen>0 && (sign==POSITIVE ? b==0 : b==0xff)) + { + bt.Skip(1); + inputLen--; + bt.Peek(b); + } + + reg.CleanNew(RoundupSize(BytesToWords(inputLen))); + + for (size_t i=inputLen; i > 0; i--) + { + bt.Get(b); + reg[(i-1)/WORD_SIZE] |= word(b) << ((i-1)%WORD_SIZE)*8; + } + + if (sign == NEGATIVE) + { + for (size_t i=inputLen; i 0; i--) + bt.Put(GetByte(i-1)); + } + else + { + // take two's complement of *this + Integer temp = Integer::Power2(8*STDMAX((size_t)ByteCount(), outputLen)) + *this; + temp.Encode(bt, outputLen, UNSIGNED); + } +} + +void Integer::DEREncode(BufferedTransformation &bt) const +{ + DERGeneralEncoder enc(bt, INTEGER); + Encode(enc, MinEncodedSize(SIGNED), SIGNED); + enc.MessageEnd(); +} + +void Integer::BERDecode(const byte *input, size_t len) +{ + StringStore store(input, len); + BERDecode(store); +} + +void Integer::BERDecode(BufferedTransformation &bt) +{ + BERGeneralDecoder dec(bt, INTEGER); + if (!dec.IsDefiniteLength() || dec.MaxRetrievable() < dec.RemainingLength()) + BERDecodeError(); + Decode(dec, (size_t)dec.RemainingLength(), SIGNED); + dec.MessageEnd(); +} + +void Integer::DEREncodeAsOctetString(BufferedTransformation &bt, size_t length) const +{ + DERGeneralEncoder enc(bt, OCTET_STRING); + Encode(enc, length); + enc.MessageEnd(); +} + +void Integer::BERDecodeAsOctetString(BufferedTransformation &bt, size_t length) +{ + BERGeneralDecoder dec(bt, OCTET_STRING); + if (!dec.IsDefiniteLength() || dec.RemainingLength() != length) + BERDecodeError(); + Decode(dec, length); + dec.MessageEnd(); +} + +size_t Integer::OpenPGPEncode(byte *output, size_t len) const +{ + ArraySink sink(output, len); + return OpenPGPEncode(sink); +} + +size_t Integer::OpenPGPEncode(BufferedTransformation &bt) const +{ + word16 bitCount = BitCount(); + bt.PutWord16(bitCount); + size_t byteCount = BitsToBytes(bitCount); + Encode(bt, byteCount); + return 2 + byteCount; +} + +void Integer::OpenPGPDecode(const byte *input, size_t len) +{ + StringStore store(input, len); + OpenPGPDecode(store); +} + +void Integer::OpenPGPDecode(BufferedTransformation &bt) +{ + word16 bitCount; + if (bt.GetWord16(bitCount) != 2 || bt.MaxRetrievable() < BitsToBytes(bitCount)) + throw OpenPGPDecodeErr(); + Decode(bt, BitsToBytes(bitCount)); +} + +void Integer::Randomize(RandomNumberGenerator &rng, size_t nbits) +{ + const size_t nbytes = nbits/8 + 1; + SecByteBlock buf(nbytes); + rng.GenerateBlock(buf, nbytes); + if (nbytes) + buf[0] = (byte)Crop(buf[0], nbits % 8); + Decode(buf, nbytes, UNSIGNED); +} + +void Integer::Randomize(RandomNumberGenerator &rng, const Integer &min, const Integer &max) +{ + if (min > max) + throw InvalidArgument("Integer: Min must be no greater than Max"); + + Integer range = max - min; + const unsigned int nbits = range.BitCount(); + + do + { + Randomize(rng, nbits); + } + while (*this > range); + + *this += min; +} + +bool Integer::Randomize(RandomNumberGenerator &rng, const Integer &min, const Integer &max, RandomNumberType rnType, const Integer &equiv, const Integer &mod) +{ + return GenerateRandomNoThrow(rng, MakeParameters("Min", min)("Max", max)("RandomNumberType", rnType)("EquivalentTo", equiv)("Mod", mod)); +} + +class KDF2_RNG : public RandomNumberGenerator +{ +public: + KDF2_RNG(const byte *seed, size_t seedSize) + : m_counter(0), m_counterAndSeed(seedSize + 4) + { + memcpy(m_counterAndSeed + 4, seed, seedSize); + } + + void GenerateBlock(byte *output, size_t size) + { + PutWord(false, BIG_ENDIAN_ORDER, m_counterAndSeed, m_counter); + ++m_counter; + P1363_KDF2::DeriveKey(output, size, m_counterAndSeed, m_counterAndSeed.size(), NULL, 0); + } + +private: + word32 m_counter; + SecByteBlock m_counterAndSeed; +}; + +bool Integer::GenerateRandomNoThrow(RandomNumberGenerator &i_rng, const NameValuePairs ¶ms) +{ + Integer min = params.GetValueWithDefault("Min", Integer::Zero()); + Integer max; + if (!params.GetValue("Max", max)) + { + int bitLength; + if (params.GetIntValue("BitLength", bitLength)) + max = Integer::Power2(bitLength); + else + throw InvalidArgument("Integer: missing Max argument"); + } + if (min > max) + throw InvalidArgument("Integer: Min must be no greater than Max"); + + Integer equiv = params.GetValueWithDefault("EquivalentTo", Integer::Zero()); + Integer mod = params.GetValueWithDefault("Mod", Integer::One()); + + if (equiv.IsNegative() || equiv >= mod) + throw InvalidArgument("Integer: invalid EquivalentTo and/or Mod argument"); + + Integer::RandomNumberType rnType = params.GetValueWithDefault("RandomNumberType", Integer::ANY); + + member_ptr kdf2Rng; + ConstByteArrayParameter seed; + if (params.GetValue("Seed", seed)) + { + ByteQueue bq; + DERSequenceEncoder seq(bq); + min.DEREncode(seq); + max.DEREncode(seq); + equiv.DEREncode(seq); + mod.DEREncode(seq); + DEREncodeUnsigned(seq, rnType); + DEREncodeOctetString(seq, seed.begin(), seed.size()); + seq.MessageEnd(); + + SecByteBlock finalSeed((size_t)bq.MaxRetrievable()); + bq.Get(finalSeed, finalSeed.size()); + kdf2Rng.reset(new KDF2_RNG(finalSeed.begin(), finalSeed.size())); + } + RandomNumberGenerator &rng = kdf2Rng.get() ? (RandomNumberGenerator &)*kdf2Rng : i_rng; + + switch (rnType) + { + case ANY: + if (mod == One()) + Randomize(rng, min, max); + else + { + Integer min1 = min + (equiv-min)%mod; + if (max < min1) + return false; + Randomize(rng, Zero(), (max - min1) / mod); + *this *= mod; + *this += min1; + } + return true; + + case PRIME: + { + const PrimeSelector *pSelector = params.GetValueWithDefault(Name::PointerToPrimeSelector(), (const PrimeSelector *)NULL); + + int i; + i = 0; + while (1) + { + if (++i==16) + { + // check if there are any suitable primes in [min, max] + Integer first = min; + if (FirstPrime(first, max, equiv, mod, pSelector)) + { + // if there is only one suitable prime, we're done + *this = first; + if (!FirstPrime(first, max, equiv, mod, pSelector)) + return true; + } + else + return false; + } + + Randomize(rng, min, max); + if (FirstPrime(*this, STDMIN(*this+mod*PrimeSearchInterval(max), max), equiv, mod, pSelector)) + return true; + } + } + + default: + throw InvalidArgument("Integer: invalid RandomNumberType argument"); + } +} + +std::istream& operator>>(std::istream& in, Integer &a) +{ + char c; + unsigned int length = 0; + SecBlock str(length + 16); + + std::ws(in); + + do + { + in.read(&c, 1); + str[length++] = c; + if (length >= str.size()) + str.Grow(length + 16); + } + while (in && (c=='-' || c=='x' || (c>='0' && c<='9') || (c>='a' && c<='f') || (c>='A' && c<='F') || c=='h' || c=='H' || c=='o' || c=='O' || c==',' || c=='.')); + + if (in.gcount()) + in.putback(c); + str[length-1] = '\0'; + a = Integer(str); + + return in; +} + +std::ostream& operator<<(std::ostream& out, const Integer &a) +{ + // Get relevant conversion specifications from ostream. + long f = out.flags() & std::ios::basefield; // Get base digits. + int base, block; + char suffix; + switch(f) + { + case std::ios::oct : + base = 8; + block = 8; + suffix = 'o'; + break; + case std::ios::hex : + base = 16; + block = 4; + suffix = 'h'; + break; + default : + base = 10; + block = 3; + suffix = '.'; + } + + SecBlock s(a.BitCount() / (BitPrecision(base)-1) + 1); + Integer temp1=a, temp2; + unsigned i=0; + const char vec[]="0123456789ABCDEF"; + + if (a.IsNegative()) + { + out << '-'; + temp1.Negate(); + } + + if (!a) + out << '0'; + + while (!!temp1) + { + word digit; + Integer::Divide(digit, temp2, temp1, base); + s[i++]=vec[digit]; + temp1=temp2; + } + + while (i--) + { + out << s[i]; +// if (i && !(i%block)) +// out << ","; + } + return out << suffix; +} + +Integer& Integer::operator++() +{ + if (NotNegative()) + { + if (Increment(reg, reg.size())) + { + reg.CleanGrow(2*reg.size()); + reg[reg.size()/2]=1; + } + } + else + { + word borrow = Decrement(reg, reg.size()); + assert(!borrow); + if (WordCount()==0) + *this = Zero(); + } + return *this; +} + +Integer& Integer::operator--() +{ + if (IsNegative()) + { + if (Increment(reg, reg.size())) + { + reg.CleanGrow(2*reg.size()); + reg[reg.size()/2]=1; + } + } + else + { + if (Decrement(reg, reg.size())) + *this = -One(); + } + return *this; +} + +void PositiveAdd(Integer &sum, const Integer &a, const Integer& b) +{ + int carry; + if (a.reg.size() == b.reg.size()) + carry = Add(sum.reg, a.reg, b.reg, a.reg.size()); + else if (a.reg.size() > b.reg.size()) + { + carry = Add(sum.reg, a.reg, b.reg, b.reg.size()); + CopyWords(sum.reg+b.reg.size(), a.reg+b.reg.size(), a.reg.size()-b.reg.size()); + carry = Increment(sum.reg+b.reg.size(), a.reg.size()-b.reg.size(), carry); + } + else + { + carry = Add(sum.reg, a.reg, b.reg, a.reg.size()); + CopyWords(sum.reg+a.reg.size(), b.reg+a.reg.size(), b.reg.size()-a.reg.size()); + carry = Increment(sum.reg+a.reg.size(), b.reg.size()-a.reg.size(), carry); + } + + if (carry) + { + sum.reg.CleanGrow(2*sum.reg.size()); + sum.reg[sum.reg.size()/2] = 1; + } + sum.sign = Integer::POSITIVE; +} + +void PositiveSubtract(Integer &diff, const Integer &a, const Integer& b) +{ + unsigned aSize = a.WordCount(); + aSize += aSize%2; + unsigned bSize = b.WordCount(); + bSize += bSize%2; + + if (aSize == bSize) + { + if (Compare(a.reg, b.reg, aSize) >= 0) + { + Subtract(diff.reg, a.reg, b.reg, aSize); + diff.sign = Integer::POSITIVE; + } + else + { + Subtract(diff.reg, b.reg, a.reg, aSize); + diff.sign = Integer::NEGATIVE; + } + } + else if (aSize > bSize) + { + word borrow = Subtract(diff.reg, a.reg, b.reg, bSize); + CopyWords(diff.reg+bSize, a.reg+bSize, aSize-bSize); + borrow = Decrement(diff.reg+bSize, aSize-bSize, borrow); + assert(!borrow); + diff.sign = Integer::POSITIVE; + } + else + { + word borrow = Subtract(diff.reg, b.reg, a.reg, aSize); + CopyWords(diff.reg+aSize, b.reg+aSize, bSize-aSize); + borrow = Decrement(diff.reg+aSize, bSize-aSize, borrow); + assert(!borrow); + diff.sign = Integer::NEGATIVE; + } +} + +// MSVC .NET 2003 workaround +template inline const T& STDMAX2(const T& a, const T& b) +{ + return a < b ? b : a; +} + +Integer Integer::Plus(const Integer& b) const +{ + Integer sum((word)0, STDMAX2(reg.size(), b.reg.size())); + if (NotNegative()) + { + if (b.NotNegative()) + PositiveAdd(sum, *this, b); + else + PositiveSubtract(sum, *this, b); + } + else + { + if (b.NotNegative()) + PositiveSubtract(sum, b, *this); + else + { + PositiveAdd(sum, *this, b); + sum.sign = Integer::NEGATIVE; + } + } + return sum; +} + +Integer& Integer::operator+=(const Integer& t) +{ + reg.CleanGrow(t.reg.size()); + if (NotNegative()) + { + if (t.NotNegative()) + PositiveAdd(*this, *this, t); + else + PositiveSubtract(*this, *this, t); + } + else + { + if (t.NotNegative()) + PositiveSubtract(*this, t, *this); + else + { + PositiveAdd(*this, *this, t); + sign = Integer::NEGATIVE; + } + } + return *this; +} + +Integer Integer::Minus(const Integer& b) const +{ + Integer diff((word)0, STDMAX2(reg.size(), b.reg.size())); + if (NotNegative()) + { + if (b.NotNegative()) + PositiveSubtract(diff, *this, b); + else + PositiveAdd(diff, *this, b); + } + else + { + if (b.NotNegative()) + { + PositiveAdd(diff, *this, b); + diff.sign = Integer::NEGATIVE; + } + else + PositiveSubtract(diff, b, *this); + } + return diff; +} + +Integer& Integer::operator-=(const Integer& t) +{ + reg.CleanGrow(t.reg.size()); + if (NotNegative()) + { + if (t.NotNegative()) + PositiveSubtract(*this, *this, t); + else + PositiveAdd(*this, *this, t); + } + else + { + if (t.NotNegative()) + { + PositiveAdd(*this, *this, t); + sign = Integer::NEGATIVE; + } + else + PositiveSubtract(*this, t, *this); + } + return *this; +} + +Integer& Integer::operator<<=(size_t n) +{ + const size_t wordCount = WordCount(); + const size_t shiftWords = n / WORD_BITS; + const unsigned int shiftBits = (unsigned int)(n % WORD_BITS); + + reg.CleanGrow(RoundupSize(wordCount+BitsToWords(n))); + ShiftWordsLeftByWords(reg, wordCount + shiftWords, shiftWords); + ShiftWordsLeftByBits(reg+shiftWords, wordCount+BitsToWords(shiftBits), shiftBits); + return *this; +} + +Integer& Integer::operator>>=(size_t n) +{ + const size_t wordCount = WordCount(); + const size_t shiftWords = n / WORD_BITS; + const unsigned int shiftBits = (unsigned int)(n % WORD_BITS); + + ShiftWordsRightByWords(reg, wordCount, shiftWords); + if (wordCount > shiftWords) + ShiftWordsRightByBits(reg, wordCount-shiftWords, shiftBits); + if (IsNegative() && WordCount()==0) // avoid -0 + *this = Zero(); + return *this; +} + +void PositiveMultiply(Integer &product, const Integer &a, const Integer &b) +{ + size_t aSize = RoundupSize(a.WordCount()); + size_t bSize = RoundupSize(b.WordCount()); + + product.reg.CleanNew(RoundupSize(aSize+bSize)); + product.sign = Integer::POSITIVE; + + IntegerSecBlock workspace(aSize + bSize); + AsymmetricMultiply(product.reg, workspace, a.reg, aSize, b.reg, bSize); +} + +void Multiply(Integer &product, const Integer &a, const Integer &b) +{ + PositiveMultiply(product, a, b); + + if (a.NotNegative() != b.NotNegative()) + product.Negate(); +} + +Integer Integer::Times(const Integer &b) const +{ + Integer product; + Multiply(product, *this, b); + return product; +} + +/* +void PositiveDivide(Integer &remainder, Integer "ient, + const Integer ÷nd, const Integer &divisor) +{ + remainder.reg.CleanNew(divisor.reg.size()); + remainder.sign = Integer::POSITIVE; + quotient.reg.New(0); + quotient.sign = Integer::POSITIVE; + unsigned i=dividend.BitCount(); + while (i--) + { + word overflow = ShiftWordsLeftByBits(remainder.reg, remainder.reg.size(), 1); + remainder.reg[0] |= dividend[i]; + if (overflow || remainder >= divisor) + { + Subtract(remainder.reg, remainder.reg, divisor.reg, remainder.reg.size()); + quotient.SetBit(i); + } + } +} +*/ + +void PositiveDivide(Integer &remainder, Integer "ient, + const Integer &a, const Integer &b) +{ + unsigned aSize = a.WordCount(); + unsigned bSize = b.WordCount(); + + if (!bSize) + throw Integer::DivideByZero(); + + if (a.PositiveCompare(b) == -1) + { + remainder = a; + remainder.sign = Integer::POSITIVE; + quotient = Integer::Zero(); + return; + } + + aSize += aSize%2; // round up to next even number + bSize += bSize%2; + + remainder.reg.CleanNew(RoundupSize(bSize)); + remainder.sign = Integer::POSITIVE; + quotient.reg.CleanNew(RoundupSize(aSize-bSize+2)); + quotient.sign = Integer::POSITIVE; + + IntegerSecBlock T(aSize+3*(bSize+2)); + Divide(remainder.reg, quotient.reg, T, a.reg, aSize, b.reg, bSize); +} + +void Integer::Divide(Integer &remainder, Integer "ient, const Integer ÷nd, const Integer &divisor) +{ + PositiveDivide(remainder, quotient, dividend, divisor); + + if (dividend.IsNegative()) + { + quotient.Negate(); + if (remainder.NotZero()) + { + --quotient; + remainder = divisor.AbsoluteValue() - remainder; + } + } + + if (divisor.IsNegative()) + quotient.Negate(); +} + +void Integer::DivideByPowerOf2(Integer &r, Integer &q, const Integer &a, unsigned int n) +{ + q = a; + q >>= n; + + const size_t wordCount = BitsToWords(n); + if (wordCount <= a.WordCount()) + { + r.reg.resize(RoundupSize(wordCount)); + CopyWords(r.reg, a.reg, wordCount); + SetWords(r.reg+wordCount, 0, r.reg.size()-wordCount); + if (n % WORD_BITS != 0) + r.reg[wordCount-1] %= (word(1) << (n % WORD_BITS)); + } + else + { + r.reg.resize(RoundupSize(a.WordCount())); + CopyWords(r.reg, a.reg, r.reg.size()); + } + r.sign = POSITIVE; + + if (a.IsNegative() && r.NotZero()) + { + --q; + r = Power2(n) - r; + } +} + +Integer Integer::DividedBy(const Integer &b) const +{ + Integer remainder, quotient; + Integer::Divide(remainder, quotient, *this, b); + return quotient; +} + +Integer Integer::Modulo(const Integer &b) const +{ + Integer remainder, quotient; + Integer::Divide(remainder, quotient, *this, b); + return remainder; +} + +void Integer::Divide(word &remainder, Integer "ient, const Integer ÷nd, word divisor) +{ + if (!divisor) + throw Integer::DivideByZero(); + + assert(divisor); + + if ((divisor & (divisor-1)) == 0) // divisor is a power of 2 + { + quotient = dividend >> (BitPrecision(divisor)-1); + remainder = dividend.reg[0] & (divisor-1); + return; + } + + unsigned int i = dividend.WordCount(); + quotient.reg.CleanNew(RoundupSize(i)); + remainder = 0; + while (i--) + { + quotient.reg[i] = DWord(dividend.reg[i], remainder) / divisor; + remainder = DWord(dividend.reg[i], remainder) % divisor; + } + + if (dividend.NotNegative()) + quotient.sign = POSITIVE; + else + { + quotient.sign = NEGATIVE; + if (remainder) + { + --quotient; + remainder = divisor - remainder; + } + } +} + +Integer Integer::DividedBy(word b) const +{ + word remainder; + Integer quotient; + Integer::Divide(remainder, quotient, *this, b); + return quotient; +} + +word Integer::Modulo(word divisor) const +{ + if (!divisor) + throw Integer::DivideByZero(); + + assert(divisor); + + word remainder; + + if ((divisor & (divisor-1)) == 0) // divisor is a power of 2 + remainder = reg[0] & (divisor-1); + else + { + unsigned int i = WordCount(); + + if (divisor <= 5) + { + DWord sum(0, 0); + while (i--) + sum += reg[i]; + remainder = sum % divisor; + } + else + { + remainder = 0; + while (i--) + remainder = DWord(reg[i], remainder) % divisor; + } + } + + if (IsNegative() && remainder) + remainder = divisor - remainder; + + return remainder; +} + +void Integer::Negate() +{ + if (!!(*this)) // don't flip sign if *this==0 + sign = Sign(1-sign); +} + +int Integer::PositiveCompare(const Integer& t) const +{ + unsigned size = WordCount(), tSize = t.WordCount(); + + if (size == tSize) + return CryptoPP::Compare(reg, t.reg, size); + else + return size > tSize ? 1 : -1; +} + +int Integer::Compare(const Integer& t) const +{ + if (NotNegative()) + { + if (t.NotNegative()) + return PositiveCompare(t); + else + return 1; + } + else + { + if (t.NotNegative()) + return -1; + else + return -PositiveCompare(t); + } +} + +Integer Integer::SquareRoot() const +{ + if (!IsPositive()) + return Zero(); + + // overestimate square root + Integer x, y = Power2((BitCount()+1)/2); + assert(y*y >= *this); + + do + { + x = y; + y = (x + *this/x) >> 1; + } while (y().Gcd(a, b); +} + +Integer Integer::InverseMod(const Integer &m) const +{ + assert(m.NotNegative()); + + if (IsNegative() || *this>=m) + return (*this%m).InverseMod(m); + + if (m.IsEven()) + { + if (!m || IsEven()) + return Zero(); // no inverse + if (*this == One()) + return One(); + + Integer u = m.InverseMod(*this); + return !u ? Zero() : (m*(*this-u)+1)/(*this); + } + + SecBlock T(m.reg.size() * 4); + Integer r((word)0, m.reg.size()); + unsigned k = AlmostInverse(r.reg, T, reg, reg.size(), m.reg, m.reg.size()); + DivideByPower2Mod(r.reg, r.reg, k, m.reg, m.reg.size()); + return r; +} + +word Integer::InverseMod(word mod) const +{ + word g0 = mod, g1 = *this % mod; + word v0 = 0, v1 = 1; + word y; + + while (g1) + { + if (g1 == 1) + return v1; + y = g0 / g1; + g0 = g0 % g1; + v0 += y * v1; + + if (!g0) + break; + if (g0 == 1) + return mod-v0; + y = g1 / g0; + g1 = g1 % g0; + v1 += y * v0; + } + return 0; +} + +// ******************************************************** + +ModularArithmetic::ModularArithmetic(BufferedTransformation &bt) +{ + BERSequenceDecoder seq(bt); + OID oid(seq); + if (oid != ASN1::prime_field()) + BERDecodeError(); + m_modulus.BERDecode(seq); + seq.MessageEnd(); + m_result.reg.resize(m_modulus.reg.size()); +} + +void ModularArithmetic::DEREncode(BufferedTransformation &bt) const +{ + DERSequenceEncoder seq(bt); + ASN1::prime_field().DEREncode(seq); + m_modulus.DEREncode(seq); + seq.MessageEnd(); +} + +void ModularArithmetic::DEREncodeElement(BufferedTransformation &out, const Element &a) const +{ + a.DEREncodeAsOctetString(out, MaxElementByteLength()); +} + +void ModularArithmetic::BERDecodeElement(BufferedTransformation &in, Element &a) const +{ + a.BERDecodeAsOctetString(in, MaxElementByteLength()); +} + +const Integer& ModularArithmetic::Half(const Integer &a) const +{ + if (a.reg.size()==m_modulus.reg.size()) + { + CryptoPP::DivideByPower2Mod(m_result.reg.begin(), a.reg, 1, m_modulus.reg, a.reg.size()); + return m_result; + } + else + return m_result1 = (a.IsEven() ? (a >> 1) : ((a+m_modulus) >> 1)); +} + +const Integer& ModularArithmetic::Add(const Integer &a, const Integer &b) const +{ + if (a.reg.size()==m_modulus.reg.size() && b.reg.size()==m_modulus.reg.size()) + { + if (CryptoPP::Add(m_result.reg.begin(), a.reg, b.reg, a.reg.size()) + || Compare(m_result.reg, m_modulus.reg, a.reg.size()) >= 0) + { + CryptoPP::Subtract(m_result.reg.begin(), m_result.reg, m_modulus.reg, a.reg.size()); + } + return m_result; + } + else + { + m_result1 = a+b; + if (m_result1 >= m_modulus) + m_result1 -= m_modulus; + return m_result1; + } +} + +Integer& ModularArithmetic::Accumulate(Integer &a, const Integer &b) const +{ + if (a.reg.size()==m_modulus.reg.size() && b.reg.size()==m_modulus.reg.size()) + { + if (CryptoPP::Add(a.reg, a.reg, b.reg, a.reg.size()) + || Compare(a.reg, m_modulus.reg, a.reg.size()) >= 0) + { + CryptoPP::Subtract(a.reg, a.reg, m_modulus.reg, a.reg.size()); + } + } + else + { + a+=b; + if (a>=m_modulus) + a-=m_modulus; + } + + return a; +} + +const Integer& ModularArithmetic::Subtract(const Integer &a, const Integer &b) const +{ + if (a.reg.size()==m_modulus.reg.size() && b.reg.size()==m_modulus.reg.size()) + { + if (CryptoPP::Subtract(m_result.reg.begin(), a.reg, b.reg, a.reg.size())) + CryptoPP::Add(m_result.reg.begin(), m_result.reg, m_modulus.reg, a.reg.size()); + return m_result; + } + else + { + m_result1 = a-b; + if (m_result1.IsNegative()) + m_result1 += m_modulus; + return m_result1; + } +} + +Integer& ModularArithmetic::Reduce(Integer &a, const Integer &b) const +{ + if (a.reg.size()==m_modulus.reg.size() && b.reg.size()==m_modulus.reg.size()) + { + if (CryptoPP::Subtract(a.reg, a.reg, b.reg, a.reg.size())) + CryptoPP::Add(a.reg, a.reg, m_modulus.reg, a.reg.size()); + } + else + { + a-=b; + if (a.IsNegative()) + a+=m_modulus; + } + + return a; +} + +const Integer& ModularArithmetic::Inverse(const Integer &a) const +{ + if (!a) + return a; + + CopyWords(m_result.reg.begin(), m_modulus.reg, m_modulus.reg.size()); + if (CryptoPP::Subtract(m_result.reg.begin(), m_result.reg, a.reg, a.reg.size())) + Decrement(m_result.reg.begin()+a.reg.size(), m_modulus.reg.size()-a.reg.size()); + + return m_result; +} + +Integer ModularArithmetic::CascadeExponentiate(const Integer &x, const Integer &e1, const Integer &y, const Integer &e2) const +{ + if (m_modulus.IsOdd()) + { + MontgomeryRepresentation dr(m_modulus); + return dr.ConvertOut(dr.CascadeExponentiate(dr.ConvertIn(x), e1, dr.ConvertIn(y), e2)); + } + else + return AbstractRing::CascadeExponentiate(x, e1, y, e2); +} + +void ModularArithmetic::SimultaneousExponentiate(Integer *results, const Integer &base, const Integer *exponents, unsigned int exponentsCount) const +{ + if (m_modulus.IsOdd()) + { + MontgomeryRepresentation dr(m_modulus); + dr.SimultaneousExponentiate(results, dr.ConvertIn(base), exponents, exponentsCount); + for (unsigned int i=0; i::SimultaneousExponentiate(results, base, exponents, exponentsCount); +} + +MontgomeryRepresentation::MontgomeryRepresentation(const Integer &m) // modulus must be odd + : ModularArithmetic(m), + m_u((word)0, m_modulus.reg.size()), + m_workspace(5*m_modulus.reg.size()) +{ + if (!m_modulus.IsOdd()) + throw InvalidArgument("MontgomeryRepresentation: Montgomery representation requires an odd modulus"); + + RecursiveInverseModPower2(m_u.reg, m_workspace, m_modulus.reg, m_modulus.reg.size()); +} + +const Integer& MontgomeryRepresentation::Multiply(const Integer &a, const Integer &b) const +{ + word *const T = m_workspace.begin(); + word *const R = m_result.reg.begin(); + const size_t N = m_modulus.reg.size(); + assert(a.reg.size()<=N && b.reg.size()<=N); + + AsymmetricMultiply(T, T+2*N, a.reg, a.reg.size(), b.reg, b.reg.size()); + SetWords(T+a.reg.size()+b.reg.size(), 0, 2*N-a.reg.size()-b.reg.size()); + MontgomeryReduce(R, T+2*N, T, m_modulus.reg, m_u.reg, N); + return m_result; +} + +const Integer& MontgomeryRepresentation::Square(const Integer &a) const +{ + word *const T = m_workspace.begin(); + word *const R = m_result.reg.begin(); + const size_t N = m_modulus.reg.size(); + assert(a.reg.size()<=N); + + CryptoPP::Square(T, T+2*N, a.reg, a.reg.size()); + SetWords(T+2*a.reg.size(), 0, 2*N-2*a.reg.size()); + MontgomeryReduce(R, T+2*N, T, m_modulus.reg, m_u.reg, N); + return m_result; +} + +Integer MontgomeryRepresentation::ConvertOut(const Integer &a) const +{ + word *const T = m_workspace.begin(); + word *const R = m_result.reg.begin(); + const size_t N = m_modulus.reg.size(); + assert(a.reg.size()<=N); + + CopyWords(T, a.reg, a.reg.size()); + SetWords(T+a.reg.size(), 0, 2*N-a.reg.size()); + MontgomeryReduce(R, T+2*N, T, m_modulus.reg, m_u.reg, N); + return m_result; +} + +const Integer& MontgomeryRepresentation::MultiplicativeInverse(const Integer &a) const +{ +// return (EuclideanMultiplicativeInverse(a, modulus)<<(2*WORD_BITS*modulus.reg.size()))%modulus; + word *const T = m_workspace.begin(); + word *const R = m_result.reg.begin(); + const size_t N = m_modulus.reg.size(); + assert(a.reg.size()<=N); + + CopyWords(T, a.reg, a.reg.size()); + SetWords(T+a.reg.size(), 0, 2*N-a.reg.size()); + MontgomeryReduce(R, T+2*N, T, m_modulus.reg, m_u.reg, N); + unsigned k = AlmostInverse(R, T, R, N, m_modulus.reg, N); + +// cout << "k=" << k << " N*32=" << 32*N << endl; + + if (k>N*WORD_BITS) + DivideByPower2Mod(R, R, k-N*WORD_BITS, m_modulus.reg, N); + else + MultiplyByPower2Mod(R, R, N*WORD_BITS-k, m_modulus.reg, N); + + return m_result; +} + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/integer.h b/CryptoPP/crypto/integer.h new file mode 100644 index 0000000..aca1db0 --- /dev/null +++ b/CryptoPP/crypto/integer.h @@ -0,0 +1,418 @@ +#ifndef CRYPTOPP_INTEGER_H +#define CRYPTOPP_INTEGER_H + +/** \file */ + +#include "cryptlib.h" +#include "secblock.h" + +#include +#include + +NAMESPACE_BEGIN(CryptoPP) + +struct InitializeInteger // used to initialize static variables +{ + InitializeInteger(); +}; + +typedef SecBlock > IntegerSecBlock; + +//! multiple precision integer and basic arithmetics +/*! This class can represent positive and negative integers + with absolute value less than (256**sizeof(word)) ** (256**sizeof(int)). + \nosubgrouping +*/ +class CRYPTOPP_DLL Integer : private InitializeInteger, public ASN1Object +{ +public: + //! \name ENUMS, EXCEPTIONS, and TYPEDEFS + //@{ + //! division by zero exception + class DivideByZero : public Exception + { + public: + DivideByZero() : Exception(OTHER_ERROR, "Integer: division by zero") {} + }; + + //! + class RandomNumberNotFound : public Exception + { + public: + RandomNumberNotFound() : Exception(OTHER_ERROR, "Integer: no integer satisfies the given parameters") {} + }; + + //! + enum Sign {POSITIVE=0, NEGATIVE=1}; + + //! + enum Signedness { + //! + UNSIGNED, + //! + SIGNED}; + + //! + enum RandomNumberType { + //! + ANY, + //! + PRIME}; + //@} + + //! \name CREATORS + //@{ + //! creates the zero integer + Integer(); + + //! copy constructor + Integer(const Integer& t); + + //! convert from signed long + Integer(signed long value); + + //! convert from lword + Integer(Sign s, lword value); + + //! convert from two words + Integer(Sign s, word highWord, word lowWord); + + //! convert from string + /*! str can be in base 2, 8, 10, or 16. Base is determined by a + case insensitive suffix of 'h', 'o', or 'b'. No suffix means base 10. + */ + explicit Integer(const char *str); + explicit Integer(const wchar_t *str); + + //! convert from big-endian byte array + Integer(const byte *encodedInteger, size_t byteCount, Signedness s=UNSIGNED); + + //! convert from big-endian form stored in a BufferedTransformation + Integer(BufferedTransformation &bt, size_t byteCount, Signedness s=UNSIGNED); + + //! convert from BER encoded byte array stored in a BufferedTransformation object + explicit Integer(BufferedTransformation &bt); + + //! create a random integer + /*! The random integer created is uniformly distributed over [0, 2**bitcount). */ + Integer(RandomNumberGenerator &rng, size_t bitcount); + + //! avoid calling constructors for these frequently used integers + static const Integer & CRYPTOPP_API Zero(); + //! avoid calling constructors for these frequently used integers + static const Integer & CRYPTOPP_API One(); + //! avoid calling constructors for these frequently used integers + static const Integer & CRYPTOPP_API Two(); + + //! create a random integer of special type + /*! Ideally, the random integer created should be uniformly distributed + over {x | min <= x <= max and x is of rnType and x % mod == equiv}. + However the actual distribution may not be uniform because sequential + search is used to find an appropriate number from a random starting + point. + May return (with very small probability) a pseudoprime when a prime + is requested and max > lastSmallPrime*lastSmallPrime (lastSmallPrime + is declared in nbtheory.h). + \throw RandomNumberNotFound if the set is empty. + */ + Integer(RandomNumberGenerator &rng, const Integer &min, const Integer &max, RandomNumberType rnType=ANY, const Integer &equiv=Zero(), const Integer &mod=One()); + + //! return the integer 2**e + static Integer CRYPTOPP_API Power2(size_t e); + //@} + + //! \name ENCODE/DECODE + //@{ + //! minimum number of bytes to encode this integer + /*! MinEncodedSize of 0 is 1 */ + size_t MinEncodedSize(Signedness=UNSIGNED) const; + //! encode in big-endian format + /*! unsigned means encode absolute value, signed means encode two's complement if negative. + if outputLen < MinEncodedSize, the most significant bytes will be dropped + if outputLen > MinEncodedSize, the most significant bytes will be padded + */ + void Encode(byte *output, size_t outputLen, Signedness=UNSIGNED) const; + //! + void Encode(BufferedTransformation &bt, size_t outputLen, Signedness=UNSIGNED) const; + + //! encode using Distinguished Encoding Rules, put result into a BufferedTransformation object + void DEREncode(BufferedTransformation &bt) const; + + //! encode absolute value as big-endian octet string + void DEREncodeAsOctetString(BufferedTransformation &bt, size_t length) const; + + //! encode absolute value in OpenPGP format, return length of output + size_t OpenPGPEncode(byte *output, size_t bufferSize) const; + //! encode absolute value in OpenPGP format, put result into a BufferedTransformation object + size_t OpenPGPEncode(BufferedTransformation &bt) const; + + //! + void Decode(const byte *input, size_t inputLen, Signedness=UNSIGNED); + //! + //* Precondition: bt.MaxRetrievable() >= inputLen + void Decode(BufferedTransformation &bt, size_t inputLen, Signedness=UNSIGNED); + + //! + void BERDecode(const byte *input, size_t inputLen); + //! + void BERDecode(BufferedTransformation &bt); + + //! decode nonnegative value as big-endian octet string + void BERDecodeAsOctetString(BufferedTransformation &bt, size_t length); + + class OpenPGPDecodeErr : public Exception + { + public: + OpenPGPDecodeErr() : Exception(INVALID_DATA_FORMAT, "OpenPGP decode error") {} + }; + + //! + void OpenPGPDecode(const byte *input, size_t inputLen); + //! + void OpenPGPDecode(BufferedTransformation &bt); + //@} + + //! \name ACCESSORS + //@{ + //! return true if *this can be represented as a signed long + bool IsConvertableToLong() const; + //! return equivalent signed long if possible, otherwise undefined + signed long ConvertToLong() const; + + //! number of significant bits = floor(log2(abs(*this))) + 1 + unsigned int BitCount() const; + //! number of significant bytes = ceiling(BitCount()/8) + unsigned int ByteCount() const; + //! number of significant words = ceiling(ByteCount()/sizeof(word)) + unsigned int WordCount() const; + + //! return the i-th bit, i=0 being the least significant bit + bool GetBit(size_t i) const; + //! return the i-th byte + byte GetByte(size_t i) const; + //! return n lowest bits of *this >> i + lword GetBits(size_t i, size_t n) const; + + //! + bool IsZero() const {return !*this;} + //! + bool NotZero() const {return !IsZero();} + //! + bool IsNegative() const {return sign == NEGATIVE;} + //! + bool NotNegative() const {return !IsNegative();} + //! + bool IsPositive() const {return NotNegative() && NotZero();} + //! + bool NotPositive() const {return !IsPositive();} + //! + bool IsEven() const {return GetBit(0) == 0;} + //! + bool IsOdd() const {return GetBit(0) == 1;} + //@} + + //! \name MANIPULATORS + //@{ + //! + Integer& operator=(const Integer& t); + + //! + Integer& operator+=(const Integer& t); + //! + Integer& operator-=(const Integer& t); + //! + Integer& operator*=(const Integer& t) {return *this = Times(t);} + //! + Integer& operator/=(const Integer& t) {return *this = DividedBy(t);} + //! + Integer& operator%=(const Integer& t) {return *this = Modulo(t);} + //! + Integer& operator/=(word t) {return *this = DividedBy(t);} + //! + Integer& operator%=(word t) {return *this = Integer(POSITIVE, 0, Modulo(t));} + + //! + Integer& operator<<=(size_t); + //! + Integer& operator>>=(size_t); + + //! + void Randomize(RandomNumberGenerator &rng, size_t bitcount); + //! + void Randomize(RandomNumberGenerator &rng, const Integer &min, const Integer &max); + //! set this Integer to a random element of {x | min <= x <= max and x is of rnType and x % mod == equiv} + /*! returns false if the set is empty */ + bool Randomize(RandomNumberGenerator &rng, const Integer &min, const Integer &max, RandomNumberType rnType, const Integer &equiv=Zero(), const Integer &mod=One()); + + bool GenerateRandomNoThrow(RandomNumberGenerator &rng, const NameValuePairs ¶ms = g_nullNameValuePairs); + void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs ¶ms = g_nullNameValuePairs) + { + if (!GenerateRandomNoThrow(rng, params)) + throw RandomNumberNotFound(); + } + + //! set the n-th bit to value + void SetBit(size_t n, bool value=1); + //! set the n-th byte to value + void SetByte(size_t n, byte value); + + //! + void Negate(); + //! + void SetPositive() {sign = POSITIVE;} + //! + void SetNegative() {if (!!(*this)) sign = NEGATIVE;} + + //! + void swap(Integer &a); + //@} + + //! \name UNARY OPERATORS + //@{ + //! + bool operator!() const; + //! + Integer operator+() const {return *this;} + //! + Integer operator-() const; + //! + Integer& operator++(); + //! + Integer& operator--(); + //! + Integer operator++(int) {Integer temp = *this; ++*this; return temp;} + //! + Integer operator--(int) {Integer temp = *this; --*this; return temp;} + //@} + + //! \name BINARY OPERATORS + //@{ + //! signed comparison + /*! \retval -1 if *this < a + \retval 0 if *this = a + \retval 1 if *this > a + */ + int Compare(const Integer& a) const; + + //! + Integer Plus(const Integer &b) const; + //! + Integer Minus(const Integer &b) const; + //! + Integer Times(const Integer &b) const; + //! + Integer DividedBy(const Integer &b) const; + //! + Integer Modulo(const Integer &b) const; + //! + Integer DividedBy(word b) const; + //! + word Modulo(word b) const; + + //! + Integer operator>>(size_t n) const {return Integer(*this)>>=n;} + //! + Integer operator<<(size_t n) const {return Integer(*this)<<=n;} + //@} + + //! \name OTHER ARITHMETIC FUNCTIONS + //@{ + //! + Integer AbsoluteValue() const; + //! + Integer Doubled() const {return Plus(*this);} + //! + Integer Squared() const {return Times(*this);} + //! extract square root, if negative return 0, else return floor of square root + Integer SquareRoot() const; + //! return whether this integer is a perfect square + bool IsSquare() const; + + //! is 1 or -1 + bool IsUnit() const; + //! return inverse if 1 or -1, otherwise return 0 + Integer MultiplicativeInverse() const; + + //! modular multiplication + CRYPTOPP_DLL friend Integer CRYPTOPP_API a_times_b_mod_c(const Integer &x, const Integer& y, const Integer& m); + //! modular exponentiation + CRYPTOPP_DLL friend Integer CRYPTOPP_API a_exp_b_mod_c(const Integer &x, const Integer& e, const Integer& m); + + //! calculate r and q such that (a == d*q + r) && (0 <= r < abs(d)) + static void CRYPTOPP_API Divide(Integer &r, Integer &q, const Integer &a, const Integer &d); + //! use a faster division algorithm when divisor is short + static void CRYPTOPP_API Divide(word &r, Integer &q, const Integer &a, word d); + + //! returns same result as Divide(r, q, a, Power2(n)), but faster + static void CRYPTOPP_API DivideByPowerOf2(Integer &r, Integer &q, const Integer &a, unsigned int n); + + //! greatest common divisor + static Integer CRYPTOPP_API Gcd(const Integer &a, const Integer &n); + //! calculate multiplicative inverse of *this mod n + Integer InverseMod(const Integer &n) const; + //! + word InverseMod(word n) const; + //@} + + //! \name INPUT/OUTPUT + //@{ + //! + friend CRYPTOPP_DLL std::istream& CRYPTOPP_API operator>>(std::istream& in, Integer &a); + //! + friend CRYPTOPP_DLL std::ostream& CRYPTOPP_API operator<<(std::ostream& out, const Integer &a); + //@} + +private: + friend class ModularArithmetic; + friend class MontgomeryRepresentation; + friend class HalfMontgomeryRepresentation; + + Integer(word value, size_t length); + + int PositiveCompare(const Integer &t) const; + friend void PositiveAdd(Integer &sum, const Integer &a, const Integer &b); + friend void PositiveSubtract(Integer &diff, const Integer &a, const Integer &b); + friend void PositiveMultiply(Integer &product, const Integer &a, const Integer &b); + friend void PositiveDivide(Integer &remainder, Integer "ient, const Integer ÷nd, const Integer &divisor); + + IntegerSecBlock reg; + Sign sign; +}; + +//! +inline bool operator==(const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)==0;} +//! +inline bool operator!=(const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)!=0;} +//! +inline bool operator> (const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)> 0;} +//! +inline bool operator>=(const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)>=0;} +//! +inline bool operator< (const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)< 0;} +//! +inline bool operator<=(const CryptoPP::Integer& a, const CryptoPP::Integer& b) {return a.Compare(b)<=0;} +//! +inline CryptoPP::Integer operator+(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.Plus(b);} +//! +inline CryptoPP::Integer operator-(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.Minus(b);} +//! +inline CryptoPP::Integer operator*(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.Times(b);} +//! +inline CryptoPP::Integer operator/(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.DividedBy(b);} +//! +inline CryptoPP::Integer operator%(const CryptoPP::Integer &a, const CryptoPP::Integer &b) {return a.Modulo(b);} +//! +inline CryptoPP::Integer operator/(const CryptoPP::Integer &a, CryptoPP::word b) {return a.DividedBy(b);} +//! +inline CryptoPP::word operator%(const CryptoPP::Integer &a, CryptoPP::word b) {return a.Modulo(b);} + +NAMESPACE_END + +NAMESPACE_BEGIN(std) +template<> inline void swap(CryptoPP::Integer &a, CryptoPP::Integer &b) +{ + a.swap(b); +} +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/iterhash.cpp b/CryptoPP/crypto/iterhash.cpp new file mode 100644 index 0000000..53c133e --- /dev/null +++ b/CryptoPP/crypto/iterhash.cpp @@ -0,0 +1,150 @@ +// iterhash.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" + +// prevent Sun's CC compiler from including this file automatically +#if !defined(__SUNPRO_CC) || defined(CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES) + +#include "iterhash.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +template void IteratedHashBase::Update(const byte *input, size_t len) +{ + HashWordType oldCountLo = m_countLo, oldCountHi = m_countHi; + if ((m_countLo = oldCountLo + HashWordType(len)) < oldCountLo) + m_countHi++; // carry from low to high + m_countHi += (HashWordType)SafeRightShift<8*sizeof(HashWordType)>(len); + if (m_countHi < oldCountHi || SafeRightShift<2*8*sizeof(HashWordType)>(len) != 0) + throw HashInputTooLong(this->AlgorithmName()); + + unsigned int blockSize = this->BlockSize(); + unsigned int num = ModPowerOf2(oldCountLo, blockSize); + T* dataBuf = this->DataBuf(); + byte* data = (byte *)dataBuf; + + if (num != 0) // process left over data + { + if ((num+len) >= blockSize) + { + memcpy(data+num, input, blockSize-num); + HashBlock(dataBuf); + input += (blockSize-num); + len-=(blockSize - num); + num=0; + // drop through and do the rest + } + else + { + memcpy(data+num, input, len); + return; + } + } + + // now process the input data in blocks of blockSize bytes and save the leftovers to m_data + if (len >= blockSize) + { + if (input == data) + { + assert(len == blockSize); + HashBlock(dataBuf); + return; + } + else if (IsAligned(input)) + { + size_t leftOver = HashMultipleBlocks((T *)input, len); + input += (len - leftOver); + len = leftOver; + } + else + do + { // copy input first if it's not aligned correctly + memcpy(data, input, blockSize); + HashBlock(dataBuf); + input+=blockSize; + len-=blockSize; + } while (len >= blockSize); + } + + memcpy(data, input, len); +} + +template byte * IteratedHashBase::CreateUpdateSpace(size_t &size) +{ + unsigned int blockSize = this->BlockSize(); + unsigned int num = ModPowerOf2(m_countLo, blockSize); + size = blockSize - num; + return (byte *)DataBuf() + num; +} + +template size_t IteratedHashBase::HashMultipleBlocks(const T *input, size_t length) +{ + unsigned int blockSize = this->BlockSize(); + bool noReverse = NativeByteOrderIs(this->GetByteOrder()); + T* dataBuf = this->DataBuf(); + do + { + if (noReverse) + this->HashEndianCorrectedBlock(input); + else + { + ByteReverse(dataBuf, input, this->BlockSize()); + this->HashEndianCorrectedBlock(dataBuf); + } + + input += blockSize/sizeof(T); + length -= blockSize; + } + while (length >= blockSize); + return length; +} + +template void IteratedHashBase::PadLastBlock(unsigned int lastBlockSize, byte padFirst) +{ + unsigned int blockSize = this->BlockSize(); + unsigned int num = ModPowerOf2(m_countLo, blockSize); + T* dataBuf = this->DataBuf(); + byte* data = (byte *)dataBuf; + data[num++] = padFirst; + if (num <= lastBlockSize) + memset(data+num, 0, lastBlockSize-num); + else + { + memset(data+num, 0, blockSize-num); + HashBlock(dataBuf); + memset(data, 0, lastBlockSize); + } +} + +template void IteratedHashBase::Restart() +{ + m_countLo = m_countHi = 0; + Init(); +} + +template void IteratedHashBase::TruncatedFinal(byte *digest, size_t size) +{ + this->ThrowIfInvalidTruncatedSize(size); + + T* dataBuf = this->DataBuf(); + T* stateBuf = this->StateBuf(); + unsigned int blockSize = this->BlockSize(); + ByteOrder order = this->GetByteOrder(); + + PadLastBlock(blockSize - 2*sizeof(HashWordType)); + ConditionalByteReverse(order, dataBuf, dataBuf, blockSize - 2*sizeof(HashWordType)); + + dataBuf[blockSize/sizeof(T)-2] = order ? this->GetBitCountHi() : this->GetBitCountLo(); + dataBuf[blockSize/sizeof(T)-1] = order ? this->GetBitCountLo() : this->GetBitCountHi(); + + HashEndianCorrectedBlock(dataBuf); + ConditionalByteReverse(order, stateBuf, stateBuf, this->DigestSize()); + memcpy(digest, stateBuf, size); + + this->Restart(); // reinit for next use +} + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/iterhash.h b/CryptoPP/crypto/iterhash.h new file mode 100644 index 0000000..de3cae8 --- /dev/null +++ b/CryptoPP/crypto/iterhash.h @@ -0,0 +1,114 @@ +#ifndef CRYPTOPP_ITERHASH_H +#define CRYPTOPP_ITERHASH_H + +#include "cryptlib.h" +#include "secblock.h" +#include "misc.h" +#include "simple.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! exception thrown when trying to hash more data than is allowed by a hash function +class CRYPTOPP_DLL HashInputTooLong : public InvalidDataFormat +{ +public: + explicit HashInputTooLong(const std::string &alg) + : InvalidDataFormat("IteratedHashBase: input data exceeds maximum allowed by hash function " + alg) {} +}; + +//! _ +template +class CRYPTOPP_NO_VTABLE IteratedHashBase : public BASE +{ +public: + typedef T HashWordType; + + IteratedHashBase() : m_countLo(0), m_countHi(0) {} + unsigned int OptimalBlockSize() const {return this->BlockSize();} + unsigned int OptimalDataAlignment() const {return GetAlignmentOf();} + void Update(const byte *input, size_t length); + byte * CreateUpdateSpace(size_t &size); + void Restart(); + void TruncatedFinal(byte *digest, size_t size); + +protected: + inline T GetBitCountHi() const {return (m_countLo >> (8*sizeof(T)-3)) + (m_countHi << 3);} + inline T GetBitCountLo() const {return m_countLo << 3;} + + void PadLastBlock(unsigned int lastBlockSize, byte padFirst=0x80); + virtual void Init() =0; + + virtual ByteOrder GetByteOrder() const =0; + virtual void HashEndianCorrectedBlock(const HashWordType *data) =0; + virtual size_t HashMultipleBlocks(const T *input, size_t length); + void HashBlock(const HashWordType *input) {HashMultipleBlocks(input, this->BlockSize());} + + virtual T* DataBuf() =0; + virtual T* StateBuf() =0; + +private: + T m_countLo, m_countHi; +}; + +//! _ +template +class CRYPTOPP_NO_VTABLE IteratedHash : public IteratedHashBase +{ +public: + typedef T_Endianness ByteOrderClass; + typedef T_HashWordType HashWordType; + + CRYPTOPP_CONSTANT(BLOCKSIZE = T_BlockSize) + // BCB2006 workaround: can't use BLOCKSIZE here + CRYPTOPP_COMPILE_ASSERT((T_BlockSize & (T_BlockSize - 1)) == 0); // blockSize is a power of 2 + unsigned int BlockSize() const {return T_BlockSize;} + + ByteOrder GetByteOrder() const {return T_Endianness::ToEnum();} + + inline static void CorrectEndianess(HashWordType *out, const HashWordType *in, size_t byteCount) + { + ConditionalByteReverse(T_Endianness::ToEnum(), out, in, byteCount); + } + +protected: + T_HashWordType* DataBuf() {return this->m_data;} + FixedSizeSecBlock m_data; +}; + +//! _ +template +class CRYPTOPP_NO_VTABLE IteratedHashWithStaticTransform + : public ClonableImpl, T_Transform> > +{ +public: + CRYPTOPP_CONSTANT(DIGESTSIZE = T_DigestSize ? T_DigestSize : T_StateSize) + unsigned int DigestSize() const {return DIGESTSIZE;}; + +protected: + IteratedHashWithStaticTransform() {this->Init();} + void HashEndianCorrectedBlock(const T_HashWordType *data) {T_Transform::Transform(this->m_state, data);} + void Init() {T_Transform::InitState(this->m_state);} + + T_HashWordType* StateBuf() {return this->m_state;} + FixedSizeSecBlock m_state; +}; + +NAMESPACE_END + +#ifdef CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES +#include "iterhash.cpp" +#endif + +NAMESPACE_BEGIN(CryptoPP) + +#ifdef WORD64_AVAILABLE +CRYPTOPP_DLL_TEMPLATE_CLASS IteratedHashBase; +CRYPTOPP_STATIC_TEMPLATE_CLASS IteratedHashBase; +#endif + +CRYPTOPP_DLL_TEMPLATE_CLASS IteratedHashBase; +CRYPTOPP_STATIC_TEMPLATE_CLASS IteratedHashBase; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/lubyrack.h b/CryptoPP/crypto/lubyrack.h new file mode 100644 index 0000000..e2b30ea --- /dev/null +++ b/CryptoPP/crypto/lubyrack.h @@ -0,0 +1,141 @@ +// lubyrack.h - written and placed in the public domain by Wei Dai + +#ifndef CRYPTOPP_LUBYRACK_H +#define CRYPTOPP_LUBYRACK_H + +/** \file */ + +#include "simple.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +template struct DigestSizeDoubleWorkaround // VC60 workaround +{ + CRYPTOPP_CONSTANT(RESULT = 2*T::DIGESTSIZE) +}; + +//! algorithm info +template +struct LR_Info : public VariableKeyLength<16, 0, 2*(INT_MAX/2), 2>, public FixedBlockSize::RESULT> +{ + static std::string StaticAlgorithmName() {return std::string("LR/")+T::StaticAlgorithmName();} +}; + +//! Luby-Rackoff +template +class LR : public LR_Info, public BlockCipherDocumentation +{ + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl > + { + public: + // VC60 workaround: have to define these functions within class definition + void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms) + { + this->AssertValidKeyLength(length); + + L = length/2; + buffer.New(2*S); + digest.New(S); + key.Assign(userKey, 2*L); + } + + protected: + CRYPTOPP_CONSTANT(S=T::DIGESTSIZE) + unsigned int L; // key length / 2 + SecByteBlock key; + + mutable T hm; + mutable SecByteBlock buffer, digest; + }; + + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + +#define KL this->key +#define KR this->key+this->L +#define BL this->buffer +#define BR this->buffer+this->S +#define IL inBlock +#define IR inBlock+this->S +#define OL outBlock +#define OR outBlock+this->S + + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const + { + this->hm.Update(KL, this->L); + this->hm.Update(IL, this->S); + this->hm.Final(BR); + xorbuf(BR, IR, this->S); + + this->hm.Update(KR, this->L); + this->hm.Update(BR, this->S); + this->hm.Final(BL); + xorbuf(BL, IL, this->S); + + this->hm.Update(KL, this->L); + this->hm.Update(BL, this->S); + this->hm.Final(this->digest); + xorbuf(BR, this->digest, this->S); + + this->hm.Update(KR, this->L); + this->hm.Update(OR, this->S); + this->hm.Final(this->digest); + xorbuf(BL, this->digest, this->S); + + if (xorBlock) + xorbuf(outBlock, xorBlock, this->buffer, 2*this->S); + else + memcpy_s(outBlock, 2*this->S, this->buffer, 2*this->S); + } + }; + + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const + { + this->hm.Update(KR, this->L); + this->hm.Update(IR, this->S); + this->hm.Final(BL); + xorbuf(BL, IL, this->S); + + this->hm.Update(KL, this->L); + this->hm.Update(BL, this->S); + this->hm.Final(BR); + xorbuf(BR, IR, this->S); + + this->hm.Update(KR, this->L); + this->hm.Update(BR, this->S); + this->hm.Final(this->digest); + xorbuf(BL, this->digest, this->S); + + this->hm.Update(KL, this->L); + this->hm.Update(OL, this->S); + this->hm.Final(this->digest); + xorbuf(BR, this->digest, this->S); + + if (xorBlock) + xorbuf(outBlock, xorBlock, this->buffer, 2*this->S); + else + memcpy(outBlock, this->buffer, 2*this->S); + } +#undef KL +#undef KR +#undef BL +#undef BR +#undef IL +#undef IR +#undef OL +#undef OR + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/luc.cpp b/CryptoPP/crypto/luc.cpp new file mode 100644 index 0000000..51af79f --- /dev/null +++ b/CryptoPP/crypto/luc.cpp @@ -0,0 +1,210 @@ +// luc.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "luc.h" +#include "asn.h" +#include "nbtheory.h" +#include "sha.h" +#include "algparam.h" + +NAMESPACE_BEGIN(CryptoPP) + +void LUC_TestInstantiations() +{ + LUC_HMP::Signer t1; + LUCFunction t2; + InvertibleLUCFunction t3; +} + +void DL_Algorithm_LUC_HMP::Sign(const DL_GroupParameters ¶ms, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const +{ + const Integer &q = params.GetSubgroupOrder(); + r = params.ExponentiateBase(k); + s = (k + x*(r+e)) % q; +} + +bool DL_Algorithm_LUC_HMP::Verify(const DL_GroupParameters ¶ms, const DL_PublicKey &publicKey, const Integer &e, const Integer &r, const Integer &s) const +{ + Integer p = params.GetGroupOrder()-1; + const Integer &q = params.GetSubgroupOrder(); + + Integer Vsg = params.ExponentiateBase(s); + Integer Vry = publicKey.ExponentiatePublicElement((r+e)%q); + return (Vsg*Vsg + Vry*Vry + r*r) % p == (Vsg * Vry * r + 4) % p; +} + +Integer DL_BasePrecomputation_LUC::Exponentiate(const DL_GroupPrecomputation &group, const Integer &exponent) const +{ + return Lucas(exponent, m_g, static_cast(group).GetModulus()); +} + +void DL_GroupParameters_LUC::SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const +{ + for (unsigned int i=0; i Integer::One() && m_n.IsOdd(); + pass = pass && m_e > Integer::One() && m_e.IsOdd() && m_e < m_n; + return pass; +} + +bool LUCFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const +{ + return GetValueHelper(this, name, valueType, pValue).Assignable() + CRYPTOPP_GET_FUNCTION_ENTRY(Modulus) + CRYPTOPP_GET_FUNCTION_ENTRY(PublicExponent) + ; +} + +void LUCFunction::AssignFrom(const NameValuePairs &source) +{ + AssignFromHelper(this, source) + CRYPTOPP_SET_FUNCTION_ENTRY(Modulus) + CRYPTOPP_SET_FUNCTION_ENTRY(PublicExponent) + ; +} + +// ***************************************************************************** +// private key operations: + +class LUCPrimeSelector : public PrimeSelector +{ +public: + LUCPrimeSelector(const Integer &e) : m_e(e) {} + bool IsAcceptable(const Integer &candidate) const + { + return RelativelyPrime(m_e, candidate+1) && RelativelyPrime(m_e, candidate-1); + } + Integer m_e; +}; + +void InvertibleLUCFunction::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg) +{ + int modulusSize = 2048; + alg.GetIntValue("ModulusSize", modulusSize) || alg.GetIntValue("KeySize", modulusSize); + + if (modulusSize < 16) + throw InvalidArgument("InvertibleLUCFunction: specified modulus size is too small"); + + m_e = alg.GetValueWithDefault("PublicExponent", Integer(17)); + + if (m_e < 5 || m_e.IsEven()) + throw InvalidArgument("InvertibleLUCFunction: invalid public exponent"); + + LUCPrimeSelector selector(m_e); + const NameValuePairs &primeParam = MakeParametersForTwoPrimesOfEqualSize(modulusSize) + ("PointerToPrimeSelector", selector.GetSelectorPointer()); + m_p.GenerateRandom(rng, primeParam); + m_q.GenerateRandom(rng, primeParam); + + m_n = m_p * m_q; + m_u = m_q.InverseMod(m_p); +} + +void InvertibleLUCFunction::Initialize(RandomNumberGenerator &rng, unsigned int keybits, const Integer &e) +{ + GenerateRandom(rng, MakeParameters("ModulusSize", (int)keybits)("PublicExponent", e)); +} + +void InvertibleLUCFunction::BERDecode(BufferedTransformation &bt) +{ + BERSequenceDecoder seq(bt); + + Integer version(seq); + if (!!version) // make sure version is 0 + BERDecodeError(); + + m_n.BERDecode(seq); + m_e.BERDecode(seq); + m_p.BERDecode(seq); + m_q.BERDecode(seq); + m_u.BERDecode(seq); + seq.MessageEnd(); +} + +void InvertibleLUCFunction::DEREncode(BufferedTransformation &bt) const +{ + DERSequenceEncoder seq(bt); + + const byte version[] = {INTEGER, 1, 0}; + seq.Put(version, sizeof(version)); + m_n.DEREncode(seq); + m_e.DEREncode(seq); + m_p.DEREncode(seq); + m_q.DEREncode(seq); + m_u.DEREncode(seq); + seq.MessageEnd(); +} + +Integer InvertibleLUCFunction::CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const +{ + // not clear how to do blinding with LUC + DoQuickSanityCheck(); + return InverseLucas(m_e, x, m_q, m_p, m_u); +} + +bool InvertibleLUCFunction::Validate(RandomNumberGenerator &rng, unsigned int level) const +{ + bool pass = LUCFunction::Validate(rng, level); + pass = pass && m_p > Integer::One() && m_p.IsOdd() && m_p < m_n; + pass = pass && m_q > Integer::One() && m_q.IsOdd() && m_q < m_n; + pass = pass && m_u.IsPositive() && m_u < m_p; + if (level >= 1) + { + pass = pass && m_p * m_q == m_n; + pass = pass && RelativelyPrime(m_e, m_p+1); + pass = pass && RelativelyPrime(m_e, m_p-1); + pass = pass && RelativelyPrime(m_e, m_q+1); + pass = pass && RelativelyPrime(m_e, m_q-1); + pass = pass && m_u * m_q % m_p == 1; + } + if (level >= 2) + pass = pass && VerifyPrime(rng, m_p, level-2) && VerifyPrime(rng, m_q, level-2); + return pass; +} + +bool InvertibleLUCFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const +{ + return GetValueHelper(this, name, valueType, pValue).Assignable() + CRYPTOPP_GET_FUNCTION_ENTRY(Prime1) + CRYPTOPP_GET_FUNCTION_ENTRY(Prime2) + CRYPTOPP_GET_FUNCTION_ENTRY(MultiplicativeInverseOfPrime2ModPrime1) + ; +} + +void InvertibleLUCFunction::AssignFrom(const NameValuePairs &source) +{ + AssignFromHelper(this, source) + CRYPTOPP_SET_FUNCTION_ENTRY(Prime1) + CRYPTOPP_SET_FUNCTION_ENTRY(Prime2) + CRYPTOPP_SET_FUNCTION_ENTRY(MultiplicativeInverseOfPrime2ModPrime1) + ; +} + +NAMESPACE_END diff --git a/CryptoPP/crypto/luc.h b/CryptoPP/crypto/luc.h new file mode 100644 index 0000000..f220e73 --- /dev/null +++ b/CryptoPP/crypto/luc.h @@ -0,0 +1,236 @@ +#ifndef CRYPTOPP_LUC_H +#define CRYPTOPP_LUC_H + +/** \file +*/ + +#include "pkcspad.h" +#include "oaep.h" +#include "integer.h" +#include "dh.h" + +#include + +NAMESPACE_BEGIN(CryptoPP) + +//! The LUC function. +/*! This class is here for historical and pedagogical interest. It has no + practical advantages over other trapdoor functions and probably shouldn't + be used in production software. The discrete log based LUC schemes + defined later in this .h file may be of more practical interest. +*/ +class LUCFunction : public TrapdoorFunction, public PublicKey +{ + typedef LUCFunction ThisClass; + +public: + void Initialize(const Integer &n, const Integer &e) + {m_n = n; m_e = e;} + + void BERDecode(BufferedTransformation &bt); + void DEREncode(BufferedTransformation &bt) const; + + Integer ApplyFunction(const Integer &x) const; + Integer PreimageBound() const {return m_n;} + Integer ImageBound() const {return m_n;} + + bool Validate(RandomNumberGenerator &rng, unsigned int level) const; + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; + void AssignFrom(const NameValuePairs &source); + + // non-derived interface + const Integer & GetModulus() const {return m_n;} + const Integer & GetPublicExponent() const {return m_e;} + + void SetModulus(const Integer &n) {m_n = n;} + void SetPublicExponent(const Integer &e) {m_e = e;} + +protected: + Integer m_n, m_e; +}; + +//! _ +class InvertibleLUCFunction : public LUCFunction, public TrapdoorFunctionInverse, public PrivateKey +{ + typedef InvertibleLUCFunction ThisClass; + +public: + void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits, const Integer &eStart=17); + void Initialize(const Integer &n, const Integer &e, const Integer &p, const Integer &q, const Integer &u) + {m_n = n; m_e = e; m_p = p; m_q = q; m_u = u;} + + void BERDecode(BufferedTransformation &bt); + void DEREncode(BufferedTransformation &bt) const; + + Integer CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const; + + bool Validate(RandomNumberGenerator &rng, unsigned int level) const; + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; + void AssignFrom(const NameValuePairs &source); + /*! parameters: (ModulusSize, PublicExponent (default 17)) */ + void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg); + + // non-derived interface + const Integer& GetPrime1() const {return m_p;} + const Integer& GetPrime2() const {return m_q;} + const Integer& GetMultiplicativeInverseOfPrime2ModPrime1() const {return m_u;} + + void SetPrime1(const Integer &p) {m_p = p;} + void SetPrime2(const Integer &q) {m_q = q;} + void SetMultiplicativeInverseOfPrime2ModPrime1(const Integer &u) {m_u = u;} + +protected: + Integer m_p, m_q, m_u; +}; + +struct LUC +{ + static std::string StaticAlgorithmName() {return "LUC";} + typedef LUCFunction PublicKey; + typedef InvertibleLUCFunction PrivateKey; +}; + +//! LUC cryptosystem +template +struct LUCES : public TF_ES +{ +}; + +//! LUC signature scheme with appendix +template +struct LUCSS : public TF_SS +{ +}; + +// analagous to the RSA schemes defined in PKCS #1 v2.0 +typedef LUCES >::Decryptor LUCES_OAEP_SHA_Decryptor; +typedef LUCES >::Encryptor LUCES_OAEP_SHA_Encryptor; + +typedef LUCSS::Signer LUCSSA_PKCS1v15_SHA_Signer; +typedef LUCSS::Verifier LUCSSA_PKCS1v15_SHA_Verifier; + +// ******************************************************** + +// no actual precomputation +class DL_GroupPrecomputation_LUC : public DL_GroupPrecomputation +{ +public: + const AbstractGroup & GetGroup() const {assert(false); throw 0;} + Element BERDecodeElement(BufferedTransformation &bt) const {return Integer(bt);} + void DEREncodeElement(BufferedTransformation &bt, const Element &v) const {v.DEREncode(bt);} + + // non-inherited + void SetModulus(const Integer &v) {m_p = v;} + const Integer & GetModulus() const {return m_p;} + +private: + Integer m_p; +}; + +//! _ +class DL_BasePrecomputation_LUC : public DL_FixedBasePrecomputation +{ +public: + // DL_FixedBasePrecomputation + bool IsInitialized() const {return m_g.NotZero();} + void SetBase(const DL_GroupPrecomputation &group, const Integer &base) {m_g = base;} + const Integer & GetBase(const DL_GroupPrecomputation &group) const {return m_g;} + void Precompute(const DL_GroupPrecomputation &group, unsigned int maxExpBits, unsigned int storage) {} + void Load(const DL_GroupPrecomputation &group, BufferedTransformation &storedPrecomputation) {} + void Save(const DL_GroupPrecomputation &group, BufferedTransformation &storedPrecomputation) const {} + Integer Exponentiate(const DL_GroupPrecomputation &group, const Integer &exponent) const; + Integer CascadeExponentiate(const DL_GroupPrecomputation &group, const Integer &exponent, const DL_FixedBasePrecomputation &pc2, const Integer &exponent2) const + {throw NotImplemented("DL_BasePrecomputation_LUC: CascadeExponentiate not implemented");} // shouldn't be called + +private: + Integer m_g; +}; + +//! _ +class DL_GroupParameters_LUC : public DL_GroupParameters_IntegerBasedImpl +{ +public: + // DL_GroupParameters + bool IsIdentity(const Integer &element) const {return element == Integer::Two();} + void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const; + Element MultiplyElements(const Element &a, const Element &b) const + {throw NotImplemented("LUC_GroupParameters: MultiplyElements can not be implemented");} + Element CascadeExponentiate(const Element &element1, const Integer &exponent1, const Element &element2, const Integer &exponent2) const + {throw NotImplemented("LUC_GroupParameters: MultiplyElements can not be implemented");} + + // NameValuePairs interface + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const + { + return GetValueHelper(this, name, valueType, pValue).Assignable(); + } + +private: + int GetFieldType() const {return 2;} +}; + +//! _ +class DL_GroupParameters_LUC_DefaultSafePrime : public DL_GroupParameters_LUC +{ +public: + typedef NoCofactorMultiplication DefaultCofactorOption; + +protected: + unsigned int GetDefaultSubgroupOrderSize(unsigned int modulusSize) const {return modulusSize-1;} +}; + +//! _ +class DL_Algorithm_LUC_HMP : public DL_ElgamalLikeSignatureAlgorithm +{ +public: + static const char * StaticAlgorithmName() {return "LUC-HMP";} + + void Sign(const DL_GroupParameters ¶ms, const Integer &x, const Integer &k, const Integer &e, Integer &r, Integer &s) const; + bool Verify(const DL_GroupParameters ¶ms, const DL_PublicKey &publicKey, const Integer &e, const Integer &r, const Integer &s) const; + + size_t RLen(const DL_GroupParameters ¶ms) const + {return params.GetGroupOrder().ByteCount();} +}; + +//! _ +struct DL_SignatureKeys_LUC +{ + typedef DL_GroupParameters_LUC GroupParameters; + typedef DL_PublicKey_GFP PublicKey; + typedef DL_PrivateKey_GFP PrivateKey; +}; + +//! LUC-HMP, based on "Digital signature schemes based on Lucas functions" by Patrick Horster, Markus Michels, Holger Petersen +template +struct LUC_HMP : public DL_SS +{ +}; + +//! _ +struct DL_CryptoKeys_LUC +{ + typedef DL_GroupParameters_LUC_DefaultSafePrime GroupParameters; + typedef DL_PublicKey_GFP PublicKey; + typedef DL_PrivateKey_GFP PrivateKey; +}; + +//! LUC-IES +template +struct LUC_IES + : public DL_ES< + DL_CryptoKeys_LUC, + DL_KeyAgreementAlgorithm_DH, + DL_KeyDerivationAlgorithm_P1363 >, + DL_EncryptionAlgorithm_Xor, DHAES_MODE>, + LUC_IES<> > +{ + static std::string StaticAlgorithmName() {return "LUC-IES";} // non-standard name +}; + +// ******************************************************** + +//! LUC-DH +typedef DH_Domain LUC_DH; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/luc1024.dat b/CryptoPP/crypto/luc1024.dat new file mode 100644 index 0000000..f81dea0 --- /dev/null +++ b/CryptoPP/crypto/luc1024.dat @@ -0,0 +1 @@ +3082015202010002818100B7FE59813AF3A5DA48144EF03E5D229E3CFB55B0E3CEB63F9F973AC8655651409C3B36BBBE83698516F42A2E0FDC87DD83541697249D67FB5A91FA73470089C4997667811283CF22C74856F1E71129DB70FB23620A60E532B7931B7F93C0B9AA6B9D60E87529002BF2204B743773F501F6C370D067C7B22F6AD9DC07E8097347020111024100CFEA6177386C04D1668C984C39A7F889B36BB2B3BED2C7B83241D267F8D2038529AEB56D82CDE43264168873375C8D1F0897666CCC3F617C2F6B52E5143303C7024100E28BAB645993166EE1A984967AE8839EA41685F1E6392DBEB83EE6CA85A54396505DBD4E5C9024BAFCF27AD24D571DC6A3795CE7F0432669BCE742AF8FAF1481024078C6F402C266595B4F85098370528C2C0309BE93F6C45FC049F6AD987471A979FE215CC41455AA85F5A5B664F59E2F8E33C97C211698D14AD05FC65044F99510 \ No newline at end of file diff --git a/CryptoPP/crypto/luc2048.dat b/CryptoPP/crypto/luc2048.dat new file mode 100644 index 0000000..a4b3cef --- /dev/null +++ b/CryptoPP/crypto/luc2048.dat @@ -0,0 +1 @@ +308202960201000282010100EF8E1C8C8FB330A26C2449F1A50F7BD457D131C66D3194ECA20CE06138CC95CBE32E1DF910E13FF2D74823363286E3461E4BA3037EA32D4728F262C2364692E5948B8577F651292D72EF42445C2AAF11A526D2235DCE172A6E762EB86178BB5B4A06B8736567DB1525C8BDEB7242C81CC9090F5EF7CFC193FABEA3E5B5407E7DFDDF2D557487C65302148969F28DEC68AC3166FD52D44F1DE2EA74451A4BA0508F09E2F4AB85D89E7D68EEE4E8F9BD5A4858BAE8BF36E3A31FF06DDECDD40AE70932ECD09B65617B3208FF203EFBB0D822CDC1887EF343EBECBB762FA9C5D9F9339C80C96D6F3D8E4F7298FF6C94581C3CBC21C8CA94015F2E48400C0556B70502011102818100FDAD5D856662FC0284BEEF8470DC328B3B853F5819F037EBC786EB0225FD5C45B5BF99073F6E6CE31E4D1BC31105A4BAABA3BEC3C28F40E5912E7D3D6E6BE6178164E52F615C65FED1AE61D9D8F858282AF3C59C25A650A9CA72DD2105D95219CFEFEDDEB067647FDBABB659FBF2FF82F33C1A3A8BA73FB5F3D0C5509DFD38FF02818100F1BFA4A7A9506E020F9A57019F4326AE3D974DE9CCEF9BCA284B313DE287378411BDF1C9A1859D9165604EFF2EB1C9A685C0B317A08CF50E5F45AF570EE2C79B35BEA60B38109B4A450E87811CB10D6873F50726248055FE645C5C74FD0482F22CB541D77ED93F8B44CA72C9F550331C516BD061816325F9EF543C4995832BFB0281805184D4DC8796329003CF0EDC79048A12C4C78A1F44D8DE37A5939776A4E19CAA1ADBC4B78BE72EF23F1A5EFFF7377439138ED19D166285D1325CE6C2A7CFA182BDD7B82B2AB63A041C80B17A4D78161C240EDB2D6A494BEB27D28168E02DAE83C50C01EE8384E31111B756DA9B5423A6817F9078E8A750D0DE2CE62CF223601D \ No newline at end of file diff --git a/CryptoPP/crypto/lucc1024.dat b/CryptoPP/crypto/lucc1024.dat new file mode 100644 index 0000000..4366892 --- /dev/null +++ b/CryptoPP/crypto/lucc1024.dat @@ -0,0 +1 @@ +3082013F0201003082011706072A8648CE3804013082010A02818100E16B572E39DB4D90689753D09CEA97B9CAE9C0AF04203AE5BC7FC985B85D5BB50B1EDEA30CAAD003B455640FEEA79E342F3E8CFF6761051B38D6931A2B0FD0DF8E2210E7DA74CAC5DC1A79D80CD8C0F9FC09D81BAEC94E2F3663F25B0140DF6B3D5AD04CBA27BCF24A92963319FB992E39544370FD28642FE07EB17EDA4D47B902818070B5AB971CEDA6C8344BA9E84E754BDCE574E05782101D72DE3FE4C2DC2EADDA858F6F5186556801DA2AB207F753CF1A179F467FB3B0828D9C6B498D1587E86FC7110873ED3A6562EE0D3CEC066C607CFE04EC0DD764A7179B31F92D80A06FB59EAD68265D13DE7925494B198CFDCC971CAA21B87E943217F03F58BF6D26A3DD020107041F021D03BDAFBB087B5A628730212217B01F15B303A0133D6AF4FC3CAF7286A8 \ No newline at end of file diff --git a/CryptoPP/crypto/lucc512.dat b/CryptoPP/crypto/lucc512.dat new file mode 100644 index 0000000..9c2cf1a --- /dev/null +++ b/CryptoPP/crypto/lucc512.dat @@ -0,0 +1 @@ +3081B302010030819406072A8648CE380401308188024100B89A4AD4826B8FDDBFE3A6C0F5C8F805B7093AFF9BB2BD697C7D113C236BAC99ABF69000E169575CA2A2DDCDD1C7D9D06C63DCCC880121D933DCF598DD85C52102405C4D256A4135C7EEDFF1D3607AE47C02DB849D7FCDD95EB4BE3E889E11B5D64CD5FB480070B4ABAE51516EE6E8E3ECE83631EE66440090EC99EE7ACC6EC2E291020107041702150268EA4C567B18D0E35B1DA9D517CE5D359CD06779 \ No newline at end of file diff --git a/CryptoPP/crypto/lucd1024.dat b/CryptoPP/crypto/lucd1024.dat new file mode 100644 index 0000000..8554fa8 --- /dev/null +++ b/CryptoPP/crypto/lucd1024.dat @@ -0,0 +1,4 @@ +30818702818100EE9C91E2C1D8B0AB999B3F32B3115A36AA95A36B23CC8507D2340FA21EAAF6F6EB +1B900839CD9F8AFBFC155467F91FD8917DD46EAC55A266B246DFFFEDDDA79D674F77884D34709DB3 +452C2C1E2578CCC0CCA91C504039C52762F23F2A391A58B2CAD2DB05666DDF5B9E3C1AC33DB487B7 +70C82B7E7DCDEE4381562FCEE427FD02010A diff --git a/CryptoPP/crypto/lucd512.dat b/CryptoPP/crypto/lucd512.dat new file mode 100644 index 0000000..a782f44 --- /dev/null +++ b/CryptoPP/crypto/lucd512.dat @@ -0,0 +1,2 @@ +3046024100C339D027E5812ED5D9DE044F3697D0273625E5EA9EC4EF3FB89ADBFA9CD1FBF4D8C0EC +1118C44609F499EF644EEAECE2F38B3F67FAC81A075F31A60B5757A87D020109 diff --git a/CryptoPP/crypto/lucs1024.dat b/CryptoPP/crypto/lucs1024.dat new file mode 100644 index 0000000..1393199 --- /dev/null +++ b/CryptoPP/crypto/lucs1024.dat @@ -0,0 +1 @@ +3082015B0201003082013306072A8648CE3804013082012602818100D57B7B758DC8041CE6CFC57DFE0AAA33FC8FEC48BEEA37562AD13359236FFFF6EED3CEB3A7BBC4269A384ED9A296160F12BC666066548E28201CE293B1791F951C8D2C5965696D82B336EFADCF1E0D619EDA43DBB86415BF3EE6F721C0AB17E770EA7B2360A054D3E4E878647245FCF87B2335098303004CDDC2B9DCDA57DB51021D034E48F160EC5855CCCD9F995988AD1B554AD1B591E64283E91A07D151028180017324ADC1F93CF002FA2B0619C60F897CDED488E457685625E1565377483C0FA4A7FD1CAE848C727E76654434CE3CCAF81EC6E6AAA156EEBBEA095F642FD0DA2D043996ACC14A1B1A6110B19C094638E29890B89AF5812E97C5F96F33B1FD7415079947994442295CA34447807662FB70621F069A98AE274D01B2777BF4E97E041F021D00F9F02A2BC1930F1AC93198F3D532BC937941D7C9A1E16F0EB932476E \ No newline at end of file diff --git a/CryptoPP/crypto/lucs512.dat b/CryptoPP/crypto/lucs512.dat new file mode 100644 index 0000000..f8fd288 --- /dev/null +++ b/CryptoPP/crypto/lucs512.dat @@ -0,0 +1 @@ +3081C70201003081A806072A8648CE38040130819C024100E64283E91A07D10F557B7B758DC8041CE6CFC57DFE0AAA33FC8FEC48BEEA37562AD13359236FFFF6EED3FB921690D2FD1339F8E1DD406EED70D7EE3085E3AADD02150F4E48F160EC5855CCCD9F995988AD1B554AD1B5F3024062503DFB092F0FD0D8BBD90B50A834A6BD5B0995BCFC1CC8C8C83103AA6837F3FBFF3E042E1B25E36963DB2FCFD7AD24A6626E65A1F6EECBB399F5CE73659F29041702150450A037413E9A711E601318AF21D32A498C0C501E \ No newline at end of file diff --git a/CryptoPP/crypto/mars.cpp b/CryptoPP/crypto/mars.cpp new file mode 100644 index 0000000..74aad3a --- /dev/null +++ b/CryptoPP/crypto/mars.cpp @@ -0,0 +1,210 @@ +// mars.cpp - modified by Sean Woods from Brian Gladman's mars6.c for Crypto++ +// key setup updated by Wei Dai to reflect IBM's "tweak" proposed in August 1999 + +/* This is an independent implementation of the MARS encryption */ +/* algorithm designed by a team at IBM as a candidate for the US */ +/* NIST Advanced Encryption Standard (AES) effort. The algorithm */ +/* is subject to Patent action by IBM, who intend to offer royalty */ +/* free use if a Patent is granted. */ +/* */ +/* Copyright in this implementation is held by Dr B R Gladman but */ +/* I hereby give permission for its free direct or derivative use */ +/* subject to acknowledgment of its origin and compliance with any */ +/* constraints that IBM place on the use of the MARS algorithm. */ +/* */ +/* Dr Brian Gladman (gladman@seven77.demon.co.uk) 4th October 1998 */ + +#include "pch.h" +#include "mars.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +ANONYMOUS_NAMESPACE_BEGIN +static word32 gen_mask(word32 x) +{ + word32 m; + + m = (~x ^ (x >> 1)) & 0x7fffffff; + m &= (m >> 1) & (m >> 2); m &= (m >> 3) & (m >> 6); + + if(!m) + return 0; + + m <<= 1; m |= (m << 1); m |= (m << 2); m |= (m << 4); + m |= (m << 1) & ~x & 0x80000000; + + return m & 0xfffffffc; +}; +NAMESPACE_END + +void MARS::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs &) +{ + AssertValidKeyLength(length); + + // Initialize T[] with the key data + FixedSizeSecBlock T; + GetUserKey(LITTLE_ENDIAN_ORDER, T.begin(), 15, userKey, length); + T[length/4] = length/4; + + for (unsigned int j=0; j<4; j++) // compute 10 words of K[] in each iteration + { + unsigned int i; + // Do linear transformation + for (i=0; i<15; i++) + T[i] = T[i] ^ rotlFixed(T[(i+8)%15] ^ T[(i+13)%15], 3) ^ (4*i+j); + + // Do four rounds of stirring + for (unsigned int k=0; k<4; k++) + for (i=0; i<15; i++) + T[i] = rotlFixed(T[i] + Sbox[T[(i+14)%15]%512], 9); + + // Store next 10 key words into K[] + for (i=0; i<10; i++) + EK[10*j+i] = T[4*i%15]; + } + + // Modify multiplication key-words + for(unsigned int i = 5; i < 37; i += 2) + { + word32 w = EK[i] | 3; + word32 m = gen_mask(w); + if(m) + w ^= (rotlMod(Sbox[265 + (EK[i] & 3)], EK[i-1]) & m); + EK[i] = w; + } +} + +#define f_mix(a,b,c,d) \ + r = rotrFixed(a, 8); \ + b ^= Sbox[a & 255]; \ + b += Sbox[(r & 255) + 256]; \ + r = rotrFixed(a, 16); \ + a = rotrFixed(a, 24); \ + c += Sbox[r & 255]; \ + d ^= Sbox[(a & 255) + 256] + +#define b_mix(a,b,c,d) \ + r = rotlFixed(a, 8); \ + b ^= Sbox[(a & 255) + 256]; \ + c -= Sbox[r & 255]; \ + r = rotlFixed(a, 16); \ + a = rotlFixed(a, 24); \ + d -= Sbox[(r & 255) + 256]; \ + d ^= Sbox[a & 255] + +#define f_ktr(a,b,c,d,i) \ + m = a + EK[i]; \ + a = rotlFixed(a, 13); \ + r = a * EK[i + 1]; \ + l = Sbox[m & 511]; \ + r = rotlFixed(r, 5); \ + l ^= r; \ + c += rotlMod(m, r); \ + r = rotlFixed(r, 5); \ + l ^= r; \ + d ^= r; \ + b += rotlMod(l, r) + +#define r_ktr(a,b,c,d,i) \ + r = a * EK[i + 1]; \ + a = rotrFixed(a, 13); \ + m = a + EK[i]; \ + l = Sbox[m & 511]; \ + r = rotlFixed(r, 5); \ + l ^= r; \ + c -= rotlMod(m, r); \ + r = rotlFixed(r, 5); \ + l ^= r; \ + d ^= r; \ + b -= rotlMod(l, r) + +typedef BlockGetAndPut Block; + +void MARS::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word32 a, b, c, d, l, m, r; + + Block::Get(inBlock)(a)(b)(c)(d); + + a += EK[0]; + b += EK[1]; + c += EK[2]; + d += EK[3]; + + int i; + for (i = 0; i < 2; i++) { + f_mix(a,b,c,d); + a += d; + f_mix(b,c,d,a); + b += c; + f_mix(c,d,a,b); + f_mix(d,a,b,c); + } + + f_ktr(a,b,c,d, 4); f_ktr(b,c,d,a, 6); f_ktr(c,d,a,b, 8); f_ktr(d,a,b,c,10); + f_ktr(a,b,c,d,12); f_ktr(b,c,d,a,14); f_ktr(c,d,a,b,16); f_ktr(d,a,b,c,18); + f_ktr(a,d,c,b,20); f_ktr(b,a,d,c,22); f_ktr(c,b,a,d,24); f_ktr(d,c,b,a,26); + f_ktr(a,d,c,b,28); f_ktr(b,a,d,c,30); f_ktr(c,b,a,d,32); f_ktr(d,c,b,a,34); + + for (i = 0; i < 2; i++) { + b_mix(a,b,c,d); + b_mix(b,c,d,a); + c -= b; + b_mix(c,d,a,b); + d -= a; + b_mix(d,a,b,c); + } + + a -= EK[36]; + b -= EK[37]; + c -= EK[38]; + d -= EK[39]; + + Block::Put(xorBlock, outBlock)(a)(b)(c)(d); +} + +void MARS::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word32 a, b, c, d, l, m, r; + + Block::Get(inBlock)(d)(c)(b)(a); + + d += EK[36]; + c += EK[37]; + b += EK[38]; + a += EK[39]; + + int i; + for (i = 0; i < 2; i++) { + f_mix(a,b,c,d); + a += d; + f_mix(b,c,d,a); + b += c; + f_mix(c,d,a,b); + f_mix(d,a,b,c); + } + + r_ktr(a,b,c,d,34); r_ktr(b,c,d,a,32); r_ktr(c,d,a,b,30); r_ktr(d,a,b,c,28); + r_ktr(a,b,c,d,26); r_ktr(b,c,d,a,24); r_ktr(c,d,a,b,22); r_ktr(d,a,b,c,20); + r_ktr(a,d,c,b,18); r_ktr(b,a,d,c,16); r_ktr(c,b,a,d,14); r_ktr(d,c,b,a,12); + r_ktr(a,d,c,b,10); r_ktr(b,a,d,c, 8); r_ktr(c,b,a,d, 6); r_ktr(d,c,b,a, 4); + + for (i = 0; i < 2; i++) { + b_mix(a,b,c,d); + b_mix(b,c,d,a); + c -= b; + b_mix(c,d,a,b); + d -= a; + b_mix(d,a,b,c); + } + + d -= EK[0]; + c -= EK[1]; + b -= EK[2]; + a -= EK[3]; + + Block::Put(xorBlock, outBlock)(d)(c)(b)(a); +} + +NAMESPACE_END diff --git a/CryptoPP/crypto/mars.h b/CryptoPP/crypto/mars.h new file mode 100644 index 0000000..9c68102 --- /dev/null +++ b/CryptoPP/crypto/mars.h @@ -0,0 +1,54 @@ +#ifndef CRYPTOPP_MARS_H +#define CRYPTOPP_MARS_H + +/** \file +*/ + +#include "seckey.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! _ +struct MARS_Info : public FixedBlockSize<16>, public VariableKeyLength<16, 16, 56, 4> +{ + static const char *StaticAlgorithmName() {return "MARS";} +}; + +/// MARS +class MARS : public MARS_Info, public BlockCipherDocumentation +{ + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + public: + void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); + + protected: + static const word32 Sbox[512]; + + FixedSizeSecBlock EK; + }; + + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef MARS::Encryption MARSEncryption; +typedef MARS::Decryption MARSDecryption; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/marss.cpp b/CryptoPP/crypto/marss.cpp new file mode 100644 index 0000000..d7eff4f --- /dev/null +++ b/CryptoPP/crypto/marss.cpp @@ -0,0 +1,139 @@ +// MARS S-Box + +#include "pch.h" +#include "mars.h" + +NAMESPACE_BEGIN(CryptoPP) + +const word32 MARS::Base::Sbox[512] = { + 0x09d0c479, 0x28c8ffe0, 0x84aa6c39, 0x9dad7287, + 0x7dff9be3, 0xd4268361, 0xc96da1d4, 0x7974cc93, + 0x85d0582e, 0x2a4b5705, 0x1ca16a62, 0xc3bd279d, + 0x0f1f25e5, 0x5160372f, 0xc695c1fb, 0x4d7ff1e4, + 0xae5f6bf4, 0x0d72ee46, 0xff23de8a, 0xb1cf8e83, + 0xf14902e2, 0x3e981e42, 0x8bf53eb6, 0x7f4bf8ac, + 0x83631f83, 0x25970205, 0x76afe784, 0x3a7931d4, + 0x4f846450, 0x5c64c3f6, 0x210a5f18, 0xc6986a26, + 0x28f4e826, 0x3a60a81c, 0xd340a664, 0x7ea820c4, + 0x526687c5, 0x7eddd12b, 0x32a11d1d, 0x9c9ef086, + 0x80f6e831, 0xab6f04ad, 0x56fb9b53, 0x8b2e095c, + 0xb68556ae, 0xd2250b0d, 0x294a7721, 0xe21fb253, + 0xae136749, 0xe82aae86, 0x93365104, 0x99404a66, + 0x78a784dc, 0xb69ba84b, 0x04046793, 0x23db5c1e, + 0x46cae1d6, 0x2fe28134, 0x5a223942, 0x1863cd5b, + 0xc190c6e3, 0x07dfb846, 0x6eb88816, 0x2d0dcc4a, + 0xa4ccae59, 0x3798670d, 0xcbfa9493, 0x4f481d45, + 0xeafc8ca8, 0xdb1129d6, 0xb0449e20, 0x0f5407fb, + 0x6167d9a8, 0xd1f45763, 0x4daa96c3, 0x3bec5958, + 0xababa014, 0xb6ccd201, 0x38d6279f, 0x02682215, + 0x8f376cd5, 0x092c237e, 0xbfc56593, 0x32889d2c, + 0x854b3e95, 0x05bb9b43, 0x7dcd5dcd, 0xa02e926c, + 0xfae527e5, 0x36a1c330, 0x3412e1ae, 0xf257f462, + 0x3c4f1d71, 0x30a2e809, 0x68e5f551, 0x9c61ba44, + 0x5ded0ab8, 0x75ce09c8, 0x9654f93e, 0x698c0cca, + 0x243cb3e4, 0x2b062b97, 0x0f3b8d9e, 0x00e050df, + 0xfc5d6166, 0xe35f9288, 0xc079550d, 0x0591aee8, + 0x8e531e74, 0x75fe3578, 0x2f6d829a, 0xf60b21ae, + 0x95e8eb8d, 0x6699486b, 0x901d7d9b, 0xfd6d6e31, + 0x1090acef, 0xe0670dd8, 0xdab2e692, 0xcd6d4365, + 0xe5393514, 0x3af345f0, 0x6241fc4d, 0x460da3a3, + 0x7bcf3729, 0x8bf1d1e0, 0x14aac070, 0x1587ed55, + 0x3afd7d3e, 0xd2f29e01, 0x29a9d1f6, 0xefb10c53, + 0xcf3b870f, 0xb414935c, 0x664465ed, 0x024acac7, + 0x59a744c1, 0x1d2936a7, 0xdc580aa6, 0xcf574ca8, + 0x040a7a10, 0x6cd81807, 0x8a98be4c, 0xaccea063, + 0xc33e92b5, 0xd1e0e03d, 0xb322517e, 0x2092bd13, + 0x386b2c4a, 0x52e8dd58, 0x58656dfb, 0x50820371, + 0x41811896, 0xe337ef7e, 0xd39fb119, 0xc97f0df6, + 0x68fea01b, 0xa150a6e5, 0x55258962, 0xeb6ff41b, + 0xd7c9cd7a, 0xa619cd9e, 0xbcf09576, 0x2672c073, + 0xf003fb3c, 0x4ab7a50b, 0x1484126a, 0x487ba9b1, + 0xa64fc9c6, 0xf6957d49, 0x38b06a75, 0xdd805fcd, + 0x63d094cf, 0xf51c999e, 0x1aa4d343, 0xb8495294, + 0xce9f8e99, 0xbffcd770, 0xc7c275cc, 0x378453a7, + 0x7b21be33, 0x397f41bd, 0x4e94d131, 0x92cc1f98, + 0x5915ea51, 0x99f861b7, 0xc9980a88, 0x1d74fd5f, + 0xb0a495f8, 0x614deed0, 0xb5778eea, 0x5941792d, + 0xfa90c1f8, 0x33f824b4, 0xc4965372, 0x3ff6d550, + 0x4ca5fec0, 0x8630e964, 0x5b3fbbd6, 0x7da26a48, + 0xb203231a, 0x04297514, 0x2d639306, 0x2eb13149, + 0x16a45272, 0x532459a0, 0x8e5f4872, 0xf966c7d9, + 0x07128dc0, 0x0d44db62, 0xafc8d52d, 0x06316131, + 0xd838e7ce, 0x1bc41d00, 0x3a2e8c0f, 0xea83837e, + 0xb984737d, 0x13ba4891, 0xc4f8b949, 0xa6d6acb3, + 0xa215cdce, 0x8359838b, 0x6bd1aa31, 0xf579dd52, + 0x21b93f93, 0xf5176781, 0x187dfdde, 0xe94aeb76, + 0x2b38fd54, 0x431de1da, 0xab394825, 0x9ad3048f, + 0xdfea32aa, 0x659473e3, 0x623f7863, 0xf3346c59, + 0xab3ab685, 0x3346a90b, 0x6b56443e, 0xc6de01f8, + 0x8d421fc0, 0x9b0ed10c, 0x88f1a1e9, 0x54c1f029, + 0x7dead57b, 0x8d7ba426, 0x4cf5178a, 0x551a7cca, + 0x1a9a5f08, 0xfcd651b9, 0x25605182, 0xe11fc6c3, + 0xb6fd9676, 0x337b3027, 0xb7c8eb14, 0x9e5fd030, + 0x6b57e354, 0xad913cf7, 0x7e16688d, 0x58872a69, + 0x2c2fc7df, 0xe389ccc6, 0x30738df1, 0x0824a734, + 0xe1797a8b, 0xa4a8d57b, 0x5b5d193b, 0xc8a8309b, + 0x73f9a978, 0x73398d32, 0x0f59573e, 0xe9df2b03, + 0xe8a5b6c8, 0x848d0704, 0x98df93c2, 0x720a1dc3, + 0x684f259a, 0x943ba848, 0xa6370152, 0x863b5ea3, + 0xd17b978b, 0x6d9b58ef, 0x0a700dd4, 0xa73d36bf, + 0x8e6a0829, 0x8695bc14, 0xe35b3447, 0x933ac568, + 0x8894b022, 0x2f511c27, 0xddfbcc3c, 0x006662b6, + 0x117c83fe, 0x4e12b414, 0xc2bca766, 0x3a2fec10, + 0xf4562420, 0x55792e2a, 0x46f5d857, 0xceda25ce, + 0xc3601d3b, 0x6c00ab46, 0xefac9c28, 0xb3c35047, + 0x611dfee3, 0x257c3207, 0xfdd58482, 0x3b14d84f, + 0x23becb64, 0xa075f3a3, 0x088f8ead, 0x07adf158, + 0x7796943c, 0xfacabf3d, 0xc09730cd, 0xf7679969, + 0xda44e9ed, 0x2c854c12, 0x35935fa3, 0x2f057d9f, + 0x690624f8, 0x1cb0bafd, 0x7b0dbdc6, 0x810f23bb, + 0xfa929a1a, 0x6d969a17, 0x6742979b, 0x74ac7d05, + 0x010e65c4, 0x86a3d963, 0xf907b5a0, 0xd0042bd3, + 0x158d7d03, 0x287a8255, 0xbba8366f, 0x096edc33, + 0x21916a7b, 0x77b56b86, 0x951622f9, 0xa6c5e650, + 0x8cea17d1, 0xcd8c62bc, 0xa3d63433, 0x358a68fd, + 0x0f9b9d3c, 0xd6aa295b, 0xfe33384a, 0xc000738e, + 0xcd67eb2f, 0xe2eb6dc2, 0x97338b02, 0x06c9f246, + 0x419cf1ad, 0x2b83c045, 0x3723f18a, 0xcb5b3089, + 0x160bead7, 0x5d494656, 0x35f8a74b, 0x1e4e6c9e, + 0x000399bd, 0x67466880, 0xb4174831, 0xacf423b2, + 0xca815ab3, 0x5a6395e7, 0x302a67c5, 0x8bdb446b, + 0x108f8fa4, 0x10223eda, 0x92b8b48b, 0x7f38d0ee, + 0xab2701d4, 0x0262d415, 0xaf224a30, 0xb3d88aba, + 0xf8b2c3af, 0xdaf7ef70, 0xcc97d3b7, 0xe9614b6c, + 0x2baebff4, 0x70f687cf, 0x386c9156, 0xce092ee5, + 0x01e87da6, 0x6ce91e6a, 0xbb7bcc84, 0xc7922c20, + 0x9d3b71fd, 0x060e41c6, 0xd7590f15, 0x4e03bb47, + 0x183c198e, 0x63eeb240, 0x2ddbf49a, 0x6d5cba54, + 0x923750af, 0xf9e14236, 0x7838162b, 0x59726c72, + 0x81b66760, 0xbb2926c1, 0x48a0ce0d, 0xa6c0496d, + 0xad43507b, 0x718d496a, 0x9df057af, 0x44b1bde6, + 0x054356dc, 0xde7ced35, 0xd51a138b, 0x62088cc9, + 0x35830311, 0xc96efca2, 0x686f86ec, 0x8e77cb68, + 0x63e1d6b8, 0xc80f9778, 0x79c491fd, 0x1b4c67f2, + 0x72698d7d, 0x5e368c31, 0xf7d95e2e, 0xa1d3493f, + 0xdcd9433e, 0x896f1552, 0x4bc4ca7a, 0xa6d1baf4, + 0xa5a96dcc, 0x0bef8b46, 0xa169fda7, 0x74df40b7, + 0x4e208804, 0x9a756607, 0x038e87c8, 0x20211e44, + 0x8b7ad4bf, 0xc6403f35, 0x1848e36d, 0x80bdb038, + 0x1e62891c, 0x643d2107, 0xbf04d6f8, 0x21092c8c, + 0xf644f389, 0x0778404e, 0x7b78adb8, 0xa2c52d53, + 0x42157abe, 0xa2253e2e, 0x7bf3f4ae, 0x80f594f9, + 0x953194e7, 0x77eb92ed, 0xb3816930, 0xda8d9336, + 0xbf447469, 0xf26d9483, 0xee6faed5, 0x71371235, + 0xde425f73, 0xb4e59f43, 0x7dbe2d4e, 0x2d37b185, + 0x49dc9a63, 0x98c39d98, 0x1301c9a2, 0x389b1bbf, + 0x0c18588d, 0xa421c1ba, 0x7aa3865c, 0x71e08558, + 0x3c5cfcaa, 0x7d239ca4, 0x0297d9dd, 0xd7dc2830, + 0x4b37802b, 0x7428ab54, 0xaeee0347, 0x4b3fbb85, + 0x692f2f08, 0x134e578e, 0x36d9e0bf, 0xae8b5fcf, + 0xedb93ecf, 0x2b27248e, 0x170eb1ef, 0x7dc57fd6, + 0x1e760f16, 0xb1136601, 0x864e1b9b, 0xd7ea7319, + 0x3ab871bd, 0xcfa4d76f, 0xe31bd782, 0x0dbeb469, + 0xabb96061, 0x5370f85d, 0xffb07e37, 0xda30d0fb, + 0xebc977b6, 0x0b98b40f, 0x3a4d0fe6, 0xdf4fc26b, + 0x159cf22a, 0xc298d6e2, 0x2b78ef6a, 0x61a94ac0, + 0xab561187, 0x14eea0f0, 0xdf0d4164, 0x19af70ee +}; + +NAMESPACE_END diff --git a/CryptoPP/crypto/marsval.dat b/CryptoPP/crypto/marsval.dat new file mode 100644 index 0000000..16a43b4 --- /dev/null +++ b/CryptoPP/crypto/marsval.dat @@ -0,0 +1,9 @@ +00000000000000000000000000000000 00000000000000000000000000000000 DCC07B8DFB0738D6E30A22DFCF27E886 +00000000000000000000000000000000 DCC07B8DFB0738D6E30A22DFCF27E886 33CAFFBDDC7F1DDA0F9C15FA2F30E2FF +CB14A1776ABBC1CDAFE7243DEF2CEA02 F94512A9B42D034EC4792204D708A69B 225DA2CB64B73F79069F21A5E3CB8522 +86EDF4DA31824CABEF6A4637C40B0BAB 4DF955AD5B398D66408D620A2B27E1A9 A4B737340AE6D2CAFD930BA97D86129F +000000000000000000000000000000000000000000000000 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 97778747D60E425C2B4202599DB856FB +D158860838874D9500000000000000000000000000000000 93A953A82C10411DD158860838874D95 4FA0E5F64893131712F01408D233E9F7 +791739A58B04581A93A953A82C10411DD158860838874D95 6761C42D3E6142D2A84FBFADB383158F F706BC0FD97E28B6F1AF4E17D8755FFF +0000000000000000000000000000000000000000000000000000000000000000 62E45B4CF3477F1DD65063729D9ABA8F 0F4B897EA014D21FBC20F1054A42F719 +FBA167983E7AEF22317CE28C02AAE1A3E8E5CC3CEDBEA82A99DBC39AD65E7227 1344ABA4D3C44708A8A72116D4F49384 458335D95EA42A9F4DCCD41AECC2390D diff --git a/CryptoPP/crypto/md2.cpp b/CryptoPP/crypto/md2.cpp new file mode 100644 index 0000000..f4331da --- /dev/null +++ b/CryptoPP/crypto/md2.cpp @@ -0,0 +1,120 @@ +// md2.cpp - modified by Wei Dai from Andrew M. Kuchling's md2.c +// The original code and all modifications are in the public domain. + +// This is the original introductory comment: + +/* + * md2.c : MD2 hash algorithm. + * + * Part of the Python Cryptography Toolkit, version 1.1 + * + * Distribute and use freely; there are no restrictions on further + * dissemination and usage except those imposed by the laws of your + * country of residence. + * + */ + +#include "pch.h" +#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 +#include "md2.h" + +NAMESPACE_BEGIN(CryptoPP) +namespace Weak1 { + +MD2::MD2() + : m_X(48), m_C(16), m_buf(16) +{ + Init(); +} + +void MD2::Init() +{ + memset(m_X, 0, 48); + memset(m_C, 0, 16); + memset(m_buf, 0, 16); + m_count = 0; +} + +void MD2::Update(const byte *buf, size_t len) +{ + static const byte S[256] = { + 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6, + 19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188, + 76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24, + 138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251, + 245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63, + 148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50, + 39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165, + 181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210, + 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157, + 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27, + 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15, + 85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197, + 234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65, + 129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123, + 8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233, + 203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228, + 166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237, + 31, 26, 219, 153, 141, 51, 159, 17, 131, 20 + }; + + while (len) + { + unsigned int L = UnsignedMin(16U-m_count, len); + memcpy(m_buf+m_count, buf, L); + m_count+=L; + buf+=L; + len-=L; + if (m_count==16) + { + byte t; + int i,j; + + m_count=0; + memcpy(m_X+16, m_buf, 16); + t=m_C[15]; + for(i=0; i<16; i++) + { + m_X[32+i]=m_X[16+i]^m_X[i]; + t=m_C[i]^=S[m_buf[i]^t]; + } + + t=0; + for(i=0; i<18; i++) + { + for(j=0; j<48; j+=8) + { + t=m_X[j+0]^=S[t]; + t=m_X[j+1]^=S[t]; + t=m_X[j+2]^=S[t]; + t=m_X[j+3]^=S[t]; + t=m_X[j+4]^=S[t]; + t=m_X[j+5]^=S[t]; + t=m_X[j+6]^=S[t]; + t=m_X[j+7]^=S[t]; + } + t=(t+i) & 0xFF; + } + } + } +} + +void MD2::TruncatedFinal(byte *hash, size_t size) +{ + ThrowIfInvalidTruncatedSize(size); + + byte padding[16]; + word32 padlen; + unsigned int i; + + padlen= 16-m_count; + for(i=0; iMD2 +class MD2 : public HashTransformation +{ +public: + MD2(); + void Update(const byte *input, size_t length); + void TruncatedFinal(byte *hash, size_t size); + unsigned int DigestSize() const {return DIGESTSIZE;} + unsigned int BlockSize() const {return BLOCKSIZE;} + static const char * StaticAlgorithmName() {return "MD2";} + + CRYPTOPP_CONSTANT(DIGESTSIZE = 16) + CRYPTOPP_CONSTANT(BLOCKSIZE = 16) + +private: + void Transform(); + void Init(); + SecByteBlock m_X, m_C, m_buf; + unsigned int m_count; +}; + +} +#if CRYPTOPP_ENABLE_NAMESPACE_WEAK >= 1 +namespace Weak {using namespace Weak1;} // import Weak1 into CryptoPP::Weak +#else +using namespace Weak1; // import Weak1 into CryptoPP with warning +#ifdef __GNUC__ +#warning "You may be using a weak algorithm that has been retained for backwards compatibility. Please '#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1' before including this .h file and prepend the class name with 'Weak::' to remove this warning." +#else +#pragma message("You may be using a weak algorithm that has been retained for backwards compatibility. Please '#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1' before including this .h file and prepend the class name with 'Weak::' to remove this warning.") +#endif +#endif + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/md4.cpp b/CryptoPP/crypto/md4.cpp new file mode 100644 index 0000000..84fe4cc --- /dev/null +++ b/CryptoPP/crypto/md4.cpp @@ -0,0 +1,110 @@ +// md4.cpp - modified by Wei Dai from Andrew M. Kuchling's md4.c +// The original code and all modifications are in the public domain. + +// This is the original introductory comment: + +/* + * md4.c : MD4 hash algorithm. + * + * Part of the Python Cryptography Toolkit, version 1.1 + * + * Distribute and use freely; there are no restrictions on further + * dissemination and usage except those imposed by the laws of your + * country of residence. + * + */ + +#include "pch.h" +#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 +#include "md4.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) +namespace Weak1 { + +void MD4::InitState(HashWordType *state) +{ + state[0] = 0x67452301L; + state[1] = 0xefcdab89L; + state[2] = 0x98badcfeL; + state[3] = 0x10325476L; +} + +void MD4::Transform (word32 *digest, const word32 *in) +{ +// #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) +#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) + + word32 A, B, C, D; + + A=digest[0]; + B=digest[1]; + C=digest[2]; + D=digest[3]; + +#define function(a,b,c,d,k,s) a=rotlFixed(a+F(b,c,d)+in[k],s); + function(A,B,C,D, 0, 3); + function(D,A,B,C, 1, 7); + function(C,D,A,B, 2,11); + function(B,C,D,A, 3,19); + function(A,B,C,D, 4, 3); + function(D,A,B,C, 5, 7); + function(C,D,A,B, 6,11); + function(B,C,D,A, 7,19); + function(A,B,C,D, 8, 3); + function(D,A,B,C, 9, 7); + function(C,D,A,B,10,11); + function(B,C,D,A,11,19); + function(A,B,C,D,12, 3); + function(D,A,B,C,13, 7); + function(C,D,A,B,14,11); + function(B,C,D,A,15,19); + +#undef function +#define function(a,b,c,d,k,s) a=rotlFixed(a+G(b,c,d)+in[k]+0x5a827999,s); + function(A,B,C,D, 0, 3); + function(D,A,B,C, 4, 5); + function(C,D,A,B, 8, 9); + function(B,C,D,A,12,13); + function(A,B,C,D, 1, 3); + function(D,A,B,C, 5, 5); + function(C,D,A,B, 9, 9); + function(B,C,D,A,13,13); + function(A,B,C,D, 2, 3); + function(D,A,B,C, 6, 5); + function(C,D,A,B,10, 9); + function(B,C,D,A,14,13); + function(A,B,C,D, 3, 3); + function(D,A,B,C, 7, 5); + function(C,D,A,B,11, 9); + function(B,C,D,A,15,13); + +#undef function +#define function(a,b,c,d,k,s) a=rotlFixed(a+H(b,c,d)+in[k]+0x6ed9eba1,s); + function(A,B,C,D, 0, 3); + function(D,A,B,C, 8, 9); + function(C,D,A,B, 4,11); + function(B,C,D,A,12,15); + function(A,B,C,D, 2, 3); + function(D,A,B,C,10, 9); + function(C,D,A,B, 6,11); + function(B,C,D,A,14,15); + function(A,B,C,D, 1, 3); + function(D,A,B,C, 9, 9); + function(C,D,A,B, 5,11); + function(B,C,D,A,13,15); + function(A,B,C,D, 3, 3); + function(D,A,B,C,11, 9); + function(C,D,A,B, 7,11); + function(B,C,D,A,15,15); + + digest[0]+=A; + digest[1]+=B; + digest[2]+=C; + digest[3]+=D; +} + +} +NAMESPACE_END diff --git a/CryptoPP/crypto/md4.h b/CryptoPP/crypto/md4.h new file mode 100644 index 0000000..ac98f94 --- /dev/null +++ b/CryptoPP/crypto/md4.h @@ -0,0 +1,35 @@ +#ifndef CRYPTOPP_MD4_H +#define CRYPTOPP_MD4_H + +#include "iterhash.h" + +NAMESPACE_BEGIN(CryptoPP) + +namespace Weak1 { + +//! MD4 +/*! \warning MD4 is considered insecure, and should not be used + unless you absolutely need it for compatibility. */ +class MD4 : public IteratedHashWithStaticTransform +{ +public: + static void InitState(HashWordType *state); + static void Transform(word32 *digest, const word32 *data); + static const char *StaticAlgorithmName() {return "MD4";} +}; + +} +#if CRYPTOPP_ENABLE_NAMESPACE_WEAK >= 1 +namespace Weak {using namespace Weak1;} // import Weak1 into CryptoPP::Weak +#else +using namespace Weak1; // import Weak1 into CryptoPP with warning +#ifdef __GNUC__ +#warning "You may be using a weak algorithm that has been retained for backwards compatibility. Please '#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1' before including this .h file and prepend the class name with 'Weak::' to remove this warning." +#else +#pragma message("You may be using a weak algorithm that has been retained for backwards compatibility. Please '#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1' before including this .h file and prepend the class name with 'Weak::' to remove this warning.") +#endif +#endif + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/md5.cpp b/CryptoPP/crypto/md5.cpp new file mode 100644 index 0000000..11035b7 --- /dev/null +++ b/CryptoPP/crypto/md5.cpp @@ -0,0 +1,118 @@ +// md5.cpp - modified by Wei Dai from Colin Plumb's public domain md5.c +// any modifications are placed in the public domain + +#include "pch.h" +#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 +#include "md5.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) +namespace Weak1 { + +void MD5_TestInstantiations() +{ + MD5 x; +} + +void MD5::InitState(HashWordType *state) +{ + state[0] = 0x67452301L; + state[1] = 0xefcdab89L; + state[2] = 0x98badcfeL; + state[3] = 0x10325476L; +} + +void MD5::Transform (word32 *digest, const word32 *in) +{ +// #define F1(x, y, z) (x & y | ~x & z) +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +#define MD5STEP(f, w, x, y, z, data, s) \ + w = rotlFixed(w + f(x, y, z) + data, s) + x + + word32 a, b, c, d; + + a=digest[0]; + b=digest[1]; + c=digest[2]; + d=digest[3]; + + MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); + MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); + MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); + MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); + MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); + MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); + MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); + MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); + MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); + MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); + + MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); + MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); + MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); + MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); + MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); + MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); + MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); + MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); + MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); + MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); + + MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); + MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); + MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); + MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); + MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); + MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); + MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); + MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); + MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); + MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); + + MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); + MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); + MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); + MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); + MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); + MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); + MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); + MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); + MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); + MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); + + digest[0]+=a; + digest[1]+=b; + digest[2]+=c; + digest[3]+=d; +} + +} +NAMESPACE_END diff --git a/CryptoPP/crypto/md5.h b/CryptoPP/crypto/md5.h new file mode 100644 index 0000000..2b35003 --- /dev/null +++ b/CryptoPP/crypto/md5.h @@ -0,0 +1,33 @@ +#ifndef CRYPTOPP_MD5_H +#define CRYPTOPP_MD5_H + +#include "iterhash.h" + +NAMESPACE_BEGIN(CryptoPP) + +namespace Weak1 { + +//! MD5 +class MD5 : public IteratedHashWithStaticTransform +{ +public: + static void InitState(HashWordType *state); + static void Transform(word32 *digest, const word32 *data); + static const char * StaticAlgorithmName() {return "MD5";} +}; + +} +#if CRYPTOPP_ENABLE_NAMESPACE_WEAK >= 1 +namespace Weak {using namespace Weak1;} // import Weak1 into CryptoPP::Weak +#else +using namespace Weak1; // import Weak1 into CryptoPP with warning +#ifdef __GNUC__ +#warning "You may be using a weak algorithm that has been retained for backwards compatibility. Please '#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1' before including this .h file and prepend the class name with 'Weak::' to remove this warning." +#else +#pragma message("You may be using a weak algorithm that has been retained for backwards compatibility. Please '#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1' before including this .h file and prepend the class name with 'Weak::' to remove this warning.") +#endif +#endif + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/md5mac.cpp b/CryptoPP/crypto/md5mac.cpp new file mode 100644 index 0000000..f5c90c3 --- /dev/null +++ b/CryptoPP/crypto/md5mac.cpp @@ -0,0 +1,166 @@ +// md5mac.cpp - modified by Wei Dai from Colin Plumb's public domain md5.c +// any modifications are placed in the public domain + +#include "pch.h" +#include "md5mac.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +const word32 MD5MAC_Base::T[12] = + { 0xac45ef97,0xcd430f29,0x551b7e45,0x3411801c, + 0x96ce77b1,0x7c8e722e,0x0aab5a5f,0x18be4336, + 0x21b4219d,0x4db987bc,0xbd279da2,0xc3d75bc7 }; + +void MD5MAC_Base::UncheckedSetKey(const byte *userKey, unsigned int keylength, const NameValuePairs &) +{ + const word32 zeros[4] = {0,0,0,0}; + + for (unsigned i=0, j; i<3; i++) + { + m_key[4*i+0] = 0x67452301L; + m_key[4*i+1] = 0xefcdab89L; + m_key[4*i+2] = 0x98badcfeL; + m_key[4*i+3] = 0x10325476L; + + memcpy(m_data, userKey, KEYLENGTH); + CorrectEndianess(m_data, m_data, KEYLENGTH); + for (j=0; j<3; j++) + memcpy(m_data+4+4*j, T+((i+j)%3)*4, 16); + Transform(m_key+4*i, m_data, zeros); + + for (j=0; j<3; j++) + memcpy(m_data+4*j, T+((i+j)%3)*4, 16); + memcpy(m_data+12, userKey, KEYLENGTH); + CorrectEndianess(m_data+12, m_data+12, KEYLENGTH); + Transform(m_key+4*i, m_data, zeros); + } + + Init(); +} + +void MD5MAC_Base::Init() +{ + m_digest[0] = m_key[0]; + m_digest[1] = m_key[1]; + m_digest[2] = m_key[2]; + m_digest[3] = m_key[3]; +} + +void MD5MAC_Base::TruncatedFinal(byte *hash, size_t size) +{ + ThrowIfInvalidTruncatedSize(size); + + PadLastBlock(56); + CorrectEndianess(m_data, m_data, 56); + + m_data[14] = GetBitCountLo(); + m_data[15] = GetBitCountHi(); + + Transform(m_digest, m_data, m_key+4); + + unsigned i; + for (i=0; i<4; i++) + m_data[i] = m_key[8+i]; + for (i=0; i<12; i++) + m_data[i+4] = T[i] ^ m_key[8+i%4]; + Transform(m_digest, m_data, m_key+4); + + CorrectEndianess(m_digest, m_digest, DIGESTSIZE); + memcpy(hash, m_digest, size); + + Restart(); // reinit for next use +} + +void MD5MAC_Base::Transform(word32 *digest, const word32 *in, const word32 *key) +{ +#define F1(x, y, z) ((z ^ (x & (y ^ z))) + key[0]) +#define F2(x, y, z) ((y ^ (z & (x ^ y))) + key[1]) +#define F3(x, y, z) ((x ^ y ^ z) + key[2]) +#define F4(x, y, z) ((y ^ (x | ~z)) + key[3]) + +#define MD5STEP(f, w, x, y, z, data, s) \ + w = rotlFixed(w + f(x, y, z) + data, s) + x + + word32 a, b, c, d; + + a=digest[0]; + b=digest[1]; + c=digest[2]; + d=digest[3]; + + MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); + MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); + MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); + MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); + MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); + MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); + MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); + MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); + MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); + MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); + + MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); + MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); + MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); + MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); + MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); + MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); + MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); + MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); + MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); + MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); + + MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); + MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); + MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); + MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); + MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); + MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); + MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); + MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); + MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); + MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); + + MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); + MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); + MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); + MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); + MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); + MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); + MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); + MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); + MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); + MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); + + digest[0]+=a; + digest[1]+=b; + digest[2]+=c; + digest[3]+=d; +} + +NAMESPACE_END diff --git a/CryptoPP/crypto/md5mac.h b/CryptoPP/crypto/md5mac.h new file mode 100644 index 0000000..bd17e70 --- /dev/null +++ b/CryptoPP/crypto/md5mac.h @@ -0,0 +1,38 @@ +#ifndef CRYPTOPP_MD5MAC_H +#define CRYPTOPP_MD5MAC_H + +/** \file +*/ + +#include "seckey.h" +#include "iterhash.h" + +NAMESPACE_BEGIN(CryptoPP) + +class CRYPTOPP_NO_VTABLE MD5MAC_Base : public FixedKeyLength<16>, public IteratedHash +{ +public: + static std::string StaticAlgorithmName() {return "MD5-MAC";} + CRYPTOPP_CONSTANT(DIGESTSIZE = 16) + + MD5MAC_Base() {SetStateSize(DIGESTSIZE);} + + void UncheckedSetKey(const byte *userKey, unsigned int keylength, const NameValuePairs ¶ms); + void TruncatedFinal(byte *mac, size_t size); + unsigned int DigestSize() const {return DIGESTSIZE;} + +protected: + static void Transform (word32 *buf, const word32 *in, const word32 *key); + void HashEndianCorrectedBlock(const word32 *data) {Transform(m_digest, data, m_key+4);} + void Init(); + + static const word32 T[12]; + FixedSizeSecBlock m_key; +}; + +//! MD5-MAC +DOCUMENTED_TYPEDEF(MessageAuthenticationCodeFinal, MD5MAC) + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/mdc.h b/CryptoPP/crypto/mdc.h new file mode 100644 index 0000000..50c368b --- /dev/null +++ b/CryptoPP/crypto/mdc.h @@ -0,0 +1,72 @@ + // mdc.h - written and placed in the public domain by Wei Dai + +#ifndef CRYPTOPP_MDC_H +#define CRYPTOPP_MDC_H + +/** \file +*/ + +#include "seckey.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! _ +template +struct MDC_Info : public FixedBlockSize, public FixedKeyLength +{ + static std::string StaticAlgorithmName() {return std::string("MDC/")+T::StaticAlgorithmName();} +}; + +//! MDC +/*! a construction by Peter Gutmann to turn an iterated hash function into a PRF */ +template +class MDC : public MDC_Info +{ + class CRYPTOPP_NO_VTABLE Enc : public BlockCipherImpl > + { + typedef typename T::HashWordType HashWordType; + + public: + void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms) + { + this->AssertValidKeyLength(length); + memcpy_s(m_key, m_key.size(), userKey, this->KEYLENGTH); + T::CorrectEndianess(Key(), Key(), this->KEYLENGTH); + } + + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const + { + T::CorrectEndianess(Buffer(), (HashWordType *)inBlock, this->BLOCKSIZE); + T::Transform(Buffer(), Key()); + if (xorBlock) + { + T::CorrectEndianess(Buffer(), Buffer(), this->BLOCKSIZE); + xorbuf(outBlock, xorBlock, m_buffer, this->BLOCKSIZE); + } + else + T::CorrectEndianess((HashWordType *)outBlock, Buffer(), this->BLOCKSIZE); + } + + bool IsPermutation() const {return false;} + + unsigned int GetAlignment() const {return sizeof(HashWordType);} + + private: + HashWordType *Key() {return (HashWordType *)m_key.data();} + const HashWordType *Key() const {return (const HashWordType *)m_key.data();} + HashWordType *Buffer() const {return (HashWordType *)m_buffer.data();} + + // VC60 workaround: bug triggered if using FixedSizeAllocatorWithCleanup + FixedSizeSecBlock::KEYLENGTH, AllocatorWithCleanup > m_key; + mutable FixedSizeSecBlock::BLOCKSIZE, AllocatorWithCleanup > m_buffer; + }; + +public: + //! use BlockCipher interface + typedef BlockCipherFinal Encryption; +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/misc.cpp b/CryptoPP/crypto/misc.cpp new file mode 100644 index 0000000..92aa7d2 --- /dev/null +++ b/CryptoPP/crypto/misc.cpp @@ -0,0 +1,98 @@ +// misc.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "misc.h" +#include "words.h" +#include + +NAMESPACE_BEGIN(CryptoPP) + +void xorbuf(byte *buf, const byte *mask, size_t count) +{ + size_t i; + + if (IsAligned(buf) && IsAligned(mask)) + { + #if defined(WORD64_AVAILABLE) && !defined(CRYPTOPP_SLOW_WORD64) + if (IsAligned(buf) && IsAligned(mask)) + { + for (i=0; i(output) && IsAligned(input) && IsAligned(mask)) + { + #if defined(WORD64_AVAILABLE) && !defined(CRYPTOPP_SLOW_WORD64) + if (IsAligned(output) && IsAligned(input) && IsAligned(mask)) + { + for (i=0; i // for memcpy and memmove + +#ifdef _MSC_VER + #include + #if _MSC_VER >= 1400 + // VC2005 workaround: disable declarations that conflict with winnt.h + #define _interlockedbittestandset CRYPTOPP_DISABLED_INTRINSIC_1 + #define _interlockedbittestandreset CRYPTOPP_DISABLED_INTRINSIC_2 + #include + #undef _interlockedbittestandset + #undef _interlockedbittestandreset + #define CRYPTOPP_FAST_ROTATE(x) 1 + #elif _MSC_VER >= 1300 + #define CRYPTOPP_FAST_ROTATE(x) ((x) == 32 | (x) == 64) + #else + #define CRYPTOPP_FAST_ROTATE(x) ((x) == 32) + #endif +#elif (defined(__MWERKS__) && TARGET_CPU_PPC) || \ + (defined(__GNUC__) && (defined(_ARCH_PWR2) || defined(_ARCH_PWR) || defined(_ARCH_PPC) || defined(_ARCH_PPC64) || defined(_ARCH_COM))) + #define CRYPTOPP_FAST_ROTATE(x) ((x) == 32) +#elif defined(__GNUC__) && (CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X86) // depend on GCC's peephole optimization to generate rotate instructions + #define CRYPTOPP_FAST_ROTATE(x) 1 +#else + #define CRYPTOPP_FAST_ROTATE(x) 0 +#endif + +#ifdef __BORLANDC__ +#include +#endif + +#if defined(__GNUC__) && defined(__linux__) +#define CRYPTOPP_BYTESWAP_AVAILABLE +#include +#endif + +NAMESPACE_BEGIN(CryptoPP) + +// ************** compile-time assertion *************** + +template +struct CompileAssert +{ + static char dummy[2*b-1]; +}; + +#define CRYPTOPP_COMPILE_ASSERT(assertion) CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, __LINE__) +#if defined(CRYPTOPP_EXPORTS) || defined(CRYPTOPP_IMPORTS) +#define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance) +#else +#define CRYPTOPP_COMPILE_ASSERT_INSTANCE(assertion, instance) static CompileAssert<(assertion)> CRYPTOPP_ASSERT_JOIN(cryptopp_assert_, instance) +#endif +#define CRYPTOPP_ASSERT_JOIN(X, Y) CRYPTOPP_DO_ASSERT_JOIN(X, Y) +#define CRYPTOPP_DO_ASSERT_JOIN(X, Y) X##Y + +// ************** misc classes *************** + +class CRYPTOPP_DLL Empty +{ +}; + +//! _ +template +class CRYPTOPP_NO_VTABLE TwoBases : public BASE1, public BASE2 +{ +}; + +//! _ +template +class CRYPTOPP_NO_VTABLE ThreeBases : public BASE1, public BASE2, public BASE3 +{ +}; + +template +class ObjectHolder +{ +protected: + T m_object; +}; + +class NotCopyable +{ +public: + NotCopyable() {} +private: + NotCopyable(const NotCopyable &); + void operator=(const NotCopyable &); +}; + +template +struct NewObject +{ + T* operator()() const {return new T;} +}; + +/*! This function safely initializes a static object in a multithreaded environment without using locks. + It may leak memory when two threads try to initialize the static object at the same time + but this should be acceptable since each static object is only initialized once per session. +*/ +template , int instance=0> +class Singleton +{ +public: + Singleton(F objectFactory = F()) : m_objectFactory(objectFactory) {} + + // prevent this function from being inlined + CRYPTOPP_NOINLINE const T & Ref(CRYPTOPP_NOINLINE_DOTDOTDOT) const; + +private: + F m_objectFactory; +}; + +template +const T & Singleton::Ref(CRYPTOPP_NOINLINE_DOTDOTDOT) const +{ + static simple_ptr s_pObject; + static char s_objectState = 0; + +retry: + switch (s_objectState) + { + case 0: + s_objectState = 1; + try + { + s_pObject.m_p = m_objectFactory(); + } + catch(...) + { + s_objectState = 0; + throw; + } + s_objectState = 2; + break; + case 1: + goto retry; + default: + break; + } + return *s_pObject.m_p; +} + +// ************** misc functions *************** + +#if (!__STDC_WANT_SECURE_LIB__) +inline void memcpy_s(void *dest, size_t sizeInBytes, const void *src, size_t count) +{ + if (count > sizeInBytes) + throw InvalidArgument("memcpy_s: buffer overflow"); + memcpy(dest, src, count); +} + +inline void memmove_s(void *dest, size_t sizeInBytes, const void *src, size_t count) +{ + if (count > sizeInBytes) + throw InvalidArgument("memmove_s: buffer overflow"); + memmove(dest, src, count); +} +#endif + +// can't use std::min or std::max in MSVC60 or Cygwin 1.1.0 +template inline const T& STDMIN(const T& a, const T& b) +{ + return b < a ? b : a; +} + +template inline const T1 UnsignedMin(const T1& a, const T2& b) +{ + CRYPTOPP_COMPILE_ASSERT((sizeof(T1)<=sizeof(T2) && T2(-1)>0) || (sizeof(T1)>sizeof(T2) && T1(-1)>0)); + assert(a==0 || a>0); // GCC workaround: get rid of the warning "comparison is always true due to limited range of data type" + assert(b>=0); + + if (sizeof(T1)<=sizeof(T2)) + return b < (T2)a ? (T1)b : a; + else + return (T1)b < a ? (T1)b : a; +} + +template inline const T& STDMAX(const T& a, const T& b) +{ + return a < b ? b : a; +} + +#define RETURN_IF_NONZERO(x) size_t returnedValue = x; if (returnedValue) return returnedValue + +// this version of the macro is fastest on Pentium 3 and Pentium 4 with MSVC 6 SP5 w/ Processor Pack +#define GETBYTE(x, y) (unsigned int)byte((x)>>(8*(y))) +// these may be faster on other CPUs/compilers +// #define GETBYTE(x, y) (unsigned int)(((x)>>(8*(y)))&255) +// #define GETBYTE(x, y) (((byte *)&(x))[y]) + +#define CRYPTOPP_GET_BYTE_AS_BYTE(x, y) byte((x)>>(8*(y))) + +template +unsigned int Parity(T value) +{ + for (unsigned int i=8*sizeof(value)/2; i>0; i/=2) + value ^= value >> i; + return (unsigned int)value&1; +} + +template +unsigned int BytePrecision(const T &value) +{ + if (!value) + return 0; + + unsigned int l=0, h=8*sizeof(value); + + while (h-l > 8) + { + unsigned int t = (l+h)/2; + if (value >> t) + l = t; + else + h = t; + } + + return h/8; +} + +template +unsigned int BitPrecision(const T &value) +{ + if (!value) + return 0; + + unsigned int l=0, h=8*sizeof(value); + + while (h-l > 1) + { + unsigned int t = (l+h)/2; + if (value >> t) + l = t; + else + h = t; + } + + return h; +} + +template +inline T Crop(T value, size_t size) +{ + if (size < 8*sizeof(value)) + return T(value & ((T(1) << size) - 1)); + else + return value; +} + +template +inline bool SafeConvert(T1 from, T2 &to) +{ + to = (T2)from; + if (from != to || (from > 0) != (to > 0)) + return false; + return true; +} + +inline size_t BitsToBytes(size_t bitCount) +{ + return ((bitCount+7)/(8)); +} + +inline size_t BytesToWords(size_t byteCount) +{ + return ((byteCount+WORD_SIZE-1)/WORD_SIZE); +} + +inline size_t BitsToWords(size_t bitCount) +{ + return ((bitCount+WORD_BITS-1)/(WORD_BITS)); +} + +inline size_t BitsToDwords(size_t bitCount) +{ + return ((bitCount+2*WORD_BITS-1)/(2*WORD_BITS)); +} + +CRYPTOPP_DLL void CRYPTOPP_API xorbuf(byte *buf, const byte *mask, size_t count); +CRYPTOPP_DLL void CRYPTOPP_API xorbuf(byte *output, const byte *input, const byte *mask, size_t count); + +template +inline bool IsPowerOf2(const T &n) +{ + return n > 0 && (n & (n-1)) == 0; +} + +template +inline T2 ModPowerOf2(const T1 &a, const T2 &b) +{ + assert(IsPowerOf2(b)); + return T2(a) & (b-1); +} + +template +inline T1 RoundDownToMultipleOf(const T1 &n, const T2 &m) +{ + if (IsPowerOf2(m)) + return n - ModPowerOf2(n, m); + else + return n - n%m; +} + +template +inline T1 RoundUpToMultipleOf(const T1 &n, const T2 &m) +{ + if (n+m-1 < n) + throw InvalidArgument("RoundUpToMultipleOf: integer overflow"); + return RoundDownToMultipleOf(n+m-1, m); +} + +template +inline unsigned int GetAlignmentOf(T *dummy=NULL) // VC60 workaround +{ +#if CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X86 + if (sizeof(T) < 16) + return 1; // alignment not needed on x86 and x64 +#endif + +#if (_MSC_VER >= 1300) + return __alignof(T); +#elif defined(__GNUC__) + return __alignof__(T); +#elif defined(CRYPTOPP_SLOW_WORD64) + return UnsignedMin(4U, sizeof(T)); +#else + return sizeof(T); +#endif +} + +inline bool IsAlignedOn(const void *p, unsigned int alignment) +{ + return alignment==1 || (IsPowerOf2(alignment) ? ModPowerOf2((size_t)p, alignment) == 0 : (size_t)p % alignment == 0); +} + +template +inline bool IsAligned(const void *p, T *dummy=NULL) // VC60 workaround +{ + return IsAlignedOn(p, GetAlignmentOf()); +} + +#ifdef IS_LITTLE_ENDIAN + typedef LittleEndian NativeByteOrder; +#else + typedef BigEndian NativeByteOrder; +#endif + +inline ByteOrder GetNativeByteOrder() +{ + return NativeByteOrder::ToEnum(); +} + +inline bool NativeByteOrderIs(ByteOrder order) +{ + return order == GetNativeByteOrder(); +} + +template +std::string IntToString(T a, unsigned int base = 10) +{ + if (a == 0) + return "0"; + bool negate = false; + if (a < 0) + { + negate = true; + a = 0-a; // VC .NET does not like -a + } + std::string result; + while (a > 0) + { + T digit = a % base; + result = char((digit < 10 ? '0' : ('a' - 10)) + digit) + result; + a /= base; + } + if (negate) + result = "-" + result; + return result; +} + +template +inline T1 SaturatingSubtract(const T1 &a, const T2 &b) +{ + return T1((a > b) ? (a - b) : 0); +} + +template +inline CipherDir GetCipherDir(const T &obj) +{ + return obj.IsForwardTransformation() ? ENCRYPTION : DECRYPTION; +} + +CRYPTOPP_DLL void CRYPTOPP_API CallNewHandler(); + +inline void IncrementCounterByOne(byte *inout, unsigned int s) +{ + for (int i=s-1, carry=1; i>=0 && carry; i--) + carry = !++inout[i]; +} + +inline void IncrementCounterByOne(byte *output, const byte *input, unsigned int s) +{ + int i, carry; + for (i=s-1, carry=1; i>=0 && carry; i--) + carry = ((output[i] = input[i]+1) == 0); + memcpy_s(output, s, input, i+1); +} + +// ************** rotate functions *************** + +template inline T rotlFixed(T x, unsigned int y) +{ + assert(y < sizeof(T)*8); + return T((x<>(sizeof(T)*8-y))); +} + +template inline T rotrFixed(T x, unsigned int y) +{ + assert(y < sizeof(T)*8); + return T((x>>y) | (x<<(sizeof(T)*8-y))); +} + +template inline T rotlVariable(T x, unsigned int y) +{ + assert(y < sizeof(T)*8); + return T((x<>(sizeof(T)*8-y))); +} + +template inline T rotrVariable(T x, unsigned int y) +{ + assert(y < sizeof(T)*8); + return T((x>>y) | (x<<(sizeof(T)*8-y))); +} + +template inline T rotlMod(T x, unsigned int y) +{ + y %= sizeof(T)*8; + return T((x<>(sizeof(T)*8-y))); +} + +template inline T rotrMod(T x, unsigned int y) +{ + y %= sizeof(T)*8; + return T((x>>y) | (x<<(sizeof(T)*8-y))); +} + +#ifdef _MSC_VER + +template<> inline word32 rotlFixed(word32 x, unsigned int y) +{ + assert(y < 8*sizeof(x)); + return y ? _lrotl(x, y) : x; +} + +template<> inline word32 rotrFixed(word32 x, unsigned int y) +{ + assert(y < 8*sizeof(x)); + return y ? _lrotr(x, y) : x; +} + +template<> inline word32 rotlVariable(word32 x, unsigned int y) +{ + assert(y < 8*sizeof(x)); + return _lrotl(x, y); +} + +template<> inline word32 rotrVariable(word32 x, unsigned int y) +{ + assert(y < 8*sizeof(x)); + return _lrotr(x, y); +} + +template<> inline word32 rotlMod(word32 x, unsigned int y) +{ + return _lrotl(x, y); +} + +template<> inline word32 rotrMod(word32 x, unsigned int y) +{ + return _lrotr(x, y); +} + +#endif // #ifdef _MSC_VER + +#if _MSC_VER >= 1300 && !defined(__INTEL_COMPILER) +// Intel C++ Compiler 10.0 calls a function instead of using the rotate instruction when using these instructions + +template<> inline word64 rotlFixed(word64 x, unsigned int y) +{ + assert(y < 8*sizeof(x)); + return y ? _rotl64(x, y) : x; +} + +template<> inline word64 rotrFixed(word64 x, unsigned int y) +{ + assert(y < 8*sizeof(x)); + return y ? _rotr64(x, y) : x; +} + +template<> inline word64 rotlVariable(word64 x, unsigned int y) +{ + assert(y < 8*sizeof(x)); + return _rotl64(x, y); +} + +template<> inline word64 rotrVariable(word64 x, unsigned int y) +{ + assert(y < 8*sizeof(x)); + return _rotr64(x, y); +} + +template<> inline word64 rotlMod(word64 x, unsigned int y) +{ + return _rotl64(x, y); +} + +template<> inline word64 rotrMod(word64 x, unsigned int y) +{ + return _rotr64(x, y); +} + +#endif // #if _MSC_VER >= 1310 + +#if _MSC_VER >= 1400 && !defined(__INTEL_COMPILER) +// Intel C++ Compiler 10.0 gives undefined externals with these + +template<> inline word16 rotlFixed(word16 x, unsigned int y) +{ + assert(y < 8*sizeof(x)); + return y ? _rotl16(x, y) : x; +} + +template<> inline word16 rotrFixed(word16 x, unsigned int y) +{ + assert(y < 8*sizeof(x)); + return y ? _rotr16(x, y) : x; +} + +template<> inline word16 rotlVariable(word16 x, unsigned int y) +{ + assert(y < 8*sizeof(x)); + return _rotl16(x, y); +} + +template<> inline word16 rotrVariable(word16 x, unsigned int y) +{ + assert(y < 8*sizeof(x)); + return _rotr16(x, y); +} + +template<> inline word16 rotlMod(word16 x, unsigned int y) +{ + return _rotl16(x, y); +} + +template<> inline word16 rotrMod(word16 x, unsigned int y) +{ + return _rotr16(x, y); +} + +template<> inline byte rotlFixed(byte x, unsigned int y) +{ + assert(y < 8*sizeof(x)); + return y ? _rotl8(x, y) : x; +} + +template<> inline byte rotrFixed(byte x, unsigned int y) +{ + assert(y < 8*sizeof(x)); + return y ? _rotr8(x, y) : x; +} + +template<> inline byte rotlVariable(byte x, unsigned int y) +{ + assert(y < 8*sizeof(x)); + return _rotl8(x, y); +} + +template<> inline byte rotrVariable(byte x, unsigned int y) +{ + assert(y < 8*sizeof(x)); + return _rotr8(x, y); +} + +template<> inline byte rotlMod(byte x, unsigned int y) +{ + return _rotl8(x, y); +} + +template<> inline byte rotrMod(byte x, unsigned int y) +{ + return _rotr8(x, y); +} + +#endif // #if _MSC_VER >= 1400 + +#if (defined(__MWERKS__) && TARGET_CPU_PPC) + +template<> inline word32 rotlFixed(word32 x, unsigned int y) +{ + assert(y < 32); + return y ? __rlwinm(x,y,0,31) : x; +} + +template<> inline word32 rotrFixed(word32 x, unsigned int y) +{ + assert(y < 32); + return y ? __rlwinm(x,32-y,0,31) : x; +} + +template<> inline word32 rotlVariable(word32 x, unsigned int y) +{ + assert(y < 32); + return (__rlwnm(x,y,0,31)); +} + +template<> inline word32 rotrVariable(word32 x, unsigned int y) +{ + assert(y < 32); + return (__rlwnm(x,32-y,0,31)); +} + +template<> inline word32 rotlMod(word32 x, unsigned int y) +{ + return (__rlwnm(x,y,0,31)); +} + +template<> inline word32 rotrMod(word32 x, unsigned int y) +{ + return (__rlwnm(x,32-y,0,31)); +} + +#endif // #if (defined(__MWERKS__) && TARGET_CPU_PPC) + +// ************** endian reversal *************** + +template +inline unsigned int GetByte(ByteOrder order, T value, unsigned int index) +{ + if (order == LITTLE_ENDIAN_ORDER) + return GETBYTE(value, index); + else + return GETBYTE(value, sizeof(T)-index-1); +} + +inline byte ByteReverse(byte value) +{ + return value; +} + +inline word16 ByteReverse(word16 value) +{ +#ifdef CRYPTOPP_BYTESWAP_AVAILABLE + return bswap_16(value); +#elif defined(_MSC_VER) && _MSC_VER >= 1300 + return _byteswap_ushort(value); +#else + return rotlFixed(value, 8U); +#endif +} + +inline word32 ByteReverse(word32 value) +{ +#if defined(__GNUC__) && defined(CRYPTOPP_X86_ASM_AVAILABLE) + __asm__ ("bswap %0" : "=r" (value) : "0" (value)); + return value; +#elif defined(CRYPTOPP_BYTESWAP_AVAILABLE) + return bswap_32(value); +#elif defined(__MWERKS__) && TARGET_CPU_PPC + return (word32)__lwbrx(&value,0); +#elif _MSC_VER >= 1400 || (_MSC_VER >= 1300 && !defined(_DLL)) + return _byteswap_ulong(value); +#elif CRYPTOPP_FAST_ROTATE(32) + // 5 instructions with rotate instruction, 9 without + return (rotrFixed(value, 8U) & 0xff00ff00) | (rotlFixed(value, 8U) & 0x00ff00ff); +#else + // 6 instructions with rotate instruction, 8 without + value = ((value & 0xFF00FF00) >> 8) | ((value & 0x00FF00FF) << 8); + return rotlFixed(value, 16U); +#endif +} + +#ifdef WORD64_AVAILABLE +inline word64 ByteReverse(word64 value) +{ +#if defined(__GNUC__) && defined(CRYPTOPP_X86_ASM_AVAILABLE) && defined(__x86_64__) + __asm__ ("bswap %0" : "=r" (value) : "0" (value)); + return value; +#elif defined(CRYPTOPP_BYTESWAP_AVAILABLE) + return bswap_64(value); +#elif defined(_MSC_VER) && _MSC_VER >= 1300 + return _byteswap_uint64(value); +#elif defined(CRYPTOPP_SLOW_WORD64) + return (word64(ByteReverse(word32(value))) << 32) | ByteReverse(word32(value>>32)); +#else + value = ((value & W64LIT(0xFF00FF00FF00FF00)) >> 8) | ((value & W64LIT(0x00FF00FF00FF00FF)) << 8); + value = ((value & W64LIT(0xFFFF0000FFFF0000)) >> 16) | ((value & W64LIT(0x0000FFFF0000FFFF)) << 16); + return rotlFixed(value, 32U); +#endif +} +#endif + +inline byte BitReverse(byte value) +{ + value = ((value & 0xAA) >> 1) | ((value & 0x55) << 1); + value = ((value & 0xCC) >> 2) | ((value & 0x33) << 2); + return rotlFixed(value, 4U); +} + +inline word16 BitReverse(word16 value) +{ + value = ((value & 0xAAAA) >> 1) | ((value & 0x5555) << 1); + value = ((value & 0xCCCC) >> 2) | ((value & 0x3333) << 2); + value = ((value & 0xF0F0) >> 4) | ((value & 0x0F0F) << 4); + return ByteReverse(value); +} + +inline word32 BitReverse(word32 value) +{ + value = ((value & 0xAAAAAAAA) >> 1) | ((value & 0x55555555) << 1); + value = ((value & 0xCCCCCCCC) >> 2) | ((value & 0x33333333) << 2); + value = ((value & 0xF0F0F0F0) >> 4) | ((value & 0x0F0F0F0F) << 4); + return ByteReverse(value); +} + +#ifdef WORD64_AVAILABLE +inline word64 BitReverse(word64 value) +{ +#ifdef CRYPTOPP_SLOW_WORD64 + return (word64(BitReverse(word32(value))) << 32) | BitReverse(word32(value>>32)); +#else + value = ((value & W64LIT(0xAAAAAAAAAAAAAAAA)) >> 1) | ((value & W64LIT(0x5555555555555555)) << 1); + value = ((value & W64LIT(0xCCCCCCCCCCCCCCCC)) >> 2) | ((value & W64LIT(0x3333333333333333)) << 2); + value = ((value & W64LIT(0xF0F0F0F0F0F0F0F0)) >> 4) | ((value & W64LIT(0x0F0F0F0F0F0F0F0F)) << 4); + return ByteReverse(value); +#endif +} +#endif + +template +inline T BitReverse(T value) +{ + if (sizeof(T) == 1) + return (T)BitReverse((byte)value); + else if (sizeof(T) == 2) + return (T)BitReverse((word16)value); + else if (sizeof(T) == 4) + return (T)BitReverse((word32)value); + else + { +#ifdef WORD64_AVAILABLE + assert(sizeof(T) == 8); + return (T)BitReverse((word64)value); +#else + assert(false); + return 0; +#endif + } +} + +template +inline T ConditionalByteReverse(ByteOrder order, T value) +{ + return NativeByteOrderIs(order) ? value : ByteReverse(value); +} + +template +void ByteReverse(T *out, const T *in, size_t byteCount) +{ + assert(byteCount % sizeof(T) == 0); + size_t count = byteCount/sizeof(T); + for (size_t i=0; i +inline void ConditionalByteReverse(ByteOrder order, T *out, const T *in, size_t byteCount) +{ + if (!NativeByteOrderIs(order)) + ByteReverse(out, in, byteCount); + else if (in != out) + memcpy_s(out, byteCount, in, byteCount); +} + +template +inline void GetUserKey(ByteOrder order, T *out, size_t outlen, const byte *in, size_t inlen) +{ + const size_t U = sizeof(T); + assert(inlen <= outlen*U); + memcpy(out, in, inlen); + memset((byte *)out+inlen, 0, outlen*U-inlen); + ConditionalByteReverse(order, out, out, RoundUpToMultipleOf(inlen, U)); +} + +#ifndef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS +inline byte UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, const byte *) +{ + return block[0]; +} + +inline word16 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, const word16 *) +{ + return (order == BIG_ENDIAN_ORDER) + ? block[1] | (block[0] << 8) + : block[0] | (block[1] << 8); +} + +inline word32 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, const word32 *) +{ + return (order == BIG_ENDIAN_ORDER) + ? word32(block[3]) | (word32(block[2]) << 8) | (word32(block[1]) << 16) | (word32(block[0]) << 24) + : word32(block[0]) | (word32(block[1]) << 8) | (word32(block[2]) << 16) | (word32(block[3]) << 24); +} + +#ifdef WORD64_AVAILABLE +inline word64 UnalignedGetWordNonTemplate(ByteOrder order, const byte *block, const word64 *) +{ + return (order == BIG_ENDIAN_ORDER) + ? + (word64(block[7]) | + (word64(block[6]) << 8) | + (word64(block[5]) << 16) | + (word64(block[4]) << 24) | + (word64(block[3]) << 32) | + (word64(block[2]) << 40) | + (word64(block[1]) << 48) | + (word64(block[0]) << 56)) + : + (word64(block[0]) | + (word64(block[1]) << 8) | + (word64(block[2]) << 16) | + (word64(block[3]) << 24) | + (word64(block[4]) << 32) | + (word64(block[5]) << 40) | + (word64(block[6]) << 48) | + (word64(block[7]) << 56)); +} +#endif + +inline void UnalignedPutWordNonTemplate(ByteOrder order, byte *block, byte value, const byte *xorBlock) +{ + block[0] = xorBlock ? (value ^ xorBlock[0]) : value; +} + +inline void UnalignedPutWordNonTemplate(ByteOrder order, byte *block, word16 value, const byte *xorBlock) +{ + if (order == BIG_ENDIAN_ORDER) + { + if (xorBlock) + { + block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); + block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); + } + else + { + block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); + block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); + } + } + else + { + if (xorBlock) + { + block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); + block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); + } + else + { + block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); + block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); + } + } +} + +inline void UnalignedPutWordNonTemplate(ByteOrder order, byte *block, word32 value, const byte *xorBlock) +{ + if (order == BIG_ENDIAN_ORDER) + { + if (xorBlock) + { + block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 3); + block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 2); + block[2] = xorBlock[2] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); + block[3] = xorBlock[3] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); + } + else + { + block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 3); + block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 2); + block[2] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); + block[3] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); + } + } + else + { + if (xorBlock) + { + block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); + block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); + block[2] = xorBlock[2] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 2); + block[3] = xorBlock[3] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 3); + } + else + { + block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); + block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); + block[2] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 2); + block[3] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 3); + } + } +} + +#ifdef WORD64_AVAILABLE +inline void UnalignedPutWordNonTemplate(ByteOrder order, byte *block, word64 value, const byte *xorBlock) +{ + if (order == BIG_ENDIAN_ORDER) + { + if (xorBlock) + { + block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 7); + block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 6); + block[2] = xorBlock[2] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 5); + block[3] = xorBlock[3] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 4); + block[4] = xorBlock[4] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 3); + block[5] = xorBlock[5] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 2); + block[6] = xorBlock[6] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); + block[7] = xorBlock[7] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); + } + else + { + block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 7); + block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 6); + block[2] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 5); + block[3] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 4); + block[4] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 3); + block[5] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 2); + block[6] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); + block[7] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); + } + } + else + { + if (xorBlock) + { + block[0] = xorBlock[0] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); + block[1] = xorBlock[1] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); + block[2] = xorBlock[2] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 2); + block[3] = xorBlock[3] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 3); + block[4] = xorBlock[4] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 4); + block[5] = xorBlock[5] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 5); + block[6] = xorBlock[6] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 6); + block[7] = xorBlock[7] ^ CRYPTOPP_GET_BYTE_AS_BYTE(value, 7); + } + else + { + block[0] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 0); + block[1] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 1); + block[2] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 2); + block[3] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 3); + block[4] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 4); + block[5] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 5); + block[6] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 6); + block[7] = CRYPTOPP_GET_BYTE_AS_BYTE(value, 7); + } + } +} +#endif +#endif // #ifndef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS + +template +inline T GetWord(bool assumeAligned, ByteOrder order, const byte *block) +{ +#ifndef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS + if (!assumeAligned) + return UnalignedGetWordNonTemplate(order, block, (T*)NULL); + assert(IsAligned(block)); +#endif + return ConditionalByteReverse(order, *reinterpret_cast(block)); +} + +template +inline void GetWord(bool assumeAligned, ByteOrder order, T &result, const byte *block) +{ + result = GetWord(assumeAligned, order, block); +} + +template +inline void PutWord(bool assumeAligned, ByteOrder order, byte *block, T value, const byte *xorBlock = NULL) +{ +#ifndef CRYPTOPP_ALLOW_UNALIGNED_DATA_ACCESS + if (!assumeAligned) + return UnalignedPutWordNonTemplate(order, block, value, xorBlock); + assert(IsAligned(block)); + assert(IsAligned(xorBlock)); +#endif + *reinterpret_cast(block) = ConditionalByteReverse(order, value) ^ (xorBlock ? *reinterpret_cast(xorBlock) : 0); +} + +template +class GetBlock +{ +public: + GetBlock(const void *block) + : m_block((const byte *)block) {} + + template + inline GetBlock & operator()(U &x) + { + CRYPTOPP_COMPILE_ASSERT(sizeof(U) >= sizeof(T)); + x = GetWord(A, B::ToEnum(), m_block); + m_block += sizeof(T); + return *this; + } + +private: + const byte *m_block; +}; + +template +class PutBlock +{ +public: + PutBlock(const void *xorBlock, void *block) + : m_xorBlock((const byte *)xorBlock), m_block((byte *)block) {} + + template + inline PutBlock & operator()(U x) + { + PutWord(A, B::ToEnum(), m_block, (T)x, m_xorBlock); + m_block += sizeof(T); + if (m_xorBlock) + m_xorBlock += sizeof(T); + return *this; + } + +private: + const byte *m_xorBlock; + byte *m_block; +}; + +template +struct BlockGetAndPut +{ + // function needed because of C++ grammatical ambiguity between expression-statements and declarations + static inline GetBlock Get(const void *block) {return GetBlock(block);} + typedef PutBlock Put; +}; + +template +std::string WordToString(T value, ByteOrder order = BIG_ENDIAN_ORDER) +{ + if (!NativeByteOrderIs(order)) + value = ByteReverse(value); + + return std::string((char *)&value, sizeof(value)); +} + +template +T StringToWord(const std::string &str, ByteOrder order = BIG_ENDIAN_ORDER) +{ + T value = 0; + memcpy_s(&value, sizeof(value), str.data(), UnsignedMin(str.size(), sizeof(value))); + return NativeByteOrderIs(order) ? value : ByteReverse(value); +} + +// ************** help remove warning on g++ *************** + +template struct SafeShifter; + +template<> struct SafeShifter +{ + template + static inline T RightShift(T value, unsigned int bits) + { + return 0; + } + + template + static inline T LeftShift(T value, unsigned int bits) + { + return 0; + } +}; + +template<> struct SafeShifter +{ + template + static inline T RightShift(T value, unsigned int bits) + { + return value >> bits; + } + + template + static inline T LeftShift(T value, unsigned int bits) + { + return value << bits; + } +}; + +template +inline T SafeRightShift(T value) +{ + return SafeShifter<(bits>=(8*sizeof(T)))>::RightShift(value, bits); +} + +template +inline T SafeLeftShift(T value) +{ + return SafeShifter<(bits>=(8*sizeof(T)))>::LeftShift(value, bits); +} + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/modarith.h b/CryptoPP/crypto/modarith.h new file mode 100644 index 0000000..7decb62 --- /dev/null +++ b/CryptoPP/crypto/modarith.h @@ -0,0 +1,158 @@ +#ifndef CRYPTOPP_MODARITH_H +#define CRYPTOPP_MODARITH_H + +// implementations are in integer.cpp + +#include "cryptlib.h" +#include "misc.h" +#include "integer.h" +#include "algebra.h" + +NAMESPACE_BEGIN(CryptoPP) + +CRYPTOPP_DLL_TEMPLATE_CLASS AbstractGroup; +CRYPTOPP_DLL_TEMPLATE_CLASS AbstractRing; +CRYPTOPP_DLL_TEMPLATE_CLASS AbstractEuclideanDomain; + +//! ring of congruence classes modulo n +/*! \note this implementation represents each congruence class as the smallest non-negative integer in that class */ +class CRYPTOPP_DLL ModularArithmetic : public AbstractRing +{ +public: + + typedef int RandomizationParameter; + typedef Integer Element; + + ModularArithmetic(const Integer &modulus = Integer::One()) + : m_modulus(modulus), m_result((word)0, modulus.reg.size()) {} + + ModularArithmetic(const ModularArithmetic &ma) + : m_modulus(ma.m_modulus), m_result((word)0, m_modulus.reg.size()) {} + + ModularArithmetic(BufferedTransformation &bt); // construct from BER encoded parameters + + virtual ModularArithmetic * Clone() const {return new ModularArithmetic(*this);} + + void DEREncode(BufferedTransformation &bt) const; + + void DEREncodeElement(BufferedTransformation &out, const Element &a) const; + void BERDecodeElement(BufferedTransformation &in, Element &a) const; + + const Integer& GetModulus() const {return m_modulus;} + void SetModulus(const Integer &newModulus) {m_modulus = newModulus; m_result.reg.resize(m_modulus.reg.size());} + + virtual bool IsMontgomeryRepresentation() const {return false;} + + virtual Integer ConvertIn(const Integer &a) const + {return a%m_modulus;} + + virtual Integer ConvertOut(const Integer &a) const + {return a;} + + const Integer& Half(const Integer &a) const; + + bool Equal(const Integer &a, const Integer &b) const + {return a==b;} + + const Integer& Identity() const + {return Integer::Zero();} + + const Integer& Add(const Integer &a, const Integer &b) const; + + Integer& Accumulate(Integer &a, const Integer &b) const; + + const Integer& Inverse(const Integer &a) const; + + const Integer& Subtract(const Integer &a, const Integer &b) const; + + Integer& Reduce(Integer &a, const Integer &b) const; + + const Integer& Double(const Integer &a) const + {return Add(a, a);} + + const Integer& MultiplicativeIdentity() const + {return Integer::One();} + + const Integer& Multiply(const Integer &a, const Integer &b) const + {return m_result1 = a*b%m_modulus;} + + const Integer& Square(const Integer &a) const + {return m_result1 = a.Squared()%m_modulus;} + + bool IsUnit(const Integer &a) const + {return Integer::Gcd(a, m_modulus).IsUnit();} + + const Integer& MultiplicativeInverse(const Integer &a) const + {return m_result1 = a.InverseMod(m_modulus);} + + const Integer& Divide(const Integer &a, const Integer &b) const + {return Multiply(a, MultiplicativeInverse(b));} + + Integer CascadeExponentiate(const Integer &x, const Integer &e1, const Integer &y, const Integer &e2) const; + + void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const; + + unsigned int MaxElementBitLength() const + {return (m_modulus-1).BitCount();} + + unsigned int MaxElementByteLength() const + {return (m_modulus-1).ByteCount();} + + Element RandomElement( RandomNumberGenerator &rng , const RandomizationParameter &ignore_for_now = 0 ) const + // left RandomizationParameter arg as ref in case RandomizationParameter becomes a more complicated struct + { + return Element( rng , Integer( (long) 0) , m_modulus - Integer( (long) 1 ) ) ; + } + + bool operator==(const ModularArithmetic &rhs) const + {return m_modulus == rhs.m_modulus;} + + static const RandomizationParameter DefaultRandomizationParameter ; + +protected: + Integer m_modulus; + mutable Integer m_result, m_result1; + +}; + +// const ModularArithmetic::RandomizationParameter ModularArithmetic::DefaultRandomizationParameter = 0 ; + +//! do modular arithmetics in Montgomery representation for increased speed +/*! \note the Montgomery representation represents each congruence class [a] as a*r%n, where r is a convenient power of 2 */ +class CRYPTOPP_DLL MontgomeryRepresentation : public ModularArithmetic +{ +public: + MontgomeryRepresentation(const Integer &modulus); // modulus must be odd + + virtual ModularArithmetic * Clone() const {return new MontgomeryRepresentation(*this);} + + bool IsMontgomeryRepresentation() const {return true;} + + Integer ConvertIn(const Integer &a) const + {return (a<<(WORD_BITS*m_modulus.reg.size()))%m_modulus;} + + Integer ConvertOut(const Integer &a) const; + + const Integer& MultiplicativeIdentity() const + {return m_result1 = Integer::Power2(WORD_BITS*m_modulus.reg.size())%m_modulus;} + + const Integer& Multiply(const Integer &a, const Integer &b) const; + + const Integer& Square(const Integer &a) const; + + const Integer& MultiplicativeInverse(const Integer &a) const; + + Integer CascadeExponentiate(const Integer &x, const Integer &e1, const Integer &y, const Integer &e2) const + {return AbstractRing::CascadeExponentiate(x, e1, y, e2);} + + void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const + {AbstractRing::SimultaneousExponentiate(results, base, exponents, exponentsCount);} + +private: + Integer m_u; + mutable IntegerSecBlock m_workspace; +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/modes.cpp b/CryptoPP/crypto/modes.cpp new file mode 100644 index 0000000..21bcc4c --- /dev/null +++ b/CryptoPP/crypto/modes.cpp @@ -0,0 +1,209 @@ +// modes.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "modes.h" + +#ifndef NDEBUG +#include "des.h" +#endif + +NAMESPACE_BEGIN(CryptoPP) + +#ifndef NDEBUG +void Modes_TestInstantiations() +{ + CFB_Mode::Encryption m0; + CFB_Mode::Decryption m1; + OFB_Mode::Encryption m2; + CTR_Mode::Encryption m3; + ECB_Mode::Encryption m4; + CBC_Mode::Encryption m5; +} +#endif + +void CTR_ModePolicy::SeekToIteration(lword iterationCount) +{ + int carry=0; + for (int i=BlockSize()-1; i>=0; i--) + { + unsigned int sum = m_register[i] + byte(iterationCount) + carry; + m_counterArray[i] = (byte) sum; + carry = sum >> 8; + iterationCount >>= 8; + } +} + +inline void CTR_ModePolicy::ProcessMultipleBlocks(byte *output, const byte *input, size_t n) +{ + unsigned int s = BlockSize(), j = 0; + for (unsigned int i=1; iProcessAndXorMultipleBlocks(m_counterArray, input, output, n); + IncrementCounterByOne(m_counterArray, m_counterArray + s*(n-1), s); +} + +void CTR_ModePolicy::OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount) +{ + assert(m_cipher->IsForwardTransformation()); // CTR mode needs the "encrypt" direction of the underlying block cipher, even to decrypt + unsigned int maxBlocks = m_cipher->OptimalNumberOfParallelBlocks(); + if (maxBlocks == 1) + { + unsigned int sizeIncrement = BlockSize(); + while (iterationCount) + { + m_cipher->ProcessAndXorBlock(m_counterArray, input, output); + IncrementCounterByOne(m_counterArray, sizeIncrement); + output += sizeIncrement; + input += sizeIncrement; + iterationCount -= 1; + } + } + else + { + unsigned int sizeIncrement = maxBlocks * BlockSize(); + while (iterationCount >= maxBlocks) + { + ProcessMultipleBlocks(output, input, maxBlocks); + output += sizeIncrement; + input += sizeIncrement; + iterationCount -= maxBlocks; + } + if (iterationCount > 0) + ProcessMultipleBlocks(output, input, iterationCount); + } +} + +void CTR_ModePolicy::CipherResynchronize(byte *keystreamBuffer, const byte *iv) +{ + unsigned int s = BlockSize(); + CopyOrZero(m_register, iv, s); + m_counterArray.New(s * m_cipher->OptimalNumberOfParallelBlocks()); + CopyOrZero(m_counterArray, iv, s); +} + +void BlockOrientedCipherModeBase::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms) +{ + m_cipher->SetKey(key, length, params); + ResizeBuffers(); + if (IsResynchronizable()) + Resynchronize(GetIVAndThrowIfInvalid(params)); +} + +void BlockOrientedCipherModeBase::ProcessData(byte *outString, const byte *inString, size_t length) +{ + if (!length) + return; + + unsigned int s = BlockSize(); + assert(length % s == 0); + + if (!RequireAlignedInput() || IsAlignedOn(inString, m_cipher->BlockAlignment())) + ProcessBlocks(outString, inString, length / s); + else + { + do + { + memcpy(m_buffer, inString, s); + ProcessBlocks(outString, m_buffer, 1); + inString += s; + outString += s; + length -= s; + } while (length > 0); + } +} + +void CBC_Encryption::ProcessBlocks(byte *outString, const byte *inString, size_t numberOfBlocks) +{ + unsigned int blockSize = BlockSize(); + xorbuf(m_register, inString, blockSize); + while (--numberOfBlocks) + { + m_cipher->ProcessBlock(m_register, outString); + inString += blockSize; + xorbuf(m_register, inString, outString, blockSize); + outString += blockSize; + } + m_cipher->ProcessBlock(m_register); + memcpy(outString, m_register, blockSize); +} + +void CBC_CTS_Encryption::ProcessLastBlock(byte *outString, const byte *inString, size_t length) +{ + if (length <= BlockSize()) + { + if (!m_stolenIV) + throw InvalidArgument("CBC_Encryption: message is too short for ciphertext stealing"); + + // steal from IV + memcpy(outString, m_register, length); + outString = m_stolenIV; + } + else + { + // steal from next to last block + xorbuf(m_register, inString, BlockSize()); + m_cipher->ProcessBlock(m_register); + inString += BlockSize(); + length -= BlockSize(); + memcpy(outString+BlockSize(), m_register, length); + } + + // output last full ciphertext block + xorbuf(m_register, inString, length); + m_cipher->ProcessBlock(m_register); + memcpy(outString, m_register, BlockSize()); +} + +void CBC_Decryption::ProcessBlocks(byte *outString, const byte *inString, size_t numberOfBlocks) +{ + unsigned int blockSize = BlockSize(); + do + { + memcpy(m_temp, inString, blockSize); // make copy in case we're doing in place decryption + m_cipher->ProcessAndXorBlock(m_temp, m_register, outString); + m_register.swap(m_temp); + inString += blockSize; + outString += blockSize; + } while (--numberOfBlocks); +} + +void CBC_CTS_Decryption::ProcessLastBlock(byte *outString, const byte *inString, size_t length) +{ + const byte *pn, *pn1; + bool stealIV = length <= BlockSize(); + + if (stealIV) + { + pn = inString; + pn1 = m_register; + } + else + { + pn = inString + BlockSize(); + pn1 = inString; + length -= BlockSize(); + } + + // decrypt last partial plaintext block + memcpy(m_temp, pn1, BlockSize()); + m_cipher->ProcessBlock(m_temp); + xorbuf(m_temp, pn, length); + + if (stealIV) + memcpy(outString, m_temp, length); + else + { + memcpy(outString+BlockSize(), m_temp, length); + // decrypt next to last plaintext block + memcpy(m_temp, pn, length); + m_cipher->ProcessBlock(m_temp); + xorbuf(outString, m_temp, m_register, BlockSize()); + } +} + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/modes.h b/CryptoPP/crypto/modes.h new file mode 100644 index 0000000..1a5f5ec --- /dev/null +++ b/CryptoPP/crypto/modes.h @@ -0,0 +1,451 @@ +#ifndef CRYPTOPP_MODES_H +#define CRYPTOPP_MODES_H + +/*! \file +*/ + +#include "cryptlib.h" +#include "secblock.h" +#include "misc.h" +#include "strciphr.h" +#include "argnames.h" +#include "algparam.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! Cipher mode documentation. See NIST SP 800-38A for definitions of these modes. + +/*! Each class derived from this one defines two types, Encryption and Decryption, + both of which implement the SymmetricCipher interface. + For each mode there are two classes, one of which is a template class, + and the other one has a name that ends in "_ExternalCipher". + The "external cipher" mode objects hold a reference to the underlying block cipher, + instead of holding an instance of it. The reference must be passed in to the constructor. + For the "cipher holder" classes, the CIPHER template parameter should be a class + derived from BlockCipherDocumentation, for example DES or AES. +*/ +struct CipherModeDocumentation : public SymmetricCipherDocumentation +{ +}; + +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CipherModeBase : public SymmetricCipher +{ +public: + size_t MinKeyLength() const {return m_cipher->MinKeyLength();} + size_t MaxKeyLength() const {return m_cipher->MaxKeyLength();} + size_t DefaultKeyLength() const {return m_cipher->DefaultKeyLength();} + size_t GetValidKeyLength(size_t n) const {return m_cipher->GetValidKeyLength(n);} + bool IsValidKeyLength(size_t n) const {return m_cipher->IsValidKeyLength(n);} + + unsigned int OptimalDataAlignment() const {return BlockSize();} + + unsigned int IVSize() const {return BlockSize();} + virtual IV_Requirement IVRequirement() const =0; + +protected: + inline unsigned int BlockSize() const {assert(m_register.size() > 0); return (unsigned int)m_register.size();} + virtual void SetFeedbackSize(unsigned int feedbackSize) + { + if (!(feedbackSize == 0 || feedbackSize == BlockSize())) + throw InvalidArgument("CipherModeBase: feedback size cannot be specified for this cipher mode"); + } + virtual void ResizeBuffers() + { + m_register.New(m_cipher->BlockSize()); + } + + BlockCipher *m_cipher; + SecByteBlock m_register; +}; + +template +class CRYPTOPP_NO_VTABLE ModePolicyCommonTemplate : public CipherModeBase, public POLICY_INTERFACE +{ + unsigned int GetAlignment() const {return m_cipher->BlockAlignment();} + void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length); +}; + +template +void ModePolicyCommonTemplate::CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length) +{ + m_cipher->SetKey(key, length, params); + ResizeBuffers(); + int feedbackSize = params.GetIntValueWithDefault(Name::FeedbackSize(), 0); + SetFeedbackSize(feedbackSize); +} + +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CFB_ModePolicy : public ModePolicyCommonTemplate +{ +public: + IV_Requirement IVRequirement() const {return RANDOM_IV;} + static const char * CRYPTOPP_API StaticAlgorithmName() {return "CFB";} + +protected: + unsigned int GetBytesPerIteration() const {return m_feedbackSize;} + byte * GetRegisterBegin() {return m_register + BlockSize() - m_feedbackSize;} + void TransformRegister() + { + assert(m_cipher->IsForwardTransformation()); // CFB mode needs the "encrypt" direction of the underlying block cipher, even to decrypt + m_cipher->ProcessBlock(m_register, m_temp); + unsigned int updateSize = BlockSize()-m_feedbackSize; + memmove_s(m_register, m_register.size(), m_register+m_feedbackSize, updateSize); + memcpy_s(m_register+updateSize, m_register.size()-updateSize, m_temp, m_feedbackSize); + } + void CipherResynchronize(const byte *iv) + { + memcpy_s(m_register, m_register.size(), iv, BlockSize()); + TransformRegister(); + } + void SetFeedbackSize(unsigned int feedbackSize) + { + if (feedbackSize > BlockSize()) + throw InvalidArgument("CFB_Mode: invalid feedback size"); + m_feedbackSize = feedbackSize ? feedbackSize : BlockSize(); + } + void ResizeBuffers() + { + CipherModeBase::ResizeBuffers(); + m_temp.New(BlockSize()); + } + + SecByteBlock m_temp; + unsigned int m_feedbackSize; +}; + +inline void CopyOrZero(void *dest, const void *src, size_t s) +{ + if (src) + memcpy_s(dest, s, src, s); + else + memset(dest, 0, s); +} + +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE OFB_ModePolicy : public ModePolicyCommonTemplate +{ +public: + bool IsRandomAccess() const {return false;} + IV_Requirement IVRequirement() const {return UNIQUE_IV;} + static const char * CRYPTOPP_API StaticAlgorithmName() {return "OFB";} + +private: + unsigned int GetBytesPerIteration() const {return BlockSize();} + unsigned int GetIterationsToBuffer() const {return 1;} + void WriteKeystream(byte *keystreamBuffer, size_t iterationCount) + { + assert(iterationCount == 1); + assert(m_cipher->IsForwardTransformation()); // OFB mode needs the "encrypt" direction of the underlying block cipher, even to decrypt + m_cipher->ProcessBlock(keystreamBuffer); + } + void CipherResynchronize(byte *keystreamBuffer, const byte *iv) + { + CopyOrZero(keystreamBuffer, iv, BlockSize()); + } +}; + +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CTR_ModePolicy : public ModePolicyCommonTemplate +{ +public: + bool IsRandomAccess() const {return true;} + IV_Requirement IVRequirement() const {return UNIQUE_IV;} + static const char * CRYPTOPP_API StaticAlgorithmName() {return "CTR";} + +private: + unsigned int GetAlignment() const {return m_cipher->BlockAlignment();} + unsigned int GetBytesPerIteration() const {return BlockSize();} + unsigned int GetIterationsToBuffer() const {return m_cipher->OptimalNumberOfParallelBlocks();} + void WriteKeystream(byte *buffer, size_t iterationCount) + {OperateKeystream(WRITE_KEYSTREAM, buffer, NULL, iterationCount);} + bool CanOperateKeystream() const {return true;} + void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount); + void CipherResynchronize(byte *keystreamBuffer, const byte *iv); + void SeekToIteration(lword iterationCount); + + inline void ProcessMultipleBlocks(byte *output, const byte *input, size_t n); + + SecByteBlock m_counterArray; +}; + +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE BlockOrientedCipherModeBase : public CipherModeBase +{ +public: + void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms); + unsigned int MandatoryBlockSize() const {return BlockSize();} + bool IsRandomAccess() const {return false;} + bool IsSelfInverting() const {return false;} + bool IsForwardTransformation() const {return m_cipher->IsForwardTransformation();} + void Resynchronize(const byte *iv) {memcpy_s(m_register, m_register.size(), iv, BlockSize());} + void ProcessData(byte *outString, const byte *inString, size_t length); + +protected: + bool RequireAlignedInput() const {return true;} + virtual void ProcessBlocks(byte *outString, const byte *inString, size_t numberOfBlocks) =0; + void ResizeBuffers() + { + CipherModeBase::ResizeBuffers(); + m_buffer.New(BlockSize()); + } + + SecByteBlock m_buffer; +}; + +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE ECB_OneWay : public BlockOrientedCipherModeBase +{ +public: + void SetKey(const byte *key, size_t length, const NameValuePairs ¶ms = g_nullNameValuePairs) + {m_cipher->SetKey(key, length, params); BlockOrientedCipherModeBase::ResizeBuffers();} + IV_Requirement IVRequirement() const {return NOT_RESYNCHRONIZABLE;} + unsigned int OptimalBlockSize() const {return BlockSize() * m_cipher->OptimalNumberOfParallelBlocks();} + void ProcessBlocks(byte *outString, const byte *inString, size_t numberOfBlocks) + {m_cipher->ProcessAndXorMultipleBlocks(inString, NULL, outString, numberOfBlocks);} + static const char * CRYPTOPP_API StaticAlgorithmName() {return "ECB";} +}; + +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CBC_ModeBase : public BlockOrientedCipherModeBase +{ +public: + IV_Requirement IVRequirement() const {return UNPREDICTABLE_RANDOM_IV;} + bool RequireAlignedInput() const {return false;} + unsigned int MinLastBlockSize() const {return 0;} + static const char * CRYPTOPP_API StaticAlgorithmName() {return "CBC";} +}; + +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CBC_Encryption : public CBC_ModeBase +{ +public: + void ProcessBlocks(byte *outString, const byte *inString, size_t numberOfBlocks); +}; + +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CBC_CTS_Encryption : public CBC_Encryption +{ +public: + void SetStolenIV(byte *iv) {m_stolenIV = iv;} + unsigned int MinLastBlockSize() const {return BlockSize()+1;} + void ProcessLastBlock(byte *outString, const byte *inString, size_t length); + static const char * CRYPTOPP_API StaticAlgorithmName() {return "CBC/CTS";} + +protected: + void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms) + { + CBC_Encryption::UncheckedSetKey(key, length, params); + m_stolenIV = params.GetValueWithDefault(Name::StolenIV(), (byte *)NULL); + } + + byte *m_stolenIV; +}; + +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CBC_Decryption : public CBC_ModeBase +{ +public: + void ProcessBlocks(byte *outString, const byte *inString, size_t numberOfBlocks); + +protected: + void ResizeBuffers() + { + BlockOrientedCipherModeBase::ResizeBuffers(); + m_temp.New(BlockSize()); + } + SecByteBlock m_temp; +}; + +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CBC_CTS_Decryption : public CBC_Decryption +{ +public: + unsigned int MinLastBlockSize() const {return BlockSize()+1;} + void ProcessLastBlock(byte *outString, const byte *inString, size_t length); +}; + +//! _ +template +class CipherModeFinalTemplate_CipherHolder : protected ObjectHolder, public AlgorithmImpl > +{ +public: + CipherModeFinalTemplate_CipherHolder() + { + this->m_cipher = &this->m_object; + this->ResizeBuffers(); + } + CipherModeFinalTemplate_CipherHolder(const byte *key, size_t length) + { + this->m_cipher = &this->m_object; + this->SetKey(key, length); + } + CipherModeFinalTemplate_CipherHolder(const byte *key, size_t length, const byte *iv) + { + this->m_cipher = &this->m_object; + this->SetKey(key, length, MakeParameters(Name::IV(), iv)); + } + CipherModeFinalTemplate_CipherHolder(const byte *key, size_t length, const byte *iv, int feedbackSize) + { + this->m_cipher = &this->m_object; + this->SetKey(key, length, MakeParameters(Name::IV(), iv)(Name::FeedbackSize(), feedbackSize)); + } + + static std::string CRYPTOPP_API StaticAlgorithmName() + {return CIPHER::StaticAlgorithmName() + "/" + BASE::StaticAlgorithmName();} +}; + +//! _ +template +class CipherModeFinalTemplate_ExternalCipher : public BASE +{ +public: + CipherModeFinalTemplate_ExternalCipher() {} + CipherModeFinalTemplate_ExternalCipher(BlockCipher &cipher) + {SetCipher(cipher);} + CipherModeFinalTemplate_ExternalCipher(BlockCipher &cipher, const byte *iv, int feedbackSize = 0) + {SetCipherWithIV(cipher, iv, feedbackSize);} + + void SetCipher(BlockCipher &cipher); + void SetCipherWithIV(BlockCipher &cipher, const byte *iv, int feedbackSize = 0); +}; + +template +void CipherModeFinalTemplate_ExternalCipher::SetCipher(BlockCipher &cipher) +{ + this->ThrowIfResynchronizable(); + this->m_cipher = &cipher; + this->ResizeBuffers(); +} + +template +void CipherModeFinalTemplate_ExternalCipher::SetCipherWithIV(BlockCipher &cipher, const byte *iv, int feedbackSize) +{ + this->ThrowIfInvalidIV(iv); + this->m_cipher = &cipher; + this->ResizeBuffers(); + this->SetFeedbackSize(feedbackSize); + if (this->IsResynchronizable()) + this->Resynchronize(iv); +} + +CRYPTOPP_DLL_TEMPLATE_CLASS CFB_CipherTemplate >; +CRYPTOPP_DLL_TEMPLATE_CLASS CFB_EncryptionTemplate >; +CRYPTOPP_DLL_TEMPLATE_CLASS CFB_DecryptionTemplate >; + +//! CFB mode +template +struct CFB_Mode : public CipherModeDocumentation +{ + typedef CipherModeFinalTemplate_CipherHolder > > > Encryption; + typedef CipherModeFinalTemplate_CipherHolder > > > Decryption; +}; + +//! CFB mode, external cipher +struct CFB_Mode_ExternalCipher : public CipherModeDocumentation +{ + typedef CipherModeFinalTemplate_ExternalCipher > > > Encryption; + typedef CipherModeFinalTemplate_ExternalCipher > > > Decryption; +}; + +//! CFB mode FIPS variant, requiring full block plaintext according to FIPS 800-38A +template +struct CFB_FIPS_Mode : public CipherModeDocumentation +{ + typedef CipherModeFinalTemplate_CipherHolder > > > > Encryption; + typedef CipherModeFinalTemplate_CipherHolder > > > > Decryption; +}; + +//! CFB mode FIPS variant, requiring full block plaintext according to FIPS 800-38A, external cipher +struct CFB_FIPS_Mode_ExternalCipher : public CipherModeDocumentation +{ + typedef CipherModeFinalTemplate_ExternalCipher > > > > Encryption; + typedef CipherModeFinalTemplate_ExternalCipher > > > > Decryption; +}; + +CRYPTOPP_DLL_TEMPLATE_CLASS AdditiveCipherTemplate >; + +//! OFB mode +template +struct OFB_Mode : public CipherModeDocumentation +{ + typedef CipherModeFinalTemplate_CipherHolder > > > Encryption; + typedef Encryption Decryption; +}; + +//! OFB mode, external cipher +struct OFB_Mode_ExternalCipher : public CipherModeDocumentation +{ + typedef CipherModeFinalTemplate_ExternalCipher > > > Encryption; + typedef Encryption Decryption; +}; + +CRYPTOPP_DLL_TEMPLATE_CLASS AdditiveCipherTemplate >; + +//! CTR mode +template +struct CTR_Mode : public CipherModeDocumentation +{ + typedef CipherModeFinalTemplate_CipherHolder > > > Encryption; + typedef Encryption Decryption; +}; + +//! CTR mode, external cipher +struct CTR_Mode_ExternalCipher : public CipherModeDocumentation +{ + typedef CipherModeFinalTemplate_ExternalCipher > > > Encryption; + typedef Encryption Decryption; +}; + +//! ECB mode +template +struct ECB_Mode : public CipherModeDocumentation +{ + typedef CipherModeFinalTemplate_CipherHolder Encryption; + typedef CipherModeFinalTemplate_CipherHolder Decryption; +}; + +CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher; + +//! ECB mode, external cipher +struct ECB_Mode_ExternalCipher : public CipherModeDocumentation +{ + typedef CipherModeFinalTemplate_ExternalCipher Encryption; + typedef Encryption Decryption; +}; + +//! CBC mode +template +struct CBC_Mode : public CipherModeDocumentation +{ + typedef CipherModeFinalTemplate_CipherHolder Encryption; + typedef CipherModeFinalTemplate_CipherHolder Decryption; +}; + +CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher; +CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher; + +//! CBC mode, external cipher +struct CBC_Mode_ExternalCipher : public CipherModeDocumentation +{ + typedef CipherModeFinalTemplate_ExternalCipher Encryption; + typedef CipherModeFinalTemplate_ExternalCipher Decryption; +}; + +//! CBC mode with ciphertext stealing +template +struct CBC_CTS_Mode : public CipherModeDocumentation +{ + typedef CipherModeFinalTemplate_CipherHolder Encryption; + typedef CipherModeFinalTemplate_CipherHolder Decryption; +}; + +CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher; +CRYPTOPP_DLL_TEMPLATE_CLASS CipherModeFinalTemplate_ExternalCipher; + +//! CBC mode with ciphertext stealing, external cipher +struct CBC_CTS_Mode_ExternalCipher : public CipherModeDocumentation +{ + typedef CipherModeFinalTemplate_ExternalCipher Encryption; + typedef CipherModeFinalTemplate_ExternalCipher Decryption; +}; + +#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY +typedef CFB_Mode_ExternalCipher::Encryption CFBEncryption; +typedef CFB_Mode_ExternalCipher::Decryption CFBDecryption; +typedef OFB_Mode_ExternalCipher::Encryption OFB; +typedef CTR_Mode_ExternalCipher::Encryption CounterMode; +#endif + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/modexppc.h b/CryptoPP/crypto/modexppc.h new file mode 100644 index 0000000..a9df756 --- /dev/null +++ b/CryptoPP/crypto/modexppc.h @@ -0,0 +1,34 @@ +#ifndef CRYPTOPP_MODEXPPC_H +#define CRYPTOPP_MODEXPPC_H + +#include "modarith.h" +#include "eprecomp.h" +#include "smartptr.h" +#include "pubkey.h" + +NAMESPACE_BEGIN(CryptoPP) + +CRYPTOPP_DLL_TEMPLATE_CLASS DL_FixedBasePrecomputationImpl; + +class ModExpPrecomputation : public DL_GroupPrecomputation +{ +public: + // DL_GroupPrecomputation + bool NeedConversions() const {return true;} + Element ConvertIn(const Element &v) const {return m_mr->ConvertIn(v);} + virtual Element ConvertOut(const Element &v) const {return m_mr->ConvertOut(v);} + const AbstractGroup & GetGroup() const {return m_mr->MultiplicativeGroup();} + Element BERDecodeElement(BufferedTransformation &bt) const {return Integer(bt);} + void DEREncodeElement(BufferedTransformation &bt, const Element &v) const {v.DEREncode(bt);} + + // non-inherited + void SetModulus(const Integer &v) {m_mr.reset(new MontgomeryRepresentation(v));} + const Integer & GetModulus() const {return m_mr->GetModulus();} + +private: + value_ptr m_mr; +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/mqueue.cpp b/CryptoPP/crypto/mqueue.cpp new file mode 100644 index 0000000..8c071e2 --- /dev/null +++ b/CryptoPP/crypto/mqueue.cpp @@ -0,0 +1,174 @@ +// mqueue.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "mqueue.h" + +NAMESPACE_BEGIN(CryptoPP) + +MessageQueue::MessageQueue(unsigned int nodeSize) + : m_queue(nodeSize), m_lengths(1, 0U), m_messageCounts(1, 0U) +{ +} + +size_t MessageQueue::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end, const std::string &channel, bool blocking) const +{ + if (begin >= MaxRetrievable()) + return 0; + + return m_queue.CopyRangeTo2(target, begin, STDMIN(MaxRetrievable(), end), channel, blocking); +} + +size_t MessageQueue::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking) +{ + transferBytes = STDMIN(MaxRetrievable(), transferBytes); + size_t blockedBytes = m_queue.TransferTo2(target, transferBytes, channel, blocking); + m_lengths.front() -= transferBytes; + return blockedBytes; +} + +bool MessageQueue::GetNextMessage() +{ + if (NumberOfMessages() > 0 && !AnyRetrievable()) + { + m_lengths.pop_front(); + if (m_messageCounts[0] == 0 && m_messageCounts.size() > 1) + m_messageCounts.pop_front(); + return true; + } + else + return false; +} + +unsigned int MessageQueue::CopyMessagesTo(BufferedTransformation &target, unsigned int count, const std::string &channel) const +{ + ByteQueue::Walker walker(m_queue); + std::deque::const_iterator it = m_lengths.begin(); + unsigned int i; + for (i=0; i 0 && q2.AnyRetrievable()) + { + size_t len = length; + const byte *data = q2.Spy(len); + len = STDMIN(len, length); + if (memcmp(inString, data, len) != 0) + goto mismatch; + inString += len; + length -= len; + q2.Skip(len); + } + + q1.Put(inString, length); + + if (messageEnd) + { + if (q2.AnyRetrievable()) + goto mismatch; + else if (q2.AnyMessages()) + q2.GetNextMessage(); + else if (q2.NumberOfMessageSeries() > 0) + goto mismatch; + else + q1.MessageEnd(); + } + + return 0; + +mismatch: + return HandleMismatchDetected(blocking); + } +} + +bool EqualityComparisonFilter::ChannelMessageSeriesEnd(const std::string &channel, int propagation, bool blocking) +{ + unsigned int i = MapChannel(channel); + + if (i == 2) + { + OutputMessageSeriesEnd(4, propagation, blocking, channel); + return false; + } + else if (m_mismatchDetected) + return false; + else + { + MessageQueue &q1 = m_q[i], &q2 = m_q[1-i]; + + if (q2.AnyRetrievable() || q2.AnyMessages()) + goto mismatch; + else if (q2.NumberOfMessageSeries() > 0) + return Output(2, (const byte *)"\1", 1, 0, blocking) != 0; + else + q1.MessageSeriesEnd(); + + return false; + +mismatch: + return HandleMismatchDetected(blocking); + } +} + +bool EqualityComparisonFilter::HandleMismatchDetected(bool blocking) +{ + m_mismatchDetected = true; + if (m_throwIfNotEqual) + throw MismatchDetected(); + return Output(1, (const byte *)"\0", 1, 0, blocking) != 0; +} + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/mqueue.h b/CryptoPP/crypto/mqueue.h new file mode 100644 index 0000000..a05cafb --- /dev/null +++ b/CryptoPP/crypto/mqueue.h @@ -0,0 +1,98 @@ +#ifndef CRYPTOPP_MQUEUE_H +#define CRYPTOPP_MQUEUE_H + +#include "queue.h" +#include "filters.h" +#include + +NAMESPACE_BEGIN(CryptoPP) + +//! Message Queue +class CRYPTOPP_DLL MessageQueue : public AutoSignaling +{ +public: + MessageQueue(unsigned int nodeSize=256); + + void IsolatedInitialize(const NameValuePairs ¶meters) + {m_queue.IsolatedInitialize(parameters); m_lengths.assign(1, 0U); m_messageCounts.assign(1, 0U);} + size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking) + { + m_queue.Put(begin, length); + m_lengths.back() += length; + if (messageEnd) + { + m_lengths.push_back(0); + m_messageCounts.back()++; + } + return 0; + } + bool IsolatedFlush(bool hardFlush, bool blocking) {return false;} + bool IsolatedMessageSeriesEnd(bool blocking) + {m_messageCounts.push_back(0); return false;} + + lword MaxRetrievable() const + {return m_lengths.front();} + bool AnyRetrievable() const + {return m_lengths.front() > 0;} + + size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=NULL_CHANNEL, bool blocking=true); + size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=NULL_CHANNEL, bool blocking=true) const; + + lword TotalBytesRetrievable() const + {return m_queue.MaxRetrievable();} + unsigned int NumberOfMessages() const + {return (unsigned int)m_lengths.size()-1;} + bool GetNextMessage(); + + unsigned int NumberOfMessagesInThisSeries() const + {return m_messageCounts[0];} + unsigned int NumberOfMessageSeries() const + {return (unsigned int)m_messageCounts.size()-1;} + + unsigned int CopyMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX, const std::string &channel=NULL_CHANNEL) const; + + const byte * Spy(size_t &contiguousSize) const; + + void swap(MessageQueue &rhs); + +private: + ByteQueue m_queue; + std::deque m_lengths; + std::deque m_messageCounts; +}; + + +//! A filter that checks messages on two channels for equality +class CRYPTOPP_DLL EqualityComparisonFilter : public Unflushable > +{ +public: + struct MismatchDetected : public Exception {MismatchDetected() : Exception(DATA_INTEGRITY_CHECK_FAILED, "EqualityComparisonFilter: did not receive the same data on two channels") {}}; + + /*! if throwIfNotEqual is false, this filter will output a '\\0' byte when it detects a mismatch, '\\1' otherwise */ + EqualityComparisonFilter(BufferedTransformation *attachment=NULL, bool throwIfNotEqual=true, const std::string &firstChannel="0", const std::string &secondChannel="1") + : m_throwIfNotEqual(throwIfNotEqual), m_mismatchDetected(false) + , m_firstChannel(firstChannel), m_secondChannel(secondChannel) + {Detach(attachment);} + + size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking); + bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true); + +private: + unsigned int MapChannel(const std::string &channel) const; + bool HandleMismatchDetected(bool blocking); + + bool m_throwIfNotEqual, m_mismatchDetected; + std::string m_firstChannel, m_secondChannel; + MessageQueue m_q[2]; +}; + +NAMESPACE_END + +NAMESPACE_BEGIN(std) +template<> inline void swap(CryptoPP::MessageQueue &a, CryptoPP::MessageQueue &b) +{ + a.swap(b); +} +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/mqv.cpp b/CryptoPP/crypto/mqv.cpp new file mode 100644 index 0000000..a290945 --- /dev/null +++ b/CryptoPP/crypto/mqv.cpp @@ -0,0 +1,13 @@ +// mqv.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "mqv.h" + +NAMESPACE_BEGIN(CryptoPP) + +void TestInstantiations_MQV() +{ + MQV mqv; +} + +NAMESPACE_END diff --git a/CryptoPP/crypto/mqv.h b/CryptoPP/crypto/mqv.h new file mode 100644 index 0000000..8692010 --- /dev/null +++ b/CryptoPP/crypto/mqv.h @@ -0,0 +1,141 @@ +#ifndef CRYPTOPP_MQV_H +#define CRYPTOPP_MQV_H + +/** \file +*/ + +#include "gfpcrypt.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! _ +template +class MQV_Domain : public AuthenticatedKeyAgreementDomain +{ +public: + typedef GROUP_PARAMETERS GroupParameters; + typedef typename GroupParameters::Element Element; + typedef MQV_Domain Domain; + + MQV_Domain() {} + + MQV_Domain(const GroupParameters ¶ms) + : m_groupParameters(params) {} + + MQV_Domain(BufferedTransformation &bt) + {m_groupParameters.BERDecode(bt);} + + template + MQV_Domain(T1 v1, T2 v2) + {m_groupParameters.Initialize(v1, v2);} + + template + MQV_Domain(T1 v1, T2 v2, T3 v3) + {m_groupParameters.Initialize(v1, v2, v3);} + + template + MQV_Domain(T1 v1, T2 v2, T3 v3, T4 v4) + {m_groupParameters.Initialize(v1, v2, v3, v4);} + + const GroupParameters & GetGroupParameters() const {return m_groupParameters;} + GroupParameters & AccessGroupParameters() {return m_groupParameters;} + + CryptoParameters & AccessCryptoParameters() {return AccessAbstractGroupParameters();} + + unsigned int AgreedValueLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(false);} + unsigned int StaticPrivateKeyLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();} + unsigned int StaticPublicKeyLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(true);} + + void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const + { + Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent()); + x.Encode(privateKey, StaticPrivateKeyLength()); + } + + void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const + { + const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); + Integer x(privateKey, StaticPrivateKeyLength()); + Element y = params.ExponentiateBase(x); + params.EncodeElement(true, y, publicKey); + } + + unsigned int EphemeralPrivateKeyLength() const {return StaticPrivateKeyLength() + StaticPublicKeyLength();} + unsigned int EphemeralPublicKeyLength() const {return StaticPublicKeyLength();} + + void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const + { + const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); + Integer x(rng, Integer::One(), params.GetMaxExponent()); + x.Encode(privateKey, StaticPrivateKeyLength()); + Element y = params.ExponentiateBase(x); + params.EncodeElement(true, y, privateKey+StaticPrivateKeyLength()); + } + + void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const + { + memcpy(publicKey, privateKey+StaticPrivateKeyLength(), EphemeralPublicKeyLength()); + } + + bool Agree(byte *agreedValue, + const byte *staticPrivateKey, const byte *ephemeralPrivateKey, + const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey, + bool validateStaticOtherPublicKey=true) const + { + try + { + const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); + Element WW = params.DecodeElement(staticOtherPublicKey, validateStaticOtherPublicKey); + Element VV = params.DecodeElement(ephemeralOtherPublicKey, true); + + Integer s(staticPrivateKey, StaticPrivateKeyLength()); + Integer u(ephemeralPrivateKey, StaticPrivateKeyLength()); + Element V = params.DecodeElement(ephemeralPrivateKey+StaticPrivateKeyLength(), false); + + const Integer &r = params.GetSubgroupOrder(); + Integer h2 = Integer::Power2((r.BitCount()+1)/2); + Integer e = ((h2+params.ConvertElementToInteger(V)%h2)*s+u) % r; + Integer tt = h2 + params.ConvertElementToInteger(VV) % h2; + + if (COFACTOR_OPTION::ToEnum() == NO_COFACTOR_MULTIPLICTION) + { + Element P = params.ExponentiateElement(WW, tt); + P = m_groupParameters.MultiplyElements(P, VV); + Element R[2]; + const Integer e2[2] = {r, e}; + params.SimultaneousExponentiate(R, P, e2, 2); + if (!params.IsIdentity(R[0]) || params.IsIdentity(R[1])) + return false; + params.EncodeElement(false, R[1], agreedValue); + } + else + { + const Integer &k = params.GetCofactor(); + if (COFACTOR_OPTION::ToEnum() == COMPATIBLE_COFACTOR_MULTIPLICTION) + e = ModularArithmetic(r).Divide(e, k); + Element P = m_groupParameters.CascadeExponentiate(VV, k*e, WW, k*(e*tt%r)); + if (params.IsIdentity(P)) + return false; + params.EncodeElement(false, P, agreedValue); + } + } + catch (DL_BadElement &) + { + return false; + } + return true; + } + +private: + DL_GroupParameters & AccessAbstractGroupParameters() {return m_groupParameters;} + const DL_GroupParameters & GetAbstractGroupParameters() const {return m_groupParameters;} + + GroupParameters m_groupParameters; +}; + +//! Menezes-Qu-Vanstone in GF(p) with key validation, AKA MQV +typedef MQV_Domain MQV; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/mqv1024.dat b/CryptoPP/crypto/mqv1024.dat new file mode 100644 index 0000000..415377a --- /dev/null +++ b/CryptoPP/crypto/mqv1024.dat @@ -0,0 +1 @@ +3082011E028181009A21FC66469293103CEF66960B17880F905C738DB692B7481922FC2D454D14067C6BFC158B93FCC1B8D128D4D86D893082F8A3592238EE8B693B6245F26F55968D7D13752D6BFBA271E8E36E11482815D887BB9F6B600E820E7E2AF2EE6ECDBC1CB35B12A4EF48A8907C090482DE7D49B751BB3A50F78BE29506114BC85D3A6102150C896422EC558A74B883BA85E2F10D4A58F28D2B09028180350C4BB19C0A9B224E5E1BACCC1B1952A97628021B4673831C851C3280F06D3EFA73DAE27E5D4E4A0499E0B2B9A369649E883A1F260EF250B5CCF3E3C922332B210EEA07D3BF92210BA7A7374A30DDDE3D1B3D575B77CD36B001EAE4A2A3BFAFF12FCE74F3330B30ACF6DCFF580ECBFB5B00FD5DD2B8EA9DB09C7E1C7100BD67 \ No newline at end of file diff --git a/CryptoPP/crypto/mqv2048.dat b/CryptoPP/crypto/mqv2048.dat new file mode 100644 index 0000000..ef32456 --- /dev/null +++ b/CryptoPP/crypto/mqv2048.dat @@ -0,0 +1 @@ +308202280282010100A5C07CE5BF0894C0BA8752F4D9A6D0BF6556D325B618A655CCFE3EEC85B56D47DBDF5A9A5C8588AE6F4C44BBCB339E869A21BE057A243DC797B912C547FBA359C4FC9965C72278370AB6C0DD246197A8D83A08C69425786482D1744C41FBB3C36BEA5963C05B0778AAEF9230C3E2E12072268038E5ADB6433542F94D8C25A6A1785E4D2D97AF119F2139E69AECA46F11B344785A0B1B280CF8D678AB9627780271A350A9B15B92E105F14733C5F15C1753F7C48A645FAAAC1BFA266B5AD6F7C46350465DA31150ABB10FF63FD6C01C849DFCD5645C5D1AF8B967372449DF90D02177E12439BD36A1EED1FAEDB8166927F755B71A5368CC27CD00AB5CF04601E7021D03134944D9AA15697107F48AC5621A1531649AD5EE8EEC1D1F282B5481028201003468652FBB1E3C7F2FBB99A89EA14FB9205F534943034CDE9D9CC57A790D9713EC7B21032EAA8ED2B24FFABD612EDADFC9265964C753AE276380294D4D16C63389A4C392A0058EF1549F6C0D13C4A09759C67650A51F7362B38C61AF2942A6004BB8C3CD4C489E66DE1567E2306821788A519727CD27945DBC5778AC6E8B1DFC05573D76DF9E9AA4F1CE657A2A07BEF833091614C0A6065507BD51099C54148327903626DE6D01FEC9A7F5F9A901C90E219D452C2E2A90AA2303A52776EF174CC85C1AA4F28924B1DFF3E3C5538D820A422374DCFB0D14D620AE282A72416C6506F02D3ED1E6208F66B9DB49294D8D605D7D146BB6A970211289B1BE7AB12531 \ No newline at end of file diff --git a/CryptoPP/crypto/nbtheory.cpp b/CryptoPP/crypto/nbtheory.cpp new file mode 100644 index 0000000..3de1fa5 --- /dev/null +++ b/CryptoPP/crypto/nbtheory.cpp @@ -0,0 +1,1134 @@ +// nbtheory.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "nbtheory.h" +#include "modarith.h" +#include "algparam.h" + +#include +#include + +#ifdef _OPENMP +// needed in MSVC 2005 to generate correct manifest +#include +#endif + +NAMESPACE_BEGIN(CryptoPP) + +const word s_lastSmallPrime = 32719; + +struct NewPrimeTable +{ + std::vector * operator()() const + { + const unsigned int maxPrimeTableSize = 3511; + + std::auto_ptr > pPrimeTable(new std::vector); + std::vector &primeTable = *pPrimeTable; + primeTable.reserve(maxPrimeTableSize); + + primeTable.push_back(2); + unsigned int testEntriesEnd = 1; + + for (unsigned int p=3; p<=s_lastSmallPrime; p+=2) + { + unsigned int j; + for (j=1; j &primeTable = Singleton, NewPrimeTable>().Ref(); + size = (unsigned int)primeTable.size(); + return &primeTable[0]; +} + +bool IsSmallPrime(const Integer &p) +{ + unsigned int primeTableSize; + const word16 * primeTable = GetPrimeTable(primeTableSize); + + if (p.IsPositive() && p <= primeTable[primeTableSize-1]) + return std::binary_search(primeTable, primeTable+primeTableSize, (word16)p.ConvertToLong()); + else + return false; +} + +bool TrialDivision(const Integer &p, unsigned bound) +{ + unsigned int primeTableSize; + const word16 * primeTable = GetPrimeTable(primeTableSize); + + assert(primeTable[primeTableSize-1] >= bound); + + unsigned int i; + for (i = 0; primeTable[i]3 && b>1 && b3 && b>1 && b>a; + + Integer z = a_exp_b_mod_c(b, m, n); + if (z==1 || z==nminus1) + return true; + for (unsigned j=1; j3); + + Integer b; + for (unsigned int i=0; i2); + + Integer b=3; + unsigned int i=0; + int j; + + while ((j=Jacobi(b.Squared()-4, n)) == 1) + { + if (++i==64 && n.IsSquare()) // avoid infinite loop if n is a square + return false; + ++b; ++b; + } + + if (j==0) + return false; + else + return Lucas(n+1, b, n)==2; +} + +bool IsStrongLucasProbablePrime(const Integer &n) +{ + if (n <= 1) + return false; + + if (n.IsEven()) + return n==2; + + assert(n>2); + + Integer b=3; + unsigned int i=0; + int j; + + while ((j=Jacobi(b.Squared()-4, n)) == 1) + { + if (++i==64 && n.IsSquare()) // avoid infinite loop if n is a square + return false; + ++b; ++b; + } + + if (j==0) + return false; + + Integer n1 = n+1; + unsigned int a; + + // calculate a = largest power of 2 that divides n1 + for (a=0; ; a++) + if (n1.GetBit(a)) + break; + Integer m = n1>>a; + + Integer z = Lucas(m, b, n); + if (z==2 || z==n-2) + return true; + for (i=1; i().Ref()) + return SmallDivisorsTest(p); + else + return SmallDivisorsTest(p) && IsStrongProbablePrime(p, 3) && IsStrongLucasProbablePrime(p); +} + +bool VerifyPrime(RandomNumberGenerator &rng, const Integer &p, unsigned int level) +{ + bool pass = IsPrime(p) && RabinMillerTest(rng, p, 1); + if (level >= 1) + pass = pass && RabinMillerTest(rng, p, 10); + return pass; +} + +unsigned int PrimeSearchInterval(const Integer &max) +{ + return max.BitCount(); +} + +static inline bool FastProbablePrimeTest(const Integer &n) +{ + return IsStrongProbablePrime(n,2); +} + +AlgorithmParameters, Integer>, Integer> + MakeParametersForTwoPrimesOfEqualSize(unsigned int productBitLength) +{ + if (productBitLength < 16) + throw InvalidArgument("invalid bit length"); + + Integer minP, maxP; + + if (productBitLength%2==0) + { + minP = Integer(182) << (productBitLength/2-8); + maxP = Integer::Power2(productBitLength/2)-1; + } + else + { + minP = Integer::Power2((productBitLength-1)/2); + maxP = Integer(181) << ((productBitLength+1)/2-8); + } + + return MakeParameters("RandomNumberType", Integer::PRIME)("Min", minP)("Max", maxP); +} + +class PrimeSieve +{ +public: + // delta == 1 or -1 means double sieve with p = 2*q + delta + PrimeSieve(const Integer &first, const Integer &last, const Integer &step, signed int delta=0); + bool NextCandidate(Integer &c); + + void DoSieve(); + static void SieveSingle(std::vector &sieve, word16 p, const Integer &first, const Integer &step, word16 stepInv); + + Integer m_first, m_last, m_step; + signed int m_delta; + word m_next; + std::vector m_sieve; +}; + +PrimeSieve::PrimeSieve(const Integer &first, const Integer &last, const Integer &step, signed int delta) + : m_first(first), m_last(last), m_step(step), m_delta(delta), m_next(0) +{ + DoSieve(); +} + +bool PrimeSieve::NextCandidate(Integer &c) +{ + bool safe = SafeConvert(std::find(m_sieve.begin()+m_next, m_sieve.end(), false) - m_sieve.begin(), m_next); + assert(safe); + if (m_next == m_sieve.size()) + { + m_first += long(m_sieve.size())*m_step; + if (m_first > m_last) + return false; + else + { + m_next = 0; + DoSieve(); + return NextCandidate(c); + } + } + else + { + c = m_first + long(m_next)*m_step; + ++m_next; + return true; + } +} + +void PrimeSieve::SieveSingle(std::vector &sieve, word16 p, const Integer &first, const Integer &step, word16 stepInv) +{ + if (stepInv) + { + size_t sieveSize = sieve.size(); + size_t j = (word32(p-(first%p))*stepInv) % p; + // if the first multiple of p is p, skip it + if (first.WordCount() <= 1 && first + step*long(j) == p) + j += p; + for (; j < sieveSize; j += p) + sieve[j] = true; + } +} + +void PrimeSieve::DoSieve() +{ + unsigned int primeTableSize; + const word16 * primeTable = GetPrimeTable(primeTableSize); + + const unsigned int maxSieveSize = 32768; + unsigned int sieveSize = STDMIN(Integer(maxSieveSize), (m_last-m_first)/m_step+1).ConvertToLong(); + + m_sieve.clear(); + m_sieve.resize(sieveSize, false); + + if (m_delta == 0) + { + for (unsigned int i = 0; i < primeTableSize; ++i) + SieveSingle(m_sieve, primeTable[i], m_first, m_step, (word16)m_step.InverseMod(primeTable[i])); + } + else + { + assert(m_step%2==0); + Integer qFirst = (m_first-m_delta) >> 1; + Integer halfStep = m_step >> 1; + for (unsigned int i = 0; i < primeTableSize; ++i) + { + word16 p = primeTable[i]; + word16 stepInv = (word16)m_step.InverseMod(p); + SieveSingle(m_sieve, p, m_first, m_step, stepInv); + + word16 halfStepInv = 2*stepInv < p ? 2*stepInv : 2*stepInv-p; + SieveSingle(m_sieve, p, qFirst, halfStep, halfStepInv); + } + } +} + +bool FirstPrime(Integer &p, const Integer &max, const Integer &equiv, const Integer &mod, const PrimeSelector *pSelector) +{ + assert(!equiv.IsNegative() && equiv < mod); + + Integer gcd = GCD(equiv, mod); + if (gcd != Integer::One()) + { + // the only possible prime p such that p%mod==equiv where GCD(mod,equiv)!=1 is GCD(mod,equiv) + if (p <= gcd && gcd <= max && IsPrime(gcd) && (!pSelector || pSelector->IsAcceptable(gcd))) + { + p = gcd; + return true; + } + else + return false; + } + + unsigned int primeTableSize; + const word16 * primeTable = GetPrimeTable(primeTableSize); + + if (p <= primeTable[primeTableSize-1]) + { + const word16 *pItr; + + --p; + if (p.IsPositive()) + pItr = std::upper_bound(primeTable, primeTable+primeTableSize, (word)p.ConvertToLong()); + else + pItr = primeTable; + + while (pItr < primeTable+primeTableSize && !(*pItr%mod == equiv && (!pSelector || pSelector->IsAcceptable(*pItr)))) + ++pItr; + + if (pItr < primeTable+primeTableSize) + { + p = *pItr; + return p <= max; + } + + p = primeTable[primeTableSize-1]+1; + } + + assert(p > primeTable[primeTableSize-1]); + + if (mod.IsOdd()) + return FirstPrime(p, max, CRT(equiv, mod, 1, 2, 1), mod<<1, pSelector); + + p += (equiv-p)%mod; + + if (p>max) + return false; + + PrimeSieve sieve(p, max, mod); + + while (sieve.NextCandidate(p)) + { + if ((!pSelector || pSelector->IsAcceptable(p)) && FastProbablePrimeTest(p) && IsPrime(p)) + return true; + } + + return false; +} + +// the following two functions are based on code and comments provided by Preda Mihailescu +static bool ProvePrime(const Integer &p, const Integer &q) +{ + assert(p < q*q*q); + assert(p % q == 1); + +// this is the Quisquater test. Numbers p having passed the Lucas - Lehmer test +// for q and verifying p < q^3 can only be built up of two factors, both = 1 mod q, +// or be prime. The next two lines build the discriminant of a quadratic equation +// which holds iff p is built up of two factors (excercise ... ) + + Integer r = (p-1)/q; + if (((r%q).Squared()-4*(r/q)).IsSquare()) + return false; + + unsigned int primeTableSize; + const word16 * primeTable = GetPrimeTable(primeTableSize); + + assert(primeTableSize >= 50); + for (int i=0; i<50; i++) + { + Integer b = a_exp_b_mod_c(primeTable[i], r, p); + if (b != 1) + return a_exp_b_mod_c(b, q, p) == 1; + } + return false; +} + +Integer MihailescuProvablePrime(RandomNumberGenerator &rng, unsigned int pbits) +{ + Integer p; + Integer minP = Integer::Power2(pbits-1); + Integer maxP = Integer::Power2(pbits) - 1; + + if (maxP <= Integer(s_lastSmallPrime).Squared()) + { + // Randomize() will generate a prime provable by trial division + p.Randomize(rng, minP, maxP, Integer::PRIME); + return p; + } + + unsigned int qbits = (pbits+2)/3 + 1 + rng.GenerateWord32(0, pbits/36); + Integer q = MihailescuProvablePrime(rng, qbits); + Integer q2 = q<<1; + + while (true) + { + // this initializes the sieve to search in the arithmetic + // progression p = p_0 + \lambda * q2 = p_0 + 2 * \lambda * q, + // with q the recursively generated prime above. We will be able + // to use Lucas tets for proving primality. A trick of Quisquater + // allows taking q > cubic_root(p) rather then square_root: this + // decreases the recursion. + + p.Randomize(rng, minP, maxP, Integer::ANY, 1, q2); + PrimeSieve sieve(p, STDMIN(p+PrimeSearchInterval(maxP)*q2, maxP), q2); + + while (sieve.NextCandidate(p)) + { + if (FastProbablePrimeTest(p) && ProvePrime(p, q)) + return p; + } + } + + // not reached + return p; +} + +Integer MaurerProvablePrime(RandomNumberGenerator &rng, unsigned int bits) +{ + const unsigned smallPrimeBound = 29, c_opt=10; + Integer p; + + unsigned int primeTableSize; + const word16 * primeTable = GetPrimeTable(primeTableSize); + + if (bits < smallPrimeBound) + { + do + p.Randomize(rng, Integer::Power2(bits-1), Integer::Power2(bits)-1, Integer::ANY, 1, 2); + while (TrialDivision(p, 1 << ((bits+1)/2))); + } + else + { + const unsigned margin = bits > 50 ? 20 : (bits-10)/2; + double relativeSize; + do + relativeSize = pow(2.0, double(rng.GenerateWord32())/0xffffffff - 1); + while (bits * relativeSize >= bits - margin); + + Integer a,b; + Integer q = MaurerProvablePrime(rng, unsigned(bits*relativeSize)); + Integer I = Integer::Power2(bits-2)/q; + Integer I2 = I << 1; + unsigned int trialDivisorBound = (unsigned int)STDMIN((unsigned long)primeTable[primeTableSize-1], (unsigned long)bits*bits/c_opt); + bool success = false; + while (!success) + { + p.Randomize(rng, I, I2, Integer::ANY); + p *= q; p <<= 1; ++p; + if (!TrialDivision(p, trialDivisorBound)) + { + a.Randomize(rng, 2, p-1, Integer::ANY); + b = a_exp_b_mod_c(a, (p-1)/q, p); + success = (GCD(b-1, p) == 1) && (a_exp_b_mod_c(b, q, p) == 1); + } + } + } + return p; +} + +Integer CRT(const Integer &xp, const Integer &p, const Integer &xq, const Integer &q, const Integer &u) +{ + // isn't operator overloading great? + return p * (u * (xq-xp) % q) + xp; +/* + Integer t1 = xq-xp; + cout << hex << t1 << endl; + Integer t2 = u * t1; + cout << hex << t2 << endl; + Integer t3 = t2 % q; + cout << hex << t3 << endl; + Integer t4 = p * t3; + cout << hex << t4 << endl; + Integer t5 = t4 + xp; + cout << hex << t5 << endl; + return t5; +*/ +} + +Integer CRT(const Integer &xp, const Integer &p, const Integer &xq, const Integer &q) +{ + return CRT(xp, p, xq, q, EuclideanMultiplicativeInverse(p, q)); +} + +Integer ModularSquareRoot(const Integer &a, const Integer &p) +{ + if (p%4 == 3) + return a_exp_b_mod_c(a, (p+1)/4, p); + + Integer q=p-1; + unsigned int r=0; + while (q.IsEven()) + { + r++; + q >>= 1; + } + + Integer n=2; + while (Jacobi(n, p) != -1) + ++n; + + Integer y = a_exp_b_mod_c(n, q, p); + Integer x = a_exp_b_mod_c(a, (q-1)/2, p); + Integer b = (x.Squared()%p)*a%p; + x = a*x%p; + Integer tempb, t; + + while (b != 1) + { + unsigned m=0; + tempb = b; + do + { + m++; + b = b.Squared()%p; + if (m==r) + return Integer::Zero(); + } + while (b != 1); + + t = y; + for (unsigned i=0; i>= 1; + b >>= 1; + k++; + } + + while (a[0]==0) + a >>= 1; + + while (b[0]==0) + b >>= 1; + + while (1) + { + switch (a.Compare(b)) + { + case -1: + b -= a; + while (b[0]==0) + b >>= 1; + break; + + case 0: + return (a <<= k); + + case 1: + a -= b; + while (a[0]==0) + a >>= 1; + break; + + default: + assert(false); + } + } +} + +Integer EuclideanMultiplicativeInverse(const Integer &a, const Integer &b) +{ + assert(b.Positive()); + + if (a.Negative()) + return EuclideanMultiplicativeInverse(a%b, b); + + if (b[0]==0) + { + if (!b || a[0]==0) + return Integer::Zero(); // no inverse + if (a==1) + return 1; + Integer u = EuclideanMultiplicativeInverse(b, a); + if (!u) + return Integer::Zero(); // no inverse + else + return (b*(a-u)+1)/a; + } + + Integer u=1, d=a, v1=b, v3=b, t1, t3, b2=(b+1)>>1; + + if (a[0]) + { + t1 = Integer::Zero(); + t3 = -b; + } + else + { + t1 = b2; + t3 = a>>1; + } + + while (!!t3) + { + while (t3[0]==0) + { + t3 >>= 1; + if (t1[0]==0) + t1 >>= 1; + else + { + t1 >>= 1; + t1 += b2; + } + } + if (t3.Positive()) + { + u = t1; + d = t3; + } + else + { + v1 = b-t1; + v3 = -t3; + } + t1 = u-v1; + t3 = d-v3; + if (t1.Negative()) + t1 += b; + } + if (d==1) + return u; + else + return Integer::Zero(); // no inverse +} +*/ + +int Jacobi(const Integer &aIn, const Integer &bIn) +{ + assert(bIn.IsOdd()); + + Integer b = bIn, a = aIn%bIn; + int result = 1; + + while (!!a) + { + unsigned i=0; + while (a.GetBit(i)==0) + i++; + a>>=i; + + if (i%2==1 && (b%8==3 || b%8==5)) + result = -result; + + if (a%4==3 && b%4==3) + result = -result; + + std::swap(a, b); + a %= b; + } + + return (b==1) ? result : 0; +} + +Integer Lucas(const Integer &e, const Integer &pIn, const Integer &n) +{ + unsigned i = e.BitCount(); + if (i==0) + return Integer::Two(); + + MontgomeryRepresentation m(n); + Integer p=m.ConvertIn(pIn%n), two=m.ConvertIn(Integer::Two()); + Integer v=p, v1=m.Subtract(m.Square(p), two); + + i--; + while (i--) + { + if (e.GetBit(i)) + { + // v = (v*v1 - p) % m; + v = m.Subtract(m.Multiply(v,v1), p); + // v1 = (v1*v1 - 2) % m; + v1 = m.Subtract(m.Square(v1), two); + } + else + { + // v1 = (v*v1 - p) % m; + v1 = m.Subtract(m.Multiply(v,v1), p); + // v = (v*v - 2) % m; + v = m.Subtract(m.Square(v), two); + } + } + return m.ConvertOut(v); +} + +// This is Peter Montgomery's unpublished Lucas sequence evalutation algorithm. +// The total number of multiplies and squares used is less than the binary +// algorithm (see above). Unfortunately I can't get it to run as fast as +// the binary algorithm because of the extra overhead. +/* +Integer Lucas(const Integer &n, const Integer &P, const Integer &modulus) +{ + if (!n) + return 2; + +#define f(A, B, C) m.Subtract(m.Multiply(A, B), C) +#define X2(A) m.Subtract(m.Square(A), two) +#define X3(A) m.Multiply(A, m.Subtract(m.Square(A), three)) + + MontgomeryRepresentation m(modulus); + Integer two=m.ConvertIn(2), three=m.ConvertIn(3); + Integer A=m.ConvertIn(P), B, C, p, d=n, e, r, t, T, U; + + while (d!=1) + { + p = d; + unsigned int b = WORD_BITS * p.WordCount(); + Integer alpha = (Integer(5)<<(2*b-2)).SquareRoot() - Integer::Power2(b-1); + r = (p*alpha)>>b; + e = d-r; + B = A; + C = two; + d = r; + + while (d!=e) + { + if (d>2)) + if ((dm3+em3==0 || dm3+em3==3) && (t = e, t >>= 2, t += e, d <= t)) + { + // #1 +// t = (d+d-e)/3; +// t = d; t += d; t -= e; t /= 3; +// e = (e+e-d)/3; +// e += e; e -= d; e /= 3; +// d = t; + +// t = (d+e)/3 + t = d; t += e; t /= 3; + e -= t; + d -= t; + + T = f(A, B, C); + U = f(T, A, B); + B = f(T, B, A); + A = U; + continue; + } + +// if (dm6 == em6 && d <= e + (e>>2)) + if (dm3 == em3 && dm2 == em2 && (t = e, t >>= 2, t += e, d <= t)) + { + // #2 +// d = (d-e)>>1; + d -= e; d >>= 1; + B = f(A, B, C); + A = X2(A); + continue; + } + +// if (d <= (e<<2)) + if (d <= (t = e, t <<= 2)) + { + // #3 + d -= e; + C = f(A, B, C); + swap(B, C); + continue; + } + + if (dm2 == em2) + { + // #4 +// d = (d-e)>>1; + d -= e; d >>= 1; + B = f(A, B, C); + A = X2(A); + continue; + } + + if (dm2 == 0) + { + // #5 + d >>= 1; + C = f(A, C, B); + A = X2(A); + continue; + } + + if (dm3 == 0) + { + // #6 +// d = d/3 - e; + d /= 3; d -= e; + T = X2(A); + C = f(T, f(A, B, C), C); + swap(B, C); + A = f(T, A, A); + continue; + } + + if (dm3+em3==0 || dm3+em3==3) + { + // #7 +// d = (d-e-e)/3; + d -= e; d -= e; d /= 3; + T = f(A, B, C); + B = f(T, A, B); + A = X3(A); + continue; + } + + if (dm3 == em3) + { + // #8 +// d = (d-e)/3; + d -= e; d /= 3; + T = f(A, B, C); + C = f(A, C, B); + B = T; + A = X3(A); + continue; + } + + assert(em2 == 0); + // #9 + e >>= 1; + C = f(C, B, A); + B = X2(B); + } + + A = f(A, B, C); + } + +#undef f +#undef X2 +#undef X3 + + return m.ConvertOut(A); +} +*/ + +Integer InverseLucas(const Integer &e, const Integer &m, const Integer &p, const Integer &q, const Integer &u) +{ + Integer d = (m*m-4); + Integer p2, q2; + #pragma omp parallel + #pragma omp sections + { + #pragma omp section + { + p2 = p-Jacobi(d,p); + p2 = Lucas(EuclideanMultiplicativeInverse(e,p2), m, p); + } + #pragma omp section + { + q2 = q-Jacobi(d,q); + q2 = Lucas(EuclideanMultiplicativeInverse(e,q2), m, q); + } + } + return CRT(p2, p, q2, q, u); +} + +Integer InverseLucas(const Integer &e, const Integer &m, const Integer &p, const Integer &q) +{ + return InverseLucas(e, m, p, q, EuclideanMultiplicativeInverse(p, q)); +} + +unsigned int FactoringWorkFactor(unsigned int n) +{ + // extrapolated from the table in Odlyzko's "The Future of Integer Factorization" + // updated to reflect the factoring of RSA-130 + if (n<5) return 0; + else return (unsigned int)(2.4 * pow((double)n, 1.0/3.0) * pow(log(double(n)), 2.0/3.0) - 5); +} + +unsigned int DiscreteLogWorkFactor(unsigned int n) +{ + // assuming discrete log takes about the same time as factoring + if (n<5) return 0; + else return (unsigned int)(2.4 * pow((double)n, 1.0/3.0) * pow(log(double(n)), 2.0/3.0) - 5); +} + +// ******************************************************** + +void PrimeAndGenerator::Generate(signed int delta, RandomNumberGenerator &rng, unsigned int pbits, unsigned int qbits) +{ + // no prime exists for delta = -1, qbits = 4, and pbits = 5 + assert(qbits > 4); + assert(pbits > qbits); + + if (qbits+1 == pbits) + { + Integer minP = Integer::Power2(pbits-1); + Integer maxP = Integer::Power2(pbits) - 1; + bool success = false; + + while (!success) + { + p.Randomize(rng, minP, maxP, Integer::ANY, 6+5*delta, 12); + PrimeSieve sieve(p, STDMIN(p+PrimeSearchInterval(maxP)*12, maxP), 12, delta); + + while (sieve.NextCandidate(p)) + { + assert(IsSmallPrime(p) || SmallDivisorsTest(p)); + q = (p-delta) >> 1; + assert(IsSmallPrime(q) || SmallDivisorsTest(q)); + if (FastProbablePrimeTest(q) && FastProbablePrimeTest(p) && IsPrime(q) && IsPrime(p)) + { + success = true; + break; + } + } + } + + if (delta == 1) + { + // find g such that g is a quadratic residue mod p, then g has order q + // g=4 always works, but this way we get the smallest quadratic residue (other than 1) + for (g=2; Jacobi(g, p) != 1; ++g) {} + // contributed by Walt Tuvell: g should be the following according to the Law of Quadratic Reciprocity + assert((p%8==1 || p%8==7) ? g==2 : (p%12==1 || p%12==11) ? g==3 : g==4); + } + else + { + assert(delta == -1); + // find g such that g*g-4 is a quadratic non-residue, + // and such that g has order q + for (g=3; ; ++g) + if (Jacobi(g*g-4, p)==-1 && Lucas(q, g, p)==2) + break; + } + } + else + { + Integer minQ = Integer::Power2(qbits-1); + Integer maxQ = Integer::Power2(qbits) - 1; + Integer minP = Integer::Power2(pbits-1); + Integer maxP = Integer::Power2(pbits) - 1; + + do + { + q.Randomize(rng, minQ, maxQ, Integer::PRIME); + } while (!p.Randomize(rng, minP, maxP, Integer::PRIME, delta%q, q)); + + // find a random g of order q + if (delta==1) + { + do + { + Integer h(rng, 2, p-2, Integer::ANY); + g = a_exp_b_mod_c(h, (p-1)/q, p); + } while (g <= 1); + assert(a_exp_b_mod_c(g, q, p)==1); + } + else + { + assert(delta==-1); + do + { + Integer h(rng, 3, p-1, Integer::ANY); + if (Jacobi(h*h-4, p)==1) + continue; + g = Lucas((p+1)/q, h, p); + } while (g <= 2); + assert(Lucas(q, g, p) == 2); + } + } +} + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/nbtheory.h b/CryptoPP/crypto/nbtheory.h new file mode 100644 index 0000000..0a1ac37 --- /dev/null +++ b/CryptoPP/crypto/nbtheory.h @@ -0,0 +1,137 @@ +// nbtheory.h - written and placed in the public domain by Wei Dai + +#ifndef CRYPTOPP_NBTHEORY_H +#define CRYPTOPP_NBTHEORY_H + +#include "integer.h" +#include "algparam.h" + +NAMESPACE_BEGIN(CryptoPP) + +// obtain pointer to small prime table and get its size +CRYPTOPP_DLL const word16 * CRYPTOPP_API GetPrimeTable(unsigned int &size); + +// ************ primality testing **************** + +// generate a provable prime +CRYPTOPP_DLL Integer CRYPTOPP_API MaurerProvablePrime(RandomNumberGenerator &rng, unsigned int bits); +CRYPTOPP_DLL Integer CRYPTOPP_API MihailescuProvablePrime(RandomNumberGenerator &rng, unsigned int bits); + +CRYPTOPP_DLL bool CRYPTOPP_API IsSmallPrime(const Integer &p); + +// returns true if p is divisible by some prime less than bound +// bound not be greater than the largest entry in the prime table +CRYPTOPP_DLL bool CRYPTOPP_API TrialDivision(const Integer &p, unsigned bound); + +// returns true if p is NOT divisible by small primes +CRYPTOPP_DLL bool CRYPTOPP_API SmallDivisorsTest(const Integer &p); + +// These is no reason to use these two, use the ones below instead +CRYPTOPP_DLL bool CRYPTOPP_API IsFermatProbablePrime(const Integer &n, const Integer &b); +CRYPTOPP_DLL bool CRYPTOPP_API IsLucasProbablePrime(const Integer &n); + +CRYPTOPP_DLL bool CRYPTOPP_API IsStrongProbablePrime(const Integer &n, const Integer &b); +CRYPTOPP_DLL bool CRYPTOPP_API IsStrongLucasProbablePrime(const Integer &n); + +// Rabin-Miller primality test, i.e. repeating the strong probable prime test +// for several rounds with random bases +CRYPTOPP_DLL bool CRYPTOPP_API RabinMillerTest(RandomNumberGenerator &rng, const Integer &w, unsigned int rounds); + +// primality test, used to generate primes +CRYPTOPP_DLL bool CRYPTOPP_API IsPrime(const Integer &p); + +// more reliable than IsPrime(), used to verify primes generated by others +CRYPTOPP_DLL bool CRYPTOPP_API VerifyPrime(RandomNumberGenerator &rng, const Integer &p, unsigned int level = 1); + +class CRYPTOPP_DLL PrimeSelector +{ +public: + const PrimeSelector *GetSelectorPointer() const {return this;} + virtual bool IsAcceptable(const Integer &candidate) const =0; +}; + +// use a fast sieve to find the first probable prime in {x | p<=x<=max and x%mod==equiv} +// returns true iff successful, value of p is undefined if no such prime exists +CRYPTOPP_DLL bool CRYPTOPP_API FirstPrime(Integer &p, const Integer &max, const Integer &equiv, const Integer &mod, const PrimeSelector *pSelector); + +CRYPTOPP_DLL unsigned int CRYPTOPP_API PrimeSearchInterval(const Integer &max); + +CRYPTOPP_DLL AlgorithmParameters, Integer>, Integer> + CRYPTOPP_API MakeParametersForTwoPrimesOfEqualSize(unsigned int productBitLength); + +// ********** other number theoretic functions ************ + +inline Integer GCD(const Integer &a, const Integer &b) + {return Integer::Gcd(a,b);} +inline bool RelativelyPrime(const Integer &a, const Integer &b) + {return Integer::Gcd(a,b) == Integer::One();} +inline Integer LCM(const Integer &a, const Integer &b) + {return a/Integer::Gcd(a,b)*b;} +inline Integer EuclideanMultiplicativeInverse(const Integer &a, const Integer &b) + {return a.InverseMod(b);} + +// use Chinese Remainder Theorem to calculate x given x mod p and x mod q +CRYPTOPP_DLL Integer CRYPTOPP_API CRT(const Integer &xp, const Integer &p, const Integer &xq, const Integer &q); +// use this one if u = inverse of p mod q has been precalculated +CRYPTOPP_DLL Integer CRYPTOPP_API CRT(const Integer &xp, const Integer &p, const Integer &xq, const Integer &q, const Integer &u); + +// if b is prime, then Jacobi(a, b) returns 0 if a%b==0, 1 if a is quadratic residue mod b, -1 otherwise +// check a number theory book for what Jacobi symbol means when b is not prime +CRYPTOPP_DLL int CRYPTOPP_API Jacobi(const Integer &a, const Integer &b); + +// calculates the Lucas function V_e(p, 1) mod n +CRYPTOPP_DLL Integer CRYPTOPP_API Lucas(const Integer &e, const Integer &p, const Integer &n); +// calculates x such that m==Lucas(e, x, p*q), p q primes +CRYPTOPP_DLL Integer CRYPTOPP_API InverseLucas(const Integer &e, const Integer &m, const Integer &p, const Integer &q); +// use this one if u=inverse of p mod q has been precalculated +CRYPTOPP_DLL Integer CRYPTOPP_API InverseLucas(const Integer &e, const Integer &m, const Integer &p, const Integer &q, const Integer &u); + +inline Integer ModularExponentiation(const Integer &a, const Integer &e, const Integer &m) + {return a_exp_b_mod_c(a, e, m);} +// returns x such that x*x%p == a, p prime +CRYPTOPP_DLL Integer CRYPTOPP_API ModularSquareRoot(const Integer &a, const Integer &p); +// returns x such that a==ModularExponentiation(x, e, p*q), p q primes, +// and e relatively prime to (p-1)*(q-1) +CRYPTOPP_DLL Integer CRYPTOPP_API ModularRoot(const Integer &a, const Integer &e, const Integer &p, const Integer &q); +// use this one if dp=d%(p-1), dq=d%(q-1), (d is inverse of e mod (p-1)*(q-1)) +// and u=inverse of p mod q have been precalculated +CRYPTOPP_DLL Integer CRYPTOPP_API ModularRoot(const Integer &a, const Integer &dp, const Integer &dq, const Integer &p, const Integer &q, const Integer &u); + +// find r1 and r2 such that ax^2 + bx + c == 0 (mod p) for x in {r1, r2}, p prime +// returns true if solutions exist +CRYPTOPP_DLL bool CRYPTOPP_API SolveModularQuadraticEquation(Integer &r1, Integer &r2, const Integer &a, const Integer &b, const Integer &c, const Integer &p); + +// returns log base 2 of estimated number of operations to calculate discrete log or factor a number +CRYPTOPP_DLL unsigned int CRYPTOPP_API DiscreteLogWorkFactor(unsigned int bitlength); +CRYPTOPP_DLL unsigned int CRYPTOPP_API FactoringWorkFactor(unsigned int bitlength); + +// ******************************************************** + +//! generator of prime numbers of special forms +class CRYPTOPP_DLL PrimeAndGenerator +{ +public: + PrimeAndGenerator() {} + // generate a random prime p of the form 2*q+delta, where delta is 1 or -1 and q is also prime + // Precondition: pbits > 5 + // warning: this is slow, because primes of this form are harder to find + PrimeAndGenerator(signed int delta, RandomNumberGenerator &rng, unsigned int pbits) + {Generate(delta, rng, pbits, pbits-1);} + // generate a random prime p of the form 2*r*q+delta, where q is also prime + // Precondition: qbits > 4 && pbits > qbits + PrimeAndGenerator(signed int delta, RandomNumberGenerator &rng, unsigned int pbits, unsigned qbits) + {Generate(delta, rng, pbits, qbits);} + + void Generate(signed int delta, RandomNumberGenerator &rng, unsigned int pbits, unsigned qbits); + + const Integer& Prime() const {return p;} + const Integer& SubPrime() const {return q;} + const Integer& Generator() const {return g;} + +private: + Integer p, q, g; +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/network.cpp b/CryptoPP/crypto/network.cpp new file mode 100644 index 0000000..b47c236 --- /dev/null +++ b/CryptoPP/crypto/network.cpp @@ -0,0 +1,550 @@ +// network.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "network.h" +#include "wait.h" + +#define CRYPTOPP_TRACE_NETWORK 0 + +NAMESPACE_BEGIN(CryptoPP) + +#ifdef HIGHRES_TIMER_AVAILABLE + +lword LimitedBandwidth::ComputeCurrentTransceiveLimit() +{ + if (!m_maxBytesPerSecond) + return ULONG_MAX; + + double curTime = GetCurTimeAndCleanUp(); + lword total = 0; + for (OpQueue::size_type i=0; i!=m_ops.size(); ++i) + total += m_ops[i].second; + return SaturatingSubtract(m_maxBytesPerSecond, total); +} + +double LimitedBandwidth::TimeToNextTransceive() +{ + if (!m_maxBytesPerSecond) + return 0; + + if (!m_nextTransceiveTime) + ComputeNextTransceiveTime(); + + return SaturatingSubtract(m_nextTransceiveTime, m_timer.ElapsedTimeAsDouble()); +} + +void LimitedBandwidth::NoteTransceive(lword size) +{ + if (m_maxBytesPerSecond) + { + double curTime = GetCurTimeAndCleanUp(); + m_ops.push_back(std::make_pair(curTime, size)); + m_nextTransceiveTime = 0; + } +} + +void LimitedBandwidth::ComputeNextTransceiveTime() +{ + double curTime = GetCurTimeAndCleanUp(); + lword total = 0; + for (unsigned int i=0; i!=m_ops.size(); ++i) + total += m_ops[i].second; + m_nextTransceiveTime = + (total < m_maxBytesPerSecond) ? curTime : m_ops.front().first + 1000; +} + +double LimitedBandwidth::GetCurTimeAndCleanUp() +{ + if (!m_maxBytesPerSecond) + return 0; + + double curTime = m_timer.ElapsedTimeAsDouble(); + while (m_ops.size() && (m_ops.front().first + 1000 < curTime)) + m_ops.pop_front(); + return curTime; +} + +void LimitedBandwidth::GetWaitObjects(WaitObjectContainer &container, const CallStack &callStack) +{ + double nextTransceiveTime = TimeToNextTransceive(); + if (nextTransceiveTime) + container.ScheduleEvent(nextTransceiveTime, CallStack("LimitedBandwidth::GetWaitObjects()", &callStack)); +} + +// ************************************************************* + +size_t NonblockingSource::GeneralPump2( + lword& byteCount, bool blockingOutput, + unsigned long maxTime, bool checkDelimiter, byte delimiter) +{ + m_blockedBySpeedLimit = false; + + if (!GetMaxBytesPerSecond()) + { + size_t ret = DoPump(byteCount, blockingOutput, maxTime, checkDelimiter, delimiter); + m_doPumpBlocked = (ret != 0); + return ret; + } + + bool forever = (maxTime == INFINITE_TIME); + unsigned long timeToGo = maxTime; + Timer timer(Timer::MILLISECONDS, forever); + lword maxSize = byteCount; + byteCount = 0; + + timer.StartTimer(); + + while (true) + { + lword curMaxSize = UnsignedMin(ComputeCurrentTransceiveLimit(), maxSize - byteCount); + + if (curMaxSize || m_doPumpBlocked) + { + if (!forever) timeToGo = SaturatingSubtract(maxTime, timer.ElapsedTime()); + size_t ret = DoPump(curMaxSize, blockingOutput, timeToGo, checkDelimiter, delimiter); + m_doPumpBlocked = (ret != 0); + if (curMaxSize) + { + NoteTransceive(curMaxSize); + byteCount += curMaxSize; + } + if (ret) + return ret; + } + + if (maxSize != ULONG_MAX && byteCount >= maxSize) + break; + + if (!forever) + { + timeToGo = SaturatingSubtract(maxTime, timer.ElapsedTime()); + if (!timeToGo) + break; + } + + double waitTime = TimeToNextTransceive(); + if (!forever && waitTime > timeToGo) + { + m_blockedBySpeedLimit = true; + break; + } + + WaitObjectContainer container; + LimitedBandwidth::GetWaitObjects(container, CallStack("NonblockingSource::GeneralPump2() - speed limit", 0)); + container.Wait((unsigned long)waitTime); + } + + return 0; +} + +size_t NonblockingSource::PumpMessages2(unsigned int &messageCount, bool blocking) +{ + if (messageCount == 0) + return 0; + + messageCount = 0; + + lword byteCount; + do { + byteCount = LWORD_MAX; + RETURN_IF_NONZERO(Pump2(byteCount, blocking)); + } while(byteCount == LWORD_MAX); + + if (!m_messageEndSent && SourceExhausted()) + { + RETURN_IF_NONZERO(AttachedTransformation()->Put2(NULL, 0, GetAutoSignalPropagation(), true)); + m_messageEndSent = true; + messageCount = 1; + } + return 0; +} + +lword NonblockingSink::TimedFlush(unsigned long maxTime, size_t targetSize) +{ + m_blockedBySpeedLimit = false; + + size_t curBufSize = GetCurrentBufferSize(); + if (curBufSize <= targetSize && (targetSize || !EofPending())) + return 0; + + if (!GetMaxBytesPerSecond()) + return DoFlush(maxTime, targetSize); + + bool forever = (maxTime == INFINITE_TIME); + unsigned long timeToGo = maxTime; + Timer timer(Timer::MILLISECONDS, forever); + lword totalFlushed = 0; + + timer.StartTimer(); + + while (true) + { + size_t flushSize = UnsignedMin(curBufSize - targetSize, ComputeCurrentTransceiveLimit()); + if (flushSize || EofPending()) + { + if (!forever) timeToGo = SaturatingSubtract(maxTime, timer.ElapsedTime()); + size_t ret = (size_t)DoFlush(timeToGo, curBufSize - flushSize); + if (ret) + { + NoteTransceive(ret); + curBufSize -= ret; + totalFlushed += ret; + } + } + + if (curBufSize <= targetSize && (targetSize || !EofPending())) + break; + + if (!forever) + { + timeToGo = SaturatingSubtract(maxTime, timer.ElapsedTime()); + if (!timeToGo) + break; + } + + double waitTime = TimeToNextTransceive(); + if (!forever && waitTime > timeToGo) + { + m_blockedBySpeedLimit = true; + break; + } + + WaitObjectContainer container; + LimitedBandwidth::GetWaitObjects(container, CallStack("NonblockingSink::TimedFlush() - speed limit", 0)); + container.Wait((unsigned long)waitTime); + } + + return totalFlushed; +} + +bool NonblockingSink::IsolatedFlush(bool hardFlush, bool blocking) +{ + TimedFlush(blocking ? INFINITE_TIME : 0); + return hardFlush && (!!GetCurrentBufferSize() || EofPending()); +} + +// ************************************************************* + +NetworkSource::NetworkSource(BufferedTransformation *attachment) + : NonblockingSource(attachment), m_buf(1024*16) + , m_waitingForResult(false), m_outputBlocked(false) + , m_dataBegin(0), m_dataEnd(0) +{ +} + +unsigned int NetworkSource::GetMaxWaitObjectCount() const +{ + return LimitedBandwidth::GetMaxWaitObjectCount() + + GetReceiver().GetMaxWaitObjectCount() + + AttachedTransformation()->GetMaxWaitObjectCount(); +} + +void NetworkSource::GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack) +{ + if (BlockedBySpeedLimit()) + LimitedBandwidth::GetWaitObjects(container, CallStack("NetworkSource::GetWaitObjects() - speed limit", &callStack)); + else if (!m_outputBlocked) + { + if (m_dataBegin == m_dataEnd) + AccessReceiver().GetWaitObjects(container, CallStack("NetworkSource::GetWaitObjects() - no data", &callStack)); + else + container.SetNoWait(CallStack("NetworkSource::GetWaitObjects() - have data", &callStack)); + } + + AttachedTransformation()->GetWaitObjects(container, CallStack("NetworkSource::GetWaitObjects() - attachment", &callStack)); +} + +size_t NetworkSource::DoPump(lword &byteCount, bool blockingOutput, unsigned long maxTime, bool checkDelimiter, byte delimiter) +{ + NetworkReceiver &receiver = AccessReceiver(); + + lword maxSize = byteCount; + byteCount = 0; + bool forever = maxTime == INFINITE_TIME; + Timer timer(Timer::MILLISECONDS, forever); + BufferedTransformation *t = AttachedTransformation(); + + if (m_outputBlocked) + goto DoOutput; + + while (true) + { + if (m_dataBegin == m_dataEnd) + { + if (receiver.EofReceived()) + break; + + if (m_waitingForResult) + { + if (receiver.MustWaitForResult() && + !receiver.Wait(SaturatingSubtract(maxTime, timer.ElapsedTime()), + CallStack("NetworkSource::DoPump() - wait receive result", 0))) + break; + + unsigned int recvResult = receiver.GetReceiveResult(); +#if CRYPTOPP_TRACE_NETWORK + OutputDebugString((IntToString((unsigned int)this) + ": Received " + IntToString(recvResult) + " bytes\n").c_str()); +#endif + m_dataEnd += recvResult; + m_waitingForResult = false; + + if (!receiver.MustWaitToReceive() && !receiver.EofReceived() && m_dataEnd != m_buf.size()) + goto ReceiveNoWait; + } + else + { + m_dataEnd = m_dataBegin = 0; + + if (receiver.MustWaitToReceive()) + { + if (!receiver.Wait(SaturatingSubtract(maxTime, timer.ElapsedTime()), + CallStack("NetworkSource::DoPump() - wait receive", 0))) + break; + + receiver.Receive(m_buf+m_dataEnd, m_buf.size()-m_dataEnd); + m_waitingForResult = true; + } + else + { +ReceiveNoWait: + m_waitingForResult = true; + // call Receive repeatedly as long as data is immediately available, + // because some receivers tend to return data in small pieces +#if CRYPTOPP_TRACE_NETWORK + OutputDebugString((IntToString((unsigned int)this) + ": Receiving " + IntToString(m_buf.size()-m_dataEnd) + " bytes\n").c_str()); +#endif + while (receiver.Receive(m_buf+m_dataEnd, m_buf.size()-m_dataEnd)) + { + unsigned int recvResult = receiver.GetReceiveResult(); +#if CRYPTOPP_TRACE_NETWORK + OutputDebugString((IntToString((unsigned int)this) + ": Received " + IntToString(recvResult) + " bytes\n").c_str()); +#endif + m_dataEnd += recvResult; + if (receiver.EofReceived() || m_dataEnd > m_buf.size() /2) + { + m_waitingForResult = false; + break; + } + } + } + } + } + else + { + m_putSize = UnsignedMin(m_dataEnd - m_dataBegin, maxSize - byteCount); + + if (checkDelimiter) + m_putSize = std::find(m_buf+m_dataBegin, m_buf+m_dataBegin+m_putSize, delimiter) - (m_buf+m_dataBegin); + +DoOutput: + size_t result = t->PutModifiable2(m_buf+m_dataBegin, m_putSize, 0, forever || blockingOutput); + if (result) + { + if (t->Wait(SaturatingSubtract(maxTime, timer.ElapsedTime()), + CallStack("NetworkSource::DoPump() - wait attachment", 0))) + goto DoOutput; + else + { + m_outputBlocked = true; + return result; + } + } + m_outputBlocked = false; + + byteCount += m_putSize; + m_dataBegin += m_putSize; + if (checkDelimiter && m_dataBegin < m_dataEnd && m_buf[m_dataBegin] == delimiter) + break; + if (maxSize != ULONG_MAX && byteCount == maxSize) + break; + // once time limit is reached, return even if there is more data waiting + // but make 0 a special case so caller can request a large amount of data to be + // pumped as long as it is immediately available + if (maxTime > 0 && timer.ElapsedTime() > maxTime) + break; + } + } + + return 0; +} + +// ************************************************************* + +NetworkSink::NetworkSink(unsigned int maxBufferSize, unsigned int autoFlushBound) + : m_maxBufferSize(maxBufferSize), m_autoFlushBound(autoFlushBound) + , m_needSendResult(false), m_wasBlocked(false), m_eofState(EOF_NONE) + , m_buffer(STDMIN(16U*1024U+256, maxBufferSize)), m_skipBytes(0) + , m_speedTimer(Timer::MILLISECONDS), m_byteCountSinceLastTimerReset(0) + , m_currentSpeed(0), m_maxObservedSpeed(0) +{ +} + +float NetworkSink::ComputeCurrentSpeed() +{ + if (m_speedTimer.ElapsedTime() > 1000) + { + m_currentSpeed = m_byteCountSinceLastTimerReset * 1000 / m_speedTimer.ElapsedTime(); + m_maxObservedSpeed = STDMAX(m_currentSpeed, m_maxObservedSpeed * 0.98f); + m_byteCountSinceLastTimerReset = 0; + m_speedTimer.StartTimer(); +// OutputDebugString(("max speed: " + IntToString((int)m_maxObservedSpeed) + " current speed: " + IntToString((int)m_currentSpeed) + "\n").c_str()); + } + return m_currentSpeed; +} + +float NetworkSink::GetMaxObservedSpeed() const +{ + lword m = GetMaxBytesPerSecond(); + return m ? STDMIN(m_maxObservedSpeed, float(CRYPTOPP_VC6_INT64 m)) : m_maxObservedSpeed; +} + +unsigned int NetworkSink::GetMaxWaitObjectCount() const +{ + return LimitedBandwidth::GetMaxWaitObjectCount() + GetSender().GetMaxWaitObjectCount(); +} + +void NetworkSink::GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack) +{ + if (BlockedBySpeedLimit()) + LimitedBandwidth::GetWaitObjects(container, CallStack("NetworkSink::GetWaitObjects() - speed limit", &callStack)); + else if (m_wasBlocked) + AccessSender().GetWaitObjects(container, CallStack("NetworkSink::GetWaitObjects() - was blocked", &callStack)); + else if (!m_buffer.IsEmpty()) + AccessSender().GetWaitObjects(container, CallStack("NetworkSink::GetWaitObjects() - buffer not empty", &callStack)); + else if (EofPending()) + AccessSender().GetWaitObjects(container, CallStack("NetworkSink::GetWaitObjects() - EOF pending", &callStack)); +} + +size_t NetworkSink::Put2(const byte *inString, size_t length, int messageEnd, bool blocking) +{ + if (m_eofState == EOF_DONE) + { + if (length || messageEnd) + throw Exception(Exception::OTHER_ERROR, "NetworkSink::Put2() being called after EOF had been sent"); + + return 0; + } + + if (m_eofState > EOF_NONE) + goto EofSite; + + { + if (m_skipBytes) + { + assert(length >= m_skipBytes); + inString += m_skipBytes; + length -= m_skipBytes; + } + + m_buffer.Put(inString, length); + + if (!blocking || m_buffer.CurrentSize() > m_autoFlushBound) + TimedFlush(0, 0); + + size_t targetSize = messageEnd ? 0 : m_maxBufferSize; + if (blocking) + TimedFlush(INFINITE_TIME, targetSize); + + if (m_buffer.CurrentSize() > targetSize) + { + assert(!blocking); + m_wasBlocked = true; + m_skipBytes += length; + size_t blockedBytes = UnsignedMin(length, m_buffer.CurrentSize() - targetSize); + return STDMAX(blockedBytes, 1); + } + + m_wasBlocked = false; + m_skipBytes = 0; + } + + if (messageEnd) + { + m_eofState = EOF_PENDING_SEND; + + EofSite: + TimedFlush(blocking ? INFINITE_TIME : 0, 0); + if (m_eofState != EOF_DONE) + return 1; + } + + return 0; +} + +lword NetworkSink::DoFlush(unsigned long maxTime, size_t targetSize) +{ + NetworkSender &sender = AccessSender(); + + bool forever = maxTime == INFINITE_TIME; + Timer timer(Timer::MILLISECONDS, forever); + unsigned int totalFlushSize = 0; + + while (true) + { + if (m_buffer.CurrentSize() <= targetSize) + break; + + if (m_needSendResult) + { + if (sender.MustWaitForResult() && + !sender.Wait(SaturatingSubtract(maxTime, timer.ElapsedTime()), + CallStack("NetworkSink::DoFlush() - wait send result", 0))) + break; + + unsigned int sendResult = sender.GetSendResult(); +#if CRYPTOPP_TRACE_NETWORK + OutputDebugString((IntToString((unsigned int)this) + ": Sent " + IntToString(sendResult) + " bytes\n").c_str()); +#endif + m_buffer.Skip(sendResult); + totalFlushSize += sendResult; + m_needSendResult = false; + + if (!m_buffer.AnyRetrievable()) + break; + } + + unsigned long timeOut = maxTime ? SaturatingSubtract(maxTime, timer.ElapsedTime()) : 0; + if (sender.MustWaitToSend() && !sender.Wait(timeOut, CallStack("NetworkSink::DoFlush() - wait send", 0))) + break; + + size_t contiguousSize = 0; + const byte *block = m_buffer.Spy(contiguousSize); + +#if CRYPTOPP_TRACE_NETWORK + OutputDebugString((IntToString((unsigned int)this) + ": Sending " + IntToString(contiguousSize) + " bytes\n").c_str()); +#endif + sender.Send(block, contiguousSize); + m_needSendResult = true; + + if (maxTime > 0 && timeOut == 0) + break; // once time limit is reached, return even if there is more data waiting + } + + m_byteCountSinceLastTimerReset += totalFlushSize; + ComputeCurrentSpeed(); + + if (m_buffer.IsEmpty() && !m_needSendResult) + { + if (m_eofState == EOF_PENDING_SEND) + { + sender.SendEof(); + m_eofState = sender.MustWaitForEof() ? EOF_PENDING_DELIVERY : EOF_DONE; + } + + while (m_eofState == EOF_PENDING_DELIVERY) + { + unsigned long timeOut = maxTime ? SaturatingSubtract(maxTime, timer.ElapsedTime()) : 0; + if (!sender.Wait(timeOut, CallStack("NetworkSink::DoFlush() - wait EOF", 0))) + break; + + if (sender.EofSent()) + m_eofState = EOF_DONE; + } + } + + return totalFlushSize; +} + +#endif // #ifdef HIGHRES_TIMER_AVAILABLE + +NAMESPACE_END diff --git a/CryptoPP/crypto/network.h b/CryptoPP/crypto/network.h new file mode 100644 index 0000000..d9b3c66 --- /dev/null +++ b/CryptoPP/crypto/network.h @@ -0,0 +1,235 @@ +#ifndef CRYPTOPP_NETWORK_H +#define CRYPTOPP_NETWORK_H + +#include "config.h" + +#ifdef HIGHRES_TIMER_AVAILABLE + +#include "filters.h" +#include "hrtimer.h" + +#include + +NAMESPACE_BEGIN(CryptoPP) + +class LimitedBandwidth +{ +public: + LimitedBandwidth(lword maxBytesPerSecond = 0) + : m_maxBytesPerSecond(maxBytesPerSecond), m_timer(Timer::MILLISECONDS) + , m_nextTransceiveTime(0) + { m_timer.StartTimer(); } + + lword GetMaxBytesPerSecond() const + { return m_maxBytesPerSecond; } + + void SetMaxBytesPerSecond(lword v) + { m_maxBytesPerSecond = v; } + + lword ComputeCurrentTransceiveLimit(); + + double TimeToNextTransceive(); + + void NoteTransceive(lword size); + +public: + /*! GetWaitObjects() must be called despite the 0 return from GetMaxWaitObjectCount(); + the 0 is because the ScheduleEvent() method is used instead of adding a wait object */ + unsigned int GetMaxWaitObjectCount() const { return 0; } + void GetWaitObjects(WaitObjectContainer &container, const CallStack &callStack); + +private: + lword m_maxBytesPerSecond; + + typedef std::deque > OpQueue; + OpQueue m_ops; + + Timer m_timer; + double m_nextTransceiveTime; + + void ComputeNextTransceiveTime(); + double GetCurTimeAndCleanUp(); +}; + +//! a Source class that can pump from a device for a specified amount of time. +class CRYPTOPP_NO_VTABLE NonblockingSource : public AutoSignaling, public LimitedBandwidth +{ +public: + NonblockingSource(BufferedTransformation *attachment) + : m_messageEndSent(false) , m_doPumpBlocked(false), m_blockedBySpeedLimit(false) {Detach(attachment);} + + //! \name NONBLOCKING SOURCE + //@{ + + //! pump up to maxSize bytes using at most maxTime milliseconds + /*! If checkDelimiter is true, pump up to delimiter, which itself is not extracted or pumped. */ + size_t GeneralPump2(lword &byteCount, bool blockingOutput=true, unsigned long maxTime=INFINITE_TIME, bool checkDelimiter=false, byte delimiter='\n'); + + lword GeneralPump(lword maxSize=LWORD_MAX, unsigned long maxTime=INFINITE_TIME, bool checkDelimiter=false, byte delimiter='\n') + { + GeneralPump2(maxSize, true, maxTime, checkDelimiter, delimiter); + return maxSize; + } + lword TimedPump(unsigned long maxTime) + {return GeneralPump(LWORD_MAX, maxTime);} + lword PumpLine(byte delimiter='\n', lword maxSize=1024) + {return GeneralPump(maxSize, INFINITE_TIME, true, delimiter);} + + size_t Pump2(lword &byteCount, bool blocking=true) + {return GeneralPump2(byteCount, blocking, blocking ? INFINITE_TIME : 0);} + size_t PumpMessages2(unsigned int &messageCount, bool blocking=true); + //@} + +protected: + virtual size_t DoPump(lword &byteCount, bool blockingOutput, + unsigned long maxTime, bool checkDelimiter, byte delimiter) =0; + + bool BlockedBySpeedLimit() const { return m_blockedBySpeedLimit; } + +private: + bool m_messageEndSent, m_doPumpBlocked, m_blockedBySpeedLimit; +}; + +//! Network Receiver +class CRYPTOPP_NO_VTABLE NetworkReceiver : public Waitable +{ +public: + virtual bool MustWaitToReceive() {return false;} + virtual bool MustWaitForResult() {return false;} + //! receive data from network source, returns whether result is immediately available + virtual bool Receive(byte* buf, size_t bufLen) =0; + virtual unsigned int GetReceiveResult() =0; + virtual bool EofReceived() const =0; +}; + +class CRYPTOPP_NO_VTABLE NonblockingSinkInfo +{ +public: + virtual ~NonblockingSinkInfo() {} + virtual size_t GetMaxBufferSize() const =0; + virtual size_t GetCurrentBufferSize() const =0; + virtual bool EofPending() const =0; + //! compute the current speed of this sink in bytes per second + virtual float ComputeCurrentSpeed() =0; + //! get the maximum observed speed of this sink in bytes per second + virtual float GetMaxObservedSpeed() const =0; +}; + +//! a Sink class that queues input and can flush to a device for a specified amount of time. +class CRYPTOPP_NO_VTABLE NonblockingSink : public Sink, public NonblockingSinkInfo, public LimitedBandwidth +{ +public: + NonblockingSink() : m_blockedBySpeedLimit(false) {} + + bool IsolatedFlush(bool hardFlush, bool blocking); + + //! flush to device for no more than maxTime milliseconds + /*! This function will repeatedly attempt to flush data to some device, until + the queue is empty, or a total of maxTime milliseconds have elapsed. + If maxTime == 0, at least one attempt will be made to flush some data, but + it is likely that not all queued data will be flushed, even if the device + is ready to receive more data without waiting. If you want to flush as much data + as possible without waiting for the device, call this function in a loop. + For example: while (sink.TimedFlush(0) > 0) {} + \return number of bytes flushed + */ + lword TimedFlush(unsigned long maxTime, size_t targetSize = 0); + + virtual void SetMaxBufferSize(size_t maxBufferSize) =0; + //! set a bound which will cause sink to flush if exceeded by GetCurrentBufferSize() + virtual void SetAutoFlushBound(size_t bound) =0; + +protected: + virtual lword DoFlush(unsigned long maxTime, size_t targetSize) = 0; + + bool BlockedBySpeedLimit() const { return m_blockedBySpeedLimit; } + +private: + bool m_blockedBySpeedLimit; +}; + +//! Network Sender +class CRYPTOPP_NO_VTABLE NetworkSender : public Waitable +{ +public: + virtual bool MustWaitToSend() {return false;} + virtual bool MustWaitForResult() {return false;} + virtual void Send(const byte* buf, size_t bufLen) =0; + virtual unsigned int GetSendResult() =0; + virtual bool MustWaitForEof() {return false;} + virtual void SendEof() =0; + virtual bool EofSent() {return false;} // implement if MustWaitForEof() == true +}; + +//! Network Source +class CRYPTOPP_NO_VTABLE NetworkSource : public NonblockingSource +{ +public: + NetworkSource(BufferedTransformation *attachment); + + unsigned int GetMaxWaitObjectCount() const; + void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack); + + bool SourceExhausted() const {return m_dataBegin == m_dataEnd && GetReceiver().EofReceived();} + +protected: + size_t DoPump(lword &byteCount, bool blockingOutput, unsigned long maxTime, bool checkDelimiter, byte delimiter); + + virtual NetworkReceiver & AccessReceiver() =0; + const NetworkReceiver & GetReceiver() const {return const_cast(this)->AccessReceiver();} + +private: + SecByteBlock m_buf; + size_t m_putSize, m_dataBegin, m_dataEnd; + bool m_waitingForResult, m_outputBlocked; +}; + +//! Network Sink +class CRYPTOPP_NO_VTABLE NetworkSink : public NonblockingSink +{ +public: + NetworkSink(unsigned int maxBufferSize, unsigned int autoFlushBound); + + unsigned int GetMaxWaitObjectCount() const; + void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack); + + size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking); + + void SetMaxBufferSize(size_t maxBufferSize) {m_maxBufferSize = maxBufferSize; m_buffer.SetNodeSize(UnsignedMin(maxBufferSize, 16U*1024U+256U));} + void SetAutoFlushBound(size_t bound) {m_autoFlushBound = bound;} + + size_t GetMaxBufferSize() const {return m_maxBufferSize;} + size_t GetCurrentBufferSize() const {return (size_t)m_buffer.CurrentSize();} + + void ClearBuffer() { m_buffer.Clear(); } + + bool EofPending() const { return m_eofState > EOF_NONE && m_eofState < EOF_DONE; } + + //! compute the current speed of this sink in bytes per second + float ComputeCurrentSpeed(); + //! get the maximum observed speed of this sink in bytes per second + float GetMaxObservedSpeed() const; + +protected: + lword DoFlush(unsigned long maxTime, size_t targetSize); + + virtual NetworkSender & AccessSender() =0; + const NetworkSender & GetSender() const {return const_cast(this)->AccessSender();} + +private: + enum EofState { EOF_NONE, EOF_PENDING_SEND, EOF_PENDING_DELIVERY, EOF_DONE }; + + size_t m_maxBufferSize, m_autoFlushBound; + bool m_needSendResult, m_wasBlocked; + EofState m_eofState; + ByteQueue m_buffer; + size_t m_skipBytes; + Timer m_speedTimer; + float m_byteCountSinceLastTimerReset, m_currentSpeed, m_maxObservedSpeed; +}; + +NAMESPACE_END + +#endif // #ifdef HIGHRES_TIMER_AVAILABLE + +#endif diff --git a/CryptoPP/crypto/nr.h b/CryptoPP/crypto/nr.h new file mode 100644 index 0000000..f13aceb --- /dev/null +++ b/CryptoPP/crypto/nr.h @@ -0,0 +1,6 @@ +#ifndef CRYPTOPP_NR_H +#define CRYPTOPP_NR_H + +#include "gfpcrypt.h" + +#endif diff --git a/CryptoPP/crypto/nr1024.dat b/CryptoPP/crypto/nr1024.dat new file mode 100644 index 0000000..6778ccf --- /dev/null +++ b/CryptoPP/crypto/nr1024.dat @@ -0,0 +1 @@ +3082014C0201003082012C06072A8648CE3804013082011F02818100F89F4EBE58E222B517D218D615BDC00611501CD18417886BD3FCBD22578C4611B1E8C06EB0FE9D473A5589BC277AA58C1979DC2869B728D78EC38B4C044A790A60314E7BD3DFDC0BBD8B770A9271D7D048F3E13C73866D096C7304782125847C70EDD721B36F1C379CF7CCEE0A728DD66336ED5F93E8A1BD3EDB22C8761EB987021526A578AB11C3A0812A636D24D120BE544B7973E4D302818100BF927ACE4D175A44622494E37F9552E97B74303321FFEF9B76CDECB14F7D612608DDFEA77C04A8FCACCF7F16CB01AE05AD5EDB65C3B9A380D720F34C7D96C8817E2EFF7D0049EE149DF61C52D7C80271206155CDAEBC8A7F4A8DCE5196E3C18FD5EDF11A394C43A5D59BC65D976817438CA0A7F01713548F61355E976DE75E1E04170215247B2531CFF01D1B1665F0CFD2A836446798353330 \ No newline at end of file diff --git a/CryptoPP/crypto/nr2048.dat b/CryptoPP/crypto/nr2048.dat new file mode 100644 index 0000000..d9f11f1 --- /dev/null +++ b/CryptoPP/crypto/nr2048.dat @@ -0,0 +1 @@ +3082025D0201003082023506072A8648CE38040130820228028201010083C69F32A1F3A67B201D7A92BA204281681DAAD29F50BD866D70A2E01438653B18602AFE606AA925389381682EC0E2CE5D5D366793917879860799ECEDDB4831ED4A4E76D9C34FFDD0BC786588F00E8A19705B997C4298F9CAF9AEE46E0A5677AA1240DC141BD78A8720A829F64C912FA3D961ADE698C5344F18FE4CE70CF7B94F45258C6A9553830FFB80B6BB7E1C510D4526C1904C1D6E2F1B8C1CA6499DBD291438717131804FA2F5F42E5C06293D6DA493C88A38EBC6A6DCF40B2BAB0BF7C7FA0F9C070F1C48FD12CA2B7337E9C58EB9AFDAC6FEEAB0BD62415B26D405D6BF47F11D70B1740BC398A76BE70723A829082EB548D35F4D78E4E015DAD12D5B021D083118E4DC11622CB53E7E4D7634BFBDE45A2D8F8B097A251803505315028201005BAC6CBFE089F75274A532564735786477478F19BE099AB38E0F843393D6D81964CBCFF4B68C5DA2614F06BB844672288F0A65216954990051BA691CA6796AFAAE91A79350F53D9DF3CC688387306EFFDCEF70A14A672E2103B8C861523703157D05DF6EB42DCD81506C88300ED8D8ED40D41AB6D669D309C976B84D82C8D18747578358CBA1EF4B00118B0DEEF11409DD8CB0D83399A33E10C18249574FA2242AE4241CD789C891FEC1C63771EE4517274493240EDAAC44AEDC42F318A5122B052244DFA9A282B8D94BC4BAB360D44E4D0204F8D28817B5B6F808047C92032AA94926D697CFA2FC211FAAE26A5F1FC2B1EB03DA68AD5E01EAC489FB64A66EA3041F021D042ADA16929DA18A7A3C8FDCDD8FC46A6D8AAB79FF33D60E2BF09DEF4F \ No newline at end of file diff --git a/CryptoPP/crypto/oaep.cpp b/CryptoPP/crypto/oaep.cpp new file mode 100644 index 0000000..cbdef84 --- /dev/null +++ b/CryptoPP/crypto/oaep.cpp @@ -0,0 +1,97 @@ +// oaep.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "oaep.h" +#include + +NAMESPACE_BEGIN(CryptoPP) + +// ******************************************************** + +size_t OAEP_Base::MaxUnpaddedLength(size_t paddedLength) const +{ + return SaturatingSubtract(paddedLength/8, 1+2*DigestSize()); +} + +void OAEP_Base::Pad(RandomNumberGenerator &rng, const byte *input, size_t inputLength, byte *oaepBlock, size_t oaepBlockLen, const NameValuePairs ¶meters) const +{ + assert (inputLength <= MaxUnpaddedLength(oaepBlockLen)); + + // convert from bit length to byte length + if (oaepBlockLen % 8 != 0) + { + oaepBlock[0] = 0; + oaepBlock++; + } + oaepBlockLen /= 8; + + std::auto_ptr pHash(NewHash()); + const size_t hLen = pHash->DigestSize(); + const size_t seedLen = hLen, dbLen = oaepBlockLen-seedLen; + byte *const maskedSeed = oaepBlock; + byte *const maskedDB = oaepBlock+seedLen; + + ConstByteArrayParameter encodingParameters; + parameters.GetValue(Name::EncodingParameters(), encodingParameters); + + // DB = pHash || 00 ... || 01 || M + pHash->CalculateDigest(maskedDB, encodingParameters.begin(), encodingParameters.size()); + memset(maskedDB+hLen, 0, dbLen-hLen-inputLength-1); + maskedDB[dbLen-inputLength-1] = 0x01; + memcpy(maskedDB+dbLen-inputLength, input, inputLength); + + rng.GenerateBlock(maskedSeed, seedLen); + std::auto_ptr pMGF(NewMGF()); + pMGF->GenerateAndMask(*pHash, maskedDB, dbLen, maskedSeed, seedLen); + pMGF->GenerateAndMask(*pHash, maskedSeed, seedLen, maskedDB, dbLen); +} + +DecodingResult OAEP_Base::Unpad(const byte *oaepBlock, size_t oaepBlockLen, byte *output, const NameValuePairs ¶meters) const +{ + bool invalid = false; + + // convert from bit length to byte length + if (oaepBlockLen % 8 != 0) + { + invalid = (oaepBlock[0] != 0) || invalid; + oaepBlock++; + } + oaepBlockLen /= 8; + + std::auto_ptr pHash(NewHash()); + const size_t hLen = pHash->DigestSize(); + const size_t seedLen = hLen, dbLen = oaepBlockLen-seedLen; + + invalid = (oaepBlockLen < 2*hLen+1) || invalid; + + SecByteBlock t(oaepBlock, oaepBlockLen); + byte *const maskedSeed = t; + byte *const maskedDB = t+seedLen; + + std::auto_ptr pMGF(NewMGF()); + pMGF->GenerateAndMask(*pHash, maskedSeed, seedLen, maskedDB, dbLen); + pMGF->GenerateAndMask(*pHash, maskedDB, dbLen, maskedSeed, seedLen); + + ConstByteArrayParameter encodingParameters; + parameters.GetValue(Name::EncodingParameters(), encodingParameters); + + // DB = pHash' || 00 ... || 01 || M + byte *M = std::find(maskedDB+hLen, maskedDB+dbLen, 0x01); + invalid = (M == maskedDB+dbLen) || invalid; + invalid = (std::find_if(maskedDB+hLen, M, std::bind2nd(std::not_equal_to(), 0)) != M) || invalid; + invalid = !pHash->VerifyDigest(maskedDB, encodingParameters.begin(), encodingParameters.size()) || invalid; + + if (invalid) + return DecodingResult(); + + M++; + memcpy(output, M, maskedDB+dbLen-M); + return DecodingResult(maskedDB+dbLen-M); +} + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/oaep.h b/CryptoPP/crypto/oaep.h new file mode 100644 index 0000000..b40c30b --- /dev/null +++ b/CryptoPP/crypto/oaep.h @@ -0,0 +1,42 @@ +#ifndef CRYPTOPP_OAEP_H +#define CRYPTOPP_OAEP_H + +#include "pubkey.h" +#include "sha.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! _ +class CRYPTOPP_DLL OAEP_Base : public PK_EncryptionMessageEncodingMethod +{ +public: + bool ParameterSupported(const char *name) const {return strcmp(name, Name::EncodingParameters()) == 0;} + size_t MaxUnpaddedLength(size_t paddedLength) const; + void Pad(RandomNumberGenerator &rng, const byte *raw, size_t inputLength, byte *padded, size_t paddedLength, const NameValuePairs ¶meters) const; + DecodingResult Unpad(const byte *padded, size_t paddedLength, byte *raw, const NameValuePairs ¶meters) const; + +protected: + virtual unsigned int DigestSize() const =0; + virtual HashTransformation * NewHash() const =0; + virtual MaskGeneratingFunction * NewMGF() const =0; +}; + +//! EME-OAEP, for use with classes derived from TF_ES +template +class OAEP : public OAEP_Base, public EncryptionStandard +{ +public: + static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string("OAEP-") + MGF::StaticAlgorithmName() + "(" + H::StaticAlgorithmName() + ")";} + typedef OAEP EncryptionMessageEncodingMethod; + +protected: + unsigned int DigestSize() const {return H::DIGESTSIZE;} + HashTransformation * NewHash() const {return new H;} + MaskGeneratingFunction * NewMGF() const {return new MGF;} +}; + +CRYPTOPP_DLL_TEMPLATE_CLASS OAEP; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/oids.h b/CryptoPP/crypto/oids.h new file mode 100644 index 0000000..56e15be --- /dev/null +++ b/CryptoPP/crypto/oids.h @@ -0,0 +1,112 @@ +#ifndef CRYPTOPP_OIDS_H +#define CRYPTOPP_OIDS_H + +// crypto-related ASN.1 object identifiers + +#include "asn.h" + +NAMESPACE_BEGIN(CryptoPP) + +NAMESPACE_BEGIN(ASN1) + +#define DEFINE_OID(value, name) inline OID name() {return value;} + +DEFINE_OID(1, iso) + DEFINE_OID(iso()+2, member_body) + DEFINE_OID(member_body()+840, iso_us) + DEFINE_OID(iso_us()+10040, ansi_x9_57) + DEFINE_OID(ansi_x9_57()+4+1, id_dsa) + DEFINE_OID(iso_us()+10045, ansi_x9_62) + DEFINE_OID(ansi_x9_62()+1, id_fieldType) + DEFINE_OID(id_fieldType()+1, prime_field) + DEFINE_OID(id_fieldType()+2, characteristic_two_field) + DEFINE_OID(characteristic_two_field()+3, id_characteristic_two_basis) + DEFINE_OID(id_characteristic_two_basis()+1, gnBasis) + DEFINE_OID(id_characteristic_two_basis()+2, tpBasis) + DEFINE_OID(id_characteristic_two_basis()+3, ppBasis) + DEFINE_OID(ansi_x9_62()+2, id_publicKeyType) + DEFINE_OID(id_publicKeyType()+1, id_ecPublicKey) + DEFINE_OID(ansi_x9_62()+3, ansi_x9_62_curves) + DEFINE_OID(ansi_x9_62_curves()+1, ansi_x9_62_curves_prime) + DEFINE_OID(ansi_x9_62_curves_prime()+1, secp192r1) + DEFINE_OID(ansi_x9_62_curves_prime()+7, secp256r1) + DEFINE_OID(iso_us()+113549, rsadsi) + DEFINE_OID(rsadsi()+1, pkcs) + DEFINE_OID(pkcs()+1, pkcs_1) + DEFINE_OID(pkcs_1()+1, rsaEncryption); + DEFINE_OID(rsadsi()+2, rsadsi_digestAlgorithm) + DEFINE_OID(rsadsi_digestAlgorithm()+2, id_md2) + DEFINE_OID(rsadsi_digestAlgorithm()+5, id_md5) + DEFINE_OID(iso()+3, identified_organization); + DEFINE_OID(identified_organization()+14, oiw); + DEFINE_OID(oiw()+14, oiw_secsig); + DEFINE_OID(oiw_secsig()+2, oiw_secsig_algorithms); + DEFINE_OID(oiw_secsig_algorithms()+26, id_sha1); + DEFINE_OID(identified_organization()+36, teletrust); + DEFINE_OID(teletrust()+3+2+1, id_ripemd160) + DEFINE_OID(identified_organization()+132, certicom); + DEFINE_OID(certicom()+0, certicom_ellipticCurve); + // these are sorted by curve type and then by OID + // first curves based on GF(p) + DEFINE_OID(certicom_ellipticCurve()+6, secp112r1); + DEFINE_OID(certicom_ellipticCurve()+7, secp112r2); + DEFINE_OID(certicom_ellipticCurve()+8, secp160r1); + DEFINE_OID(certicom_ellipticCurve()+9, secp160k1); + DEFINE_OID(certicom_ellipticCurve()+10, secp256k1); + DEFINE_OID(certicom_ellipticCurve()+28, secp128r1); + DEFINE_OID(certicom_ellipticCurve()+29, secp128r2); + DEFINE_OID(certicom_ellipticCurve()+30, secp160r2); + DEFINE_OID(certicom_ellipticCurve()+31, secp192k1); + DEFINE_OID(certicom_ellipticCurve()+32, secp224k1); + DEFINE_OID(certicom_ellipticCurve()+33, secp224r1); + DEFINE_OID(certicom_ellipticCurve()+34, secp384r1); + DEFINE_OID(certicom_ellipticCurve()+35, secp521r1); + // then curves based on GF(2^n) + DEFINE_OID(certicom_ellipticCurve()+1, sect163k1); + DEFINE_OID(certicom_ellipticCurve()+2, sect163r1); + DEFINE_OID(certicom_ellipticCurve()+3, sect239k1); + DEFINE_OID(certicom_ellipticCurve()+4, sect113r1); + DEFINE_OID(certicom_ellipticCurve()+5, sect113r2); + DEFINE_OID(certicom_ellipticCurve()+15, sect163r2); + DEFINE_OID(certicom_ellipticCurve()+16, sect283k1); + DEFINE_OID(certicom_ellipticCurve()+17, sect283r1); + DEFINE_OID(certicom_ellipticCurve()+22, sect131r1); + DEFINE_OID(certicom_ellipticCurve()+23, sect131r2); + DEFINE_OID(certicom_ellipticCurve()+24, sect193r1); + DEFINE_OID(certicom_ellipticCurve()+25, sect193r2); + DEFINE_OID(certicom_ellipticCurve()+26, sect233k1); + DEFINE_OID(certicom_ellipticCurve()+27, sect233r1); + DEFINE_OID(certicom_ellipticCurve()+36, sect409k1); + DEFINE_OID(certicom_ellipticCurve()+37, sect409r1); + DEFINE_OID(certicom_ellipticCurve()+38, sect571k1); + DEFINE_OID(certicom_ellipticCurve()+39, sect571r1); +DEFINE_OID(2, joint_iso_ccitt) + DEFINE_OID(joint_iso_ccitt()+16, country) + DEFINE_OID(country()+840, joint_iso_ccitt_us) + DEFINE_OID(joint_iso_ccitt_us()+1, us_organization) + DEFINE_OID(us_organization()+101, us_gov) + DEFINE_OID(us_gov()+3, csor) + DEFINE_OID(csor()+4, nistalgorithms) + DEFINE_OID(nistalgorithms()+1, aes) + DEFINE_OID(aes()+1, id_aes128_ECB) + DEFINE_OID(aes()+2, id_aes128_cbc) + DEFINE_OID(aes()+3, id_aes128_ofb) + DEFINE_OID(aes()+4, id_aes128_cfb) + DEFINE_OID(aes()+21, id_aes192_ECB) + DEFINE_OID(aes()+22, id_aes192_cbc) + DEFINE_OID(aes()+23, id_aes192_ofb) + DEFINE_OID(aes()+24, id_aes192_cfb) + DEFINE_OID(aes()+41, id_aes256_ECB) + DEFINE_OID(aes()+42, id_aes256_cbc) + DEFINE_OID(aes()+43, id_aes256_ofb) + DEFINE_OID(aes()+44, id_aes256_cfb) + DEFINE_OID(nistalgorithms()+2, nist_hashalgs) + DEFINE_OID(nist_hashalgs()+1, id_sha256) + DEFINE_OID(nist_hashalgs()+2, id_sha384) + DEFINE_OID(nist_hashalgs()+3, id_sha512) + +NAMESPACE_END + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/osrng.cpp b/CryptoPP/crypto/osrng.cpp new file mode 100644 index 0000000..6ad488c --- /dev/null +++ b/CryptoPP/crypto/osrng.cpp @@ -0,0 +1,171 @@ +// osrng.cpp - written and placed in the public domain by Wei Dai + +// Thanks to Leonard Janke for the suggestion for AutoSeededRandomPool. + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "osrng.h" + +#ifdef OS_RNG_AVAILABLE + +#include "rng.h" + +#ifdef CRYPTOPP_WIN32_AVAILABLE +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x0400 +#endif +#include +#include +#endif + +#ifdef CRYPTOPP_UNIX_AVAILABLE +#include +#include +#include +#endif + +NAMESPACE_BEGIN(CryptoPP) + +#if defined(NONBLOCKING_RNG_AVAILABLE) || defined(BLOCKING_RNG_AVAILABLE) +OS_RNG_Err::OS_RNG_Err(const std::string &operation) + : Exception(OTHER_ERROR, "OS_Rng: " + operation + " operation failed with error " + +#ifdef CRYPTOPP_WIN32_AVAILABLE + "0x" + IntToString(GetLastError(), 16) +#else + IntToString(errno) +#endif + ) +{ +} +#endif + +#ifdef NONBLOCKING_RNG_AVAILABLE + +#ifdef CRYPTOPP_WIN32_AVAILABLE + +MicrosoftCryptoProvider::MicrosoftCryptoProvider() +{ + if(!CryptAcquireContext(&m_hProvider, 0, 0, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) + throw OS_RNG_Err("CryptAcquireContext"); +} + +MicrosoftCryptoProvider::~MicrosoftCryptoProvider() +{ + CryptReleaseContext(m_hProvider, 0); +} + +#endif + +NonblockingRng::NonblockingRng() +{ +#ifndef CRYPTOPP_WIN32_AVAILABLE + m_fd = open("/dev/urandom",O_RDONLY); + if (m_fd == -1) + throw OS_RNG_Err("open /dev/urandom"); +#endif +} + +NonblockingRng::~NonblockingRng() +{ +#ifndef CRYPTOPP_WIN32_AVAILABLE + close(m_fd); +#endif +} + +void NonblockingRng::GenerateBlock(byte *output, size_t size) +{ +#ifdef CRYPTOPP_WIN32_AVAILABLE +# ifdef WORKAROUND_MS_BUG_Q258000 + const MicrosoftCryptoProvider &m_Provider = Singleton().Ref(); +# endif + if (!CryptGenRandom(m_Provider.GetProviderHandle(), (DWORD)size, output)) + throw OS_RNG_Err("CryptGenRandom"); +#else + if (read(m_fd, output, size) != size) + throw OS_RNG_Err("read /dev/urandom"); +#endif +} + +#endif + +// ************************************************************* + +#ifdef BLOCKING_RNG_AVAILABLE + +#ifndef CRYPTOPP_BLOCKING_RNG_FILENAME +#ifdef __OpenBSD__ +#define CRYPTOPP_BLOCKING_RNG_FILENAME "/dev/srandom" +#else +#define CRYPTOPP_BLOCKING_RNG_FILENAME "/dev/random" +#endif +#endif + +BlockingRng::BlockingRng() +{ + m_fd = open(CRYPTOPP_BLOCKING_RNG_FILENAME,O_RDONLY); + if (m_fd == -1) + throw OS_RNG_Err("open " CRYPTOPP_BLOCKING_RNG_FILENAME); +} + +BlockingRng::~BlockingRng() +{ + close(m_fd); +} + +void BlockingRng::GenerateBlock(byte *output, size_t size) +{ + while (size) + { + // on some systems /dev/random will block until all bytes + // are available, on others it will returns immediately + ssize_t len = read(m_fd, output, size); + if (len < 0) + throw OS_RNG_Err("read " CRYPTOPP_BLOCKING_RNG_FILENAME); + size -= len; + output += len; + if (size) + sleep(1); + } +} + +#endif + +// ************************************************************* + +void OS_GenerateRandomBlock(bool blocking, byte *output, size_t size) +{ +#ifdef NONBLOCKING_RNG_AVAILABLE + if (blocking) +#endif + { +#ifdef BLOCKING_RNG_AVAILABLE + BlockingRng rng; + rng.GenerateBlock(output, size); +#endif + } + +#ifdef BLOCKING_RNG_AVAILABLE + if (!blocking) +#endif + { +#ifdef NONBLOCKING_RNG_AVAILABLE + NonblockingRng rng; + rng.GenerateBlock(output, size); +#endif + } +} + +void AutoSeededRandomPool::Reseed(bool blocking, unsigned int seedSize) +{ + SecByteBlock seed(seedSize); + OS_GenerateRandomBlock(blocking, seed, seedSize); + IncorporateEntropy(seed, seedSize); +} + +NAMESPACE_END + +#endif + +#endif diff --git a/CryptoPP/crypto/osrng.h b/CryptoPP/crypto/osrng.h new file mode 100644 index 0000000..839e768 --- /dev/null +++ b/CryptoPP/crypto/osrng.h @@ -0,0 +1,153 @@ +#ifndef CRYPTOPP_OSRNG_H +#define CRYPTOPP_OSRNG_H + +#include "config.h" + +#ifdef OS_RNG_AVAILABLE + +#include "randpool.h" +#include "rng.h" +#include "aes.h" +#include "sha.h" +#include "fips140.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! Exception class for Operating-System Random Number Generator. +class CRYPTOPP_DLL OS_RNG_Err : public Exception +{ +public: + OS_RNG_Err(const std::string &operation); +}; + +#ifdef NONBLOCKING_RNG_AVAILABLE + +#ifdef CRYPTOPP_WIN32_AVAILABLE +class CRYPTOPP_DLL MicrosoftCryptoProvider +{ +public: + MicrosoftCryptoProvider(); + ~MicrosoftCryptoProvider(); +#if defined(_WIN64) + typedef unsigned __int64 ProviderHandle; // type HCRYPTPROV, avoid #include +#else + typedef unsigned long ProviderHandle; +#endif + ProviderHandle GetProviderHandle() const {return m_hProvider;} +private: + ProviderHandle m_hProvider; +}; + +#pragma comment(lib, "advapi32.lib") +#endif + +//! encapsulate CryptoAPI's CryptGenRandom or /dev/urandom +class CRYPTOPP_DLL NonblockingRng : public RandomNumberGenerator +{ +public: + NonblockingRng(); + ~NonblockingRng(); + void GenerateBlock(byte *output, size_t size); + +protected: +#ifdef CRYPTOPP_WIN32_AVAILABLE +# ifndef WORKAROUND_MS_BUG_Q258000 + MicrosoftCryptoProvider m_Provider; +# endif +#else + int m_fd; +#endif +}; + +#endif + +#ifdef BLOCKING_RNG_AVAILABLE + +//! encapsulate /dev/random, or /dev/srandom on OpenBSD +class CRYPTOPP_DLL BlockingRng : public RandomNumberGenerator +{ +public: + BlockingRng(); + ~BlockingRng(); + void GenerateBlock(byte *output, size_t size); + +protected: + int m_fd; +}; + +#endif + +CRYPTOPP_DLL void CRYPTOPP_API OS_GenerateRandomBlock(bool blocking, byte *output, size_t size); + +//! Automaticly Seeded Randomness Pool +/*! This class seeds itself using an operating system provided RNG. */ +class CRYPTOPP_DLL AutoSeededRandomPool : public RandomPool +{ +public: + //! use blocking to choose seeding with BlockingRng or NonblockingRng. the parameter is ignored if only one of these is available + explicit AutoSeededRandomPool(bool blocking = false, unsigned int seedSize = 32) + {Reseed(blocking, seedSize);} + void Reseed(bool blocking = false, unsigned int seedSize = 32); +}; + +//! RNG from ANSI X9.17 Appendix C, seeded using an OS provided RNG +template +class AutoSeededX917RNG : public RandomNumberGenerator, public NotCopyable +{ +public: + //! use blocking to choose seeding with BlockingRng or NonblockingRng. the parameter is ignored if only one of these is available + explicit AutoSeededX917RNG(bool blocking = false) + {Reseed(blocking);} + void Reseed(bool blocking = false, const byte *additionalEntropy = NULL, size_t length = 0); + // exposed for testing + void Reseed(const byte *key, size_t keylength, const byte *seed, const byte *timeVector); + + bool CanIncorporateEntropy() const {return true;} + void IncorporateEntropy(const byte *input, size_t length) {Reseed(false, input, length);} + void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length) {m_rng->GenerateIntoBufferedTransformation(target, channel, length);} + +private: + member_ptr m_rng; +}; + +template +void AutoSeededX917RNG::Reseed(const byte *key, size_t keylength, const byte *seed, const byte *timeVector) +{ + m_rng.reset(new X917RNG(new typename BLOCK_CIPHER::Encryption(key, keylength), seed, timeVector)); +} + +template +void AutoSeededX917RNG::Reseed(bool blocking, const byte *input, size_t length) +{ + SecByteBlock seed(BLOCK_CIPHER::BLOCKSIZE + BLOCK_CIPHER::DEFAULT_KEYLENGTH); + const byte *key; + do + { + OS_GenerateRandomBlock(blocking, seed, seed.size()); + if (length > 0) + { + SHA256 hash; + hash.Update(seed, seed.size()); + hash.Update(input, length); + hash.TruncatedFinal(seed, UnsignedMin(hash.DigestSize(), seed.size())); + } + key = seed + BLOCK_CIPHER::BLOCKSIZE; + } // check that seed and key don't have same value + while (memcmp(key, seed, STDMIN((unsigned int)BLOCK_CIPHER::BLOCKSIZE, (unsigned int)BLOCK_CIPHER::DEFAULT_KEYLENGTH)) == 0); + + Reseed(key, BLOCK_CIPHER::DEFAULT_KEYLENGTH, seed, NULL); +} + +CRYPTOPP_DLL_TEMPLATE_CLASS AutoSeededX917RNG; + +#if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 +typedef AutoSeededX917RNG DefaultAutoSeededRNG; +#else +typedef AutoSeededRandomPool DefaultAutoSeededRNG; +#endif + +NAMESPACE_END + +#endif + +#endif diff --git a/CryptoPP/crypto/panama.cpp b/CryptoPP/crypto/panama.cpp new file mode 100644 index 0000000..06f0235 --- /dev/null +++ b/CryptoPP/crypto/panama.cpp @@ -0,0 +1,505 @@ +// panama.cpp - written and placed in the public domain by Wei Dai + +// use "cl /EP /P /DCRYPTOPP_GENERATE_X64_MASM panama.cpp" to generate MASM code + +#include "pch.h" + +#ifndef CRYPTOPP_GENERATE_X64_MASM + +#include "panama.h" +#include "misc.h" +#include "cpu.h" + +NAMESPACE_BEGIN(CryptoPP) + +template +void Panama::Reset() +{ + memset(m_state, 0, m_state.SizeInBytes()); +#if CRYPTOPP_BOOL_SSSE3_ASM_AVAILABLE + m_state[17] = HasSSSE3(); +#endif +} + +#endif // #ifndef CRYPTOPP_GENERATE_X64_MASM + +#ifdef CRYPTOPP_X64_MASM_AVAILABLE +extern "C" { +void Panama_SSE2_Pull(size_t count, word32 *state, word32 *z, const word32 *y); +} +#elif CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE + +#ifdef CRYPTOPP_GENERATE_X64_MASM + Panama_SSE2_Pull PROC FRAME + alloc_stack(2*16+8) + save_xmm128 xmm6, 0h + save_xmm128 xmm7, 10h + .endprolog +#else +#pragma warning(disable: 4731) // frame pointer register 'ebp' modified by inline assembly code +void CRYPTOPP_NOINLINE Panama_SSE2_Pull(size_t count, word32 *state, word32 *z, const word32 *y) +{ +#ifdef __GNUC__ + __asm__ __volatile__ + ( + ".intel_syntax noprefix;" + AS_PUSH_IF86( bx) +#else + AS2( mov AS_REG_1, count) + AS2( mov AS_REG_2, state) + AS2( mov AS_REG_3, z) + AS2( mov AS_REG_4, y) +#endif +#endif // #ifdef CRYPTOPP_GENERATE_X64_MASM + +#if CRYPTOPP_BOOL_X86 + #define REG_loopEnd [esp] +#elif defined(CRYPTOPP_GENERATE_X64_MASM) + #define REG_loopEnd rdi +#else + #define REG_loopEnd r8 +#endif + + AS2( shl AS_REG_1, 5) + ASJ( jz, 5, f) + AS2( mov AS_REG_6d, [AS_REG_2+4*17]) + AS2( add AS_REG_1, AS_REG_6) + + #if CRYPTOPP_BOOL_X64 + AS2( mov REG_loopEnd, AS_REG_1) + #else + AS1( push ebp) + AS1( push AS_REG_1) + #endif + + AS2( movdqa xmm0, XMMWORD_PTR [AS_REG_2+0*16]) + AS2( movdqa xmm1, XMMWORD_PTR [AS_REG_2+1*16]) + AS2( movdqa xmm2, XMMWORD_PTR [AS_REG_2+2*16]) + AS2( movdqa xmm3, XMMWORD_PTR [AS_REG_2+3*16]) + AS2( mov eax, dword ptr [AS_REG_2+4*16]) + + ASL(4) + // gamma and pi +#if CRYPTOPP_BOOL_SSSE3_ASM_AVAILABLE + AS2( test AS_REG_6, 1) + ASJ( jnz, 6, f) +#endif + AS2( movdqa xmm6, xmm2) + AS2( movss xmm6, xmm3) + ASS( pshufd xmm5, xmm6, 0, 3, 2, 1) + AS2( movd xmm6, eax) + AS2( movdqa xmm7, xmm3) + AS2( movss xmm7, xmm6) + ASS( pshufd xmm6, xmm7, 0, 3, 2, 1) +#if CRYPTOPP_BOOL_SSSE3_ASM_AVAILABLE + ASJ( jmp, 7, f) + ASL(6) + AS2( movdqa xmm5, xmm3) + AS3( palignr xmm5, xmm2, 4) + AS2( movd xmm6, eax) + AS3( palignr xmm6, xmm3, 4) + ASL(7) +#endif + + AS2( movd AS_REG_1d, xmm2) + AS1( not AS_REG_1d) + AS2( movd AS_REG_7d, xmm3) + AS2( or AS_REG_1d, AS_REG_7d) + AS2( xor eax, AS_REG_1d) + +#define SSE2_Index(i) ASM_MOD(((i)*13+16), 17) + +#define pi(i) \ + AS2( movd AS_REG_1d, xmm7)\ + AS2( rol AS_REG_1d, ASM_MOD((ASM_MOD(5*i,17)*(ASM_MOD(5*i,17)+1)/2), 32))\ + AS2( mov [AS_REG_2+SSE2_Index(ASM_MOD(5*(i), 17))*4], AS_REG_1d) + +#define pi4(x, y, z, a, b, c, d) \ + AS2( pcmpeqb xmm7, xmm7)\ + AS2( pxor xmm7, x)\ + AS2( por xmm7, y)\ + AS2( pxor xmm7, z)\ + pi(a)\ + ASS( pshuflw xmm7, xmm7, 1, 0, 3, 2)\ + pi(b)\ + AS2( punpckhqdq xmm7, xmm7)\ + pi(c)\ + ASS( pshuflw xmm7, xmm7, 1, 0, 3, 2)\ + pi(d) + + pi4(xmm1, xmm2, xmm3, 1, 5, 9, 13) + pi4(xmm0, xmm1, xmm2, 2, 6, 10, 14) + pi4(xmm6, xmm0, xmm1, 3, 7, 11, 15) + pi4(xmm5, xmm6, xmm0, 4, 8, 12, 16) + + // output keystream and update buffer here to hide partial memory stalls between pi and theta + AS2( movdqa xmm4, xmm3) + AS2( punpcklqdq xmm3, xmm2) // 1 5 2 6 + AS2( punpckhdq xmm4, xmm2) // 9 10 13 14 + AS2( movdqa xmm2, xmm1) + AS2( punpcklqdq xmm1, xmm0) // 3 7 4 8 + AS2( punpckhdq xmm2, xmm0) // 11 12 15 16 + + // keystream + AS2( test AS_REG_3, AS_REG_3) + ASJ( jz, 0, f) + AS2( movdqa xmm6, xmm4) + AS2( punpcklqdq xmm4, xmm2) + AS2( punpckhqdq xmm6, xmm2) + AS2( test AS_REG_4, 15) + ASJ( jnz, 2, f) + AS2( test AS_REG_4, AS_REG_4) + ASJ( jz, 1, f) + AS2( pxor xmm4, [AS_REG_4]) + AS2( pxor xmm6, [AS_REG_4+16]) + AS2( add AS_REG_4, 32) + ASJ( jmp, 1, f) + ASL(2) + AS2( movdqu xmm0, [AS_REG_4]) + AS2( movdqu xmm2, [AS_REG_4+16]) + AS2( pxor xmm4, xmm0) + AS2( pxor xmm6, xmm2) + AS2( add AS_REG_4, 32) + ASL(1) + AS2( test AS_REG_3, 15) + ASJ( jnz, 3, f) + AS2( movdqa XMMWORD_PTR [AS_REG_3], xmm4) + AS2( movdqa XMMWORD_PTR [AS_REG_3+16], xmm6) + AS2( add AS_REG_3, 32) + ASJ( jmp, 0, f) + ASL(3) + AS2( movdqu XMMWORD_PTR [AS_REG_3], xmm4) + AS2( movdqu XMMWORD_PTR [AS_REG_3+16], xmm6) + AS2( add AS_REG_3, 32) + ASL(0) + + // buffer update + AS2( lea AS_REG_1, [AS_REG_6 + 32]) + AS2( and AS_REG_1, 31*32) + AS2( lea AS_REG_7, [AS_REG_6 + (32-24)*32]) + AS2( and AS_REG_7, 31*32) + + AS2( movdqa xmm0, XMMWORD_PTR [AS_REG_2+20*4+AS_REG_1+0*8]) + AS2( pxor xmm3, xmm0) + ASS( pshufd xmm0, xmm0, 2, 3, 0, 1) + AS2( movdqa XMMWORD_PTR [AS_REG_2+20*4+AS_REG_1+0*8], xmm3) + AS2( pxor xmm0, XMMWORD_PTR [AS_REG_2+20*4+AS_REG_7+2*8]) + AS2( movdqa XMMWORD_PTR [AS_REG_2+20*4+AS_REG_7+2*8], xmm0) + + AS2( movdqa xmm4, XMMWORD_PTR [AS_REG_2+20*4+AS_REG_1+2*8]) + AS2( pxor xmm1, xmm4) + AS2( movdqa XMMWORD_PTR [AS_REG_2+20*4+AS_REG_1+2*8], xmm1) + AS2( pxor xmm4, XMMWORD_PTR [AS_REG_2+20*4+AS_REG_7+0*8]) + AS2( movdqa XMMWORD_PTR [AS_REG_2+20*4+AS_REG_7+0*8], xmm4) + + // theta + AS2( movdqa xmm3, XMMWORD_PTR [AS_REG_2+3*16]) + AS2( movdqa xmm2, XMMWORD_PTR [AS_REG_2+2*16]) + AS2( movdqa xmm1, XMMWORD_PTR [AS_REG_2+1*16]) + AS2( movdqa xmm0, XMMWORD_PTR [AS_REG_2+0*16]) + +#if CRYPTOPP_BOOL_SSSE3_ASM_AVAILABLE + AS2( test AS_REG_6, 1) + ASJ( jnz, 8, f) +#endif + AS2( movd xmm6, eax) + AS2( movdqa xmm7, xmm3) + AS2( movss xmm7, xmm6) + AS2( movdqa xmm6, xmm2) + AS2( movss xmm6, xmm3) + AS2( movdqa xmm5, xmm1) + AS2( movss xmm5, xmm2) + AS2( movdqa xmm4, xmm0) + AS2( movss xmm4, xmm1) + ASS( pshufd xmm7, xmm7, 0, 3, 2, 1) + ASS( pshufd xmm6, xmm6, 0, 3, 2, 1) + ASS( pshufd xmm5, xmm5, 0, 3, 2, 1) + ASS( pshufd xmm4, xmm4, 0, 3, 2, 1) +#if CRYPTOPP_BOOL_SSSE3_ASM_AVAILABLE + ASJ( jmp, 9, f) + ASL(8) + AS2( movd xmm7, eax) + AS3( palignr xmm7, xmm3, 4) + AS2( movq xmm6, xmm3) + AS3( palignr xmm6, xmm2, 4) + AS2( movq xmm5, xmm2) + AS3( palignr xmm5, xmm1, 4) + AS2( movq xmm4, xmm1) + AS3( palignr xmm4, xmm0, 4) + ASL(9) +#endif + + AS2( xor eax, 1) + AS2( movd AS_REG_1d, xmm0) + AS2( xor eax, AS_REG_1d) + AS2( movd AS_REG_1d, xmm3) + AS2( xor eax, AS_REG_1d) + + AS2( pxor xmm3, xmm2) + AS2( pxor xmm2, xmm1) + AS2( pxor xmm1, xmm0) + AS2( pxor xmm0, xmm7) + AS2( pxor xmm3, xmm7) + AS2( pxor xmm2, xmm6) + AS2( pxor xmm1, xmm5) + AS2( pxor xmm0, xmm4) + + // sigma + AS2( lea AS_REG_1, [AS_REG_6 + (32-4)*32]) + AS2( and AS_REG_1, 31*32) + AS2( lea AS_REG_7, [AS_REG_6 + 16*32]) + AS2( and AS_REG_7, 31*32) + + AS2( movdqa xmm4, XMMWORD_PTR [AS_REG_2+20*4+AS_REG_1+0*16]) + AS2( movdqa xmm5, XMMWORD_PTR [AS_REG_2+20*4+AS_REG_7+0*16]) + AS2( movdqa xmm6, xmm4) + AS2( punpcklqdq xmm4, xmm5) + AS2( punpckhqdq xmm6, xmm5) + AS2( pxor xmm3, xmm4) + AS2( pxor xmm2, xmm6) + + AS2( movdqa xmm4, XMMWORD_PTR [AS_REG_2+20*4+AS_REG_1+1*16]) + AS2( movdqa xmm5, XMMWORD_PTR [AS_REG_2+20*4+AS_REG_7+1*16]) + AS2( movdqa xmm6, xmm4) + AS2( punpcklqdq xmm4, xmm5) + AS2( punpckhqdq xmm6, xmm5) + AS2( pxor xmm1, xmm4) + AS2( pxor xmm0, xmm6) + + // loop + AS2( add AS_REG_6, 32) + AS2( cmp AS_REG_6, REG_loopEnd) + ASJ( jne, 4, b) + + // save state + AS2( mov [AS_REG_2+4*16], eax) + AS2( movdqa XMMWORD_PTR [AS_REG_2+3*16], xmm3) + AS2( movdqa XMMWORD_PTR [AS_REG_2+2*16], xmm2) + AS2( movdqa XMMWORD_PTR [AS_REG_2+1*16], xmm1) + AS2( movdqa XMMWORD_PTR [AS_REG_2+0*16], xmm0) + + #if CRYPTOPP_BOOL_X86 + AS2( add esp, 4) + AS1( pop ebp) + #endif + ASL(5) + +#ifdef __GNUC__ + AS_POP_IF86( bx) + ".att_syntax prefix;" + : + #if CRYPTOPP_BOOL_X64 + : "D" (count), "S" (state), "d" (z), "c" (y) + : "%r8", "%r9", "r10", "%eax", "memory", "cc", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7" + #else + : "c" (count), "d" (state), "S" (z), "D" (y) + : "%eax", "memory", "cc" + #endif + ); +#endif +#ifdef CRYPTOPP_GENERATE_X64_MASM + movdqa xmm6, [rsp + 0h] + movdqa xmm7, [rsp + 10h] + add rsp, 2*16+8 + ret + Panama_SSE2_Pull ENDP +#else +} +#endif +#endif // #ifdef CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE + +#ifndef CRYPTOPP_GENERATE_X64_MASM + +template +void Panama::Iterate(size_t count, const word32 *p, word32 *z, const word32 *y) +{ + word32 bstart = m_state[17]; + word32 *const aPtr = m_state; + word32 cPtr[17]; + +#define bPtr ((byte *)(aPtr+20)) + +// reorder the state for SSE2 +// a and c: 4 8 12 16 | 3 7 11 15 | 2 6 10 14 | 1 5 9 13 | 0 +// xmm0 xmm1 xmm2 xmm3 eax +#define a(i) aPtr[((i)*13+16) % 17] // 13 is inverse of 4 mod 17 +#define c(i) cPtr[((i)*13+16) % 17] +// b: 0 4 | 1 5 | 2 6 | 3 7 +#define b(i, j) b##i[(j)*2%8 + (j)/4] + +// output +#define OA(i) z[i] = ConditionalByteReverse(B::ToEnum(), a(i+9)) +#define OX(i) z[i] = y[i] ^ ConditionalByteReverse(B::ToEnum(), a(i+9)) +// buffer update +#define US(i) {word32 t=b(0,i); b(0,i)=ConditionalByteReverse(B::ToEnum(), p[i])^t; b(25,(i+6)%8)^=t;} +#define UL(i) {word32 t=b(0,i); b(0,i)=a(i+1)^t; b(25,(i+6)%8)^=t;} +// gamma and pi +#define GP(i) c(5*i%17) = rotlFixed(a(i) ^ (a((i+1)%17) | ~a((i+2)%17)), ((5*i%17)*((5*i%17)+1)/2)%32) +// theta and sigma +#define T(i,x) a(i) = c(i) ^ c((i+1)%17) ^ c((i+4)%17) ^ x +#define TS1S(i) T(i+1, ConditionalByteReverse(B::ToEnum(), p[i])) +#define TS1L(i) T(i+1, b(4,i)) +#define TS2(i) T(i+9, b(16,i)) + + while (count--) + { + if (z) + { + if (y) + { + OX(0); OX(1); OX(2); OX(3); OX(4); OX(5); OX(6); OX(7); + y += 8; + } + else + { + OA(0); OA(1); OA(2); OA(3); OA(4); OA(5); OA(6); OA(7); + } + z += 8; + } + + word32 *const b16 = (word32 *)(bPtr+((bstart+16*32) & 31*32)); + word32 *const b4 = (word32 *)(bPtr+((bstart+(32-4)*32) & 31*32)); + bstart += 32; + word32 *const b0 = (word32 *)(bPtr+((bstart) & 31*32)); + word32 *const b25 = (word32 *)(bPtr+((bstart+(32-25)*32) & 31*32)); + + if (p) + { + US(0); US(1); US(2); US(3); US(4); US(5); US(6); US(7); + } + else + { + UL(0); UL(1); UL(2); UL(3); UL(4); UL(5); UL(6); UL(7); + } + + GP(0); + GP(1); + GP(2); + GP(3); + GP(4); + GP(5); + GP(6); + GP(7); + GP(8); + GP(9); + GP(10); + GP(11); + GP(12); + GP(13); + GP(14); + GP(15); + GP(16); + + T(0,1); + + if (p) + { + TS1S(0); TS1S(1); TS1S(2); TS1S(3); TS1S(4); TS1S(5); TS1S(6); TS1S(7); + p += 8; + } + else + { + TS1L(0); TS1L(1); TS1L(2); TS1L(3); TS1L(4); TS1L(5); TS1L(6); TS1L(7); + } + + TS2(0); TS2(1); TS2(2); TS2(3); TS2(4); TS2(5); TS2(6); TS2(7); + } + m_state[17] = bstart; +} + +namespace Weak { +template +size_t PanamaHash::HashMultipleBlocks(const word32 *input, size_t length) +{ + this->Iterate(length / this->BLOCKSIZE, input); + return length % this->BLOCKSIZE; +} + +template +void PanamaHash::TruncatedFinal(byte *hash, size_t size) +{ + this->ThrowIfInvalidTruncatedSize(size); + + PadLastBlock(this->BLOCKSIZE, 0x01); + + HashEndianCorrectedBlock(this->m_data); + + this->Iterate(32); // pull + + FixedSizeSecBlock buf; + this->Iterate(1, NULL, buf, NULL); + + memcpy(hash, buf, size); + + this->Restart(); // reinit for next use +} +} + +template +void PanamaCipherPolicy::CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length) +{ + assert(length==32); + memcpy(m_key, key, 32); +} + +template +void PanamaCipherPolicy::CipherResynchronize(byte *keystreamBuffer, const byte *iv) +{ + this->Reset(); + this->Iterate(1, m_key); + if (iv && IsAligned(iv)) + this->Iterate(1, (const word32 *)iv); + else + { + FixedSizeSecBlock buf; + if (iv) + memcpy(buf, iv, 32); + else + memset(buf, 0, 32); + this->Iterate(1, buf); + } + +#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE || defined(CRYPTOPP_X64_MASM_AVAILABLE) + if (B::ToEnum() == LITTLE_ENDIAN_ORDER && HasSSE2()) + Panama_SSE2_Pull(32, this->m_state, NULL, NULL); + else +#endif + this->Iterate(32); +} + +#if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X64 +template +unsigned int PanamaCipherPolicy::GetAlignment() const +{ +#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE || defined(CRYPTOPP_X64_MASM_AVAILABLE) + if (B::ToEnum() == LITTLE_ENDIAN_ORDER && HasSSE2()) + return 16; + else +#endif + return 1; +} +#endif + +template +void PanamaCipherPolicy::OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount) +{ +#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE || defined(CRYPTOPP_X64_MASM_AVAILABLE) + if (B::ToEnum() == LITTLE_ENDIAN_ORDER && HasSSE2()) + Panama_SSE2_Pull(iterationCount, this->m_state, (word32 *)output, (const word32 *)input); + else +#endif + this->Iterate(iterationCount, NULL, (word32 *)output, (const word32 *)input); +} + +template class Panama; +template class Panama; + +template class Weak::PanamaHash; +template class Weak::PanamaHash; + +template class PanamaCipherPolicy; +template class PanamaCipherPolicy; + +NAMESPACE_END + +#endif // #ifndef CRYPTOPP_GENERATE_X64_MASM diff --git a/CryptoPP/crypto/panama.h b/CryptoPP/crypto/panama.h new file mode 100644 index 0000000..18a19bb --- /dev/null +++ b/CryptoPP/crypto/panama.h @@ -0,0 +1,144 @@ +#ifndef CRYPTOPP_PANAMA_H +#define CRYPTOPP_PANAMA_H + +#include "strciphr.h" +#include "iterhash.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// base class, do not use directly +template +class CRYPTOPP_NO_VTABLE Panama +{ +public: + void Reset(); + void Iterate(size_t count, const word32 *p=NULL, word32 *z=NULL, const word32 *y=NULL); + +protected: + typedef word32 Stage[8]; + CRYPTOPP_CONSTANT(STAGES = 32) + + FixedSizeAlignedSecBlock m_state; +}; + +namespace Weak { +/// Panama Hash +template +class PanamaHash : protected Panama, public AlgorithmImpl, PanamaHash > +{ +public: + CRYPTOPP_CONSTANT(DIGESTSIZE = 32) + PanamaHash() {Panama::Reset();} + unsigned int DigestSize() const {return DIGESTSIZE;} + void TruncatedFinal(byte *hash, size_t size); + static const char * StaticAlgorithmName() {return B::ToEnum() == BIG_ENDIAN_ORDER ? "Panama-BE" : "Panama-LE";} + +protected: + void Init() {Panama::Reset();} + void HashEndianCorrectedBlock(const word32 *data) {this->Iterate(1, data);} // push + size_t HashMultipleBlocks(const word32 *input, size_t length); + word32* StateBuf() {return NULL;} +}; +} + +//! MAC construction using a hermetic hash function +template +class HermeticHashFunctionMAC : public AlgorithmImpl > >, T_Info> +{ +public: + void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms) + { + m_key.Assign(key, length); + Restart(); + } + + void Restart() + { + m_hash.Restart(); + m_keyed = false; + } + + void Update(const byte *input, size_t length) + { + if (!m_keyed) + KeyHash(); + m_hash.Update(input, length); + } + + void TruncatedFinal(byte *digest, size_t digestSize) + { + if (!m_keyed) + KeyHash(); + m_hash.TruncatedFinal(digest, digestSize); + m_keyed = false; + } + + unsigned int DigestSize() const + {return m_hash.DigestSize();} + unsigned int BlockSize() const + {return m_hash.BlockSize();} + unsigned int OptimalBlockSize() const + {return m_hash.OptimalBlockSize();} + unsigned int OptimalDataAlignment() const + {return m_hash.OptimalDataAlignment();} + +protected: + void KeyHash() + { + m_hash.Update(m_key, m_key.size()); + m_keyed = true; + } + + T_Hash m_hash; + bool m_keyed; + SecByteBlock m_key; +}; + +namespace Weak { +/// Panama MAC +template +class PanamaMAC : public HermeticHashFunctionMAC > +{ +public: + PanamaMAC() {} + PanamaMAC(const byte *key, unsigned int length) + {this->SetKey(key, length);} +}; +} + +//! algorithm info +template +struct PanamaCipherInfo : public FixedKeyLength<32, SimpleKeyingInterface::UNIQUE_IV, 32> +{ + static const char * StaticAlgorithmName() {return B::ToEnum() == BIG_ENDIAN_ORDER ? "Panama-BE" : "Panama-LE";} +}; + +//! _ +template +class PanamaCipherPolicy : public AdditiveCipherConcretePolicy, + public PanamaCipherInfo, + protected Panama +{ +protected: + void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length); + void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount); + bool IsRandomAccess() const {return false;} + void CipherResynchronize(byte *keystreamBuffer, const byte *iv); +#if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X64 + unsigned int GetAlignment() const; +#endif + + FixedSizeSecBlock m_key; +}; + +//! Panama Stream Cipher +template +struct PanamaCipher : public PanamaCipherInfo, public SymmetricCipherDocumentation +{ + typedef SymmetricCipherFinal, AdditiveCipherTemplate<> >, PanamaCipherInfo > Encryption; + typedef Encryption Decryption; +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/pch.cpp b/CryptoPP/crypto/pch.cpp new file mode 100644 index 0000000..9e6b2e0 --- /dev/null +++ b/CryptoPP/crypto/pch.cpp @@ -0,0 +1 @@ +#include "pch.h" diff --git a/CryptoPP/crypto/pch.h b/CryptoPP/crypto/pch.h new file mode 100644 index 0000000..765ebde --- /dev/null +++ b/CryptoPP/crypto/pch.h @@ -0,0 +1,21 @@ +#ifndef CRYPTOPP_PCH_H +#define CRYPTOPP_PCH_H + +#ifdef CRYPTOPP_GENERATE_X64_MASM + + #include "cpu.h" + +#else + + #include "config.h" + + #ifdef USE_PRECOMPILED_HEADERS + #include "simple.h" + #include "secblock.h" + #include "misc.h" + #include "smartptr.h" + #endif + +#endif + +#endif diff --git a/CryptoPP/crypto/pkcspad.cpp b/CryptoPP/crypto/pkcspad.cpp new file mode 100644 index 0000000..5a8b6ca --- /dev/null +++ b/CryptoPP/crypto/pkcspad.cpp @@ -0,0 +1,124 @@ +// pkcspad.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_PKCSPAD_CPP // SunCC workaround: compiler could cause this file to be included twice +#define CRYPTOPP_PKCSPAD_CPP + +#include "pkcspad.h" +#include + +NAMESPACE_BEGIN(CryptoPP) + +// more in dll.cpp +template<> const byte PKCS_DigestDecoration::decoration[] = {0x30,0x20,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x02,0x05,0x00,0x04,0x10}; +template<> const unsigned int PKCS_DigestDecoration::length = sizeof(PKCS_DigestDecoration::decoration); + +template<> const byte PKCS_DigestDecoration::decoration[] = {0x30,0x20,0x30,0x0c,0x06,0x08,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x02,0x05,0x05,0x00,0x04,0x10}; +template<> const unsigned int PKCS_DigestDecoration::length = sizeof(PKCS_DigestDecoration::decoration); + +template<> const byte PKCS_DigestDecoration::decoration[] = {0x30,0x21,0x30,0x09,0x06,0x05,0x2b,0x24,0x03,0x02,0x01,0x05,0x00,0x04,0x14}; +template<> const unsigned int PKCS_DigestDecoration::length = sizeof(PKCS_DigestDecoration::decoration); + +template<> const byte PKCS_DigestDecoration::decoration[] = {0x30,0x29,0x30,0x0D,0x06,0x09,0x2B,0x06,0x01,0x04,0x01,0xDA,0x47,0x0C,0x02,0x05,0x00,0x04,0x18}; +template<> const unsigned int PKCS_DigestDecoration::length = sizeof(PKCS_DigestDecoration::decoration); + +size_t PKCS_EncryptionPaddingScheme::MaxUnpaddedLength(size_t paddedLength) const +{ + return SaturatingSubtract(paddedLength/8, 10U); +} + +void PKCS_EncryptionPaddingScheme::Pad(RandomNumberGenerator &rng, const byte *input, size_t inputLen, byte *pkcsBlock, size_t pkcsBlockLen, const NameValuePairs ¶meters) const +{ + assert (inputLen <= MaxUnpaddedLength(pkcsBlockLen)); // this should be checked by caller + + // convert from bit length to byte length + if (pkcsBlockLen % 8 != 0) + { + pkcsBlock[0] = 0; + pkcsBlock++; + } + pkcsBlockLen /= 8; + + pkcsBlock[0] = 2; // block type 2 + + // pad with non-zero random bytes + for (unsigned i = 1; i < pkcsBlockLen-inputLen-1; i++) + pkcsBlock[i] = (byte)rng.GenerateWord32(1, 0xff); + + pkcsBlock[pkcsBlockLen-inputLen-1] = 0; // separator + memcpy(pkcsBlock+pkcsBlockLen-inputLen, input, inputLen); +} + +DecodingResult PKCS_EncryptionPaddingScheme::Unpad(const byte *pkcsBlock, size_t pkcsBlockLen, byte *output, const NameValuePairs ¶meters) const +{ + bool invalid = false; + size_t maxOutputLen = MaxUnpaddedLength(pkcsBlockLen); + + // convert from bit length to byte length + if (pkcsBlockLen % 8 != 0) + { + invalid = (pkcsBlock[0] != 0) || invalid; + pkcsBlock++; + } + pkcsBlockLen /= 8; + + // Require block type 2. + invalid = (pkcsBlock[0] != 2) || invalid; + + // skip past the padding until we find the separator + size_t i=1; + while (i maxOutputLen) || invalid; + + if (invalid) + return DecodingResult(); + + memcpy (output, pkcsBlock+i, outputLen); + return DecodingResult(outputLen); +} + +// ******************************************************** + +#ifndef CRYPTOPP_IMPORTS + +void PKCS1v15_SignatureMessageEncodingMethod::ComputeMessageRepresentative(RandomNumberGenerator &rng, + const byte *recoverableMessage, size_t recoverableMessageLength, + HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, + byte *representative, size_t representativeBitLength) const +{ + assert(representativeBitLength >= MinRepresentativeBitLength(hashIdentifier.second, hash.DigestSize())); + + size_t pkcsBlockLen = representativeBitLength; + // convert from bit length to byte length + if (pkcsBlockLen % 8 != 0) + { + representative[0] = 0; + representative++; + } + pkcsBlockLen /= 8; + + representative[0] = 1; // block type 1 + + unsigned int digestSize = hash.DigestSize(); + byte *pPadding = representative + 1; + byte *pDigest = representative + pkcsBlockLen - digestSize; + byte *pHashId = pDigest - hashIdentifier.second; + byte *pSeparator = pHashId - 1; + + // pad with 0xff + memset(pPadding, 0xff, pSeparator-pPadding); + *pSeparator = 0; + memcpy(pHashId, hashIdentifier.first, hashIdentifier.second); + hash.Final(pDigest); +} + +#endif + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/pkcspad.h b/CryptoPP/crypto/pkcspad.h new file mode 100644 index 0000000..096a923 --- /dev/null +++ b/CryptoPP/crypto/pkcspad.h @@ -0,0 +1,94 @@ +#ifndef CRYPTOPP_PKCSPAD_H +#define CRYPTOPP_PKCSPAD_H + +#include "cryptlib.h" +#include "pubkey.h" + +#ifdef CRYPTOPP_IS_DLL +#include "sha.h" +#endif + +NAMESPACE_BEGIN(CryptoPP) + +//! EME-PKCS1-v1_5 +class PKCS_EncryptionPaddingScheme : public PK_EncryptionMessageEncodingMethod +{ +public: + static const char * StaticAlgorithmName() {return "EME-PKCS1-v1_5";} + + size_t MaxUnpaddedLength(size_t paddedLength) const; + void Pad(RandomNumberGenerator &rng, const byte *raw, size_t inputLength, byte *padded, size_t paddedLength, const NameValuePairs ¶meters) const; + DecodingResult Unpad(const byte *padded, size_t paddedLength, byte *raw, const NameValuePairs ¶meters) const; +}; + +template class PKCS_DigestDecoration +{ +public: + static const byte decoration[]; + static const unsigned int length; +}; + +// PKCS_DigestDecoration can be instantiated with the following +// classes as specified in PKCS#1 v2.0 and P1363a +class SHA1; +class RIPEMD160; +class Tiger; +class SHA224; +class SHA256; +class SHA384; +class SHA512; +namespace Weak1 { +class MD2; +class MD5; +} +// end of list + +#ifdef CRYPTOPP_IS_DLL +CRYPTOPP_DLL_TEMPLATE_CLASS PKCS_DigestDecoration; +CRYPTOPP_DLL_TEMPLATE_CLASS PKCS_DigestDecoration; +CRYPTOPP_DLL_TEMPLATE_CLASS PKCS_DigestDecoration; +CRYPTOPP_DLL_TEMPLATE_CLASS PKCS_DigestDecoration; +CRYPTOPP_DLL_TEMPLATE_CLASS PKCS_DigestDecoration; +#endif + +//! EMSA-PKCS1-v1_5 +class CRYPTOPP_DLL PKCS1v15_SignatureMessageEncodingMethod : public PK_DeterministicSignatureMessageEncodingMethod +{ +public: + static const char * CRYPTOPP_API StaticAlgorithmName() {return "EMSA-PKCS1-v1_5";} + + size_t MinRepresentativeBitLength(size_t hashIdentifierSize, size_t digestSize) const + {return 8 * (digestSize + hashIdentifierSize + 10);} + + void ComputeMessageRepresentative(RandomNumberGenerator &rng, + const byte *recoverableMessage, size_t recoverableMessageLength, + HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, + byte *representative, size_t representativeBitLength) const; + + struct HashIdentifierLookup + { + template struct HashIdentifierLookup2 + { + static HashIdentifier Lookup() + { + return HashIdentifier(PKCS_DigestDecoration::decoration, PKCS_DigestDecoration::length); + } + }; + }; +}; + +//! PKCS #1 version 1.5, for use with RSAES and RSASS +/*! Only the following hash functions are supported by this signature standard: + \dontinclude pkcspad.h + \skip can be instantiated + \until end of list +*/ +struct PKCS1v15 : public SignatureStandard, public EncryptionStandard +{ + typedef PKCS_EncryptionPaddingScheme EncryptionMessageEncodingMethod; + typedef PKCS1v15_SignatureMessageEncodingMethod SignatureMessageEncodingMethod; +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/polynomi.cpp b/CryptoPP/crypto/polynomi.cpp new file mode 100644 index 0000000..40258ad --- /dev/null +++ b/CryptoPP/crypto/polynomi.cpp @@ -0,0 +1,577 @@ +// polynomi.cpp - written and placed in the public domain by Wei Dai + +// Part of the code for polynomial evaluation and interpolation +// originally came from Hal Finney's public domain secsplit.c. + +#include "pch.h" +#include "polynomi.h" +#include "secblock.h" + +#include +#include + +NAMESPACE_BEGIN(CryptoPP) + +template +void PolynomialOver::Randomize(RandomNumberGenerator &rng, const RandomizationParameter ¶meter, const Ring &ring) +{ + m_coefficients.resize(parameter.m_coefficientCount); + for (unsigned int i=0; i +void PolynomialOver::FromStr(const char *str, const Ring &ring) +{ + std::istringstream in((char *)str); + bool positive = true; + CoefficientType coef; + unsigned int power; + + while (in) + { + std::ws(in); + if (in.peek() == 'x') + coef = ring.MultiplicativeIdentity(); + else + in >> coef; + + std::ws(in); + if (in.peek() == 'x') + { + in.get(); + std::ws(in); + if (in.peek() == '^') + { + in.get(); + in >> power; + } + else + power = 1; + } + else + power = 0; + + if (!positive) + coef = ring.Inverse(coef); + + SetCoefficient(power, coef, ring); + + std::ws(in); + switch (in.get()) + { + case '+': + positive = true; + break; + case '-': + positive = false; + break; + default: + return; // something's wrong with the input string + } + } +} + +template +unsigned int PolynomialOver::CoefficientCount(const Ring &ring) const +{ + unsigned count = m_coefficients.size(); + while (count && ring.Equal(m_coefficients[count-1], ring.Identity())) + count--; + const_cast &>(m_coefficients).resize(count); + return count; +} + +template +typename PolynomialOver::CoefficientType PolynomialOver::GetCoefficient(unsigned int i, const Ring &ring) const +{ + return (i < m_coefficients.size()) ? m_coefficients[i] : ring.Identity(); +} + +template +PolynomialOver& PolynomialOver::operator=(const PolynomialOver& t) +{ + if (this != &t) + { + m_coefficients.resize(t.m_coefficients.size()); + for (unsigned int i=0; i +PolynomialOver& PolynomialOver::Accumulate(const PolynomialOver& t, const Ring &ring) +{ + unsigned int count = t.CoefficientCount(ring); + + if (count > CoefficientCount(ring)) + m_coefficients.resize(count, ring.Identity()); + + for (unsigned int i=0; i +PolynomialOver& PolynomialOver::Reduce(const PolynomialOver& t, const Ring &ring) +{ + unsigned int count = t.CoefficientCount(ring); + + if (count > CoefficientCount(ring)) + m_coefficients.resize(count, ring.Identity()); + + for (unsigned int i=0; i +typename PolynomialOver::CoefficientType PolynomialOver::EvaluateAt(const CoefficientType &x, const Ring &ring) const +{ + int degree = Degree(ring); + + if (degree < 0) + return ring.Identity(); + + CoefficientType result = m_coefficients[degree]; + for (int j=degree-1; j>=0; j--) + { + result = ring.Multiply(result, x); + ring.Accumulate(result, m_coefficients[j]); + } + return result; +} + +template +PolynomialOver& PolynomialOver::ShiftLeft(unsigned int n, const Ring &ring) +{ + unsigned int i = CoefficientCount(ring) + n; + m_coefficients.resize(i, ring.Identity()); + while (i > n) + { + i--; + m_coefficients[i] = m_coefficients[i-n]; + } + while (i) + { + i--; + m_coefficients[i] = ring.Identity(); + } + return *this; +} + +template +PolynomialOver& PolynomialOver::ShiftRight(unsigned int n, const Ring &ring) +{ + unsigned int count = CoefficientCount(ring); + if (count > n) + { + for (unsigned int i=0; i +void PolynomialOver::SetCoefficient(unsigned int i, const CoefficientType &value, const Ring &ring) +{ + if (i >= m_coefficients.size()) + m_coefficients.resize(i+1, ring.Identity()); + m_coefficients[i] = value; +} + +template +void PolynomialOver::Negate(const Ring &ring) +{ + unsigned int count = CoefficientCount(ring); + for (unsigned int i=0; i +void PolynomialOver::swap(PolynomialOver &t) +{ + m_coefficients.swap(t.m_coefficients); +} + +template +bool PolynomialOver::Equals(const PolynomialOver& t, const Ring &ring) const +{ + unsigned int count = CoefficientCount(ring); + + if (count != t.CoefficientCount(ring)) + return false; + + for (unsigned int i=0; i +PolynomialOver PolynomialOver::Plus(const PolynomialOver& t, const Ring &ring) const +{ + unsigned int i; + unsigned int count = CoefficientCount(ring); + unsigned int tCount = t.CoefficientCount(ring); + + if (count > tCount) + { + PolynomialOver result(ring, count); + + for (i=0; i result(ring, tCount); + + for (i=0; i +PolynomialOver PolynomialOver::Minus(const PolynomialOver& t, const Ring &ring) const +{ + unsigned int i; + unsigned int count = CoefficientCount(ring); + unsigned int tCount = t.CoefficientCount(ring); + + if (count > tCount) + { + PolynomialOver result(ring, count); + + for (i=0; i result(ring, tCount); + + for (i=0; i +PolynomialOver PolynomialOver::Inverse(const Ring &ring) const +{ + unsigned int count = CoefficientCount(ring); + PolynomialOver result(ring, count); + + for (unsigned int i=0; i +PolynomialOver PolynomialOver::Times(const PolynomialOver& t, const Ring &ring) const +{ + if (IsZero(ring) || t.IsZero(ring)) + return PolynomialOver(); + + unsigned int count1 = CoefficientCount(ring), count2 = t.CoefficientCount(ring); + PolynomialOver result(ring, count1 + count2 - 1); + + for (unsigned int i=0; i +PolynomialOver PolynomialOver::DividedBy(const PolynomialOver& t, const Ring &ring) const +{ + PolynomialOver remainder, quotient; + Divide(remainder, quotient, *this, t, ring); + return quotient; +} + +template +PolynomialOver PolynomialOver::Modulo(const PolynomialOver& t, const Ring &ring) const +{ + PolynomialOver remainder, quotient; + Divide(remainder, quotient, *this, t, ring); + return remainder; +} + +template +PolynomialOver PolynomialOver::MultiplicativeInverse(const Ring &ring) const +{ + return Degree(ring)==0 ? ring.MultiplicativeInverse(m_coefficients[0]) : ring.Identity(); +} + +template +bool PolynomialOver::IsUnit(const Ring &ring) const +{ + return Degree(ring)==0 && ring.IsUnit(m_coefficients[0]); +} + +template +std::istream& PolynomialOver::Input(std::istream &in, const Ring &ring) +{ + char c; + unsigned int length = 0; + SecBlock str(length + 16); + bool paren = false; + + std::ws(in); + + if (in.peek() == '(') + { + paren = true; + in.get(); + } + + do + { + in.read(&c, 1); + str[length++] = c; + if (length >= str.size()) + str.Grow(length + 16); + } + // if we started with a left paren, then read until we find a right paren, + // otherwise read until the end of the line + while (in && ((paren && c != ')') || (!paren && c != '\n'))); + + str[length-1] = '\0'; + *this = PolynomialOver(str, ring); + + return in; +} + +template +std::ostream& PolynomialOver::Output(std::ostream &out, const Ring &ring) const +{ + unsigned int i = CoefficientCount(ring); + if (i) + { + bool firstTerm = true; + + while (i--) + { + if (m_coefficients[i] != ring.Identity()) + { + if (firstTerm) + { + firstTerm = false; + if (!i || !ring.Equal(m_coefficients[i], ring.MultiplicativeIdentity())) + out << m_coefficients[i]; + } + else + { + CoefficientType inverse = ring.Inverse(m_coefficients[i]); + std::ostringstream pstr, nstr; + + pstr << m_coefficients[i]; + nstr << inverse; + + if (pstr.str().size() <= nstr.str().size()) + { + out << " + "; + if (!i || !ring.Equal(m_coefficients[i], ring.MultiplicativeIdentity())) + out << m_coefficients[i]; + } + else + { + out << " - "; + if (!i || !ring.Equal(inverse, ring.MultiplicativeIdentity())) + out << inverse; + } + } + + switch (i) + { + case 0: + break; + case 1: + out << "x"; + break; + default: + out << "x^" << i; + } + } + } + } + else + { + out << ring.Identity(); + } + return out; +} + +template +void PolynomialOver::Divide(PolynomialOver &r, PolynomialOver &q, const PolynomialOver &a, const PolynomialOver &d, const Ring &ring) +{ + unsigned int i = a.CoefficientCount(ring); + const int dDegree = d.Degree(ring); + + if (dDegree < 0) + throw DivideByZero(); + + r = a; + q.m_coefficients.resize(STDMAX(0, int(i - dDegree))); + + while (i > (unsigned int)dDegree) + { + --i; + q.m_coefficients[i-dDegree] = ring.Divide(r.m_coefficients[i], d.m_coefficients[dDegree]); + for (int j=0; j<=dDegree; j++) + ring.Reduce(r.m_coefficients[i-dDegree+j], ring.Multiply(q.m_coefficients[i-dDegree], d.m_coefficients[j])); + } + + r.CoefficientCount(ring); // resize r.m_coefficients +} + +// ******************************************************** + +// helper function for Interpolate() and InterpolateAt() +template +void RingOfPolynomialsOver::CalculateAlpha(std::vector &alpha, const CoefficientType x[], const CoefficientType y[], unsigned int n) const +{ + for (unsigned int j=0; j=k; --j) + { + m_ring.Reduce(alpha[j], alpha[j-1]); + + CoefficientType d = m_ring.Subtract(x[j], x[j-k]); + if (!m_ring.IsUnit(d)) + throw InterpolationFailed(); + alpha[j] = m_ring.Divide(alpha[j], d); + } + } +} + +template +typename RingOfPolynomialsOver::Element RingOfPolynomialsOver::Interpolate(const CoefficientType x[], const CoefficientType y[], unsigned int n) const +{ + assert(n > 0); + + std::vector alpha(n); + CalculateAlpha(alpha, x, y, n); + + std::vector coefficients((size_t)n, m_ring.Identity()); + coefficients[0] = alpha[n-1]; + + for (int j=n-2; j>=0; --j) + { + for (unsigned int i=n-j-1; i>0; i--) + coefficients[i] = m_ring.Subtract(coefficients[i-1], m_ring.Multiply(coefficients[i], x[j])); + + coefficients[0] = m_ring.Subtract(alpha[j], m_ring.Multiply(coefficients[0], x[j])); + } + + return PolynomialOver(coefficients.begin(), coefficients.end()); +} + +template +typename RingOfPolynomialsOver::CoefficientType RingOfPolynomialsOver::InterpolateAt(const CoefficientType &position, const CoefficientType x[], const CoefficientType y[], unsigned int n) const +{ + assert(n > 0); + + std::vector alpha(n); + CalculateAlpha(alpha, x, y, n); + + CoefficientType result = alpha[n-1]; + for (int j=n-2; j>=0; --j) + { + result = m_ring.Multiply(result, m_ring.Subtract(position, x[j])); + m_ring.Accumulate(result, alpha[j]); + } + return result; +} + +template +void PrepareBulkPolynomialInterpolation(const Ring &ring, Element *w, const Element x[], unsigned int n) +{ + for (unsigned int i=0; i +void PrepareBulkPolynomialInterpolationAt(const Ring &ring, Element *v, const Element &position, const Element x[], const Element w[], unsigned int n) +{ + assert(n > 0); + + std::vector a(2*n-1); + unsigned int i; + + for (i=0; i1; i--) + a[i-1] = ring.Multiply(a[2*i], a[2*i-1]); + + a[0] = ring.MultiplicativeIdentity(); + + for (i=0; i +Element BulkPolynomialInterpolateAt(const Ring &ring, const Element y[], const Element v[], unsigned int n) +{ + Element result = ring.Identity(); + for (unsigned int i=0; i +const PolynomialOverFixedRing &PolynomialOverFixedRing::Zero() +{ + return Singleton().Ref(); +} + +template +const PolynomialOverFixedRing &PolynomialOverFixedRing::One() +{ + return Singleton().Ref(); +} + +NAMESPACE_END diff --git a/CryptoPP/crypto/polynomi.h b/CryptoPP/crypto/polynomi.h new file mode 100644 index 0000000..6022165 --- /dev/null +++ b/CryptoPP/crypto/polynomi.h @@ -0,0 +1,459 @@ +#ifndef CRYPTOPP_POLYNOMI_H +#define CRYPTOPP_POLYNOMI_H + +/*! \file */ + +#include "cryptlib.h" +#include "misc.h" +#include "algebra.h" + +#include +#include + +NAMESPACE_BEGIN(CryptoPP) + +//! represents single-variable polynomials over arbitrary rings +/*! \nosubgrouping */ +template class PolynomialOver +{ +public: + //! \name ENUMS, EXCEPTIONS, and TYPEDEFS + //@{ + //! division by zero exception + class DivideByZero : public Exception + { + public: + DivideByZero() : Exception(OTHER_ERROR, "PolynomialOver: division by zero") {} + }; + + //! specify the distribution for randomization functions + class RandomizationParameter + { + public: + RandomizationParameter(unsigned int coefficientCount, const typename T::RandomizationParameter &coefficientParameter ) + : m_coefficientCount(coefficientCount), m_coefficientParameter(coefficientParameter) {} + + private: + unsigned int m_coefficientCount; + typename T::RandomizationParameter m_coefficientParameter; + friend class PolynomialOver; + }; + + typedef T Ring; + typedef typename T::Element CoefficientType; + //@} + + //! \name CREATORS + //@{ + //! creates the zero polynomial + PolynomialOver() {} + + //! + PolynomialOver(const Ring &ring, unsigned int count) + : m_coefficients((size_t)count, ring.Identity()) {} + + //! copy constructor + PolynomialOver(const PolynomialOver &t) + : m_coefficients(t.m_coefficients.size()) {*this = t;} + + //! construct constant polynomial + PolynomialOver(const CoefficientType &element) + : m_coefficients(1, element) {} + + //! construct polynomial with specified coefficients, starting from coefficient of x^0 + template PolynomialOver(Iterator begin, Iterator end) + : m_coefficients(begin, end) {} + + //! convert from string + PolynomialOver(const char *str, const Ring &ring) {FromStr(str, ring);} + + //! convert from big-endian byte array + PolynomialOver(const byte *encodedPolynomialOver, unsigned int byteCount); + + //! convert from Basic Encoding Rules encoded byte array + explicit PolynomialOver(const byte *BEREncodedPolynomialOver); + + //! convert from BER encoded byte array stored in a BufferedTransformation object + explicit PolynomialOver(BufferedTransformation &bt); + + //! create a random PolynomialOver + PolynomialOver(RandomNumberGenerator &rng, const RandomizationParameter ¶meter, const Ring &ring) + {Randomize(rng, parameter, ring);} + //@} + + //! \name ACCESSORS + //@{ + //! the zero polynomial will return a degree of -1 + int Degree(const Ring &ring) const {return int(CoefficientCount(ring))-1;} + //! + unsigned int CoefficientCount(const Ring &ring) const; + //! return coefficient for x^i + CoefficientType GetCoefficient(unsigned int i, const Ring &ring) const; + //@} + + //! \name MANIPULATORS + //@{ + //! + PolynomialOver& operator=(const PolynomialOver& t); + + //! + void Randomize(RandomNumberGenerator &rng, const RandomizationParameter ¶meter, const Ring &ring); + + //! set the coefficient for x^i to value + void SetCoefficient(unsigned int i, const CoefficientType &value, const Ring &ring); + + //! + void Negate(const Ring &ring); + + //! + void swap(PolynomialOver &t); + //@} + + + //! \name BASIC ARITHMETIC ON POLYNOMIALS + //@{ + bool Equals(const PolynomialOver &t, const Ring &ring) const; + bool IsZero(const Ring &ring) const {return CoefficientCount(ring)==0;} + + PolynomialOver Plus(const PolynomialOver& t, const Ring &ring) const; + PolynomialOver Minus(const PolynomialOver& t, const Ring &ring) const; + PolynomialOver Inverse(const Ring &ring) const; + + PolynomialOver Times(const PolynomialOver& t, const Ring &ring) const; + PolynomialOver DividedBy(const PolynomialOver& t, const Ring &ring) const; + PolynomialOver Modulo(const PolynomialOver& t, const Ring &ring) const; + PolynomialOver MultiplicativeInverse(const Ring &ring) const; + bool IsUnit(const Ring &ring) const; + + PolynomialOver& Accumulate(const PolynomialOver& t, const Ring &ring); + PolynomialOver& Reduce(const PolynomialOver& t, const Ring &ring); + + //! + PolynomialOver Doubled(const Ring &ring) const {return Plus(*this, ring);} + //! + PolynomialOver Squared(const Ring &ring) const {return Times(*this, ring);} + + CoefficientType EvaluateAt(const CoefficientType &x, const Ring &ring) const; + + PolynomialOver& ShiftLeft(unsigned int n, const Ring &ring); + PolynomialOver& ShiftRight(unsigned int n, const Ring &ring); + + //! calculate r and q such that (a == d*q + r) && (0 <= degree of r < degree of d) + static void Divide(PolynomialOver &r, PolynomialOver &q, const PolynomialOver &a, const PolynomialOver &d, const Ring &ring); + //@} + + //! \name INPUT/OUTPUT + //@{ + std::istream& Input(std::istream &in, const Ring &ring); + std::ostream& Output(std::ostream &out, const Ring &ring) const; + //@} + +private: + void FromStr(const char *str, const Ring &ring); + + std::vector m_coefficients; +}; + +//! Polynomials over a fixed ring +/*! Having a fixed ring allows overloaded operators */ +template class PolynomialOverFixedRing : private PolynomialOver +{ + typedef PolynomialOver B; + typedef PolynomialOverFixedRing ThisType; + +public: + typedef T Ring; + typedef typename T::Element CoefficientType; + typedef typename B::DivideByZero DivideByZero; + typedef typename B::RandomizationParameter RandomizationParameter; + + //! \name CREATORS + //@{ + //! creates the zero polynomial + PolynomialOverFixedRing(unsigned int count = 0) : B(ms_fixedRing, count) {} + + //! copy constructor + PolynomialOverFixedRing(const ThisType &t) : B(t) {} + + explicit PolynomialOverFixedRing(const B &t) : B(t) {} + + //! construct constant polynomial + PolynomialOverFixedRing(const CoefficientType &element) : B(element) {} + + //! construct polynomial with specified coefficients, starting from coefficient of x^0 + template PolynomialOverFixedRing(Iterator first, Iterator last) + : B(first, last) {} + + //! convert from string + explicit PolynomialOverFixedRing(const char *str) : B(str, ms_fixedRing) {} + + //! convert from big-endian byte array + PolynomialOverFixedRing(const byte *encodedPoly, unsigned int byteCount) : B(encodedPoly, byteCount) {} + + //! convert from Basic Encoding Rules encoded byte array + explicit PolynomialOverFixedRing(const byte *BEREncodedPoly) : B(BEREncodedPoly) {} + + //! convert from BER encoded byte array stored in a BufferedTransformation object + explicit PolynomialOverFixedRing(BufferedTransformation &bt) : B(bt) {} + + //! create a random PolynomialOverFixedRing + PolynomialOverFixedRing(RandomNumberGenerator &rng, const RandomizationParameter ¶meter) : B(rng, parameter, ms_fixedRing) {} + + static const ThisType &Zero(); + static const ThisType &One(); + //@} + + //! \name ACCESSORS + //@{ + //! the zero polynomial will return a degree of -1 + int Degree() const {return B::Degree(ms_fixedRing);} + //! degree + 1 + unsigned int CoefficientCount() const {return B::CoefficientCount(ms_fixedRing);} + //! return coefficient for x^i + CoefficientType GetCoefficient(unsigned int i) const {return B::GetCoefficient(i, ms_fixedRing);} + //! return coefficient for x^i + CoefficientType operator[](unsigned int i) const {return B::GetCoefficient(i, ms_fixedRing);} + //@} + + //! \name MANIPULATORS + //@{ + //! + ThisType& operator=(const ThisType& t) {B::operator=(t); return *this;} + //! + ThisType& operator+=(const ThisType& t) {Accumulate(t, ms_fixedRing); return *this;} + //! + ThisType& operator-=(const ThisType& t) {Reduce(t, ms_fixedRing); return *this;} + //! + ThisType& operator*=(const ThisType& t) {return *this = *this*t;} + //! + ThisType& operator/=(const ThisType& t) {return *this = *this/t;} + //! + ThisType& operator%=(const ThisType& t) {return *this = *this%t;} + + //! + ThisType& operator<<=(unsigned int n) {ShiftLeft(n, ms_fixedRing); return *this;} + //! + ThisType& operator>>=(unsigned int n) {ShiftRight(n, ms_fixedRing); return *this;} + + //! set the coefficient for x^i to value + void SetCoefficient(unsigned int i, const CoefficientType &value) {B::SetCoefficient(i, value, ms_fixedRing);} + + //! + void Randomize(RandomNumberGenerator &rng, const RandomizationParameter ¶meter) {B::Randomize(rng, parameter, ms_fixedRing);} + + //! + void Negate() {B::Negate(ms_fixedRing);} + + void swap(ThisType &t) {B::swap(t);} + //@} + + //! \name UNARY OPERATORS + //@{ + //! + bool operator!() const {return CoefficientCount()==0;} + //! + ThisType operator+() const {return *this;} + //! + ThisType operator-() const {return ThisType(Inverse(ms_fixedRing));} + //@} + + //! \name BINARY OPERATORS + //@{ + //! + friend ThisType operator>>(ThisType a, unsigned int n) {return ThisType(a>>=n);} + //! + friend ThisType operator<<(ThisType a, unsigned int n) {return ThisType(a<<=n);} + //@} + + //! \name OTHER ARITHMETIC FUNCTIONS + //@{ + //! + ThisType MultiplicativeInverse() const {return ThisType(B::MultiplicativeInverse(ms_fixedRing));} + //! + bool IsUnit() const {return B::IsUnit(ms_fixedRing);} + + //! + ThisType Doubled() const {return ThisType(B::Doubled(ms_fixedRing));} + //! + ThisType Squared() const {return ThisType(B::Squared(ms_fixedRing));} + + CoefficientType EvaluateAt(const CoefficientType &x) const {return B::EvaluateAt(x, ms_fixedRing);} + + //! calculate r and q such that (a == d*q + r) && (0 <= r < abs(d)) + static void Divide(ThisType &r, ThisType &q, const ThisType &a, const ThisType &d) + {B::Divide(r, q, a, d, ms_fixedRing);} + //@} + + //! \name INPUT/OUTPUT + //@{ + //! + friend std::istream& operator>>(std::istream& in, ThisType &a) + {return a.Input(in, ms_fixedRing);} + //! + friend std::ostream& operator<<(std::ostream& out, const ThisType &a) + {return a.Output(out, ms_fixedRing);} + //@} + +private: + struct NewOnePolynomial + { + ThisType * operator()() const + { + return new ThisType(ms_fixedRing.MultiplicativeIdentity()); + } + }; + + static const Ring ms_fixedRing; +}; + +//! Ring of polynomials over another ring +template class RingOfPolynomialsOver : public AbstractEuclideanDomain > +{ +public: + typedef T CoefficientRing; + typedef PolynomialOver Element; + typedef typename Element::CoefficientType CoefficientType; + typedef typename Element::RandomizationParameter RandomizationParameter; + + RingOfPolynomialsOver(const CoefficientRing &ring) : m_ring(ring) {} + + Element RandomElement(RandomNumberGenerator &rng, const RandomizationParameter ¶meter) + {return Element(rng, parameter, m_ring);} + + bool Equal(const Element &a, const Element &b) const + {return a.Equals(b, m_ring);} + + const Element& Identity() const + {return this->result = m_ring.Identity();} + + const Element& Add(const Element &a, const Element &b) const + {return this->result = a.Plus(b, m_ring);} + + Element& Accumulate(Element &a, const Element &b) const + {a.Accumulate(b, m_ring); return a;} + + const Element& Inverse(const Element &a) const + {return this->result = a.Inverse(m_ring);} + + const Element& Subtract(const Element &a, const Element &b) const + {return this->result = a.Minus(b, m_ring);} + + Element& Reduce(Element &a, const Element &b) const + {return a.Reduce(b, m_ring);} + + const Element& Double(const Element &a) const + {return this->result = a.Doubled(m_ring);} + + const Element& MultiplicativeIdentity() const + {return this->result = m_ring.MultiplicativeIdentity();} + + const Element& Multiply(const Element &a, const Element &b) const + {return this->result = a.Times(b, m_ring);} + + const Element& Square(const Element &a) const + {return this->result = a.Squared(m_ring);} + + bool IsUnit(const Element &a) const + {return a.IsUnit(m_ring);} + + const Element& MultiplicativeInverse(const Element &a) const + {return this->result = a.MultiplicativeInverse(m_ring);} + + const Element& Divide(const Element &a, const Element &b) const + {return this->result = a.DividedBy(b, m_ring);} + + const Element& Mod(const Element &a, const Element &b) const + {return this->result = a.Modulo(b, m_ring);} + + void DivisionAlgorithm(Element &r, Element &q, const Element &a, const Element &d) const + {Element::Divide(r, q, a, d, m_ring);} + + class InterpolationFailed : public Exception + { + public: + InterpolationFailed() : Exception(OTHER_ERROR, "RingOfPolynomialsOver: interpolation failed") {} + }; + + Element Interpolate(const CoefficientType x[], const CoefficientType y[], unsigned int n) const; + + // a faster version of Interpolate(x, y, n).EvaluateAt(position) + CoefficientType InterpolateAt(const CoefficientType &position, const CoefficientType x[], const CoefficientType y[], unsigned int n) const; +/* + void PrepareBulkInterpolation(CoefficientType *w, const CoefficientType x[], unsigned int n) const; + void PrepareBulkInterpolationAt(CoefficientType *v, const CoefficientType &position, const CoefficientType x[], const CoefficientType w[], unsigned int n) const; + CoefficientType BulkInterpolateAt(const CoefficientType y[], const CoefficientType v[], unsigned int n) const; +*/ +protected: + void CalculateAlpha(std::vector &alpha, const CoefficientType x[], const CoefficientType y[], unsigned int n) const; + + CoefficientRing m_ring; +}; + +template +void PrepareBulkPolynomialInterpolation(const Ring &ring, Element *w, const Element x[], unsigned int n); +template +void PrepareBulkPolynomialInterpolationAt(const Ring &ring, Element *v, const Element &position, const Element x[], const Element w[], unsigned int n); +template +Element BulkPolynomialInterpolateAt(const Ring &ring, const Element y[], const Element v[], unsigned int n); + +//! +template +inline bool operator==(const CryptoPP::PolynomialOverFixedRing &a, const CryptoPP::PolynomialOverFixedRing &b) + {return a.Equals(b, a.ms_fixedRing);} +//! +template +inline bool operator!=(const CryptoPP::PolynomialOverFixedRing &a, const CryptoPP::PolynomialOverFixedRing &b) + {return !(a==b);} + +//! +template +inline bool operator> (const CryptoPP::PolynomialOverFixedRing &a, const CryptoPP::PolynomialOverFixedRing &b) + {return a.Degree() > b.Degree();} +//! +template +inline bool operator>=(const CryptoPP::PolynomialOverFixedRing &a, const CryptoPP::PolynomialOverFixedRing &b) + {return a.Degree() >= b.Degree();} +//! +template +inline bool operator< (const CryptoPP::PolynomialOverFixedRing &a, const CryptoPP::PolynomialOverFixedRing &b) + {return a.Degree() < b.Degree();} +//! +template +inline bool operator<=(const CryptoPP::PolynomialOverFixedRing &a, const CryptoPP::PolynomialOverFixedRing &b) + {return a.Degree() <= b.Degree();} + +//! +template +inline CryptoPP::PolynomialOverFixedRing operator+(const CryptoPP::PolynomialOverFixedRing &a, const CryptoPP::PolynomialOverFixedRing &b) + {return CryptoPP::PolynomialOverFixedRing(a.Plus(b, a.ms_fixedRing));} +//! +template +inline CryptoPP::PolynomialOverFixedRing operator-(const CryptoPP::PolynomialOverFixedRing &a, const CryptoPP::PolynomialOverFixedRing &b) + {return CryptoPP::PolynomialOverFixedRing(a.Minus(b, a.ms_fixedRing));} +//! +template +inline CryptoPP::PolynomialOverFixedRing operator*(const CryptoPP::PolynomialOverFixedRing &a, const CryptoPP::PolynomialOverFixedRing &b) + {return CryptoPP::PolynomialOverFixedRing(a.Times(b, a.ms_fixedRing));} +//! +template +inline CryptoPP::PolynomialOverFixedRing operator/(const CryptoPP::PolynomialOverFixedRing &a, const CryptoPP::PolynomialOverFixedRing &b) + {return CryptoPP::PolynomialOverFixedRing(a.DividedBy(b, a.ms_fixedRing));} +//! +template +inline CryptoPP::PolynomialOverFixedRing operator%(const CryptoPP::PolynomialOverFixedRing &a, const CryptoPP::PolynomialOverFixedRing &b) + {return CryptoPP::PolynomialOverFixedRing(a.Modulo(b, a.ms_fixedRing));} + +NAMESPACE_END + +NAMESPACE_BEGIN(std) +template inline void swap(CryptoPP::PolynomialOver &a, CryptoPP::PolynomialOver &b) +{ + a.swap(b); +} +template inline void swap(CryptoPP::PolynomialOverFixedRing &a, CryptoPP::PolynomialOverFixedRing &b) +{ + a.swap(b); +} +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/pssr.cpp b/CryptoPP/crypto/pssr.cpp new file mode 100644 index 0000000..34ce71a --- /dev/null +++ b/CryptoPP/crypto/pssr.cpp @@ -0,0 +1,145 @@ +// pssr.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "pssr.h" +#include + +NAMESPACE_BEGIN(CryptoPP) + +// more in dll.cpp +template<> const byte EMSA2HashId::id = 0x31; +template<> const byte EMSA2HashId::id = 0x32; +template<> const byte EMSA2HashId::id = 0x37; + +#ifndef CRYPTOPP_IMPORTS + +size_t PSSR_MEM_Base::MinRepresentativeBitLength(size_t hashIdentifierLength, size_t digestLength) const +{ + size_t saltLen = SaltLen(digestLength); + size_t minPadLen = MinPadLen(digestLength); + return 9 + 8*(minPadLen + saltLen + digestLength + hashIdentifierLength); +} + +size_t PSSR_MEM_Base::MaxRecoverableLength(size_t representativeBitLength, size_t hashIdentifierLength, size_t digestLength) const +{ + if (AllowRecovery()) + return SaturatingSubtract(representativeBitLength, MinRepresentativeBitLength(hashIdentifierLength, digestLength)) / 8; + return 0; +} + +bool PSSR_MEM_Base::IsProbabilistic() const +{ + return SaltLen(1) > 0; +} + +bool PSSR_MEM_Base::AllowNonrecoverablePart() const +{ + return true; +} + +bool PSSR_MEM_Base::RecoverablePartFirst() const +{ + return false; +} + +void PSSR_MEM_Base::ComputeMessageRepresentative(RandomNumberGenerator &rng, + const byte *recoverableMessage, size_t recoverableMessageLength, + HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, + byte *representative, size_t representativeBitLength) const +{ + assert(representativeBitLength >= MinRepresentativeBitLength(hashIdentifier.second, hash.DigestSize())); + + const size_t u = hashIdentifier.second + 1; + const size_t representativeByteLength = BitsToBytes(representativeBitLength); + const size_t digestSize = hash.DigestSize(); + const size_t saltSize = SaltLen(digestSize); + byte *const h = representative + representativeByteLength - u - digestSize; + + SecByteBlock digest(digestSize), salt(saltSize); + hash.Final(digest); + rng.GenerateBlock(salt, saltSize); + + // compute H = hash of M' + byte c[8]; + PutWord(false, BIG_ENDIAN_ORDER, c, (word32)SafeRightShift<29>(recoverableMessageLength)); + PutWord(false, BIG_ENDIAN_ORDER, c+4, word32(recoverableMessageLength << 3)); + hash.Update(c, 8); + hash.Update(recoverableMessage, recoverableMessageLength); + hash.Update(digest, digestSize); + hash.Update(salt, saltSize); + hash.Final(h); + + // compute representative + GetMGF().GenerateAndMask(hash, representative, representativeByteLength - u - digestSize, h, digestSize, false); + byte *xorStart = representative + representativeByteLength - u - digestSize - salt.size() - recoverableMessageLength - 1; + xorStart[0] ^= 1; + xorbuf(xorStart + 1, recoverableMessage, recoverableMessageLength); + xorbuf(xorStart + 1 + recoverableMessageLength, salt, salt.size()); + memcpy(representative + representativeByteLength - u, hashIdentifier.first, hashIdentifier.second); + representative[representativeByteLength - 1] = hashIdentifier.second ? 0xcc : 0xbc; + if (representativeBitLength % 8 != 0) + representative[0] = (byte)Crop(representative[0], representativeBitLength % 8); +} + +DecodingResult PSSR_MEM_Base::RecoverMessageFromRepresentative( + HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, + byte *representative, size_t representativeBitLength, + byte *recoverableMessage) const +{ + assert(representativeBitLength >= MinRepresentativeBitLength(hashIdentifier.second, hash.DigestSize())); + + const size_t u = hashIdentifier.second + 1; + const size_t representativeByteLength = BitsToBytes(representativeBitLength); + const size_t digestSize = hash.DigestSize(); + const size_t saltSize = SaltLen(digestSize); + const byte *const h = representative + representativeByteLength - u - digestSize; + + SecByteBlock digest(digestSize); + hash.Final(digest); + + DecodingResult result(0); + bool &valid = result.isValidCoding; + size_t &recoverableMessageLength = result.messageLength; + + valid = (representative[representativeByteLength - 1] == (hashIdentifier.second ? 0xcc : 0xbc)) && valid; + valid = (memcmp(representative + representativeByteLength - u, hashIdentifier.first, hashIdentifier.second) == 0) && valid; + + GetMGF().GenerateAndMask(hash, representative, representativeByteLength - u - digestSize, h, digestSize); + if (representativeBitLength % 8 != 0) + representative[0] = (byte)Crop(representative[0], representativeBitLength % 8); + + // extract salt and recoverableMessage from DB = 00 ... || 01 || M || salt + byte *salt = representative + representativeByteLength - u - digestSize - saltSize; + byte *M = std::find_if(representative, salt-1, std::bind2nd(std::not_equal_to(), 0)); + recoverableMessageLength = salt-M-1; + if (*M == 0x01 + && (size_t)(M - representative - (representativeBitLength % 8 != 0)) >= MinPadLen(digestSize) + && recoverableMessageLength <= MaxRecoverableLength(representativeBitLength, hashIdentifier.second, digestSize)) + { + memcpy(recoverableMessage, M+1, recoverableMessageLength); + } + else + { + recoverableMessageLength = 0; + valid = false; + } + + // verify H = hash of M' + byte c[8]; + PutWord(false, BIG_ENDIAN_ORDER, c, (word32)SafeRightShift<29>(recoverableMessageLength)); + PutWord(false, BIG_ENDIAN_ORDER, c+4, word32(recoverableMessageLength << 3)); + hash.Update(c, 8); + hash.Update(recoverableMessage, recoverableMessageLength); + hash.Update(digest, digestSize); + hash.Update(salt, saltSize); + valid = hash.Verify(h) && valid; + + if (!AllowRecovery() && valid && recoverableMessageLength != 0) + {throw NotImplemented("PSSR_MEM: message recovery disabled");} + + return result; +} + +#endif + +NAMESPACE_END diff --git a/CryptoPP/crypto/pssr.h b/CryptoPP/crypto/pssr.h new file mode 100644 index 0000000..e1ee5fe --- /dev/null +++ b/CryptoPP/crypto/pssr.h @@ -0,0 +1,66 @@ +#ifndef CRYPTOPP_PSSR_H +#define CRYPTOPP_PSSR_H + +#include "pubkey.h" +#include "emsa2.h" + +#ifdef CRYPTOPP_IS_DLL +#include "sha.h" +#endif + +NAMESPACE_BEGIN(CryptoPP) + +class CRYPTOPP_DLL PSSR_MEM_Base : public PK_RecoverableSignatureMessageEncodingMethod +{ + virtual bool AllowRecovery() const =0; + virtual size_t SaltLen(size_t hashLen) const =0; + virtual size_t MinPadLen(size_t hashLen) const =0; + virtual const MaskGeneratingFunction & GetMGF() const =0; + +public: + size_t MinRepresentativeBitLength(size_t hashIdentifierLength, size_t digestLength) const; + size_t MaxRecoverableLength(size_t representativeBitLength, size_t hashIdentifierLength, size_t digestLength) const; + bool IsProbabilistic() const; + bool AllowNonrecoverablePart() const; + bool RecoverablePartFirst() const; + void ComputeMessageRepresentative(RandomNumberGenerator &rng, + const byte *recoverableMessage, size_t recoverableMessageLength, + HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, + byte *representative, size_t representativeBitLength) const; + DecodingResult RecoverMessageFromRepresentative( + HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, + byte *representative, size_t representativeBitLength, + byte *recoverableMessage) const; +}; + +template class PSSR_MEM_BaseWithHashId; +template<> class PSSR_MEM_BaseWithHashId : public EMSA2HashIdLookup {}; +template<> class PSSR_MEM_BaseWithHashId : public PSSR_MEM_Base {}; + +template +class PSSR_MEM : public PSSR_MEM_BaseWithHashId +{ + virtual bool AllowRecovery() const {return ALLOW_RECOVERY;} + virtual size_t SaltLen(size_t hashLen) const {return SALT_LEN < 0 ? hashLen : SALT_LEN;} + virtual size_t MinPadLen(size_t hashLen) const {return MIN_PAD_LEN < 0 ? hashLen : MIN_PAD_LEN;} + virtual const MaskGeneratingFunction & GetMGF() const {static MGF mgf; return mgf;} + +public: + static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string(ALLOW_RECOVERY ? "PSSR-" : "PSS-") + MGF::StaticAlgorithmName();} +}; + +//! PSSR-MGF1 +struct PSSR : public SignatureStandard +{ + typedef PSSR_MEM SignatureMessageEncodingMethod; +}; + +//! PSS-MGF1 +struct PSS : public SignatureStandard +{ + typedef PSSR_MEM SignatureMessageEncodingMethod; +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/pubkey.cpp b/CryptoPP/crypto/pubkey.cpp new file mode 100644 index 0000000..3b53ee5 --- /dev/null +++ b/CryptoPP/crypto/pubkey.cpp @@ -0,0 +1,157 @@ +// pubkey.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "pubkey.h" + +NAMESPACE_BEGIN(CryptoPP) + +void P1363_MGF1KDF2_Common(HashTransformation &hash, byte *output, size_t outputLength, const byte *input, size_t inputLength, const byte *derivationParams, size_t derivationParamsLength, bool mask, unsigned int counterStart) +{ + ArraySink *sink; + HashFilter filter(hash, sink = mask ? new ArrayXorSink(output, outputLength) : new ArraySink(output, outputLength)); + word32 counter = counterStart; + while (sink->AvailableSize() > 0) + { + filter.Put(input, inputLength); + filter.PutWord32(counter++); + filter.Put(derivationParams, derivationParamsLength); + filter.MessageEnd(); + } +} + +bool PK_DeterministicSignatureMessageEncodingMethod::VerifyMessageRepresentative( + HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, + byte *representative, size_t representativeBitLength) const +{ + SecByteBlock computedRepresentative(BitsToBytes(representativeBitLength)); + ComputeMessageRepresentative(NullRNG(), NULL, 0, hash, hashIdentifier, messageEmpty, computedRepresentative, representativeBitLength); + return memcmp(representative, computedRepresentative, computedRepresentative.size()) == 0; +} + +bool PK_RecoverableSignatureMessageEncodingMethod::VerifyMessageRepresentative( + HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, + byte *representative, size_t representativeBitLength) const +{ + SecByteBlock recoveredMessage(MaxRecoverableLength(representativeBitLength, hashIdentifier.second, hash.DigestSize())); + DecodingResult result = RecoverMessageFromRepresentative( + hash, hashIdentifier, messageEmpty, representative, representativeBitLength, recoveredMessage); + return result.isValidCoding && result.messageLength == 0; +} + +void TF_SignerBase::InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const +{ + PK_MessageAccumulatorBase &ma = static_cast(messageAccumulator); + HashIdentifier id = GetHashIdentifier(); + const MessageEncodingInterface &encoding = GetMessageEncodingInterface(); + + if (MessageRepresentativeBitLength() < encoding.MinRepresentativeBitLength(id.second, ma.AccessHash().DigestSize())) + throw PK_SignatureScheme::KeyTooShort(); + + size_t maxRecoverableLength = encoding.MaxRecoverableLength(MessageRepresentativeBitLength(), GetHashIdentifier().second, ma.AccessHash().DigestSize()); + + if (maxRecoverableLength == 0) + {throw NotImplemented("TF_SignerBase: this algorithm does not support messsage recovery or the key is too short");} + if (recoverableMessageLength > maxRecoverableLength) + throw InvalidArgument("TF_SignerBase: the recoverable message part is too long for the given key and algorithm"); + + ma.m_recoverableMessage.Assign(recoverableMessage, recoverableMessageLength); + encoding.ProcessRecoverableMessage( + ma.AccessHash(), + recoverableMessage, recoverableMessageLength, + NULL, 0, ma.m_semisignature); +} + +size_t TF_SignerBase::SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart) const +{ + PK_MessageAccumulatorBase &ma = static_cast(messageAccumulator); + HashIdentifier id = GetHashIdentifier(); + const MessageEncodingInterface &encoding = GetMessageEncodingInterface(); + + if (MessageRepresentativeBitLength() < encoding.MinRepresentativeBitLength(id.second, ma.AccessHash().DigestSize())) + throw PK_SignatureScheme::KeyTooShort(); + + SecByteBlock representative(MessageRepresentativeLength()); + encoding.ComputeMessageRepresentative(rng, + ma.m_recoverableMessage, ma.m_recoverableMessage.size(), + ma.AccessHash(), id, ma.m_empty, + representative, MessageRepresentativeBitLength()); + ma.m_empty = true; + + Integer r(representative, representative.size()); + size_t signatureLength = SignatureLength(); + GetTrapdoorFunctionInterface().CalculateRandomizedInverse(rng, r).Encode(signature, signatureLength); + return signatureLength; +} + +void TF_VerifierBase::InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const +{ + PK_MessageAccumulatorBase &ma = static_cast(messageAccumulator); + HashIdentifier id = GetHashIdentifier(); + const MessageEncodingInterface &encoding = GetMessageEncodingInterface(); + + if (MessageRepresentativeBitLength() < encoding.MinRepresentativeBitLength(id.second, ma.AccessHash().DigestSize())) + throw PK_SignatureScheme::KeyTooShort(); + + ma.m_representative.New(MessageRepresentativeLength()); + Integer x = GetTrapdoorFunctionInterface().ApplyFunction(Integer(signature, signatureLength)); + if (x.BitCount() > MessageRepresentativeBitLength()) + x = Integer::Zero(); // don't return false here to prevent timing attack + x.Encode(ma.m_representative, ma.m_representative.size()); +} + +bool TF_VerifierBase::VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const +{ + PK_MessageAccumulatorBase &ma = static_cast(messageAccumulator); + HashIdentifier id = GetHashIdentifier(); + const MessageEncodingInterface &encoding = GetMessageEncodingInterface(); + + if (MessageRepresentativeBitLength() < encoding.MinRepresentativeBitLength(id.second, ma.AccessHash().DigestSize())) + throw PK_SignatureScheme::KeyTooShort(); + + bool result = encoding.VerifyMessageRepresentative( + ma.AccessHash(), id, ma.m_empty, ma.m_representative, MessageRepresentativeBitLength()); + ma.m_empty = true; + return result; +} + +DecodingResult TF_VerifierBase::RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const +{ + PK_MessageAccumulatorBase &ma = static_cast(messageAccumulator); + HashIdentifier id = GetHashIdentifier(); + const MessageEncodingInterface &encoding = GetMessageEncodingInterface(); + + if (MessageRepresentativeBitLength() < encoding.MinRepresentativeBitLength(id.second, ma.AccessHash().DigestSize())) + throw PK_SignatureScheme::KeyTooShort(); + + DecodingResult result = encoding.RecoverMessageFromRepresentative( + ma.AccessHash(), id, ma.m_empty, ma.m_representative, MessageRepresentativeBitLength(), recoveredMessage); + ma.m_empty = true; + return result; +} + +DecodingResult TF_DecryptorBase::Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs ¶meters) const +{ + SecByteBlock paddedBlock(PaddedBlockByteLength()); + Integer x = GetTrapdoorFunctionInterface().CalculateInverse(rng, Integer(ciphertext, FixedCiphertextLength())); + if (x.ByteCount() > paddedBlock.size()) + x = Integer::Zero(); // don't return false here to prevent timing attack + x.Encode(paddedBlock, paddedBlock.size()); + return GetMessageEncodingInterface().Unpad(paddedBlock, PaddedBlockBitLength(), plaintext, parameters); +} + +void TF_EncryptorBase::Encrypt(RandomNumberGenerator &rng, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs ¶meters) const +{ + if (plaintextLength > FixedMaxPlaintextLength()) + throw InvalidArgument(AlgorithmName() + ": message too long for this public key"); + + SecByteBlock paddedBlock(PaddedBlockByteLength()); + GetMessageEncodingInterface().Pad(rng, plaintext, plaintextLength, paddedBlock, PaddedBlockBitLength(), parameters); + GetTrapdoorFunctionInterface().ApplyRandomizedFunction(rng, Integer(paddedBlock, paddedBlock.size())).Encode(ciphertext, FixedCiphertextLength()); +} + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/pubkey.h b/CryptoPP/crypto/pubkey.h new file mode 100644 index 0000000..0d45ea3 --- /dev/null +++ b/CryptoPP/crypto/pubkey.h @@ -0,0 +1,1678 @@ +// pubkey.h - written and placed in the public domain by Wei Dai + +#ifndef CRYPTOPP_PUBKEY_H +#define CRYPTOPP_PUBKEY_H + +/** \file + + This file contains helper classes/functions for implementing public key algorithms. + + The class hierachies in this .h file tend to look like this: +

+                  x1
+                 / \
+                y1  z1
+                 |  |
+            x2  x2
+                 |  |
+                y2  z2
+                 |  |
+            x3  x3
+                 |  |
+                y3  z3
+
+ - x1, y1, z1 are abstract interface classes defined in cryptlib.h + - x2, y2, z2 are implementations of the interfaces using "abstract policies", which + are pure virtual functions that should return interfaces to interchangeable algorithms. + These classes have "Base" suffixes. + - x3, y3, z3 hold actual algorithms and implement those virtual functions. + These classes have "Impl" suffixes. + + The "TF_" prefix means an implementation using trapdoor functions on integers. + The "DL_" prefix means an implementation using group operations (in groups where discrete log is hard). +*/ + +#include "modarith.h" +#include "filters.h" +#include "eprecomp.h" +#include "fips140.h" +#include "argnames.h" +#include + +// VC60 workaround: this macro is defined in shlobj.h and conflicts with a template parameter used in this file +#undef INTERFACE + +NAMESPACE_BEGIN(CryptoPP) + +//! _ +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunctionBounds +{ +public: + virtual ~TrapdoorFunctionBounds() {} + + virtual Integer PreimageBound() const =0; + virtual Integer ImageBound() const =0; + virtual Integer MaxPreimage() const {return --PreimageBound();} + virtual Integer MaxImage() const {return --ImageBound();} +}; + +//! _ +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomizedTrapdoorFunction : public TrapdoorFunctionBounds +{ +public: + virtual Integer ApplyRandomizedFunction(RandomNumberGenerator &rng, const Integer &x) const =0; + virtual bool IsRandomized() const {return true;} +}; + +//! _ +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunction : public RandomizedTrapdoorFunction +{ +public: + Integer ApplyRandomizedFunction(RandomNumberGenerator &rng, const Integer &x) const + {return ApplyFunction(x);} + bool IsRandomized() const {return false;} + + virtual Integer ApplyFunction(const Integer &x) const =0; +}; + +//! _ +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE RandomizedTrapdoorFunctionInverse +{ +public: + virtual ~RandomizedTrapdoorFunctionInverse() {} + + virtual Integer CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const =0; + virtual bool IsRandomized() const {return true;} +}; + +//! _ +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TrapdoorFunctionInverse : public RandomizedTrapdoorFunctionInverse +{ +public: + virtual ~TrapdoorFunctionInverse() {} + + Integer CalculateRandomizedInverse(RandomNumberGenerator &rng, const Integer &x) const + {return CalculateInverse(rng, x);} + bool IsRandomized() const {return false;} + + virtual Integer CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const =0; +}; + +// ******************************************************** + +//! message encoding method for public key encryption +class CRYPTOPP_NO_VTABLE PK_EncryptionMessageEncodingMethod +{ +public: + virtual ~PK_EncryptionMessageEncodingMethod() {} + + virtual bool ParameterSupported(const char *name) const {return false;} + + //! max size of unpadded message in bytes, given max size of padded message in bits (1 less than size of modulus) + virtual size_t MaxUnpaddedLength(size_t paddedLength) const =0; + + virtual void Pad(RandomNumberGenerator &rng, const byte *raw, size_t inputLength, byte *padded, size_t paddedBitLength, const NameValuePairs ¶meters) const =0; + + virtual DecodingResult Unpad(const byte *padded, size_t paddedBitLength, byte *raw, const NameValuePairs ¶meters) const =0; +}; + +// ******************************************************** + +//! _ +template +class CRYPTOPP_NO_VTABLE TF_Base +{ +protected: + virtual const TrapdoorFunctionBounds & GetTrapdoorFunctionBounds() const =0; + + typedef TFI TrapdoorFunctionInterface; + virtual const TrapdoorFunctionInterface & GetTrapdoorFunctionInterface() const =0; + + typedef MEI MessageEncodingInterface; + virtual const MessageEncodingInterface & GetMessageEncodingInterface() const =0; +}; + +// ******************************************************** + +//! _ +template +class CRYPTOPP_NO_VTABLE PK_FixedLengthCryptoSystemImpl : public BASE +{ +public: + size_t MaxPlaintextLength(size_t ciphertextLength) const + {return ciphertextLength == FixedCiphertextLength() ? FixedMaxPlaintextLength() : 0;} + size_t CiphertextLength(size_t plaintextLength) const + {return plaintextLength <= FixedMaxPlaintextLength() ? FixedCiphertextLength() : 0;} + + virtual size_t FixedMaxPlaintextLength() const =0; + virtual size_t FixedCiphertextLength() const =0; +}; + +//! _ +template +class CRYPTOPP_NO_VTABLE TF_CryptoSystemBase : public PK_FixedLengthCryptoSystemImpl, protected BASE +{ +public: + bool ParameterSupported(const char *name) const {return this->GetMessageEncodingInterface().ParameterSupported(name);} + size_t FixedMaxPlaintextLength() const {return this->GetMessageEncodingInterface().MaxUnpaddedLength(PaddedBlockBitLength());} + size_t FixedCiphertextLength() const {return this->GetTrapdoorFunctionBounds().MaxImage().ByteCount();} + +protected: + size_t PaddedBlockByteLength() const {return BitsToBytes(PaddedBlockBitLength());} + size_t PaddedBlockBitLength() const {return this->GetTrapdoorFunctionBounds().PreimageBound().BitCount()-1;} +}; + +//! _ +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_DecryptorBase : public TF_CryptoSystemBase > +{ +public: + DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs ¶meters = g_nullNameValuePairs) const; +}; + +//! _ +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_EncryptorBase : public TF_CryptoSystemBase > +{ +public: + void Encrypt(RandomNumberGenerator &rng, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs ¶meters = g_nullNameValuePairs) const; +}; + +// ******************************************************** + +typedef std::pair HashIdentifier; + +//! interface for message encoding method for public key signature schemes +class CRYPTOPP_NO_VTABLE PK_SignatureMessageEncodingMethod +{ +public: + virtual ~PK_SignatureMessageEncodingMethod() {} + + virtual size_t MinRepresentativeBitLength(size_t hashIdentifierLength, size_t digestLength) const + {return 0;} + virtual size_t MaxRecoverableLength(size_t representativeBitLength, size_t hashIdentifierLength, size_t digestLength) const + {return 0;} + + bool IsProbabilistic() const + {return true;} + bool AllowNonrecoverablePart() const + {throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");} + virtual bool RecoverablePartFirst() const + {throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");} + + // for verification, DL + virtual void ProcessSemisignature(HashTransformation &hash, const byte *semisignature, size_t semisignatureLength) const {} + + // for signature + virtual void ProcessRecoverableMessage(HashTransformation &hash, + const byte *recoverableMessage, size_t recoverableMessageLength, + const byte *presignature, size_t presignatureLength, + SecByteBlock &semisignature) const + { + if (RecoverablePartFirst()) + assert(!"ProcessRecoverableMessage() not implemented"); + } + + virtual void ComputeMessageRepresentative(RandomNumberGenerator &rng, + const byte *recoverableMessage, size_t recoverableMessageLength, + HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, + byte *representative, size_t representativeBitLength) const =0; + + virtual bool VerifyMessageRepresentative( + HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, + byte *representative, size_t representativeBitLength) const =0; + + virtual DecodingResult RecoverMessageFromRepresentative( // for TF + HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, + byte *representative, size_t representativeBitLength, + byte *recoveredMessage) const + {throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");} + + virtual DecodingResult RecoverMessageFromSemisignature( // for DL + HashTransformation &hash, HashIdentifier hashIdentifier, + const byte *presignature, size_t presignatureLength, + const byte *semisignature, size_t semisignatureLength, + byte *recoveredMessage) const + {throw NotImplemented("PK_MessageEncodingMethod: this signature scheme does not support message recovery");} + + // VC60 workaround + struct HashIdentifierLookup + { + template struct HashIdentifierLookup2 + { + static HashIdentifier CRYPTOPP_API Lookup() + { + return HashIdentifier(NULL, 0); + } + }; + }; +}; + +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_DeterministicSignatureMessageEncodingMethod : public PK_SignatureMessageEncodingMethod +{ +public: + bool VerifyMessageRepresentative( + HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, + byte *representative, size_t representativeBitLength) const; +}; + +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_RecoverableSignatureMessageEncodingMethod : public PK_SignatureMessageEncodingMethod +{ +public: + bool VerifyMessageRepresentative( + HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, + byte *representative, size_t representativeBitLength) const; +}; + +class CRYPTOPP_DLL DL_SignatureMessageEncodingMethod_DSA : public PK_DeterministicSignatureMessageEncodingMethod +{ +public: + void ComputeMessageRepresentative(RandomNumberGenerator &rng, + const byte *recoverableMessage, size_t recoverableMessageLength, + HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, + byte *representative, size_t representativeBitLength) const; +}; + +class CRYPTOPP_DLL DL_SignatureMessageEncodingMethod_NR : public PK_DeterministicSignatureMessageEncodingMethod +{ +public: + void ComputeMessageRepresentative(RandomNumberGenerator &rng, + const byte *recoverableMessage, size_t recoverableMessageLength, + HashTransformation &hash, HashIdentifier hashIdentifier, bool messageEmpty, + byte *representative, size_t representativeBitLength) const; +}; + +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE PK_MessageAccumulatorBase : public PK_MessageAccumulator +{ +public: + PK_MessageAccumulatorBase() : m_empty(true) {} + + virtual HashTransformation & AccessHash() =0; + + void Update(const byte *input, size_t length) + { + AccessHash().Update(input, length); + m_empty = m_empty && length == 0; + } + + SecByteBlock m_recoverableMessage, m_representative, m_presignature, m_semisignature; + Integer m_k, m_s; + bool m_empty; +}; + +template +class PK_MessageAccumulatorImpl : public PK_MessageAccumulatorBase, protected ObjectHolder +{ +public: + HashTransformation & AccessHash() {return this->m_object;} +}; + +//! _ +template +class CRYPTOPP_NO_VTABLE TF_SignatureSchemeBase : public INTERFACE, protected BASE +{ +public: + size_t SignatureLength() const + {return this->GetTrapdoorFunctionBounds().MaxPreimage().ByteCount();} + size_t MaxRecoverableLength() const + {return this->GetMessageEncodingInterface().MaxRecoverableLength(MessageRepresentativeBitLength(), GetHashIdentifier().second, GetDigestSize());} + size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const + {return this->MaxRecoverableLength();} + + bool IsProbabilistic() const + {return this->GetTrapdoorFunctionInterface().IsRandomized() || this->GetMessageEncodingInterface().IsProbabilistic();} + bool AllowNonrecoverablePart() const + {return this->GetMessageEncodingInterface().AllowNonrecoverablePart();} + bool RecoverablePartFirst() const + {return this->GetMessageEncodingInterface().RecoverablePartFirst();} + +protected: + size_t MessageRepresentativeLength() const {return BitsToBytes(MessageRepresentativeBitLength());} + size_t MessageRepresentativeBitLength() const {return this->GetTrapdoorFunctionBounds().ImageBound().BitCount()-1;} + virtual HashIdentifier GetHashIdentifier() const =0; + virtual size_t GetDigestSize() const =0; +}; + +//! _ +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_SignerBase : public TF_SignatureSchemeBase > +{ +public: + void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const; + size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart=true) const; +}; + +//! _ +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE TF_VerifierBase : public TF_SignatureSchemeBase > +{ +public: + void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const; + bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const; + DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &recoveryAccumulator) const; +}; + +// ******************************************************** + +//! _ +template +struct TF_CryptoSchemeOptions +{ + typedef T1 AlgorithmInfo; + typedef T2 Keys; + typedef typename Keys::PrivateKey PrivateKey; + typedef typename Keys::PublicKey PublicKey; + typedef T3 MessageEncodingMethod; +}; + +//! _ +template +struct TF_SignatureSchemeOptions : public TF_CryptoSchemeOptions +{ + typedef T4 HashFunction; +}; + +//! _ +template +class CRYPTOPP_NO_VTABLE TF_ObjectImplBase : public AlgorithmImpl +{ +public: + typedef SCHEME_OPTIONS SchemeOptions; + typedef KEY_CLASS KeyClass; + + PublicKey & AccessPublicKey() {return AccessKey();} + const PublicKey & GetPublicKey() const {return GetKey();} + + PrivateKey & AccessPrivateKey() {return AccessKey();} + const PrivateKey & GetPrivateKey() const {return GetKey();} + + virtual const KeyClass & GetKey() const =0; + virtual KeyClass & AccessKey() =0; + + const KeyClass & GetTrapdoorFunction() const {return GetKey();} + + PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng) const + { + return new PK_MessageAccumulatorImpl; + } + PK_MessageAccumulator * NewVerificationAccumulator() const + { + return new PK_MessageAccumulatorImpl; + } + +protected: + const typename BASE::MessageEncodingInterface & GetMessageEncodingInterface() const + {return Singleton().Ref();} + const TrapdoorFunctionBounds & GetTrapdoorFunctionBounds() const + {return GetKey();} + const typename BASE::TrapdoorFunctionInterface & GetTrapdoorFunctionInterface() const + {return GetKey();} + + // for signature scheme + HashIdentifier GetHashIdentifier() const + { + typedef CPP_TYPENAME SchemeOptions::MessageEncodingMethod::HashIdentifierLookup::template HashIdentifierLookup2 L; + return L::Lookup(); + } + size_t GetDigestSize() const + { + typedef CPP_TYPENAME SchemeOptions::HashFunction H; + return H::DIGESTSIZE; + } +}; + +//! _ +template +class TF_ObjectImplExtRef : public TF_ObjectImplBase +{ +public: + TF_ObjectImplExtRef(const KEY *pKey = NULL) : m_pKey(pKey) {} + void SetKeyPtr(const KEY *pKey) {m_pKey = pKey;} + + const KEY & GetKey() const {return *m_pKey;} + KEY & AccessKey() {throw NotImplemented("TF_ObjectImplExtRef: cannot modify refererenced key");} + +private: + const KEY * m_pKey; +}; + +//! _ +template +class CRYPTOPP_NO_VTABLE TF_ObjectImpl : public TF_ObjectImplBase +{ +public: + typedef KEY_CLASS KeyClass; + + const KeyClass & GetKey() const {return m_trapdoorFunction;} + KeyClass & AccessKey() {return m_trapdoorFunction;} + +private: + KeyClass m_trapdoorFunction; +}; + +//! _ +template +class TF_DecryptorImpl : public TF_ObjectImpl +{ +}; + +//! _ +template +class TF_EncryptorImpl : public TF_ObjectImpl +{ +}; + +//! _ +template +class TF_SignerImpl : public TF_ObjectImpl +{ +}; + +//! _ +template +class TF_VerifierImpl : public TF_ObjectImpl +{ +}; + +// ******************************************************** + +//! _ +class CRYPTOPP_NO_VTABLE MaskGeneratingFunction +{ +public: + virtual ~MaskGeneratingFunction() {} + virtual void GenerateAndMask(HashTransformation &hash, byte *output, size_t outputLength, const byte *input, size_t inputLength, bool mask = true) const =0; +}; + +CRYPTOPP_DLL void CRYPTOPP_API P1363_MGF1KDF2_Common(HashTransformation &hash, byte *output, size_t outputLength, const byte *input, size_t inputLength, const byte *derivationParams, size_t derivationParamsLength, bool mask, unsigned int counterStart); + +//! _ +class P1363_MGF1 : public MaskGeneratingFunction +{ +public: + static const char * CRYPTOPP_API StaticAlgorithmName() {return "MGF1";} + void GenerateAndMask(HashTransformation &hash, byte *output, size_t outputLength, const byte *input, size_t inputLength, bool mask = true) const + { + P1363_MGF1KDF2_Common(hash, output, outputLength, input, inputLength, NULL, 0, mask, 0); + } +}; + +// ******************************************************** + +//! _ +template +class P1363_KDF2 +{ +public: + static void CRYPTOPP_API DeriveKey(byte *output, size_t outputLength, const byte *input, size_t inputLength, const byte *derivationParams, size_t derivationParamsLength) + { + H h; + P1363_MGF1KDF2_Common(h, output, outputLength, input, inputLength, derivationParams, derivationParamsLength, false, 1); + } +}; + +// ******************************************************** + +//! to be thrown by DecodeElement and AgreeWithStaticPrivateKey +class DL_BadElement : public InvalidDataFormat +{ +public: + DL_BadElement() : InvalidDataFormat("CryptoPP: invalid group element") {} +}; + +//! interface for DL group parameters +template +class CRYPTOPP_NO_VTABLE DL_GroupParameters : public CryptoParameters +{ + typedef DL_GroupParameters ThisClass; + +public: + typedef T Element; + + DL_GroupParameters() : m_validationLevel(0) {} + + // CryptoMaterial + bool Validate(RandomNumberGenerator &rng, unsigned int level) const + { + if (!GetBasePrecomputation().IsInitialized()) + return false; + + if (m_validationLevel > level) + return true; + + bool pass = ValidateGroup(rng, level); + pass = pass && ValidateElement(level, GetSubgroupGenerator(), &GetBasePrecomputation()); + + m_validationLevel = pass ? level+1 : 0; + + return pass; + } + + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const + { + return GetValueHelper(this, name, valueType, pValue) + CRYPTOPP_GET_FUNCTION_ENTRY(SubgroupOrder) + CRYPTOPP_GET_FUNCTION_ENTRY(SubgroupGenerator) + ; + } + + bool SupportsPrecomputation() const {return true;} + + void Precompute(unsigned int precomputationStorage=16) + { + AccessBasePrecomputation().Precompute(GetGroupPrecomputation(), GetSubgroupOrder().BitCount(), precomputationStorage); + } + + void LoadPrecomputation(BufferedTransformation &storedPrecomputation) + { + AccessBasePrecomputation().Load(GetGroupPrecomputation(), storedPrecomputation); + m_validationLevel = 0; + } + + void SavePrecomputation(BufferedTransformation &storedPrecomputation) const + { + GetBasePrecomputation().Save(GetGroupPrecomputation(), storedPrecomputation); + } + + // non-inherited + virtual const Element & GetSubgroupGenerator() const {return GetBasePrecomputation().GetBase(GetGroupPrecomputation());} + virtual void SetSubgroupGenerator(const Element &base) {AccessBasePrecomputation().SetBase(GetGroupPrecomputation(), base);} + virtual Element ExponentiateBase(const Integer &exponent) const + { + return GetBasePrecomputation().Exponentiate(GetGroupPrecomputation(), exponent); + } + virtual Element ExponentiateElement(const Element &base, const Integer &exponent) const + { + Element result; + SimultaneousExponentiate(&result, base, &exponent, 1); + return result; + } + + virtual const DL_GroupPrecomputation & GetGroupPrecomputation() const =0; + virtual const DL_FixedBasePrecomputation & GetBasePrecomputation() const =0; + virtual DL_FixedBasePrecomputation & AccessBasePrecomputation() =0; + virtual const Integer & GetSubgroupOrder() const =0; // order of subgroup generated by base element + virtual Integer GetMaxExponent() const =0; + virtual Integer GetGroupOrder() const {return GetSubgroupOrder()*GetCofactor();} // one of these two needs to be overriden + virtual Integer GetCofactor() const {return GetGroupOrder()/GetSubgroupOrder();} + virtual unsigned int GetEncodedElementSize(bool reversible) const =0; + virtual void EncodeElement(bool reversible, const Element &element, byte *encoded) const =0; + virtual Element DecodeElement(const byte *encoded, bool checkForGroupMembership) const =0; + virtual Integer ConvertElementToInteger(const Element &element) const =0; + virtual bool ValidateGroup(RandomNumberGenerator &rng, unsigned int level) const =0; + virtual bool ValidateElement(unsigned int level, const Element &element, const DL_FixedBasePrecomputation *precomp) const =0; + virtual bool FastSubgroupCheckAvailable() const =0; + virtual bool IsIdentity(const Element &element) const =0; + virtual void SimultaneousExponentiate(Element *results, const Element &base, const Integer *exponents, unsigned int exponentsCount) const =0; + +protected: + void ParametersChanged() {m_validationLevel = 0;} + +private: + mutable unsigned int m_validationLevel; +}; + +//! _ +template , class BASE = DL_GroupParameters > +class DL_GroupParametersImpl : public BASE +{ +public: + typedef GROUP_PRECOMP GroupPrecomputation; + typedef typename GROUP_PRECOMP::Element Element; + typedef BASE_PRECOMP BasePrecomputation; + + const DL_GroupPrecomputation & GetGroupPrecomputation() const {return m_groupPrecomputation;} + const DL_FixedBasePrecomputation & GetBasePrecomputation() const {return m_gpc;} + DL_FixedBasePrecomputation & AccessBasePrecomputation() {return m_gpc;} + +protected: + GROUP_PRECOMP m_groupPrecomputation; + BASE_PRECOMP m_gpc; +}; + +//! _ +template +class CRYPTOPP_NO_VTABLE DL_Key +{ +public: + virtual const DL_GroupParameters & GetAbstractGroupParameters() const =0; + virtual DL_GroupParameters & AccessAbstractGroupParameters() =0; +}; + +//! interface for DL public keys +template +class CRYPTOPP_NO_VTABLE DL_PublicKey : public DL_Key +{ + typedef DL_PublicKey ThisClass; + +public: + typedef T Element; + + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const + { + return GetValueHelper(this, name, valueType, pValue, &this->GetAbstractGroupParameters()) + CRYPTOPP_GET_FUNCTION_ENTRY(PublicElement); + } + + void AssignFrom(const NameValuePairs &source); + + // non-inherited + virtual const Element & GetPublicElement() const {return GetPublicPrecomputation().GetBase(this->GetAbstractGroupParameters().GetGroupPrecomputation());} + virtual void SetPublicElement(const Element &y) {AccessPublicPrecomputation().SetBase(this->GetAbstractGroupParameters().GetGroupPrecomputation(), y);} + virtual Element ExponentiatePublicElement(const Integer &exponent) const + { + const DL_GroupParameters ¶ms = this->GetAbstractGroupParameters(); + return GetPublicPrecomputation().Exponentiate(params.GetGroupPrecomputation(), exponent); + } + virtual Element CascadeExponentiateBaseAndPublicElement(const Integer &baseExp, const Integer &publicExp) const + { + const DL_GroupParameters ¶ms = this->GetAbstractGroupParameters(); + return params.GetBasePrecomputation().CascadeExponentiate(params.GetGroupPrecomputation(), baseExp, GetPublicPrecomputation(), publicExp); + } + + virtual const DL_FixedBasePrecomputation & GetPublicPrecomputation() const =0; + virtual DL_FixedBasePrecomputation & AccessPublicPrecomputation() =0; +}; + +//! interface for DL private keys +template +class CRYPTOPP_NO_VTABLE DL_PrivateKey : public DL_Key +{ + typedef DL_PrivateKey ThisClass; + +public: + typedef T Element; + + void MakePublicKey(DL_PublicKey &pub) const + { + pub.AccessAbstractGroupParameters().AssignFrom(this->GetAbstractGroupParameters()); + pub.SetPublicElement(this->GetAbstractGroupParameters().ExponentiateBase(GetPrivateExponent())); + } + + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const + { + return GetValueHelper(this, name, valueType, pValue, &this->GetAbstractGroupParameters()) + CRYPTOPP_GET_FUNCTION_ENTRY(PrivateExponent); + } + + void AssignFrom(const NameValuePairs &source) + { + this->AccessAbstractGroupParameters().AssignFrom(source); + AssignFromHelper(this, source) + CRYPTOPP_SET_FUNCTION_ENTRY(PrivateExponent); + } + + virtual const Integer & GetPrivateExponent() const =0; + virtual void SetPrivateExponent(const Integer &x) =0; +}; + +template +void DL_PublicKey::AssignFrom(const NameValuePairs &source) +{ + DL_PrivateKey *pPrivateKey = NULL; + if (source.GetThisPointer(pPrivateKey)) + pPrivateKey->MakePublicKey(*this); + else + { + this->AccessAbstractGroupParameters().AssignFrom(source); + AssignFromHelper(this, source) + CRYPTOPP_SET_FUNCTION_ENTRY(PublicElement); + } +} + +class OID; + +//! _ +template +class DL_KeyImpl : public PK +{ +public: + typedef GP GroupParameters; + + O GetAlgorithmID() const {return GetGroupParameters().GetAlgorithmID();} +// void BERDecode(BufferedTransformation &bt) +// {PK::BERDecode(bt);} +// void DEREncode(BufferedTransformation &bt) const +// {PK::DEREncode(bt);} + bool BERDecodeAlgorithmParameters(BufferedTransformation &bt) + {AccessGroupParameters().BERDecode(bt); return true;} + bool DEREncodeAlgorithmParameters(BufferedTransformation &bt) const + {GetGroupParameters().DEREncode(bt); return true;} + + const GP & GetGroupParameters() const {return m_groupParameters;} + GP & AccessGroupParameters() {return m_groupParameters;} + +private: + GP m_groupParameters; +}; + +class X509PublicKey; +class PKCS8PrivateKey; + +//! _ +template +class DL_PrivateKeyImpl : public DL_PrivateKey, public DL_KeyImpl +{ +public: + typedef typename GP::Element Element; + + // GeneratableCryptoMaterial + bool Validate(RandomNumberGenerator &rng, unsigned int level) const + { + bool pass = GetAbstractGroupParameters().Validate(rng, level); + + const Integer &q = GetAbstractGroupParameters().GetSubgroupOrder(); + const Integer &x = GetPrivateExponent(); + + pass = pass && x.IsPositive() && x < q; + if (level >= 1) + pass = pass && Integer::Gcd(x, q) == Integer::One(); + return pass; + } + + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const + { + return GetValueHelper >(this, name, valueType, pValue).Assignable(); + } + + void AssignFrom(const NameValuePairs &source) + { + AssignFromHelper >(this, source); + } + + void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs ¶ms) + { + if (!params.GetThisObject(this->AccessGroupParameters())) + this->AccessGroupParameters().GenerateRandom(rng, params); +// std::pair seed; + Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent()); +// Integer::ANY, Integer::Zero(), Integer::One(), +// params.GetValue("DeterministicKeyGenerationSeed", seed) ? &seed : NULL); + SetPrivateExponent(x); + } + + bool SupportsPrecomputation() const {return true;} + + void Precompute(unsigned int precomputationStorage=16) + {AccessAbstractGroupParameters().Precompute(precomputationStorage);} + + void LoadPrecomputation(BufferedTransformation &storedPrecomputation) + {AccessAbstractGroupParameters().LoadPrecomputation(storedPrecomputation);} + + void SavePrecomputation(BufferedTransformation &storedPrecomputation) const + {GetAbstractGroupParameters().SavePrecomputation(storedPrecomputation);} + + // DL_Key + const DL_GroupParameters & GetAbstractGroupParameters() const {return this->GetGroupParameters();} + DL_GroupParameters & AccessAbstractGroupParameters() {return this->AccessGroupParameters();} + + // DL_PrivateKey + const Integer & GetPrivateExponent() const {return m_x;} + void SetPrivateExponent(const Integer &x) {m_x = x;} + + // PKCS8PrivateKey + void BERDecodePrivateKey(BufferedTransformation &bt, bool, size_t) + {m_x.BERDecode(bt);} + void DEREncodePrivateKey(BufferedTransformation &bt) const + {m_x.DEREncode(bt);} + +private: + Integer m_x; +}; + +//! _ +template +class DL_PrivateKey_WithSignaturePairwiseConsistencyTest : public BASE +{ +public: + void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs ¶ms) + { + BASE::GenerateRandom(rng, params); + + if (FIPS_140_2_ComplianceEnabled()) + { + typename SIGNATURE_SCHEME::Signer signer(*this); + typename SIGNATURE_SCHEME::Verifier verifier(signer); + SignaturePairwiseConsistencyTest_FIPS_140_Only(signer, verifier); + } + } +}; + +//! _ +template +class DL_PublicKeyImpl : public DL_PublicKey, public DL_KeyImpl +{ +public: + typedef typename GP::Element Element; + + // CryptoMaterial + bool Validate(RandomNumberGenerator &rng, unsigned int level) const + { + bool pass = GetAbstractGroupParameters().Validate(rng, level); + pass = pass && GetAbstractGroupParameters().ValidateElement(level, this->GetPublicElement(), &GetPublicPrecomputation()); + return pass; + } + + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const + { + return GetValueHelper >(this, name, valueType, pValue).Assignable(); + } + + void AssignFrom(const NameValuePairs &source) + { + AssignFromHelper >(this, source); + } + + bool SupportsPrecomputation() const {return true;} + + void Precompute(unsigned int precomputationStorage=16) + { + AccessAbstractGroupParameters().Precompute(precomputationStorage); + AccessPublicPrecomputation().Precompute(GetAbstractGroupParameters().GetGroupPrecomputation(), GetAbstractGroupParameters().GetSubgroupOrder().BitCount(), precomputationStorage); + } + + void LoadPrecomputation(BufferedTransformation &storedPrecomputation) + { + AccessAbstractGroupParameters().LoadPrecomputation(storedPrecomputation); + AccessPublicPrecomputation().Load(GetAbstractGroupParameters().GetGroupPrecomputation(), storedPrecomputation); + } + + void SavePrecomputation(BufferedTransformation &storedPrecomputation) const + { + GetAbstractGroupParameters().SavePrecomputation(storedPrecomputation); + GetPublicPrecomputation().Save(GetAbstractGroupParameters().GetGroupPrecomputation(), storedPrecomputation); + } + + // DL_Key + const DL_GroupParameters & GetAbstractGroupParameters() const {return this->GetGroupParameters();} + DL_GroupParameters & AccessAbstractGroupParameters() {return this->AccessGroupParameters();} + + // DL_PublicKey + const DL_FixedBasePrecomputation & GetPublicPrecomputation() const {return m_ypc;} + DL_FixedBasePrecomputation & AccessPublicPrecomputation() {return m_ypc;} + + // non-inherited + bool operator==(const DL_PublicKeyImpl &rhs) const + {return this->GetGroupParameters() == rhs.GetGroupParameters() && this->GetPublicElement() == rhs.GetPublicElement();} + +private: + typename GP::BasePrecomputation m_ypc; +}; + +//! interface for Elgamal-like signature algorithms +template +class CRYPTOPP_NO_VTABLE DL_ElgamalLikeSignatureAlgorithm +{ +public: + virtual void Sign(const DL_GroupParameters ¶ms, const Integer &privateKey, const Integer &k, const Integer &e, Integer &r, Integer &s) const =0; + virtual bool Verify(const DL_GroupParameters ¶ms, const DL_PublicKey &publicKey, const Integer &e, const Integer &r, const Integer &s) const =0; + virtual Integer RecoverPresignature(const DL_GroupParameters ¶ms, const DL_PublicKey &publicKey, const Integer &r, const Integer &s) const + {throw NotImplemented("DL_ElgamalLikeSignatureAlgorithm: this signature scheme does not support message recovery");} + virtual size_t RLen(const DL_GroupParameters ¶ms) const + {return params.GetSubgroupOrder().ByteCount();} + virtual size_t SLen(const DL_GroupParameters ¶ms) const + {return params.GetSubgroupOrder().ByteCount();} +}; + +//! interface for DL key agreement algorithms +template +class CRYPTOPP_NO_VTABLE DL_KeyAgreementAlgorithm +{ +public: + typedef T Element; + + virtual Element AgreeWithEphemeralPrivateKey(const DL_GroupParameters ¶ms, const DL_FixedBasePrecomputation &publicPrecomputation, const Integer &privateExponent) const =0; + virtual Element AgreeWithStaticPrivateKey(const DL_GroupParameters ¶ms, const Element &publicElement, bool validateOtherPublicKey, const Integer &privateExponent) const =0; +}; + +//! interface for key derivation algorithms used in DL cryptosystems +template +class CRYPTOPP_NO_VTABLE DL_KeyDerivationAlgorithm +{ +public: + virtual bool ParameterSupported(const char *name) const {return false;} + virtual void Derive(const DL_GroupParameters &groupParams, byte *derivedKey, size_t derivedLength, const T &agreedElement, const T &ephemeralPublicKey, const NameValuePairs &derivationParams) const =0; +}; + +//! interface for symmetric encryption algorithms used in DL cryptosystems +class CRYPTOPP_NO_VTABLE DL_SymmetricEncryptionAlgorithm +{ +public: + virtual bool ParameterSupported(const char *name) const {return false;} + virtual size_t GetSymmetricKeyLength(size_t plaintextLength) const =0; + virtual size_t GetSymmetricCiphertextLength(size_t plaintextLength) const =0; + virtual size_t GetMaxSymmetricPlaintextLength(size_t ciphertextLength) const =0; + virtual void SymmetricEncrypt(RandomNumberGenerator &rng, const byte *key, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs ¶meters) const =0; + virtual DecodingResult SymmetricDecrypt(const byte *key, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs ¶meters) const =0; +}; + +//! _ +template +class CRYPTOPP_NO_VTABLE DL_Base +{ +protected: + typedef KI KeyInterface; + typedef typename KI::Element Element; + + const DL_GroupParameters & GetAbstractGroupParameters() const {return GetKeyInterface().GetAbstractGroupParameters();} + DL_GroupParameters & AccessAbstractGroupParameters() {return AccessKeyInterface().AccessAbstractGroupParameters();} + + virtual KeyInterface & AccessKeyInterface() =0; + virtual const KeyInterface & GetKeyInterface() const =0; +}; + +//! _ +template +class CRYPTOPP_NO_VTABLE DL_SignatureSchemeBase : public INTERFACE, public DL_Base +{ +public: + size_t SignatureLength() const + { + return GetSignatureAlgorithm().RLen(this->GetAbstractGroupParameters()) + + GetSignatureAlgorithm().SLen(this->GetAbstractGroupParameters()); + } + size_t MaxRecoverableLength() const + {return GetMessageEncodingInterface().MaxRecoverableLength(0, GetHashIdentifier().second, GetDigestSize());} + size_t MaxRecoverableLengthFromSignatureLength(size_t signatureLength) const + {assert(false); return 0;} // TODO + + bool IsProbabilistic() const + {return true;} + bool AllowNonrecoverablePart() const + {return GetMessageEncodingInterface().AllowNonrecoverablePart();} + bool RecoverablePartFirst() const + {return GetMessageEncodingInterface().RecoverablePartFirst();} + +protected: + size_t MessageRepresentativeLength() const {return BitsToBytes(MessageRepresentativeBitLength());} + size_t MessageRepresentativeBitLength() const {return this->GetAbstractGroupParameters().GetSubgroupOrder().BitCount();} + + virtual const DL_ElgamalLikeSignatureAlgorithm & GetSignatureAlgorithm() const =0; + virtual const PK_SignatureMessageEncodingMethod & GetMessageEncodingInterface() const =0; + virtual HashIdentifier GetHashIdentifier() const =0; + virtual size_t GetDigestSize() const =0; +}; + +//! _ +template +class CRYPTOPP_NO_VTABLE DL_SignerBase : public DL_SignatureSchemeBase > +{ +public: + // for validation testing + void RawSign(const Integer &k, const Integer &e, Integer &r, Integer &s) const + { + const DL_ElgamalLikeSignatureAlgorithm &alg = this->GetSignatureAlgorithm(); + const DL_GroupParameters ¶ms = this->GetAbstractGroupParameters(); + const DL_PrivateKey &key = this->GetKeyInterface(); + + r = params.ConvertElementToInteger(params.ExponentiateBase(k)); + alg.Sign(params, key.GetPrivateExponent(), k, e, r, s); + } + + void InputRecoverableMessage(PK_MessageAccumulator &messageAccumulator, const byte *recoverableMessage, size_t recoverableMessageLength) const + { + PK_MessageAccumulatorBase &ma = static_cast(messageAccumulator); + ma.m_recoverableMessage.Assign(recoverableMessage, recoverableMessageLength); + this->GetMessageEncodingInterface().ProcessRecoverableMessage(ma.AccessHash(), + recoverableMessage, recoverableMessageLength, + ma.m_presignature, ma.m_presignature.size(), + ma.m_semisignature); + } + + size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart) const + { + this->GetMaterial().DoQuickSanityCheck(); + + PK_MessageAccumulatorBase &ma = static_cast(messageAccumulator); + const DL_ElgamalLikeSignatureAlgorithm &alg = this->GetSignatureAlgorithm(); + const DL_GroupParameters ¶ms = this->GetAbstractGroupParameters(); + const DL_PrivateKey &key = this->GetKeyInterface(); + + SecByteBlock representative(this->MessageRepresentativeLength()); + this->GetMessageEncodingInterface().ComputeMessageRepresentative( + rng, + ma.m_recoverableMessage, ma.m_recoverableMessage.size(), + ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty, + representative, this->MessageRepresentativeBitLength()); + ma.m_empty = true; + Integer e(representative, representative.size()); + + // hash message digest into random number k to prevent reusing the same k on a different messages + // after virtual machine rollback + if (rng.CanIncorporateEntropy()) + rng.IncorporateEntropy(representative, representative.size()); + Integer k(rng, 1, params.GetSubgroupOrder()-1); + Integer r, s; + r = params.ConvertElementToInteger(params.ExponentiateBase(k)); + alg.Sign(params, key.GetPrivateExponent(), k, e, r, s); + + /* + Integer r, s; + if (this->MaxRecoverableLength() > 0) + r.Decode(ma.m_semisignature, ma.m_semisignature.size()); + else + r.Decode(ma.m_presignature, ma.m_presignature.size()); + alg.Sign(params, key.GetPrivateExponent(), ma.m_k, e, r, s); + */ + + size_t rLen = alg.RLen(params); + r.Encode(signature, rLen); + s.Encode(signature+rLen, alg.SLen(params)); + + if (restart) + RestartMessageAccumulator(rng, ma); + + return this->SignatureLength(); + } + +protected: + void RestartMessageAccumulator(RandomNumberGenerator &rng, PK_MessageAccumulatorBase &ma) const + { + // k needs to be generated before hashing for signature schemes with recovery + // but to defend against VM rollbacks we need to generate k after hashing. + // so this code is commented out, since no DL-based signature scheme with recovery + // has been implemented in Crypto++ anyway + /* + const DL_ElgamalLikeSignatureAlgorithm &alg = this->GetSignatureAlgorithm(); + const DL_GroupParameters ¶ms = this->GetAbstractGroupParameters(); + ma.m_k.Randomize(rng, 1, params.GetSubgroupOrder()-1); + ma.m_presignature.New(params.GetEncodedElementSize(false)); + params.ConvertElementToInteger(params.ExponentiateBase(ma.m_k)).Encode(ma.m_presignature, ma.m_presignature.size()); + */ + } +}; + +//! _ +template +class CRYPTOPP_NO_VTABLE DL_VerifierBase : public DL_SignatureSchemeBase > +{ +public: + void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const + { + PK_MessageAccumulatorBase &ma = static_cast(messageAccumulator); + const DL_ElgamalLikeSignatureAlgorithm &alg = this->GetSignatureAlgorithm(); + const DL_GroupParameters ¶ms = this->GetAbstractGroupParameters(); + + size_t rLen = alg.RLen(params); + ma.m_semisignature.Assign(signature, rLen); + ma.m_s.Decode(signature+rLen, alg.SLen(params)); + + this->GetMessageEncodingInterface().ProcessSemisignature(ma.AccessHash(), ma.m_semisignature, ma.m_semisignature.size()); + } + + bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const + { + this->GetMaterial().DoQuickSanityCheck(); + + PK_MessageAccumulatorBase &ma = static_cast(messageAccumulator); + const DL_ElgamalLikeSignatureAlgorithm &alg = this->GetSignatureAlgorithm(); + const DL_GroupParameters ¶ms = this->GetAbstractGroupParameters(); + const DL_PublicKey &key = this->GetKeyInterface(); + + SecByteBlock representative(this->MessageRepresentativeLength()); + this->GetMessageEncodingInterface().ComputeMessageRepresentative(NullRNG(), ma.m_recoverableMessage, ma.m_recoverableMessage.size(), + ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty, + representative, this->MessageRepresentativeBitLength()); + ma.m_empty = true; + Integer e(representative, representative.size()); + + Integer r(ma.m_semisignature, ma.m_semisignature.size()); + return alg.Verify(params, key, e, r, ma.m_s); + } + + DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const + { + this->GetMaterial().DoQuickSanityCheck(); + + PK_MessageAccumulatorBase &ma = static_cast(messageAccumulator); + const DL_ElgamalLikeSignatureAlgorithm &alg = this->GetSignatureAlgorithm(); + const DL_GroupParameters ¶ms = this->GetAbstractGroupParameters(); + const DL_PublicKey &key = this->GetKeyInterface(); + + SecByteBlock representative(this->MessageRepresentativeLength()); + this->GetMessageEncodingInterface().ComputeMessageRepresentative( + NullRNG(), + ma.m_recoverableMessage, ma.m_recoverableMessage.size(), + ma.AccessHash(), this->GetHashIdentifier(), ma.m_empty, + representative, this->MessageRepresentativeBitLength()); + ma.m_empty = true; + Integer e(representative, representative.size()); + + ma.m_presignature.New(params.GetEncodedElementSize(false)); + Integer r(ma.m_semisignature, ma.m_semisignature.size()); + alg.RecoverPresignature(params, key, r, ma.m_s).Encode(ma.m_presignature, ma.m_presignature.size()); + + return this->GetMessageEncodingInterface().RecoverMessageFromSemisignature( + ma.AccessHash(), this->GetHashIdentifier(), + ma.m_presignature, ma.m_presignature.size(), + ma.m_semisignature, ma.m_semisignature.size(), + recoveredMessage); + } +}; + +//! _ +template +class CRYPTOPP_NO_VTABLE DL_CryptoSystemBase : public PK, public DL_Base +{ +public: + typedef typename DL_Base::Element Element; + + size_t MaxPlaintextLength(size_t ciphertextLength) const + { + unsigned int minLen = this->GetAbstractGroupParameters().GetEncodedElementSize(true); + return ciphertextLength < minLen ? 0 : GetSymmetricEncryptionAlgorithm().GetMaxSymmetricPlaintextLength(ciphertextLength - minLen); + } + + size_t CiphertextLength(size_t plaintextLength) const + { + size_t len = GetSymmetricEncryptionAlgorithm().GetSymmetricCiphertextLength(plaintextLength); + return len == 0 ? 0 : this->GetAbstractGroupParameters().GetEncodedElementSize(true) + len; + } + + bool ParameterSupported(const char *name) const + {return GetKeyDerivationAlgorithm().ParameterSupported(name) || GetSymmetricEncryptionAlgorithm().ParameterSupported(name);} + +protected: + virtual const DL_KeyAgreementAlgorithm & GetKeyAgreementAlgorithm() const =0; + virtual const DL_KeyDerivationAlgorithm & GetKeyDerivationAlgorithm() const =0; + virtual const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const =0; +}; + +//! _ +template +class CRYPTOPP_NO_VTABLE DL_DecryptorBase : public DL_CryptoSystemBase > +{ +public: + typedef T Element; + + DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs ¶meters = g_nullNameValuePairs) const + { + try + { + const DL_KeyAgreementAlgorithm &agreeAlg = this->GetKeyAgreementAlgorithm(); + const DL_KeyDerivationAlgorithm &derivAlg = this->GetKeyDerivationAlgorithm(); + const DL_SymmetricEncryptionAlgorithm &encAlg = this->GetSymmetricEncryptionAlgorithm(); + const DL_GroupParameters ¶ms = this->GetAbstractGroupParameters(); + const DL_PrivateKey &key = this->GetKeyInterface(); + + Element q = params.DecodeElement(ciphertext, true); + size_t elementSize = params.GetEncodedElementSize(true); + ciphertext += elementSize; + ciphertextLength -= elementSize; + + Element z = agreeAlg.AgreeWithStaticPrivateKey(params, q, true, key.GetPrivateExponent()); + + SecByteBlock derivedKey(encAlg.GetSymmetricKeyLength(encAlg.GetMaxSymmetricPlaintextLength(ciphertextLength))); + derivAlg.Derive(params, derivedKey, derivedKey.size(), z, q, parameters); + + return encAlg.SymmetricDecrypt(derivedKey, ciphertext, ciphertextLength, plaintext, parameters); + } + catch (DL_BadElement &) + { + return DecodingResult(); + } + } +}; + +//! _ +template +class CRYPTOPP_NO_VTABLE DL_EncryptorBase : public DL_CryptoSystemBase > +{ +public: + typedef T Element; + + void Encrypt(RandomNumberGenerator &rng, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs ¶meters = g_nullNameValuePairs) const + { + const DL_KeyAgreementAlgorithm &agreeAlg = this->GetKeyAgreementAlgorithm(); + const DL_KeyDerivationAlgorithm &derivAlg = this->GetKeyDerivationAlgorithm(); + const DL_SymmetricEncryptionAlgorithm &encAlg = this->GetSymmetricEncryptionAlgorithm(); + const DL_GroupParameters ¶ms = this->GetAbstractGroupParameters(); + const DL_PublicKey &key = this->GetKeyInterface(); + + Integer x(rng, Integer::One(), params.GetMaxExponent()); + Element q = params.ExponentiateBase(x); + params.EncodeElement(true, q, ciphertext); + unsigned int elementSize = params.GetEncodedElementSize(true); + ciphertext += elementSize; + + Element z = agreeAlg.AgreeWithEphemeralPrivateKey(params, key.GetPublicPrecomputation(), x); + + SecByteBlock derivedKey(encAlg.GetSymmetricKeyLength(plaintextLength)); + derivAlg.Derive(params, derivedKey, derivedKey.size(), z, q, parameters); + + encAlg.SymmetricEncrypt(rng, derivedKey, plaintext, plaintextLength, ciphertext, parameters); + } +}; + +//! _ +template +struct DL_SchemeOptionsBase +{ + typedef T1 AlgorithmInfo; + typedef T2 GroupParameters; + typedef typename GroupParameters::Element Element; +}; + +//! _ +template +struct DL_KeyedSchemeOptions : public DL_SchemeOptionsBase +{ + typedef T2 Keys; + typedef typename Keys::PrivateKey PrivateKey; + typedef typename Keys::PublicKey PublicKey; +}; + +//! _ +template +struct DL_SignatureSchemeOptions : public DL_KeyedSchemeOptions +{ + typedef T3 SignatureAlgorithm; + typedef T4 MessageEncodingMethod; + typedef T5 HashFunction; +}; + +//! _ +template +struct DL_CryptoSchemeOptions : public DL_KeyedSchemeOptions +{ + typedef T3 KeyAgreementAlgorithm; + typedef T4 KeyDerivationAlgorithm; + typedef T5 SymmetricEncryptionAlgorithm; +}; + +//! _ +template +class CRYPTOPP_NO_VTABLE DL_ObjectImplBase : public AlgorithmImpl +{ +public: + typedef SCHEME_OPTIONS SchemeOptions; + typedef typename KEY::Element Element; + + PrivateKey & AccessPrivateKey() {return m_key;} + PublicKey & AccessPublicKey() {return m_key;} + + // KeyAccessor + const KEY & GetKey() const {return m_key;} + KEY & AccessKey() {return m_key;} + +protected: + typename BASE::KeyInterface & AccessKeyInterface() {return m_key;} + const typename BASE::KeyInterface & GetKeyInterface() const {return m_key;} + + // for signature scheme + HashIdentifier GetHashIdentifier() const + { + typedef typename SchemeOptions::MessageEncodingMethod::HashIdentifierLookup HashLookup; + return HashLookup::template HashIdentifierLookup2::Lookup(); + } + size_t GetDigestSize() const + { + typedef CPP_TYPENAME SchemeOptions::HashFunction H; + return H::DIGESTSIZE; + } + +private: + KEY m_key; +}; + +//! _ +template +class CRYPTOPP_NO_VTABLE DL_ObjectImpl : public DL_ObjectImplBase +{ +public: + typedef typename KEY::Element Element; + +protected: + const DL_ElgamalLikeSignatureAlgorithm & GetSignatureAlgorithm() const + {return Singleton().Ref();} + const DL_KeyAgreementAlgorithm & GetKeyAgreementAlgorithm() const + {return Singleton().Ref();} + const DL_KeyDerivationAlgorithm & GetKeyDerivationAlgorithm() const + {return Singleton().Ref();} + const DL_SymmetricEncryptionAlgorithm & GetSymmetricEncryptionAlgorithm() const + {return Singleton().Ref();} + HashIdentifier GetHashIdentifier() const + {return HashIdentifier();} + const PK_SignatureMessageEncodingMethod & GetMessageEncodingInterface() const + {return Singleton().Ref();} +}; + +//! _ +template +class DL_SignerImpl : public DL_ObjectImpl, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey> +{ +public: + PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng) const + { + std::auto_ptr p(new PK_MessageAccumulatorImpl); + this->RestartMessageAccumulator(rng, *p); + return p.release(); + } +}; + +//! _ +template +class DL_VerifierImpl : public DL_ObjectImpl, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey> +{ +public: + PK_MessageAccumulator * NewVerificationAccumulator() const + { + return new PK_MessageAccumulatorImpl; + } +}; + +//! _ +template +class DL_EncryptorImpl : public DL_ObjectImpl, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PublicKey> +{ +}; + +//! _ +template +class DL_DecryptorImpl : public DL_ObjectImpl, SCHEME_OPTIONS, typename SCHEME_OPTIONS::PrivateKey> +{ +}; + +// ******************************************************** + +//! _ +template +class CRYPTOPP_NO_VTABLE DL_SimpleKeyAgreementDomainBase : public SimpleKeyAgreementDomain +{ +public: + typedef T Element; + + CryptoParameters & AccessCryptoParameters() {return AccessAbstractGroupParameters();} + unsigned int AgreedValueLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(false);} + unsigned int PrivateKeyLength() const {return GetAbstractGroupParameters().GetSubgroupOrder().ByteCount();} + unsigned int PublicKeyLength() const {return GetAbstractGroupParameters().GetEncodedElementSize(true);} + + void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const + { + Integer x(rng, Integer::One(), GetAbstractGroupParameters().GetMaxExponent()); + x.Encode(privateKey, PrivateKeyLength()); + } + + void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const + { + const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); + Integer x(privateKey, PrivateKeyLength()); + Element y = params.ExponentiateBase(x); + params.EncodeElement(true, y, publicKey); + } + + bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const + { + try + { + const DL_GroupParameters ¶ms = GetAbstractGroupParameters(); + Integer x(privateKey, PrivateKeyLength()); + Element w = params.DecodeElement(otherPublicKey, validateOtherPublicKey); + + Element z = GetKeyAgreementAlgorithm().AgreeWithStaticPrivateKey( + GetAbstractGroupParameters(), w, validateOtherPublicKey, x); + params.EncodeElement(false, z, agreedValue); + } + catch (DL_BadElement &) + { + return false; + } + return true; + } + + const Element &GetGenerator() const {return GetAbstractGroupParameters().GetSubgroupGenerator();} + +protected: + virtual const DL_KeyAgreementAlgorithm & GetKeyAgreementAlgorithm() const =0; + virtual DL_GroupParameters & AccessAbstractGroupParameters() =0; + const DL_GroupParameters & GetAbstractGroupParameters() const {return const_cast *>(this)->AccessAbstractGroupParameters();} +}; + +enum CofactorMultiplicationOption {NO_COFACTOR_MULTIPLICTION, COMPATIBLE_COFACTOR_MULTIPLICTION, INCOMPATIBLE_COFACTOR_MULTIPLICTION}; +typedef EnumToType NoCofactorMultiplication; +typedef EnumToType CompatibleCofactorMultiplication; +typedef EnumToType IncompatibleCofactorMultiplication; + +//! DH key agreement algorithm +template +class DL_KeyAgreementAlgorithm_DH : public DL_KeyAgreementAlgorithm +{ +public: + typedef ELEMENT Element; + + static const char * CRYPTOPP_API StaticAlgorithmName() + {return COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION ? "DHC" : "DH";} + + Element AgreeWithEphemeralPrivateKey(const DL_GroupParameters ¶ms, const DL_FixedBasePrecomputation &publicPrecomputation, const Integer &privateExponent) const + { + return publicPrecomputation.Exponentiate(params.GetGroupPrecomputation(), + COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION ? privateExponent*params.GetCofactor() : privateExponent); + } + + Element AgreeWithStaticPrivateKey(const DL_GroupParameters ¶ms, const Element &publicElement, bool validateOtherPublicKey, const Integer &privateExponent) const + { + if (COFACTOR_OPTION::ToEnum() == COMPATIBLE_COFACTOR_MULTIPLICTION) + { + const Integer &k = params.GetCofactor(); + return params.ExponentiateElement(publicElement, + ModularArithmetic(params.GetSubgroupOrder()).Divide(privateExponent, k)*k); + } + else if (COFACTOR_OPTION::ToEnum() == INCOMPATIBLE_COFACTOR_MULTIPLICTION) + return params.ExponentiateElement(publicElement, privateExponent*params.GetCofactor()); + else + { + assert(COFACTOR_OPTION::ToEnum() == NO_COFACTOR_MULTIPLICTION); + + if (!validateOtherPublicKey) + return params.ExponentiateElement(publicElement, privateExponent); + + if (params.FastSubgroupCheckAvailable()) + { + if (!params.ValidateElement(2, publicElement, NULL)) + throw DL_BadElement(); + return params.ExponentiateElement(publicElement, privateExponent); + } + else + { + const Integer e[2] = {params.GetSubgroupOrder(), privateExponent}; + Element r[2]; + params.SimultaneousExponentiate(r, publicElement, e, 2); + if (!params.IsIdentity(r[0])) + throw DL_BadElement(); + return r[1]; + } + } + } +}; + +// ******************************************************** + +//! A template implementing constructors for public key algorithm classes +template +class CRYPTOPP_NO_VTABLE PK_FinalTemplate : public BASE +{ +public: + PK_FinalTemplate() {} + + PK_FinalTemplate(const CryptoMaterial &key) + {this->AccessKey().AssignFrom(key);} + + PK_FinalTemplate(BufferedTransformation &bt) + {this->AccessKey().BERDecode(bt);} + + PK_FinalTemplate(const AsymmetricAlgorithm &algorithm) + {this->AccessKey().AssignFrom(algorithm.GetMaterial());} + + PK_FinalTemplate(const Integer &v1) + {this->AccessKey().Initialize(v1);} + +#if (defined(_MSC_VER) && _MSC_VER < 1300) + + template + PK_FinalTemplate(T1 &v1, T2 &v2) + {this->AccessKey().Initialize(v1, v2);} + + template + PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3) + {this->AccessKey().Initialize(v1, v2, v3);} + + template + PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4) + {this->AccessKey().Initialize(v1, v2, v3, v4);} + + template + PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5) + {this->AccessKey().Initialize(v1, v2, v3, v4, v5);} + + template + PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5, T6 &v6) + {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);} + + template + PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5, T6 &v6, T7 &v7) + {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);} + + template + PK_FinalTemplate(T1 &v1, T2 &v2, T3 &v3, T4 &v4, T5 &v5, T6 &v6, T7 &v7, T8 &v8) + {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);} + +#else + + template + PK_FinalTemplate(const T1 &v1, const T2 &v2) + {this->AccessKey().Initialize(v1, v2);} + + template + PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3) + {this->AccessKey().Initialize(v1, v2, v3);} + + template + PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4) + {this->AccessKey().Initialize(v1, v2, v3, v4);} + + template + PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5) + {this->AccessKey().Initialize(v1, v2, v3, v4, v5);} + + template + PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6) + {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);} + + template + PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7) + {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);} + + template + PK_FinalTemplate(const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7, const T8 &v8) + {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);} + + template + PK_FinalTemplate(T1 &v1, const T2 &v2) + {this->AccessKey().Initialize(v1, v2);} + + template + PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3) + {this->AccessKey().Initialize(v1, v2, v3);} + + template + PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4) + {this->AccessKey().Initialize(v1, v2, v3, v4);} + + template + PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5) + {this->AccessKey().Initialize(v1, v2, v3, v4, v5);} + + template + PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6) + {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6);} + + template + PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7) + {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7);} + + template + PK_FinalTemplate(T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5, const T6 &v6, const T7 &v7, const T8 &v8) + {this->AccessKey().Initialize(v1, v2, v3, v4, v5, v6, v7, v8);} + +#endif +}; + +//! Base class for public key encryption standard classes. These classes are used to select from variants of algorithms. Note that not all standards apply to all algorithms. +struct EncryptionStandard {}; + +//! Base class for public key signature standard classes. These classes are used to select from variants of algorithms. Note that not all standards apply to all algorithms. +struct SignatureStandard {}; + +template +class TF_ES; + +//! Trapdoor Function Based Encryption Scheme +template > +class TF_ES : public KEYS +{ + typedef typename STANDARD::EncryptionMessageEncodingMethod MessageEncodingMethod; + +public: + //! see EncryptionStandard for a list of standards + typedef STANDARD Standard; + typedef TF_CryptoSchemeOptions SchemeOptions; + + static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string(KEYS::StaticAlgorithmName()) + "/" + MessageEncodingMethod::StaticAlgorithmName();} + + //! implements PK_Decryptor interface + typedef PK_FinalTemplate > Decryptor; + //! implements PK_Encryptor interface + typedef PK_FinalTemplate > Encryptor; +}; + +template // VC60 workaround: doesn't work if KEYS is first parameter +class TF_SS; + +//! Trapdoor Function Based Signature Scheme +template > // VC60 workaround: doesn't work if KEYS is first parameter +class TF_SS : public KEYS +{ +public: + //! see SignatureStandard for a list of standards + typedef STANDARD Standard; + typedef typename Standard::SignatureMessageEncodingMethod MessageEncodingMethod; + typedef TF_SignatureSchemeOptions SchemeOptions; + + static std::string CRYPTOPP_API StaticAlgorithmName() {return std::string(KEYS::StaticAlgorithmName()) + "/" + MessageEncodingMethod::StaticAlgorithmName() + "(" + H::StaticAlgorithmName() + ")";} + + //! implements PK_Signer interface + typedef PK_FinalTemplate > Signer; + //! implements PK_Verifier interface + typedef PK_FinalTemplate > Verifier; +}; + +template +class DL_SS; + +//! Discrete Log Based Signature Scheme +template > +class DL_SS : public KEYS +{ + typedef DL_SignatureSchemeOptions SchemeOptions; + +public: + static std::string StaticAlgorithmName() {return SA::StaticAlgorithmName() + std::string("/EMSA1(") + H::StaticAlgorithmName() + ")";} + + //! implements PK_Signer interface + typedef PK_FinalTemplate > Signer; + //! implements PK_Verifier interface + typedef PK_FinalTemplate > Verifier; +}; + +//! Discrete Log Based Encryption Scheme +template +class DL_ES : public KEYS +{ + typedef DL_CryptoSchemeOptions SchemeOptions; + +public: + //! implements PK_Decryptor interface + typedef PK_FinalTemplate > Decryptor; + //! implements PK_Encryptor interface + typedef PK_FinalTemplate > Encryptor; +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/pwdbased.h b/CryptoPP/crypto/pwdbased.h new file mode 100644 index 0000000..0751030 --- /dev/null +++ b/CryptoPP/crypto/pwdbased.h @@ -0,0 +1,213 @@ +// pwdbased.h - written and placed in the public domain by Wei Dai + +#ifndef CRYPTOPP_PWDBASED_H +#define CRYPTOPP_PWDBASED_H + +#include "cryptlib.h" +#include "hmac.h" +#include "hrtimer.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! abstract base class for password based key derivation function +class PasswordBasedKeyDerivationFunction +{ +public: + virtual size_t MaxDerivedKeyLength() const =0; + virtual bool UsesPurposeByte() const =0; + //! derive key from password + /*! If timeInSeconds != 0, will iterate until time elapsed, as measured by ThreadUserTimer + Returns actual iteration count, which is equal to iterations if timeInSeconds == 0, and not less than iterations otherwise. */ + virtual unsigned int DeriveKey(byte *derived, size_t derivedLen, byte purpose, const byte *password, size_t passwordLen, const byte *salt, size_t saltLen, unsigned int iterations, double timeInSeconds=0) const =0; +}; + +//! PBKDF1 from PKCS #5, T should be a HashTransformation class +template +class PKCS5_PBKDF1 : public PasswordBasedKeyDerivationFunction +{ +public: + size_t MaxDerivedKeyLength() const {return T::DIGESTSIZE;} + bool UsesPurposeByte() const {return false;} + // PKCS #5 says PBKDF1 should only take 8-byte salts. This implementation allows salts of any length. + unsigned int DeriveKey(byte *derived, size_t derivedLen, byte purpose, const byte *password, size_t passwordLen, const byte *salt, size_t saltLen, unsigned int iterations, double timeInSeconds=0) const; +}; + +//! PBKDF2 from PKCS #5, T should be a HashTransformation class +template +class PKCS5_PBKDF2_HMAC : public PasswordBasedKeyDerivationFunction +{ +public: + size_t MaxDerivedKeyLength() const {return 0xffffffffU;} // should multiply by T::DIGESTSIZE, but gets overflow that way + bool UsesPurposeByte() const {return false;} + unsigned int DeriveKey(byte *derived, size_t derivedLen, byte purpose, const byte *password, size_t passwordLen, const byte *salt, size_t saltLen, unsigned int iterations, double timeInSeconds=0) const; +}; + +/* +class PBKDF2Params +{ +public: + SecByteBlock m_salt; + unsigned int m_interationCount; + ASNOptional > m_keyLength; +}; +*/ + +template +unsigned int PKCS5_PBKDF1::DeriveKey(byte *derived, size_t derivedLen, byte purpose, const byte *password, size_t passwordLen, const byte *salt, size_t saltLen, unsigned int iterations, double timeInSeconds) const +{ + assert(derivedLen <= MaxDerivedKeyLength()); + assert(iterations > 0 || timeInSeconds > 0); + + if (!iterations) + iterations = 1; + + T hash; + hash.Update(password, passwordLen); + hash.Update(salt, saltLen); + + SecByteBlock buffer(hash.DigestSize()); + hash.Final(buffer); + + unsigned int i; + ThreadUserTimer timer; + + if (timeInSeconds) + timer.StartTimer(); + + for (i=1; i +unsigned int PKCS5_PBKDF2_HMAC::DeriveKey(byte *derived, size_t derivedLen, byte purpose, const byte *password, size_t passwordLen, const byte *salt, size_t saltLen, unsigned int iterations, double timeInSeconds) const +{ + assert(derivedLen <= MaxDerivedKeyLength()); + assert(iterations > 0 || timeInSeconds > 0); + + if (!iterations) + iterations = 1; + + HMAC hmac(password, passwordLen); + SecByteBlock buffer(hmac.DigestSize()); + ThreadUserTimer timer; + + unsigned int i=1; + while (derivedLen > 0) + { + hmac.Update(salt, saltLen); + unsigned int j; + for (j=0; j<4; j++) + { + byte b = byte(i >> ((3-j)*8)); + hmac.Update(&b, 1); + } + hmac.Final(buffer); + + size_t segmentLen = STDMIN(derivedLen, buffer.size()); + memcpy(derived, buffer, segmentLen); + + if (timeInSeconds) + { + timeInSeconds = timeInSeconds / ((derivedLen + buffer.size() - 1) / buffer.size()); + timer.StartTimer(); + } + + for (j=1; j +class PKCS12_PBKDF : public PasswordBasedKeyDerivationFunction +{ +public: + size_t MaxDerivedKeyLength() const {return size_t(0)-1;} + bool UsesPurposeByte() const {return true;} + unsigned int DeriveKey(byte *derived, size_t derivedLen, byte purpose, const byte *password, size_t passwordLen, const byte *salt, size_t saltLen, unsigned int iterations, double timeInSeconds) const; +}; + +template +unsigned int PKCS12_PBKDF::DeriveKey(byte *derived, size_t derivedLen, byte purpose, const byte *password, size_t passwordLen, const byte *salt, size_t saltLen, unsigned int iterations, double timeInSeconds) const +{ + assert(derivedLen <= MaxDerivedKeyLength()); + assert(iterations > 0 || timeInSeconds > 0); + + if (!iterations) + iterations = 1; + + const size_t v = T::BLOCKSIZE; // v is in bytes rather than bits as in PKCS #12 + const size_t DLen = v, SLen = RoundUpToMultipleOf(saltLen, v); + const size_t PLen = RoundUpToMultipleOf(passwordLen, v), ILen = SLen + PLen; + SecByteBlock buffer(DLen + SLen + PLen); + byte *D = buffer, *S = buffer+DLen, *P = buffer+DLen+SLen, *I = S; + + memset(D, purpose, DLen); + size_t i; + for (i=0; i 0) + { + hash.CalculateDigest(Ai, buffer, buffer.size()); + + if (timeInSeconds) + { + timeInSeconds = timeInSeconds / ((derivedLen + Ai.size() - 1) / Ai.size()); + timer.StartTimer(); + } + + for (i=1; inext; current; current=current->next) + { + m_tail->next = new ByteQueueNode(*current); + m_tail = m_tail->next; + } + + m_tail->next = NULL; + + Put(copy.m_lazyString, copy.m_lazyLength); +} + +ByteQueue::~ByteQueue() +{ + Destroy(); +} + +void ByteQueue::Destroy() +{ + for (ByteQueueNode *next, *current=m_head; current; current=next) + { + next=current->next; + delete current; + } +} + +void ByteQueue::IsolatedInitialize(const NameValuePairs ¶meters) +{ + m_nodeSize = parameters.GetIntValueWithDefault("NodeSize", 256); + Clear(); +} + +lword ByteQueue::CurrentSize() const +{ + lword size=0; + + for (ByteQueueNode *current=m_head; current; current=current->next) + size += current->CurrentSize(); + + return size + m_lazyLength; +} + +bool ByteQueue::IsEmpty() const +{ + return m_head==m_tail && m_head->CurrentSize()==0 && m_lazyLength==0; +} + +void ByteQueue::Clear() +{ + for (ByteQueueNode *next, *current=m_head->next; current; current=next) + { + next=current->next; + delete current; + } + + m_tail = m_head; + m_head->Clear(); + m_head->next = NULL; + m_lazyLength = 0; +} + +size_t ByteQueue::Put2(const byte *inString, size_t length, int messageEnd, bool blocking) +{ + if (m_lazyLength > 0) + FinalizeLazyPut(); + + size_t len; + while ((len=m_tail->Put(inString, length)) < length) + { + inString += len; + length -= len; + if (m_autoNodeSize && m_nodeSize < s_maxAutoNodeSize) + do + { + m_nodeSize *= 2; + } + while (m_nodeSize < length && m_nodeSize < s_maxAutoNodeSize); + m_tail->next = new ByteQueueNode(STDMAX(m_nodeSize, length)); + m_tail = m_tail->next; + } + + return 0; +} + +void ByteQueue::CleanupUsedNodes() +{ + while (m_head != m_tail && m_head->UsedUp()) + { + ByteQueueNode *temp=m_head; + m_head=m_head->next; + delete temp; + } + + if (m_head->CurrentSize() == 0) + m_head->Clear(); +} + +void ByteQueue::LazyPut(const byte *inString, size_t size) +{ + if (m_lazyLength > 0) + FinalizeLazyPut(); + + if (inString == m_tail->buf+m_tail->m_tail) + Put(inString, size); + else + { + m_lazyString = const_cast(inString); + m_lazyLength = size; + m_lazyStringModifiable = false; + } +} + +void ByteQueue::LazyPutModifiable(byte *inString, size_t size) +{ + if (m_lazyLength > 0) + FinalizeLazyPut(); + m_lazyString = inString; + m_lazyLength = size; + m_lazyStringModifiable = true; +} + +void ByteQueue::UndoLazyPut(size_t size) +{ + if (m_lazyLength < size) + throw InvalidArgument("ByteQueue: size specified for UndoLazyPut is too large"); + + m_lazyLength -= size; +} + +void ByteQueue::FinalizeLazyPut() +{ + size_t len = m_lazyLength; + m_lazyLength = 0; + if (len) + Put(m_lazyString, len); +} + +size_t ByteQueue::Get(byte &outByte) +{ + if (m_head->Get(outByte)) + { + if (m_head->UsedUp()) + CleanupUsedNodes(); + return 1; + } + else if (m_lazyLength > 0) + { + outByte = *m_lazyString++; + m_lazyLength--; + return 1; + } + else + return 0; +} + +size_t ByteQueue::Get(byte *outString, size_t getMax) +{ + ArraySink sink(outString, getMax); + return (size_t)TransferTo(sink, getMax); +} + +size_t ByteQueue::Peek(byte &outByte) const +{ + if (m_head->Peek(outByte)) + return 1; + else if (m_lazyLength > 0) + { + outByte = *m_lazyString; + return 1; + } + else + return 0; +} + +size_t ByteQueue::Peek(byte *outString, size_t peekMax) const +{ + ArraySink sink(outString, peekMax); + return (size_t)CopyTo(sink, peekMax); +} + +size_t ByteQueue::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking) +{ + if (blocking) + { + lword bytesLeft = transferBytes; + for (ByteQueueNode *current=m_head; bytesLeft && current; current=current->next) + bytesLeft -= current->TransferTo(target, bytesLeft, channel); + CleanupUsedNodes(); + + size_t len = (size_t)STDMIN(bytesLeft, (lword)m_lazyLength); + if (len) + { + if (m_lazyStringModifiable) + target.ChannelPutModifiable(channel, m_lazyString, len); + else + target.ChannelPut(channel, m_lazyString, len); + m_lazyString += len; + m_lazyLength -= len; + bytesLeft -= len; + } + transferBytes -= bytesLeft; + return 0; + } + else + { + Walker walker(*this); + size_t blockedBytes = walker.TransferTo2(target, transferBytes, channel, blocking); + Skip(transferBytes); + return blockedBytes; + } +} + +size_t ByteQueue::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end, const std::string &channel, bool blocking) const +{ + Walker walker(*this); + walker.Skip(begin); + lword transferBytes = end-begin; + size_t blockedBytes = walker.TransferTo2(target, transferBytes, channel, blocking); + begin += transferBytes; + return blockedBytes; +} + +void ByteQueue::Unget(byte inByte) +{ + Unget(&inByte, 1); +} + +void ByteQueue::Unget(const byte *inString, size_t length) +{ + size_t len = STDMIN(length, m_head->m_head); + length -= len; + m_head->m_head -= len; + memcpy(m_head->buf + m_head->m_head, inString + length, len); + + if (length > 0) + { + ByteQueueNode *newHead = new ByteQueueNode(length); + newHead->next = m_head; + m_head = newHead; + m_head->Put(inString, length); + } +} + +const byte * ByteQueue::Spy(size_t &contiguousSize) const +{ + contiguousSize = m_head->m_tail - m_head->m_head; + if (contiguousSize == 0 && m_lazyLength > 0) + { + contiguousSize = m_lazyLength; + return m_lazyString; + } + else + return m_head->buf + m_head->m_head; +} + +byte * ByteQueue::CreatePutSpace(size_t &size) +{ + if (m_lazyLength > 0) + FinalizeLazyPut(); + + if (m_tail->m_tail == m_tail->MaxSize()) + { + m_tail->next = new ByteQueueNode(STDMAX(m_nodeSize, size)); + m_tail = m_tail->next; + } + + size = m_tail->MaxSize() - m_tail->m_tail; + return m_tail->buf + m_tail->m_tail; +} + +ByteQueue & ByteQueue::operator=(const ByteQueue &rhs) +{ + Destroy(); + CopyFrom(rhs); + return *this; +} + +bool ByteQueue::operator==(const ByteQueue &rhs) const +{ + const lword currentSize = CurrentSize(); + + if (currentSize != rhs.CurrentSize()) + return false; + + Walker walker1(*this), walker2(rhs); + byte b1, b2; + + while (walker1.Get(b1) && walker2.Get(b2)) + if (b1 != b2) + return false; + + return true; +} + +byte ByteQueue::operator[](lword i) const +{ + for (ByteQueueNode *current=m_head; current; current=current->next) + { + if (i < current->CurrentSize()) + return (*current)[(size_t)i]; + + i -= current->CurrentSize(); + } + + assert(i < m_lazyLength); + return m_lazyString[i]; +} + +void ByteQueue::swap(ByteQueue &rhs) +{ + std::swap(m_autoNodeSize, rhs.m_autoNodeSize); + std::swap(m_nodeSize, rhs.m_nodeSize); + std::swap(m_head, rhs.m_head); + std::swap(m_tail, rhs.m_tail); + std::swap(m_lazyString, rhs.m_lazyString); + std::swap(m_lazyLength, rhs.m_lazyLength); + std::swap(m_lazyStringModifiable, rhs.m_lazyStringModifiable); +} + +// ******************************************************** + +void ByteQueue::Walker::IsolatedInitialize(const NameValuePairs ¶meters) +{ + m_node = m_queue.m_head; + m_position = 0; + m_offset = 0; + m_lazyString = m_queue.m_lazyString; + m_lazyLength = m_queue.m_lazyLength; +} + +size_t ByteQueue::Walker::Get(byte &outByte) +{ + ArraySink sink(&outByte, 1); + return (size_t)TransferTo(sink, 1); +} + +size_t ByteQueue::Walker::Get(byte *outString, size_t getMax) +{ + ArraySink sink(outString, getMax); + return (size_t)TransferTo(sink, getMax); +} + +size_t ByteQueue::Walker::Peek(byte &outByte) const +{ + ArraySink sink(&outByte, 1); + return (size_t)CopyTo(sink, 1); +} + +size_t ByteQueue::Walker::Peek(byte *outString, size_t peekMax) const +{ + ArraySink sink(outString, peekMax); + return (size_t)CopyTo(sink, peekMax); +} + +size_t ByteQueue::Walker::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking) +{ + lword bytesLeft = transferBytes; + size_t blockedBytes = 0; + + while (m_node) + { + size_t len = (size_t)STDMIN(bytesLeft, (lword)m_node->CurrentSize()-m_offset); + blockedBytes = target.ChannelPut2(channel, m_node->buf+m_node->m_head+m_offset, len, 0, blocking); + + if (blockedBytes) + goto done; + + m_position += len; + bytesLeft -= len; + + if (!bytesLeft) + { + m_offset += len; + goto done; + } + + m_node = m_node->next; + m_offset = 0; + } + + if (bytesLeft && m_lazyLength) + { + size_t len = (size_t)STDMIN(bytesLeft, (lword)m_lazyLength); + blockedBytes = target.ChannelPut2(channel, m_lazyString, len, 0, blocking); + if (blockedBytes) + goto done; + + m_lazyString += len; + m_lazyLength -= len; + bytesLeft -= len; + } + +done: + transferBytes -= bytesLeft; + return blockedBytes; +} + +size_t ByteQueue::Walker::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end, const std::string &channel, bool blocking) const +{ + Walker walker(*this); + walker.Skip(begin); + lword transferBytes = end-begin; + size_t blockedBytes = walker.TransferTo2(target, transferBytes, channel, blocking); + begin += transferBytes; + return blockedBytes; +} + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/queue.h b/CryptoPP/crypto/queue.h new file mode 100644 index 0000000..a7c4f4c --- /dev/null +++ b/CryptoPP/crypto/queue.h @@ -0,0 +1,141 @@ +// specification file for an unlimited queue for storing bytes + +#ifndef CRYPTOPP_QUEUE_H +#define CRYPTOPP_QUEUE_H + +#include "simple.h" +//#include + +NAMESPACE_BEGIN(CryptoPP) + +/** The queue is implemented as a linked list of byte arrays, but you don't need to + know about that. So just ignore this next line. :) */ +class ByteQueueNode; + +//! Byte Queue +class CRYPTOPP_DLL ByteQueue : public Bufferless +{ +public: + ByteQueue(size_t nodeSize=0); + ByteQueue(const ByteQueue ©); + ~ByteQueue(); + + lword MaxRetrievable() const + {return CurrentSize();} + bool AnyRetrievable() const + {return !IsEmpty();} + + void IsolatedInitialize(const NameValuePairs ¶meters); + byte * CreatePutSpace(size_t &size); + size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking); + + size_t Get(byte &outByte); + size_t Get(byte *outString, size_t getMax); + + size_t Peek(byte &outByte) const; + size_t Peek(byte *outString, size_t peekMax) const; + + size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=NULL_CHANNEL, bool blocking=true); + size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=NULL_CHANNEL, bool blocking=true) const; + + // these member functions are not inherited + void SetNodeSize(size_t nodeSize); + + lword CurrentSize() const; + bool IsEmpty() const; + + void Clear(); + + void Unget(byte inByte); + void Unget(const byte *inString, size_t length); + + const byte * Spy(size_t &contiguousSize) const; + + void LazyPut(const byte *inString, size_t size); + void LazyPutModifiable(byte *inString, size_t size); + void UndoLazyPut(size_t size); + void FinalizeLazyPut(); + + ByteQueue & operator=(const ByteQueue &rhs); + bool operator==(const ByteQueue &rhs) const; + byte operator[](lword i) const; + void swap(ByteQueue &rhs); + + class Walker : public InputRejecting + { + public: + Walker(const ByteQueue &queue) + : m_queue(queue) {Initialize();} + + lword GetCurrentPosition() {return m_position;} + + lword MaxRetrievable() const + {return m_queue.CurrentSize() - m_position;} + + void IsolatedInitialize(const NameValuePairs ¶meters); + + size_t Get(byte &outByte); + size_t Get(byte *outString, size_t getMax); + + size_t Peek(byte &outByte) const; + size_t Peek(byte *outString, size_t peekMax) const; + + size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=NULL_CHANNEL, bool blocking=true); + size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=NULL_CHANNEL, bool blocking=true) const; + + private: + const ByteQueue &m_queue; + const ByteQueueNode *m_node; + lword m_position; + size_t m_offset; + const byte *m_lazyString; + size_t m_lazyLength; + }; + + friend class Walker; + +private: + void CleanupUsedNodes(); + void CopyFrom(const ByteQueue ©); + void Destroy(); + + bool m_autoNodeSize; + size_t m_nodeSize; + ByteQueueNode *m_head, *m_tail; + byte *m_lazyString; + size_t m_lazyLength; + bool m_lazyStringModifiable; +}; + +//! use this to make sure LazyPut is finalized in event of exception +class CRYPTOPP_DLL LazyPutter +{ +public: + LazyPutter(ByteQueue &bq, const byte *inString, size_t size) + : m_bq(bq) {bq.LazyPut(inString, size);} + ~LazyPutter() + {try {m_bq.FinalizeLazyPut();} catch(...) {}} +protected: + LazyPutter(ByteQueue &bq) : m_bq(bq) {} +private: + ByteQueue &m_bq; +}; + +//! like LazyPutter, but does a LazyPutModifiable instead +class LazyPutterModifiable : public LazyPutter +{ +public: + LazyPutterModifiable(ByteQueue &bq, byte *inString, size_t size) + : LazyPutter(bq) {bq.LazyPutModifiable(inString, size);} +}; + +NAMESPACE_END + +NAMESPACE_BEGIN(std) +template<> inline void swap(CryptoPP::ByteQueue &a, CryptoPP::ByteQueue &b) +{ + a.swap(b); +} +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/rabi1024.dat b/CryptoPP/crypto/rabi1024.dat new file mode 100644 index 0000000..ef84137 --- /dev/null +++ b/CryptoPP/crypto/rabi1024.dat @@ -0,0 +1 @@ +3082015202818100D132EDB1360E31D7B8DD84BB03111FDE0243FFE4031ED12B440E7FF36A634E57772EC81FFDC065607494717C6E16A5AB642283553442CC22569535C7A20E3D1C3E2B3747B26E9856D4A13D0325DC116DAAF8554B000321A753E5CFA730CA60F3E3FE2CA9750C6734A2A113AD4A76B6DAC5E199AB55F34CE6984BF56F6DFAC51D020105020102024100F90CBF726FA70ACB5074BD8E79932B74E9949057B627ABB29F41E5057AE699A03BC240EBB9637E956ABC0B6A20F633F78168A908086E2011FC5D030B9B94B51B024100D7097ACACD8BF8ED641A7D8A17A23F8FB385B92B760EEEB9A1233E1D25892F742315DE23DA0751F24EAE4C0C5B696D0AA0D16EAE94194193DC89D479A9626A2702403B5475CD2A7F519EF08433407826D89983C104AF1E74B44B79B31770149D224089300F828E0DF4CBC864BDB394C0F32CCF055F7B2B8872BF0B5F148020637B9C \ No newline at end of file diff --git a/CryptoPP/crypto/rabi2048.dat b/CryptoPP/crypto/rabi2048.dat new file mode 100644 index 0000000..cb638ef --- /dev/null +++ b/CryptoPP/crypto/rabi2048.dat @@ -0,0 +1 @@ +308202970282010100B8F2A74040753A7706CB98B80DD9EE33FB7969FCA65A2025E96853267AEF80ABB184FE463B9475F5166307FAFA988F6CA4BBC7122E9555755191AA408BAF4464221394342104ED2762EEA4FED8B5CDB4234442AB979A487446AB37C4A4FD67C259EB942E28B50DD54F3AA14447931821291D4C21BB8BD58C41302F3E1D2E6FF84F84AACEC02196282C492E0354985A66EBA50B1903EDF70D98BD9837E694876505760C58C186F0B5F6500711500297956C9825EBDCCF90633239484F9A3572271D3CD585BFC195BED0D5FFCABE785B25BFF6ACFF2B7C125D54B26CFEF60B1B077B2F953960DAEB57F102B6A1E30AA88B643090BC4D8971077C1B54EA61E4E45102011302010D02818100D02603BBFDB55F1063DFCEBB4CA32F551330E0F2901D87DF2A395EF6AF340F6352CE3514FCE85705652DC6BD401CD0D5D13855B124DA172D5183A7474B85B683AA03382775F3D8DC600F33E696246F9F2134E2DA061923F47B85A923EBB375B07DE3B43EE4FD71D3E24B4B416DAE6E4C2B6D32A9B45BF04296AECAD60C33DA0702818100E3773B5D8B828BEA922392100C54CDF41D0CD26B4C34A64F483B7975AB35920DA0E3F6AE238E72E26F8A498D9AD0C4A75C52F25421E1E2E3865ADD1A0FCEA4DE932DBE6EBEFA689494855B11714B960F57C5102C0E8876D253ABA8C2D6A511DBC0F30589A0FBE66AD6BCEFDFC4F67F8347726A52736274B7F744ECACFF6198E702818100BF84B25DB607930F80ED57C7AF89E7604B7E8E0D341C9C4A0C94FFE6D4B38810553B1E92F7BF9651D3D0149A9188E1FFD1FB86753A327ABC6169AF92271E7204A2C76488FBC781984BA99C3C48C8A799054DA34A201743C3064B4609831B35FBA2B8B1BC67FFD0C685DBA92FE688AD51D1F161C06EC0B9E0D0E187863BFBBEC0 \ No newline at end of file diff --git a/CryptoPP/crypto/rabin.cpp b/CryptoPP/crypto/rabin.cpp new file mode 100644 index 0000000..51d6c8c --- /dev/null +++ b/CryptoPP/crypto/rabin.cpp @@ -0,0 +1,221 @@ +// rabin.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "rabin.h" +#include "nbtheory.h" +#include "asn.h" +#include "sha.h" +#include "modarith.h" + +NAMESPACE_BEGIN(CryptoPP) + +void RabinFunction::BERDecode(BufferedTransformation &bt) +{ + BERSequenceDecoder seq(bt); + m_n.BERDecode(seq); + m_r.BERDecode(seq); + m_s.BERDecode(seq); + seq.MessageEnd(); +} + +void RabinFunction::DEREncode(BufferedTransformation &bt) const +{ + DERSequenceEncoder seq(bt); + m_n.DEREncode(seq); + m_r.DEREncode(seq); + m_s.DEREncode(seq); + seq.MessageEnd(); +} + +Integer RabinFunction::ApplyFunction(const Integer &in) const +{ + DoQuickSanityCheck(); + + Integer out = in.Squared()%m_n; + if (in.IsOdd()) + out = out*m_r%m_n; + if (Jacobi(in, m_n)==-1) + out = out*m_s%m_n; + return out; +} + +bool RabinFunction::Validate(RandomNumberGenerator &rng, unsigned int level) const +{ + bool pass = true; + pass = pass && m_n > Integer::One() && m_n%4 == 1; + pass = pass && m_r > Integer::One() && m_r < m_n; + pass = pass && m_s > Integer::One() && m_s < m_n; + if (level >= 1) + pass = pass && Jacobi(m_r, m_n) == -1 && Jacobi(m_s, m_n) == -1; + return pass; +} + +bool RabinFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const +{ + return GetValueHelper(this, name, valueType, pValue).Assignable() + CRYPTOPP_GET_FUNCTION_ENTRY(Modulus) + CRYPTOPP_GET_FUNCTION_ENTRY(QuadraticResidueModPrime1) + CRYPTOPP_GET_FUNCTION_ENTRY(QuadraticResidueModPrime2) + ; +} + +void RabinFunction::AssignFrom(const NameValuePairs &source) +{ + AssignFromHelper(this, source) + CRYPTOPP_SET_FUNCTION_ENTRY(Modulus) + CRYPTOPP_SET_FUNCTION_ENTRY(QuadraticResidueModPrime1) + CRYPTOPP_SET_FUNCTION_ENTRY(QuadraticResidueModPrime2) + ; +} + +// ***************************************************************************** +// private key operations: + +// generate a random private key +void InvertibleRabinFunction::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg) +{ + int modulusSize = 2048; + alg.GetIntValue("ModulusSize", modulusSize) || alg.GetIntValue("KeySize", modulusSize); + + if (modulusSize < 16) + throw InvalidArgument("InvertibleRabinFunction: specified modulus size is too small"); + + // VC70 workaround: putting these after primeParam causes overlapped stack allocation + bool rFound=false, sFound=false; + Integer t=2; + + const NameValuePairs &primeParam = MakeParametersForTwoPrimesOfEqualSize(modulusSize) + ("EquivalentTo", 3)("Mod", 4); + m_p.GenerateRandom(rng, primeParam); + m_q.GenerateRandom(rng, primeParam); + + while (!(rFound && sFound)) + { + int jp = Jacobi(t, m_p); + int jq = Jacobi(t, m_q); + + if (!rFound && jp==1 && jq==-1) + { + m_r = t; + rFound = true; + } + + if (!sFound && jp==-1 && jq==1) + { + m_s = t; + sFound = true; + } + + ++t; + } + + m_n = m_p * m_q; + m_u = m_q.InverseMod(m_p); +} + +void InvertibleRabinFunction::BERDecode(BufferedTransformation &bt) +{ + BERSequenceDecoder seq(bt); + m_n.BERDecode(seq); + m_r.BERDecode(seq); + m_s.BERDecode(seq); + m_p.BERDecode(seq); + m_q.BERDecode(seq); + m_u.BERDecode(seq); + seq.MessageEnd(); +} + +void InvertibleRabinFunction::DEREncode(BufferedTransformation &bt) const +{ + DERSequenceEncoder seq(bt); + m_n.DEREncode(seq); + m_r.DEREncode(seq); + m_s.DEREncode(seq); + m_p.DEREncode(seq); + m_q.DEREncode(seq); + m_u.DEREncode(seq); + seq.MessageEnd(); +} + +Integer InvertibleRabinFunction::CalculateInverse(RandomNumberGenerator &rng, const Integer &in) const +{ + DoQuickSanityCheck(); + + ModularArithmetic modn(m_n); + Integer r(rng, Integer::One(), m_n - Integer::One()); + r = modn.Square(r); + Integer r2 = modn.Square(r); + Integer c = modn.Multiply(in, r2); // blind + + Integer cp=c%m_p, cq=c%m_q; + + int jp = Jacobi(cp, m_p); + int jq = Jacobi(cq, m_q); + + if (jq==-1) + { + cp = cp*EuclideanMultiplicativeInverse(m_r, m_p)%m_p; + cq = cq*EuclideanMultiplicativeInverse(m_r, m_q)%m_q; + } + + if (jp==-1) + { + cp = cp*EuclideanMultiplicativeInverse(m_s, m_p)%m_p; + cq = cq*EuclideanMultiplicativeInverse(m_s, m_q)%m_q; + } + + cp = ModularSquareRoot(cp, m_p); + cq = ModularSquareRoot(cq, m_q); + + if (jp==-1) + cp = m_p-cp; + + Integer out = CRT(cq, m_q, cp, m_p, m_u); + + out = modn.Divide(out, r); // unblind + + if ((jq==-1 && out.IsEven()) || (jq==1 && out.IsOdd())) + out = m_n-out; + + return out; +} + +bool InvertibleRabinFunction::Validate(RandomNumberGenerator &rng, unsigned int level) const +{ + bool pass = RabinFunction::Validate(rng, level); + pass = pass && m_p > Integer::One() && m_p%4 == 3 && m_p < m_n; + pass = pass && m_q > Integer::One() && m_q%4 == 3 && m_q < m_n; + pass = pass && m_u.IsPositive() && m_u < m_p; + if (level >= 1) + { + pass = pass && m_p * m_q == m_n; + pass = pass && m_u * m_q % m_p == 1; + pass = pass && Jacobi(m_r, m_p) == 1; + pass = pass && Jacobi(m_r, m_q) == -1; + pass = pass && Jacobi(m_s, m_p) == -1; + pass = pass && Jacobi(m_s, m_q) == 1; + } + if (level >= 2) + pass = pass && VerifyPrime(rng, m_p, level-2) && VerifyPrime(rng, m_q, level-2); + return pass; +} + +bool InvertibleRabinFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const +{ + return GetValueHelper(this, name, valueType, pValue).Assignable() + CRYPTOPP_GET_FUNCTION_ENTRY(Prime1) + CRYPTOPP_GET_FUNCTION_ENTRY(Prime2) + CRYPTOPP_GET_FUNCTION_ENTRY(MultiplicativeInverseOfPrime2ModPrime1) + ; +} + +void InvertibleRabinFunction::AssignFrom(const NameValuePairs &source) +{ + AssignFromHelper(this, source) + CRYPTOPP_SET_FUNCTION_ENTRY(Prime1) + CRYPTOPP_SET_FUNCTION_ENTRY(Prime2) + CRYPTOPP_SET_FUNCTION_ENTRY(MultiplicativeInverseOfPrime2ModPrime1) + ; +} + +NAMESPACE_END diff --git a/CryptoPP/crypto/rabin.h b/CryptoPP/crypto/rabin.h new file mode 100644 index 0000000..60deabb --- /dev/null +++ b/CryptoPP/crypto/rabin.h @@ -0,0 +1,107 @@ +#ifndef CRYPTOPP_RABIN_H +#define CRYPTOPP_RABIN_H + +/** \file +*/ + +#include "oaep.h" +#include "pssr.h" +#include "integer.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! _ +class RabinFunction : public TrapdoorFunction, public PublicKey +{ + typedef RabinFunction ThisClass; + +public: + void Initialize(const Integer &n, const Integer &r, const Integer &s) + {m_n = n; m_r = r; m_s = s;} + + void BERDecode(BufferedTransformation &bt); + void DEREncode(BufferedTransformation &bt) const; + + Integer ApplyFunction(const Integer &x) const; + Integer PreimageBound() const {return m_n;} + Integer ImageBound() const {return m_n;} + + bool Validate(RandomNumberGenerator &rng, unsigned int level) const; + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; + void AssignFrom(const NameValuePairs &source); + + const Integer& GetModulus() const {return m_n;} + const Integer& GetQuadraticResidueModPrime1() const {return m_r;} + const Integer& GetQuadraticResidueModPrime2() const {return m_s;} + + void SetModulus(const Integer &n) {m_n = n;} + void SetQuadraticResidueModPrime1(const Integer &r) {m_r = r;} + void SetQuadraticResidueModPrime2(const Integer &s) {m_s = s;} + +protected: + Integer m_n, m_r, m_s; +}; + +//! _ +class InvertibleRabinFunction : public RabinFunction, public TrapdoorFunctionInverse, public PrivateKey +{ + typedef InvertibleRabinFunction ThisClass; + +public: + void Initialize(const Integer &n, const Integer &r, const Integer &s, + const Integer &p, const Integer &q, const Integer &u) + {m_n = n; m_r = r; m_s = s; m_p = p; m_q = q; m_u = u;} + void Initialize(RandomNumberGenerator &rng, unsigned int keybits) + {GenerateRandomWithKeySize(rng, keybits);} + + void BERDecode(BufferedTransformation &bt); + void DEREncode(BufferedTransformation &bt) const; + + Integer CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const; + + bool Validate(RandomNumberGenerator &rng, unsigned int level) const; + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; + void AssignFrom(const NameValuePairs &source); + /*! parameters: (ModulusSize) */ + void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg); + + const Integer& GetPrime1() const {return m_p;} + const Integer& GetPrime2() const {return m_q;} + const Integer& GetMultiplicativeInverseOfPrime2ModPrime1() const {return m_u;} + + void SetPrime1(const Integer &p) {m_p = p;} + void SetPrime2(const Integer &q) {m_q = q;} + void SetMultiplicativeInverseOfPrime2ModPrime1(const Integer &u) {m_u = u;} + +protected: + Integer m_p, m_q, m_u; +}; + +//! Rabin +struct Rabin +{ + static std::string StaticAlgorithmName() {return "Rabin-Crypto++Variant";} + typedef RabinFunction PublicKey; + typedef InvertibleRabinFunction PrivateKey; +}; + +//! Rabin encryption +template +struct RabinES : public TF_ES +{ +}; + +//! Rabin signature +template +struct RabinSS : public TF_SS +{ +}; + +// More typedefs for backwards compatibility +class SHA1; +typedef RabinES >::Decryptor RabinDecryptor; +typedef RabinES >::Encryptor RabinEncryptor; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/randpool.cpp b/CryptoPP/crypto/randpool.cpp new file mode 100644 index 0000000..2a38f5d --- /dev/null +++ b/CryptoPP/crypto/randpool.cpp @@ -0,0 +1,61 @@ +// randpool.cpp - written and placed in the public domain by Wei Dai +// RandomPool used to follow the design of randpool in PGP 2.6.x, +// but as of version 5.5 it has been redesigned to reduce the risk +// of reusing random numbers after state rollback (which may occur +// when running in a virtual machine like VMware). + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "randpool.h" +#include "aes.h" +#include "sha.h" +#include "hrtimer.h" +#include + +NAMESPACE_BEGIN(CryptoPP) + +RandomPool::RandomPool() + : m_pCipher(new AES::Encryption), m_keySet(false) +{ +} + +void RandomPool::IncorporateEntropy(const byte *input, size_t length) +{ + SHA256 hash; + hash.Update(m_key, 32); + hash.Update(input, length); + hash.Final(m_key); + m_keySet = false; +} + +void RandomPool::GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword size) +{ + if (size > 0) + { + if (!m_keySet) + m_pCipher->SetKey(m_key, 32); + + Timer timer; + TimerWord tw = timer.GetCurrentTimerValue(); + CRYPTOPP_COMPILE_ASSERT(sizeof(tw) <= 16); + *(TimerWord *)m_seed.data() += tw; + + time_t t = time(NULL); + CRYPTOPP_COMPILE_ASSERT(sizeof(t) <= 8); + *(time_t *)(m_seed.data()+8) += t; + + do + { + m_pCipher->ProcessBlock(m_seed); + size_t len = UnsignedMin(16, size); + target.ChannelPut(channel, m_seed, len); + size -= len; + } while (size > 0); + } +} + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/randpool.h b/CryptoPP/crypto/randpool.h new file mode 100644 index 0000000..4c444be --- /dev/null +++ b/CryptoPP/crypto/randpool.h @@ -0,0 +1,33 @@ +#ifndef CRYPTOPP_RANDPOOL_H +#define CRYPTOPP_RANDPOOL_H + +#include "cryptlib.h" +#include "filters.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! Randomness Pool +/*! This class can be used to generate cryptographic quality + pseudorandom bytes after seeding the pool with IncorporateEntropy() */ +class CRYPTOPP_DLL RandomPool : public RandomNumberGenerator, public NotCopyable +{ +public: + RandomPool(); + + bool CanIncorporateEntropy() const {return true;} + void IncorporateEntropy(const byte *input, size_t length); + void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword size); + + // for backwards compatibility. use RandomNumberSource, RandomNumberStore, and RandomNumberSink for other BufferTransformation functionality + void Put(const byte *input, size_t length) {IncorporateEntropy(input, length);} + +private: + FixedSizeSecBlock m_key; + FixedSizeSecBlock m_seed; + member_ptr m_pCipher; + bool m_keySet; +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/rc2.cpp b/CryptoPP/crypto/rc2.cpp new file mode 100644 index 0000000..2cc8cf1 --- /dev/null +++ b/CryptoPP/crypto/rc2.cpp @@ -0,0 +1,118 @@ +// rc2.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "rc2.h" +#include "misc.h" +#include "argnames.h" + +NAMESPACE_BEGIN(CryptoPP) + +void RC2::Base::UncheckedSetKey(const byte *key, unsigned int keyLen, const NameValuePairs ¶ms) +{ + AssertValidKeyLength(keyLen); + + int effectiveLen = params.GetIntValueWithDefault(Name::EffectiveKeyLength(), DEFAULT_EFFECTIVE_KEYLENGTH); + if (effectiveLen > MAX_EFFECTIVE_KEYLENGTH) + throw InvalidArgument("RC2: effective key length parameter exceeds maximum"); + + static const unsigned char PITABLE[256] = { + 217,120,249,196, 25,221,181,237, 40,233,253,121, 74,160,216,157, + 198,126, 55,131, 43,118, 83,142, 98, 76,100,136, 68,139,251,162, + 23,154, 89,245,135,179, 79, 19, 97, 69,109,141, 9,129,125, 50, + 189,143, 64,235,134,183,123, 11,240,149, 33, 34, 92,107, 78,130, + 84,214,101,147,206, 96,178, 28,115, 86,192, 20,167,140,241,220, + 18,117,202, 31, 59,190,228,209, 66, 61,212, 48,163, 60,182, 38, + 111,191, 14,218, 70,105, 7, 87, 39,242, 29,155,188,148, 67, 3, + 248, 17,199,246,144,239, 62,231, 6,195,213, 47,200,102, 30,215, + 8,232,234,222,128, 82,238,247,132,170,114,172, 53, 77,106, 42, + 150, 26,210,113, 90, 21, 73,116, 75,159,208, 94, 4, 24,164,236, + 194,224, 65,110, 15, 81,203,204, 36,145,175, 80,161,244,112, 57, + 153,124, 58,133, 35,184,180,122,252, 2, 54, 91, 37, 85,151, 49, + 45, 93,250,152,227,138,146,174, 5,223, 41, 16,103,108,186,201, + 211, 0,230,207,225,158,168, 44, 99, 22, 1, 63, 88,226,137,169, + 13, 56, 52, 27,171, 51,255,176,187, 72, 12, 95,185,177,205, 46, + 197,243,219, 71,229,165,156,119, 10,166, 32,104,254,127,193,173}; + + SecByteBlock L(128); + memcpy(L, key, keyLen); + + int i; + for (i=keyLen; i<128; i++) + L[i] = PITABLE[(L[i-1] + L[i-keyLen]) & 255]; + + unsigned int T8 = (effectiveLen+7) / 8; + byte TM = 255 >> ((8-(effectiveLen%8))%8); + L[128-T8] = PITABLE[L[128-T8] & TM]; + + for (i=127-T8; i>=0; i--) + L[i] = PITABLE[L[i+1] ^ L[i+T8]]; + + for (i=0; i<64; i++) + K[i] = L[2*i] + (L[2*i+1] << 8); +} + +typedef BlockGetAndPut Block; + +void RC2::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word16 R0, R1, R2, R3; + Block::Get(inBlock)(R0)(R1)(R2)(R3); + + for (int i = 0; i < 16; i++) + { + R0 += (R1 & ~R3) + (R2 & R3) + K[4*i+0]; + R0 = rotlFixed(R0, 1); + + R1 += (R2 & ~R0) + (R3 & R0) + K[4*i+1]; + R1 = rotlFixed(R1, 2); + + R2 += (R3 & ~R1) + (R0 & R1) + K[4*i+2]; + R2 = rotlFixed(R2, 3); + + R3 += (R0 & ~R2) + (R1 & R2) + K[4*i+3]; + R3 = rotlFixed(R3, 5); + + if (i == 4 || i == 10) + { + R0 += K[R3 & 63]; + R1 += K[R0 & 63]; + R2 += K[R1 & 63]; + R3 += K[R2 & 63]; + } + } + + Block::Put(xorBlock, outBlock)(R0)(R1)(R2)(R3); +} + +void RC2::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word16 R0, R1, R2, R3; + Block::Get(inBlock)(R0)(R1)(R2)(R3); + + for (int i = 15; i >= 0; i--) + { + if (i == 4 || i == 10) + { + R3 -= K[R2 & 63]; + R2 -= K[R1 & 63]; + R1 -= K[R0 & 63]; + R0 -= K[R3 & 63]; + } + + R3 = rotrFixed(R3, 5); + R3 -= (R0 & ~R2) + (R1 & R2) + K[4*i+3]; + + R2 = rotrFixed(R2, 3); + R2 -= (R3 & ~R1) + (R0 & R1) + K[4*i+2]; + + R1 = rotrFixed(R1, 2); + R1 -= (R2 & ~R0) + (R3 & R0) + K[4*i+1]; + + R0 = rotrFixed(R0, 1); + R0 -= (R1 & ~R3) + (R2 & R3) + K[4*i+0]; + } + + Block::Put(xorBlock, outBlock)(R0)(R1)(R2)(R3); +} + +NAMESPACE_END diff --git a/CryptoPP/crypto/rc2.h b/CryptoPP/crypto/rc2.h new file mode 100644 index 0000000..25c10f3 --- /dev/null +++ b/CryptoPP/crypto/rc2.h @@ -0,0 +1,72 @@ +#ifndef CRYPTOPP_RC2_H +#define CRYPTOPP_RC2_H + +/** \file +*/ + +#include "seckey.h" +#include "secblock.h" +#include "algparam.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! _ +struct RC2_Info : public FixedBlockSize<8>, public VariableKeyLength<16, 1, 128> +{ + CRYPTOPP_CONSTANT(DEFAULT_EFFECTIVE_KEYLENGTH = 1024) + CRYPTOPP_CONSTANT(MAX_EFFECTIVE_KEYLENGTH = 1024) + static const char *StaticAlgorithmName() {return "RC2";} +}; + +/// RC2 +class RC2 : public RC2_Info, public BlockCipherDocumentation +{ + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + public: + void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); + + protected: + FixedSizeSecBlock K; // expanded key table + }; + + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + +public: + class Encryption : public BlockCipherFinal + { + public: + Encryption() {} + Encryption(const byte *key, size_t keyLen=DEFAULT_KEYLENGTH) + {SetKey(key, keyLen);} + Encryption(const byte *key, size_t keyLen, int effectiveKeyLen) + {SetKey(key, keyLen, MakeParameters("EffectiveKeyLength", effectiveKeyLen));} + }; + + class Decryption : public BlockCipherFinal + { + public: + Decryption() {} + Decryption(const byte *key, size_t keyLen=DEFAULT_KEYLENGTH) + {SetKey(key, keyLen);} + Decryption(const byte *key, size_t keyLen, int effectiveKeyLen) + {SetKey(key, keyLen, MakeParameters("EffectiveKeyLength", effectiveKeyLen));} + }; +}; + +typedef RC2::Encryption RC2Encryption; +typedef RC2::Decryption RC2Decryption; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/rc2val.dat b/CryptoPP/crypto/rc2val.dat new file mode 100644 index 0000000..f28d48c --- /dev/null +++ b/CryptoPP/crypto/rc2val.dat @@ -0,0 +1,48 @@ +08 +3F +00000000 00000000 +00000000 00000000 +ebb773f9 93278eff + +08 +40 +ffffffff ffffffff +ffffffff ffffffff +278b27e4 2e2f0d49 + +08 +40 +30000000 00000000 +10000000 00000001 +30649edf 9be7d2c2 + +01 +40 +88 +00000000 00000000 +61a8a244 adacccf0 + +07 +40 +88bca90e 90875a +00000000 00000000 +6ccf4308 974c267f + +10 +40 +88bca90e 90875a7f 0f79c384 627bafb2 +00000000 00000000 +1a807d27 2bbe5db1 + +10 +80 +88bca90e 90875a7f 0f79c384 627bafb2 +00000000 00000000 +2269552a b0f85ca6 + +21 +81 +88bca90e 90875a7f 0f79c384 627bafb2 16f80a6f 85920584 + c42fceb0 be255daf 1e +00000000 00000000 +5b78d3a4 3dfff1f1 diff --git a/CryptoPP/crypto/rc5.cpp b/CryptoPP/crypto/rc5.cpp new file mode 100644 index 0000000..7fd6239 --- /dev/null +++ b/CryptoPP/crypto/rc5.cpp @@ -0,0 +1,79 @@ +// rc5.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "rc5.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +void RC5::Base::UncheckedSetKey(const byte *k, unsigned int keylen, const NameValuePairs ¶ms) +{ + AssertValidKeyLength(keylen); + + r = GetRoundsAndThrowIfInvalid(params, this); + sTable.New(2*(r+1)); + + static const RC5_WORD MAGIC_P = 0xb7e15163L; // magic constant P for wordsize + static const RC5_WORD MAGIC_Q = 0x9e3779b9L; // magic constant Q for wordsize + static const int U=sizeof(RC5_WORD); + + const unsigned int c = STDMAX((keylen+U-1)/U, 1U); // RC6 paper says c=1 if keylen==0 + SecBlock l(c); + + GetUserKey(LITTLE_ENDIAN_ORDER, l.begin(), c, k, keylen); + + sTable[0] = MAGIC_P; + for (unsigned j=1; j Block; + +void RC5::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + const RC5_WORD *sptr = sTable; + RC5_WORD a, b; + + Block::Get(inBlock)(a)(b); + a += sptr[0]; + b += sptr[1]; + sptr += 2; + + for(unsigned i=0; i, public VariableKeyLength<16, 0, 255>, public VariableRounds<16> +{ + static const char *StaticAlgorithmName() {return "RC5";} + typedef word32 RC5_WORD; +}; + +/// RC5 +class RC5 : public RC5_Info, public BlockCipherDocumentation +{ + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + public: + void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); + + protected: + unsigned int r; // number of rounds + SecBlock sTable; // expanded key table + }; + + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef RC5::Encryption RC5Encryption; +typedef RC5::Decryption RC5Decryption; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/rc5val.dat b/CryptoPP/crypto/rc5val.dat new file mode 100644 index 0000000..4f4de59 --- /dev/null +++ b/CryptoPP/crypto/rc5val.dat @@ -0,0 +1,5 @@ +00000000000000000000000000000000 0000000000000000 21A5DBEE154B8F6D +915F4619BE41B2516355A50110A9CE91 21A5DBEE154B8F6D F7C013AC5B2B8952 +783348E75AEB0F2FD7B169BB8DC16787 F7C013AC5B2B8952 2F42B3B70369FC92 +DC49DB1375A5584F6485B413B5F12BAF 2F42B3B70369FC92 65C178B284D197CC +5269F149D41BA0152497574D7F153125 65C178B284D197CC EB44E415DA319824 diff --git a/CryptoPP/crypto/rc6.cpp b/CryptoPP/crypto/rc6.cpp new file mode 100644 index 0000000..f2cf808 --- /dev/null +++ b/CryptoPP/crypto/rc6.cpp @@ -0,0 +1,96 @@ +// rc6.cpp - written and placed in the public domain by Sean Woods +// based on Wei Dai's RC5 code. + +#include "pch.h" +#include "rc6.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +void RC6::Base::UncheckedSetKey(const byte *k, unsigned int keylen, const NameValuePairs ¶ms) +{ + AssertValidKeyLength(keylen); + + r = GetRoundsAndThrowIfInvalid(params, this); + sTable.New(2*(r+2)); + + static const RC6_WORD MAGIC_P = 0xb7e15163L; // magic constant P for wordsize + static const RC6_WORD MAGIC_Q = 0x9e3779b9L; // magic constant Q for wordsize + static const int U=sizeof(RC6_WORD); + + const unsigned int c = STDMAX((keylen+U-1)/U, 1U); // RC6 paper says c=1 if keylen==0 + SecBlock l(c); + + GetUserKey(LITTLE_ENDIAN_ORDER, l.begin(), c, k, keylen); + + sTable[0] = MAGIC_P; + for (unsigned j=1; j Block; + +void RC6::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + const RC6_WORD *sptr = sTable; + RC6_WORD a, b, c, d, t, u; + + Block::Get(inBlock)(a)(b)(c)(d); + b += sptr[0]; + d += sptr[1]; + sptr += 2; + + for(unsigned i=0; i, public VariableKeyLength<16, 0, 255>, public VariableRounds<20> +{ + static const char *StaticAlgorithmName() {return "RC6";} + typedef word32 RC6_WORD; +}; + +/// RC6 +class RC6 : public RC6_Info, public BlockCipherDocumentation +{ + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + public: + void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); + + protected: + unsigned int r; // number of rounds + SecBlock sTable; // expanded key table + }; + + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef RC6::Encryption RC6Encryption; +typedef RC6::Decryption RC6Decryption; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/rc6val.dat b/CryptoPP/crypto/rc6val.dat new file mode 100644 index 0000000..d9401b2 --- /dev/null +++ b/CryptoPP/crypto/rc6val.dat @@ -0,0 +1,17 @@ +00000000000000000000000000000000 + 00000000000000000000000000000000 8FC3A53656B1F778C129DF4E9848A41E + +0123456789ABCDEF0112233445566778 + 02132435465768798A9BACBDCEDFE0F1 524E192F4715C6231F51F6367EA43F18 + +000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000 6cd61bcb190b30384e8a3f168690ae82 + +0123456789abcdef0112233445566778899aabbccddeeff0 + 02132435465768798a9bacbdcedfe0f1 688329d019e505041e52e92af95291d4 + +0000000000000000000000000000000000000000000000000000000000000000 + 00000000000000000000000000000000 8f5fbd0510d15fa893fa3fda6e857ec2 + +0123456789abcdef0112233445566778899aabbccddeeff01032547698badcfe + 02132435465768798a9bacbdcedfe0f1 c8241816f0d7e48920ad16a1674e5d48 \ No newline at end of file diff --git a/CryptoPP/crypto/rdtables.cpp b/CryptoPP/crypto/rdtables.cpp new file mode 100644 index 0000000..8dd8b80 --- /dev/null +++ b/CryptoPP/crypto/rdtables.cpp @@ -0,0 +1,697 @@ +// Rijndael tables + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "rijndael.h" + +// VC60 workaround: gives a C4786 warning without this function +// when runtime lib is set to multithread debug DLL +// even though warning 4786 is disabled! +void Rijndael_VC60Workaround() +{ +} + +NAMESPACE_BEGIN(CryptoPP) + +/* +Te0[x] = S [x].[02, 01, 01, 03]; +Te1[x] = S [x].[03, 02, 01, 01]; +Te2[x] = S [x].[01, 03, 02, 01]; +Te3[x] = S [x].[01, 01, 03, 02]; + +Td0[x] = Si[x].[0e, 09, 0d, 0b]; +Td1[x] = Si[x].[0b, 0e, 09, 0d]; +Td2[x] = Si[x].[0d, 0b, 0e, 09]; +Td3[x] = Si[x].[09, 0d, 0b, 0e]; +*/ + +const byte Rijndael::Base::Se[256] = { + 0x63, 0x7c, 0x77, 0x7b, + 0xf2, 0x6b, 0x6f, 0xc5, + 0x30, 0x01, 0x67, 0x2b, + 0xfe, 0xd7, 0xab, 0x76, + 0xca, 0x82, 0xc9, 0x7d, + 0xfa, 0x59, 0x47, 0xf0, + 0xad, 0xd4, 0xa2, 0xaf, + 0x9c, 0xa4, 0x72, 0xc0, + 0xb7, 0xfd, 0x93, 0x26, + 0x36, 0x3f, 0xf7, 0xcc, + 0x34, 0xa5, 0xe5, 0xf1, + 0x71, 0xd8, 0x31, 0x15, + 0x04, 0xc7, 0x23, 0xc3, + 0x18, 0x96, 0x05, 0x9a, + 0x07, 0x12, 0x80, 0xe2, + 0xeb, 0x27, 0xb2, 0x75, + 0x09, 0x83, 0x2c, 0x1a, + 0x1b, 0x6e, 0x5a, 0xa0, + 0x52, 0x3b, 0xd6, 0xb3, + 0x29, 0xe3, 0x2f, 0x84, + 0x53, 0xd1, 0x00, 0xed, + 0x20, 0xfc, 0xb1, 0x5b, + 0x6a, 0xcb, 0xbe, 0x39, + 0x4a, 0x4c, 0x58, 0xcf, + 0xd0, 0xef, 0xaa, 0xfb, + 0x43, 0x4d, 0x33, 0x85, + 0x45, 0xf9, 0x02, 0x7f, + 0x50, 0x3c, 0x9f, 0xa8, + 0x51, 0xa3, 0x40, 0x8f, + 0x92, 0x9d, 0x38, 0xf5, + 0xbc, 0xb6, 0xda, 0x21, + 0x10, 0xff, 0xf3, 0xd2, + 0xcd, 0x0c, 0x13, 0xec, + 0x5f, 0x97, 0x44, 0x17, + 0xc4, 0xa7, 0x7e, 0x3d, + 0x64, 0x5d, 0x19, 0x73, + 0x60, 0x81, 0x4f, 0xdc, + 0x22, 0x2a, 0x90, 0x88, + 0x46, 0xee, 0xb8, 0x14, + 0xde, 0x5e, 0x0b, 0xdb, + 0xe0, 0x32, 0x3a, 0x0a, + 0x49, 0x06, 0x24, 0x5c, + 0xc2, 0xd3, 0xac, 0x62, + 0x91, 0x95, 0xe4, 0x79, + 0xe7, 0xc8, 0x37, 0x6d, + 0x8d, 0xd5, 0x4e, 0xa9, + 0x6c, 0x56, 0xf4, 0xea, + 0x65, 0x7a, 0xae, 0x08, + 0xba, 0x78, 0x25, 0x2e, + 0x1c, 0xa6, 0xb4, 0xc6, + 0xe8, 0xdd, 0x74, 0x1f, + 0x4b, 0xbd, 0x8b, 0x8a, + 0x70, 0x3e, 0xb5, 0x66, + 0x48, 0x03, 0xf6, 0x0e, + 0x61, 0x35, 0x57, 0xb9, + 0x86, 0xc1, 0x1d, 0x9e, + 0xe1, 0xf8, 0x98, 0x11, + 0x69, 0xd9, 0x8e, 0x94, + 0x9b, 0x1e, 0x87, 0xe9, + 0xce, 0x55, 0x28, 0xdf, + 0x8c, 0xa1, 0x89, 0x0d, + 0xbf, 0xe6, 0x42, 0x68, + 0x41, 0x99, 0x2d, 0x0f, + 0xb0, 0x54, 0xbb, 0x16, +}; + +const byte Rijndael::Base::Sd[256] = { + 0x52, 0x09, 0x6a, 0xd5, + 0x30, 0x36, 0xa5, 0x38, + 0xbf, 0x40, 0xa3, 0x9e, + 0x81, 0xf3, 0xd7, 0xfb, + 0x7c, 0xe3, 0x39, 0x82, + 0x9b, 0x2f, 0xff, 0x87, + 0x34, 0x8e, 0x43, 0x44, + 0xc4, 0xde, 0xe9, 0xcb, + 0x54, 0x7b, 0x94, 0x32, + 0xa6, 0xc2, 0x23, 0x3d, + 0xee, 0x4c, 0x95, 0x0b, + 0x42, 0xfa, 0xc3, 0x4e, + 0x08, 0x2e, 0xa1, 0x66, + 0x28, 0xd9, 0x24, 0xb2, + 0x76, 0x5b, 0xa2, 0x49, + 0x6d, 0x8b, 0xd1, 0x25, + 0x72, 0xf8, 0xf6, 0x64, + 0x86, 0x68, 0x98, 0x16, + 0xd4, 0xa4, 0x5c, 0xcc, + 0x5d, 0x65, 0xb6, 0x92, + 0x6c, 0x70, 0x48, 0x50, + 0xfd, 0xed, 0xb9, 0xda, + 0x5e, 0x15, 0x46, 0x57, + 0xa7, 0x8d, 0x9d, 0x84, + 0x90, 0xd8, 0xab, 0x00, + 0x8c, 0xbc, 0xd3, 0x0a, + 0xf7, 0xe4, 0x58, 0x05, + 0xb8, 0xb3, 0x45, 0x06, + 0xd0, 0x2c, 0x1e, 0x8f, + 0xca, 0x3f, 0x0f, 0x02, + 0xc1, 0xaf, 0xbd, 0x03, + 0x01, 0x13, 0x8a, 0x6b, + 0x3a, 0x91, 0x11, 0x41, + 0x4f, 0x67, 0xdc, 0xea, + 0x97, 0xf2, 0xcf, 0xce, + 0xf0, 0xb4, 0xe6, 0x73, + 0x96, 0xac, 0x74, 0x22, + 0xe7, 0xad, 0x35, 0x85, + 0xe2, 0xf9, 0x37, 0xe8, + 0x1c, 0x75, 0xdf, 0x6e, + 0x47, 0xf1, 0x1a, 0x71, + 0x1d, 0x29, 0xc5, 0x89, + 0x6f, 0xb7, 0x62, 0x0e, + 0xaa, 0x18, 0xbe, 0x1b, + 0xfc, 0x56, 0x3e, 0x4b, + 0xc6, 0xd2, 0x79, 0x20, + 0x9a, 0xdb, 0xc0, 0xfe, + 0x78, 0xcd, 0x5a, 0xf4, + 0x1f, 0xdd, 0xa8, 0x33, + 0x88, 0x07, 0xc7, 0x31, + 0xb1, 0x12, 0x10, 0x59, + 0x27, 0x80, 0xec, 0x5f, + 0x60, 0x51, 0x7f, 0xa9, + 0x19, 0xb5, 0x4a, 0x0d, + 0x2d, 0xe5, 0x7a, 0x9f, + 0x93, 0xc9, 0x9c, 0xef, + 0xa0, 0xe0, 0x3b, 0x4d, + 0xae, 0x2a, 0xf5, 0xb0, + 0xc8, 0xeb, 0xbb, 0x3c, + 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2b, 0x04, 0x7e, + 0xba, 0x77, 0xd6, 0x26, + 0xe1, 0x69, 0x14, 0x63, + 0x55, 0x21, 0x0c, 0x7d, +}; + +const word32 Rijndael::Base::Te[4*256] = { + 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, + 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U, + 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU, + 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU, + 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U, + 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU, + 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU, + 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU, + 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU, + 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU, + 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U, + 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU, + 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU, + 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U, + 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU, + 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU, + 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU, + 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU, + 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU, + 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U, + 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU, + 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU, + 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU, + 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU, + 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U, + 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U, + 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U, + 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U, + 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU, + 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U, + 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U, + 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU, + 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU, + 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U, + 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U, + 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U, + 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU, + 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U, + 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU, + 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U, + 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU, + 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U, + 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U, + 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU, + 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U, + 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U, + 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U, + 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U, + 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U, + 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U, + 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U, + 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U, + 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU, + 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U, + 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U, + 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U, + 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U, + 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U, + 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U, + 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU, + 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U, + 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U, + 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U, + 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU, + + 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU, + 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U, + 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU, + 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U, + 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU, + 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U, + 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU, + 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U, + 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U, + 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU, + 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U, + 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U, + 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U, + 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU, + 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U, + 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U, + 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU, + 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U, + 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U, + 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U, + 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU, + 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU, + 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U, + 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU, + 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU, + 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U, + 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU, + 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U, + 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU, + 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U, + 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U, + 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U, + 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU, + 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U, + 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU, + 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U, + 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU, + 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U, + 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U, + 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU, + 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU, + 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU, + 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U, + 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U, + 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU, + 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U, + 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU, + 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U, + 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU, + 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U, + 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU, + 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU, + 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U, + 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU, + 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U, + 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU, + 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U, + 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U, + 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U, + 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU, + 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU, + 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U, + 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU, + 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U, + + 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU, + 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U, + 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU, + 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U, + 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU, + 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U, + 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU, + 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U, + 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U, + 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU, + 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U, + 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U, + 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U, + 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU, + 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U, + 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U, + 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU, + 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U, + 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U, + 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U, + 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU, + 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU, + 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U, + 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU, + 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU, + 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U, + 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU, + 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U, + 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU, + 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U, + 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U, + 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U, + 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU, + 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U, + 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU, + 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U, + 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU, + 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U, + 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U, + 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU, + 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU, + 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU, + 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U, + 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U, + 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU, + 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U, + 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU, + 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U, + 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU, + 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U, + 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU, + 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU, + 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U, + 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU, + 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U, + 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU, + 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U, + 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U, + 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U, + 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU, + 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU, + 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U, + 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU, + 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U, + + 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U, + 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U, + 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U, + 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU, + 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU, + 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU, + 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U, + 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU, + 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU, + 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U, + 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U, + 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU, + 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU, + 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU, + 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU, + 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU, + 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U, + 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU, + 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU, + 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U, + 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U, + 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U, + 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U, + 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U, + 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU, + 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U, + 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU, + 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU, + 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U, + 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U, + 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U, + 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU, + 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U, + 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU, + 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU, + 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U, + 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U, + 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU, + 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U, + 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU, + 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U, + 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U, + 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U, + 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U, + 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU, + 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U, + 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU, + 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U, + 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU, + 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U, + 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU, + 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU, + 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU, + 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU, + 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U, + 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U, + 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U, + 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U, + 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U, + 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U, + 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU, + 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U, + 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU, + 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU, +}; + +const word32 Rijndael::Base::Td[4*256] = { + 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, + 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U, + 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U, + 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU, + 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U, + 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U, + 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU, + 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U, + 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU, + 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U, + 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U, + 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U, + 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U, + 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU, + 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U, + 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU, + 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U, + 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU, + 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U, + 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U, + 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U, + 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU, + 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U, + 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU, + 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U, + 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU, + 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U, + 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU, + 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU, + 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U, + 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU, + 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U, + 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU, + 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U, + 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U, + 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U, + 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU, + 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U, + 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U, + 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU, + 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U, + 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U, + 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U, + 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U, + 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U, + 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU, + 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U, + 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U, + 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U, + 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U, + 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U, + 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU, + 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU, + 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU, + 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU, + 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U, + 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U, + 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU, + 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU, + 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U, + 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU, + 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U, + 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U, + 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U, + + 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU, + 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U, + 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU, + 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U, + 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U, + 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U, + 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U, + 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U, + 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U, + 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU, + 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU, + 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU, + 0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U, + 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU, + 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U, + 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U, + 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U, + 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU, + 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU, + 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U, + 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU, + 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U, + 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU, + 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU, + 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U, + 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U, + 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U, + 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU, + 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U, + 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU, + 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U, + 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U, + 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U, + 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU, + 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U, + 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U, + 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U, + 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U, + 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U, + 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U, + 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU, + 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU, + 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U, + 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU, + 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U, + 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU, + 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU, + 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U, + 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU, + 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U, + 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U, + 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U, + 0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U, + 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U, + 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U, + 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U, + 0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU, + 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U, + 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U, + 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU, + 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U, + 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U, + 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U, + 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U, + + 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U, + 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U, + 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U, + 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U, + 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU, + 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U, + 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U, + 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U, + 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U, + 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU, + 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U, + 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U, + 0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU, + 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U, + 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U, + 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U, + 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U, + 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U, + 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U, + 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU, + + 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U, + 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U, + 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U, + 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U, + 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U, + 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU, + 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU, + 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U, + 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU, + 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U, + 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU, + 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU, + 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU, + 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU, + 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U, + 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U, + 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U, + 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U, + 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U, + 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U, + 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U, + 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU, + 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU, + 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U, + 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U, + 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU, + 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU, + 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U, + 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U, + 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U, + 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U, + 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U, + 0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U, + 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U, + 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU, + 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U, + 0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U, + 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U, + 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U, + 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U, + 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U, + 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU, + 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U, + 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U, + + 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU, + 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU, + 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U, + 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U, + 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU, + 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU, + 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U, + 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU, + 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U, + 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU, + 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U, + 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U, + 0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U, + 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U, + 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U, + 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU, + 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU, + 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U, + 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U, + 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU, + 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU, + 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U, + 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U, + 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U, + 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U, + 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU, + 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U, + 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U, + 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU, + 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU, + 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U, + 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U, + 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U, + 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU, + 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U, + 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U, + 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U, + 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U, + 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U, + 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U, + 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U, + 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU, + 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U, + 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U, + 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU, + 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU, + 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U, + 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU, + 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U, + 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U, + 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U, + 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U, + 0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U, + 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U, + 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU, + 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU, + 0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU, + 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU, + 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U, + 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U, + 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U, + 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU, + 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U, + 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U, +}; + +const word32 Rijndael::Base::rcon[] = { + 0x01000000, 0x02000000, 0x04000000, 0x08000000, + 0x10000000, 0x20000000, 0x40000000, 0x80000000, + 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/regtest.cpp b/CryptoPP/crypto/regtest.cpp new file mode 100644 index 0000000..0cfb9ce --- /dev/null +++ b/CryptoPP/crypto/regtest.cpp @@ -0,0 +1,89 @@ +#include "factory.h" + +#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 +#include "modes.h" +#include "dh.h" +#include "esign.h" +#include "md2.h" +#include "rw.h" +#include "md5.h" +#include "rsa.h" +#include "ripemd.h" +#include "dsa.h" +#include "seal.h" +#include "whrlpool.h" +#include "ttmac.h" +#include "camellia.h" +#include "shacal2.h" +#include "tea.h" +#include "panama.h" +#include "pssr.h" +#include "aes.h" +#include "salsa.h" +#include "vmac.h" +#include "tiger.h" +#include "md5.h" +#include "sosemanuk.h" +#include "arc4.h" + +USING_NAMESPACE(CryptoPP) + +void RegisterFactories() +{ + static bool s_registered = false; + if (s_registered) + return; + + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor(); +#ifdef WORD64_AVAILABLE + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor(); +#endif + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor >(); + RegisterDefaultFactoryFor >(); + RegisterDefaultFactoryFor >(); + RegisterDefaultFactoryFor >(); + RegisterDefaultFactoryFor >(); + RegisterDefaultFactoryFor(); + RegisterDefaultFactoryFor >(); + RegisterDefaultFactoryFor >(); + RegisterDefaultFactoryFor >(); + RegisterDefaultFactoryFor >(); + RegisterAsymmetricCipherDefaultFactories > >("RSA/OAEP-MGF1(SHA-1)"); + RegisterAsymmetricCipherDefaultFactories >("DLIES(NoCofactorMultiplication, KDF2(SHA-1), XOR, HMAC(SHA-1), DHAES)"); + RegisterSignatureSchemeDefaultFactories("DSA(1363)"); + RegisterSignatureSchemeDefaultFactories >("NR(1363)/EMSA1(SHA-1)"); + RegisterSignatureSchemeDefaultFactories >("DSA-1363/EMSA1(SHA-1)"); + RegisterSignatureSchemeDefaultFactories >("RSA/PKCS1-1.5(MD2)"); + RegisterSignatureSchemeDefaultFactories >("RSA/PKCS1-1.5(SHA-1)"); + RegisterSignatureSchemeDefaultFactories >("ESIGN/EMSA5-MGF1(SHA-1)"); + RegisterSignatureSchemeDefaultFactories >("RW/EMSA2(SHA-1)"); + RegisterSignatureSchemeDefaultFactories >("RSA/PSS-MGF1(SHA-1)"); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories >(); + RegisterSymmetricCipherDefaultFactories(); + RegisterSymmetricCipherDefaultFactories(); + RegisterSymmetricCipherDefaultFactories(); + + s_registered = true; +} diff --git a/CryptoPP/crypto/resource.h b/CryptoPP/crypto/resource.h new file mode 100644 index 0000000..a2e492c --- /dev/null +++ b/CryptoPP/crypto/resource.h @@ -0,0 +1,15 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by cryptopp.rc +// + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/CryptoPP/crypto/rijndael.cpp b/CryptoPP/crypto/rijndael.cpp new file mode 100644 index 0000000..c1682d8 --- /dev/null +++ b/CryptoPP/crypto/rijndael.cpp @@ -0,0 +1,722 @@ +// rijndael.cpp - modified by Chris Morgan +// and Wei Dai from Paulo Baretto's Rijndael implementation +// The original code and all modifications are in the public domain. + +// use "cl /EP /P /DCRYPTOPP_GENERATE_X64_MASM rijndael.cpp" to generate MASM code + +/* +Defense against timing attacks was added in July 2006 by Wei Dai. + +The code now uses smaller tables in the first and last rounds, +and preloads them into L1 cache before usage (by loading at least +one element in each cache line). + +We try to delay subsequent accesses to each table (used in the first +and last rounds) until all of the table has been preloaded. Hopefully +the compiler isn't smart enough to optimize that code away. + +After preloading the table, we also try not to access any memory location +other than the table and the stack, in order to prevent table entries from +being unloaded from L1 cache, until that round is finished. +(Some popular CPUs have 2-way associative caches.) +*/ + +// This is the original introductory comment: + +/** + * version 3.0 (December 2000) + * + * Optimised ANSI C code for the Rijndael cipher (now AES) + * + * author Vincent Rijmen + * author Antoon Bosselaers + * author Paulo Barreto + * + * This code is hereby placed in the public domain. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS +#ifndef CRYPTOPP_GENERATE_X64_MASM + +#include "rijndael.h" +#include "misc.h" +#include "cpu.h" + +NAMESPACE_BEGIN(CryptoPP) + +void Rijndael::Base::UncheckedSetKey(const byte *userKey, unsigned int keylen, const NameValuePairs &) +{ + AssertValidKeyLength(keylen); + + m_rounds = keylen/4 + 6; + m_key.New(4*(m_rounds+1)); + + word32 temp, *rk = m_key; + const word32 *rc = rcon; + + GetUserKey(BIG_ENDIAN_ORDER, rk, keylen/4, userKey, keylen); + + while (true) + { + temp = rk[keylen/4-1]; + rk[keylen/4] = rk[0] ^ + (word32(Se[GETBYTE(temp, 2)]) << 24) ^ + (word32(Se[GETBYTE(temp, 1)]) << 16) ^ + (word32(Se[GETBYTE(temp, 0)]) << 8) ^ + Se[GETBYTE(temp, 3)] ^ + *(rc++); + rk[keylen/4+1] = rk[1] ^ rk[keylen/4]; + rk[keylen/4+2] = rk[2] ^ rk[keylen/4+1]; + rk[keylen/4+3] = rk[3] ^ rk[keylen/4+2]; + + if (rk + keylen/4 + 4 == m_key.end()) + break; + + if (keylen == 24) + { + rk[10] = rk[ 4] ^ rk[ 9]; + rk[11] = rk[ 5] ^ rk[10]; + } + else if (keylen == 32) + { + temp = rk[11]; + rk[12] = rk[ 4] ^ + (word32(Se[GETBYTE(temp, 3)]) << 24) ^ + (word32(Se[GETBYTE(temp, 2)]) << 16) ^ + (word32(Se[GETBYTE(temp, 1)]) << 8) ^ + Se[GETBYTE(temp, 0)]; + rk[13] = rk[ 5] ^ rk[12]; + rk[14] = rk[ 6] ^ rk[13]; + rk[15] = rk[ 7] ^ rk[14]; + } + rk += keylen/4; + } + + if (!IsForwardTransformation()) + { + unsigned int i, j; + rk = m_key; + + /* invert the order of the round keys: */ + for (i = 0, j = 4*m_rounds; i < j; i += 4, j -= 4) { + temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp; + temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp; + temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp; + temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp; + } + /* apply the inverse MixColumn transform to all round keys but the first and the last: */ + for (i = 1; i < m_rounds; i++) { + rk += 4; + rk[0] = + Td[0*256+Se[GETBYTE(rk[0], 3)]] ^ + Td[1*256+Se[GETBYTE(rk[0], 2)]] ^ + Td[2*256+Se[GETBYTE(rk[0], 1)]] ^ + Td[3*256+Se[GETBYTE(rk[0], 0)]]; + rk[1] = + Td[0*256+Se[GETBYTE(rk[1], 3)]] ^ + Td[1*256+Se[GETBYTE(rk[1], 2)]] ^ + Td[2*256+Se[GETBYTE(rk[1], 1)]] ^ + Td[3*256+Se[GETBYTE(rk[1], 0)]]; + rk[2] = + Td[0*256+Se[GETBYTE(rk[2], 3)]] ^ + Td[1*256+Se[GETBYTE(rk[2], 2)]] ^ + Td[2*256+Se[GETBYTE(rk[2], 1)]] ^ + Td[3*256+Se[GETBYTE(rk[2], 0)]]; + rk[3] = + Td[0*256+Se[GETBYTE(rk[3], 3)]] ^ + Td[1*256+Se[GETBYTE(rk[3], 2)]] ^ + Td[2*256+Se[GETBYTE(rk[3], 1)]] ^ + Td[3*256+Se[GETBYTE(rk[3], 0)]]; + } + } + + ConditionalByteReverse(BIG_ENDIAN_ORDER, m_key.begin(), m_key.begin(), 16); + ConditionalByteReverse(BIG_ENDIAN_ORDER, m_key + m_rounds*4, m_key + m_rounds*4, 16); +} + +#ifdef CRYPTOPP_X64_MASM_AVAILABLE +extern "C" { +void Rijndael_Enc_ProcessAndXorBlock(const word32 *table, word32 cacheLineSize, const word32 *k, const word32 *kLoopEnd, const byte *inBlock, const byte *xorBlock, byte *outBlock); +} +#endif + +#pragma warning(disable: 4731) // frame pointer register 'ebp' modified by inline assembly code + +void Rijndael::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ +#endif // #ifdef CRYPTOPP_GENERATE_X64_MASM + +#ifdef CRYPTOPP_X64_MASM_AVAILABLE + Rijndael_Enc_ProcessAndXorBlock(Te, g_cacheLineSize, m_key, m_key + m_rounds*4, inBlock, xorBlock, outBlock); + return; +#endif + +#if defined(CRYPTOPP_X86_ASM_AVAILABLE) + #ifdef CRYPTOPP_GENERATE_X64_MASM + ALIGN 8 + Rijndael_Enc_ProcessAndXorBlock PROC FRAME + rex_push_reg rbx + push_reg rsi + push_reg rdi + push_reg r12 + push_reg r13 + push_reg r14 + push_reg r15 + .endprolog + mov AS_REG_7, rcx + mov rdi, [rsp + 5*8 + 7*8] ; inBlock + #else + if (HasMMX()) + { + const word32 *k = m_key; + const word32 *kLoopEnd = k + m_rounds*4; + #endif + + #if CRYPTOPP_BOOL_X64 + #define K_REG r8 + #define K_END_REG r9 + #define SAVE_K + #define RESTORE_K + #define RESTORE_K_END + #define SAVE_0(x) AS2(mov r13d, x) + #define SAVE_1(x) AS2(mov r14d, x) + #define SAVE_2(x) AS2(mov r15d, x) + #define RESTORE_0(x) AS2(mov x, r13d) + #define RESTORE_1(x) AS2(mov x, r14d) + #define RESTORE_2(x) AS2(mov x, r15d) + #else + #define K_REG esi + #define K_END_REG edi + #define SAVE_K AS2(movd mm4, esi) + #define RESTORE_K AS2(movd esi, mm4) + #define RESTORE_K_END AS2(movd edi, mm5) + #define SAVE_0(x) AS2(movd mm0, x) + #define SAVE_1(x) AS2(movd mm1, x) + #define SAVE_2(x) AS2(movd mm2, x) + #define RESTORE_0(x) AS2(movd x, mm0) + #define RESTORE_1(x) AS2(movd x, mm1) + #define RESTORE_2(x) AS2(movd x, mm2) + #endif +#ifdef __GNUC__ + word32 t0, t1, t2, t3; + __asm__ __volatile__ + ( + ".intel_syntax noprefix;" + #if CRYPTOPP_BOOL_X64 + AS2( mov K_REG, rsi) + AS2( mov K_END_REG, rcx) + #else + AS1( push ebx) + AS1( push ebp) + AS2( movd mm5, ecx) + #endif + AS2( mov AS_REG_7, WORD_REG(ax)) +#elif CRYPTOPP_BOOL_X86 + #if _MSC_VER < 1300 + const word32 *t = Te; + AS2( mov eax, t) + #endif + AS2( mov edx, g_cacheLineSize) + AS2( mov WORD_REG(di), inBlock) + AS2( mov K_REG, k) + AS2( movd mm5, kLoopEnd) + #if _MSC_VER < 1300 + AS1( push ebx) + AS1( push ebp) + AS2( mov AS_REG_7, eax) + #else + AS1( push ebp) + AS2( lea AS_REG_7, Te) + #endif +#endif + AS2( mov eax, [K_REG+0*4]) // s0 + AS2( xor eax, [WORD_REG(di)+0*4]) + SAVE_0(eax) + AS2( mov ebx, [K_REG+1*4]) + AS2( xor ebx, [WORD_REG(di)+1*4]) + SAVE_1(ebx) + AS2( and ebx, eax) + AS2( mov eax, [K_REG+2*4]) + AS2( xor eax, [WORD_REG(di)+2*4]) + SAVE_2(eax) + AS2( and ebx, eax) + AS2( mov ecx, [K_REG+3*4]) + AS2( xor ecx, [WORD_REG(di)+3*4]) + AS2( and ebx, ecx) + + // read Te0 into L1 cache. this code could be simplifed by using lfence, but that is an SSE2 instruction + AS2( and ebx, 0) + AS2( mov edi, ebx) // make index depend on previous loads to simulate lfence + ASL(2) + AS2( and ebx, [AS_REG_7+WORD_REG(di)]) + AS2( add edi, edx) + AS2( and ebx, [AS_REG_7+WORD_REG(di)]) + AS2( add edi, edx) + AS2( and ebx, [AS_REG_7+WORD_REG(di)]) + AS2( add edi, edx) + AS2( and ebx, [AS_REG_7+WORD_REG(di)]) + AS2( add edi, edx) + AS2( cmp edi, 1024) + ASJ( jl, 2, b) + AS2( and ebx, [AS_REG_7+1020]) +#if CRYPTOPP_BOOL_X64 + AS2( xor r13d, ebx) + AS2( xor r14d, ebx) + AS2( xor r15d, ebx) +#else + AS2( movd mm6, ebx) + AS2( pxor mm2, mm6) + AS2( pxor mm1, mm6) + AS2( pxor mm0, mm6) +#endif + AS2( xor ecx, ebx) + + AS2( mov edi, [K_REG+4*4]) // t0 + AS2( mov eax, [K_REG+5*4]) + AS2( mov ebx, [K_REG+6*4]) + AS2( mov edx, [K_REG+7*4]) + AS2( add K_REG, 8*4) + SAVE_K + +#define QUARTER_ROUND(t, a, b, c, d) \ + AS2(movzx esi, t##l)\ + AS2(d, [AS_REG_7+0*1024+4*WORD_REG(si)])\ + AS2(movzx esi, t##h)\ + AS2(c, [AS_REG_7+1*1024+4*WORD_REG(si)])\ + AS2(shr e##t##x, 16)\ + AS2(movzx esi, t##l)\ + AS2(b, [AS_REG_7+2*1024+4*WORD_REG(si)])\ + AS2(movzx esi, t##h)\ + AS2(a, [AS_REG_7+3*1024+4*WORD_REG(si)]) + +#define s0 xor edi +#define s1 xor eax +#define s2 xor ebx +#define s3 xor ecx +#define t0 xor edi +#define t1 xor eax +#define t2 xor ebx +#define t3 xor edx + + QUARTER_ROUND(c, t0, t1, t2, t3) + RESTORE_2(ecx) + QUARTER_ROUND(c, t3, t0, t1, t2) + RESTORE_1(ecx) + QUARTER_ROUND(c, t2, t3, t0, t1) + RESTORE_0(ecx) + QUARTER_ROUND(c, t1, t2, t3, t0) + SAVE_2(ebx) + SAVE_1(eax) + SAVE_0(edi) +#undef QUARTER_ROUND + + RESTORE_K + + ASL(0) + AS2( mov edi, [K_REG+0*4]) + AS2( mov eax, [K_REG+1*4]) + AS2( mov ebx, [K_REG+2*4]) + AS2( mov ecx, [K_REG+3*4]) + +#define QUARTER_ROUND(t, a, b, c, d) \ + AS2(movzx esi, t##l)\ + AS2(a, [AS_REG_7+3*1024+4*WORD_REG(si)])\ + AS2(movzx esi, t##h)\ + AS2(b, [AS_REG_7+2*1024+4*WORD_REG(si)])\ + AS2(shr e##t##x, 16)\ + AS2(movzx esi, t##l)\ + AS2(c, [AS_REG_7+1*1024+4*WORD_REG(si)])\ + AS2(movzx esi, t##h)\ + AS2(d, [AS_REG_7+0*1024+4*WORD_REG(si)]) + + QUARTER_ROUND(d, s0, s1, s2, s3) + RESTORE_2(edx) + QUARTER_ROUND(d, s3, s0, s1, s2) + RESTORE_1(edx) + QUARTER_ROUND(d, s2, s3, s0, s1) + RESTORE_0(edx) + QUARTER_ROUND(d, s1, s2, s3, s0) + RESTORE_K + SAVE_2(ebx) + SAVE_1(eax) + SAVE_0(edi) + + AS2( mov edi, [K_REG+4*4]) + AS2( mov eax, [K_REG+5*4]) + AS2( mov ebx, [K_REG+6*4]) + AS2( mov edx, [K_REG+7*4]) + + QUARTER_ROUND(c, t0, t1, t2, t3) + RESTORE_2(ecx) + QUARTER_ROUND(c, t3, t0, t1, t2) + RESTORE_1(ecx) + QUARTER_ROUND(c, t2, t3, t0, t1) + RESTORE_0(ecx) + QUARTER_ROUND(c, t1, t2, t3, t0) + SAVE_2(ebx) + SAVE_1(eax) + SAVE_0(edi) + + RESTORE_K + RESTORE_K_END + AS2( add K_REG, 8*4) + SAVE_K + AS2( cmp K_END_REG, K_REG) + ASJ( jne, 0, b) + +#undef QUARTER_ROUND +#undef s0 +#undef s1 +#undef s2 +#undef s3 +#undef t0 +#undef t1 +#undef t2 +#undef t3 + + AS2( mov eax, [K_END_REG+0*4]) + AS2( mov ecx, [K_END_REG+1*4]) + AS2( mov esi, [K_END_REG+2*4]) + AS2( mov edi, [K_END_REG+3*4]) + +#define QUARTER_ROUND(a, b, c, d) \ + AS2( movzx ebx, dl)\ + AS2( movzx ebx, BYTE PTR [AS_REG_7+1+4*WORD_REG(bx)])\ + AS2( shl ebx, 3*8)\ + AS2( xor a, ebx)\ + AS2( movzx ebx, dh)\ + AS2( movzx ebx, BYTE PTR [AS_REG_7+1+4*WORD_REG(bx)])\ + AS2( shl ebx, 2*8)\ + AS2( xor b, ebx)\ + AS2( shr edx, 16)\ + AS2( movzx ebx, dl)\ + AS2( shr edx, 8)\ + AS2( movzx ebx, BYTE PTR [AS_REG_7+1+4*WORD_REG(bx)])\ + AS2( shl ebx, 1*8)\ + AS2( xor c, ebx)\ + AS2( movzx ebx, BYTE PTR [AS_REG_7+1+4*WORD_REG(dx)])\ + AS2( xor d, ebx) + + QUARTER_ROUND(eax, ecx, esi, edi) + RESTORE_2(edx) + QUARTER_ROUND(edi, eax, ecx, esi) + RESTORE_1(edx) + QUARTER_ROUND(esi, edi, eax, ecx) + RESTORE_0(edx) + QUARTER_ROUND(ecx, esi, edi, eax) + +#undef QUARTER_ROUND + +#if CRYPTOPP_BOOL_X86 + AS1(emms) + AS1(pop ebp) + #if defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER < 1300) + AS1(pop ebx) + #endif +#endif + +#ifdef __GNUC__ + ".att_syntax prefix;" + : "=a" (t0), "=c" (t1), "=S" (t2), "=D" (t3) + : "a" (Te), "D" (inBlock), "S" (k), "c" (kLoopEnd), "d" (g_cacheLineSize) + : "memory", "cc" + #if CRYPTOPP_BOOL_X64 + , "%ebx", "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15" + #endif + ); + + if (xorBlock) + { + t0 ^= ((const word32 *)xorBlock)[0]; + t1 ^= ((const word32 *)xorBlock)[1]; + t2 ^= ((const word32 *)xorBlock)[2]; + t3 ^= ((const word32 *)xorBlock)[3]; + } + ((word32 *)outBlock)[0] = t0; + ((word32 *)outBlock)[1] = t1; + ((word32 *)outBlock)[2] = t2; + ((word32 *)outBlock)[3] = t3; +#else + #if CRYPTOPP_BOOL_X64 + mov rbx, [rsp + 6*8 + 7*8] ; xorBlock + #else + AS2( mov ebx, xorBlock) + #endif + AS2( test WORD_REG(bx), WORD_REG(bx)) + ASJ( jz, 1, f) + AS2( xor eax, [WORD_REG(bx)+0*4]) + AS2( xor ecx, [WORD_REG(bx)+1*4]) + AS2( xor esi, [WORD_REG(bx)+2*4]) + AS2( xor edi, [WORD_REG(bx)+3*4]) + ASL(1) + #if CRYPTOPP_BOOL_X64 + mov rbx, [rsp + 7*8 + 7*8] ; outBlock + #else + AS2( mov ebx, outBlock) + #endif + AS2( mov [WORD_REG(bx)+0*4], eax) + AS2( mov [WORD_REG(bx)+1*4], ecx) + AS2( mov [WORD_REG(bx)+2*4], esi) + AS2( mov [WORD_REG(bx)+3*4], edi) +#endif + +#if CRYPTOPP_GENERATE_X64_MASM + pop r15 + pop r14 + pop r13 + pop r12 + pop rdi + pop rsi + pop rbx + ret + Rijndael_Enc_ProcessAndXorBlock ENDP +#else + } + else +#endif +#endif // #ifdef CRYPTOPP_X86_ASM_AVAILABLE +#ifndef CRYPTOPP_GENERATE_X64_MASM + { + word32 s0, s1, s2, s3, t0, t1, t2, t3; + const word32 *rk = m_key; + + s0 = ((const word32 *)inBlock)[0] ^ rk[0]; + s1 = ((const word32 *)inBlock)[1] ^ rk[1]; + s2 = ((const word32 *)inBlock)[2] ^ rk[2]; + s3 = ((const word32 *)inBlock)[3] ^ rk[3]; + t0 = rk[4]; + t1 = rk[5]; + t2 = rk[6]; + t3 = rk[7]; + rk += 8; + + // timing attack countermeasure. see comments at top for more details + const int cacheLineSize = GetCacheLineSize(); + unsigned int i; + word32 u = 0; + for (i=0; i<1024; i+=cacheLineSize) + u &= *(const word32 *)(((const byte *)Te)+i); + u &= Te[255]; + s0 |= u; s1 |= u; s2 |= u; s3 |= u; + + // first round +#ifdef IS_BIG_ENDIAN +#define QUARTER_ROUND(t, a, b, c, d) \ + a ^= rotrFixed(Te[byte(t)], 24); t >>= 8;\ + b ^= rotrFixed(Te[byte(t)], 16); t >>= 8;\ + c ^= rotrFixed(Te[byte(t)], 8); t >>= 8;\ + d ^= Te[t]; +#else +#define QUARTER_ROUND(t, a, b, c, d) \ + d ^= Te[byte(t)]; t >>= 8;\ + c ^= rotrFixed(Te[byte(t)], 8); t >>= 8;\ + b ^= rotrFixed(Te[byte(t)], 16); t >>= 8;\ + a ^= rotrFixed(Te[t], 24); +#endif + + QUARTER_ROUND(s3, t0, t1, t2, t3) + QUARTER_ROUND(s2, t3, t0, t1, t2) + QUARTER_ROUND(s1, t2, t3, t0, t1) + QUARTER_ROUND(s0, t1, t2, t3, t0) +#undef QUARTER_ROUND + + // Nr - 2 full rounds: + unsigned int r = m_rounds/2 - 1; + do + { +#define QUARTER_ROUND(t, a, b, c, d) \ + a ^= Te[3*256+byte(t)]; t >>= 8;\ + b ^= Te[2*256+byte(t)]; t >>= 8;\ + c ^= Te[1*256+byte(t)]; t >>= 8;\ + d ^= Te[t]; + + s0 = rk[0]; s1 = rk[1]; s2 = rk[2]; s3 = rk[3]; + + QUARTER_ROUND(t3, s0, s1, s2, s3) + QUARTER_ROUND(t2, s3, s0, s1, s2) + QUARTER_ROUND(t1, s2, s3, s0, s1) + QUARTER_ROUND(t0, s1, s2, s3, s0) + + t0 = rk[4]; t1 = rk[5]; t2 = rk[6]; t3 = rk[7]; + + QUARTER_ROUND(s3, t0, t1, t2, t3) + QUARTER_ROUND(s2, t3, t0, t1, t2) + QUARTER_ROUND(s1, t2, t3, t0, t1) + QUARTER_ROUND(s0, t1, t2, t3, t0) +#undef QUARTER_ROUND + + rk += 8; + } while (--r); + + // timing attack countermeasure. see comments at top for more details + u = 0; + for (i=0; i<256; i+=cacheLineSize) + u &= *(const word32 *)(Se+i); + u &= *(const word32 *)(Se+252); + t0 |= u; t1 |= u; t2 |= u; t3 |= u; + + word32 tbw[4]; + byte *const tempBlock = (byte *)tbw; + word32 *const obw = (word32 *)outBlock; + const word32 *const xbw = (const word32 *)xorBlock; + +#define QUARTER_ROUND(t, a, b, c, d) \ + tempBlock[a] = Se[byte(t)]; t >>= 8;\ + tempBlock[b] = Se[byte(t)]; t >>= 8;\ + tempBlock[c] = Se[byte(t)]; t >>= 8;\ + tempBlock[d] = Se[t]; + + QUARTER_ROUND(t2, 15, 2, 5, 8) + QUARTER_ROUND(t1, 11, 14, 1, 4) + QUARTER_ROUND(t0, 7, 10, 13, 0) + QUARTER_ROUND(t3, 3, 6, 9, 12) +#undef QUARTER_ROUND + + if (xbw) + { + obw[0] = tbw[0] ^ xbw[0] ^ rk[0]; + obw[1] = tbw[1] ^ xbw[1] ^ rk[1]; + obw[2] = tbw[2] ^ xbw[2] ^ rk[2]; + obw[3] = tbw[3] ^ xbw[3] ^ rk[3]; + } + else + { + obw[0] = tbw[0] ^ rk[0]; + obw[1] = tbw[1] ^ rk[1]; + obw[2] = tbw[2] ^ rk[2]; + obw[3] = tbw[3] ^ rk[3]; + } + } +} + +void Rijndael::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word32 s0, s1, s2, s3, t0, t1, t2, t3; + const word32 *rk = m_key; + + s0 = ((const word32 *)inBlock)[0] ^ rk[0]; + s1 = ((const word32 *)inBlock)[1] ^ rk[1]; + s2 = ((const word32 *)inBlock)[2] ^ rk[2]; + s3 = ((const word32 *)inBlock)[3] ^ rk[3]; + t0 = rk[4]; + t1 = rk[5]; + t2 = rk[6]; + t3 = rk[7]; + rk += 8; + + // timing attack countermeasure. see comments at top for more details + const int cacheLineSize = GetCacheLineSize(); + unsigned int i; + word32 u = 0; + for (i=0; i<1024; i+=cacheLineSize) + u &= *(const word32 *)(((const byte *)Td)+i); + u &= Td[255]; + s0 |= u; s1 |= u; s2 |= u; s3 |= u; + + // first round +#ifdef IS_BIG_ENDIAN +#define QUARTER_ROUND(t, a, b, c, d) \ + a ^= rotrFixed(Td[byte(t)], 24); t >>= 8;\ + b ^= rotrFixed(Td[byte(t)], 16); t >>= 8;\ + c ^= rotrFixed(Td[byte(t)], 8); t >>= 8;\ + d ^= Td[t]; +#else +#define QUARTER_ROUND(t, a, b, c, d) \ + d ^= Td[byte(t)]; t >>= 8;\ + c ^= rotrFixed(Td[byte(t)], 8); t >>= 8;\ + b ^= rotrFixed(Td[byte(t)], 16); t >>= 8;\ + a ^= rotrFixed(Td[t], 24); +#endif + + QUARTER_ROUND(s3, t2, t1, t0, t3) + QUARTER_ROUND(s2, t1, t0, t3, t2) + QUARTER_ROUND(s1, t0, t3, t2, t1) + QUARTER_ROUND(s0, t3, t2, t1, t0) +#undef QUARTER_ROUND + + // Nr - 2 full rounds: + unsigned int r = m_rounds/2 - 1; + do + { +#define QUARTER_ROUND(t, a, b, c, d) \ + a ^= Td[3*256+byte(t)]; t >>= 8;\ + b ^= Td[2*256+byte(t)]; t >>= 8;\ + c ^= Td[1*256+byte(t)]; t >>= 8;\ + d ^= Td[t]; + + s0 = rk[0]; s1 = rk[1]; s2 = rk[2]; s3 = rk[3]; + + QUARTER_ROUND(t3, s2, s1, s0, s3) + QUARTER_ROUND(t2, s1, s0, s3, s2) + QUARTER_ROUND(t1, s0, s3, s2, s1) + QUARTER_ROUND(t0, s3, s2, s1, s0) + + t0 = rk[4]; t1 = rk[5]; t2 = rk[6]; t3 = rk[7]; + + QUARTER_ROUND(s3, t2, t1, t0, t3) + QUARTER_ROUND(s2, t1, t0, t3, t2) + QUARTER_ROUND(s1, t0, t3, t2, t1) + QUARTER_ROUND(s0, t3, t2, t1, t0) +#undef QUARTER_ROUND + + rk += 8; + } while (--r); + + // timing attack countermeasure. see comments at top for more details + u = 0; + for (i=0; i<256; i+=cacheLineSize) + u &= *(const word32 *)(Sd+i); + u &= *(const word32 *)(Sd+252); + t0 |= u; t1 |= u; t2 |= u; t3 |= u; + + word32 tbw[4]; + byte *const tempBlock = (byte *)tbw; + word32 *const obw = (word32 *)outBlock; + const word32 *const xbw = (const word32 *)xorBlock; + +#define QUARTER_ROUND(t, a, b, c, d) \ + tempBlock[a] = Sd[byte(t)]; t >>= 8;\ + tempBlock[b] = Sd[byte(t)]; t >>= 8;\ + tempBlock[c] = Sd[byte(t)]; t >>= 8;\ + tempBlock[d] = Sd[t]; + + QUARTER_ROUND(t2, 7, 2, 13, 8) + QUARTER_ROUND(t1, 3, 14, 9, 4) + QUARTER_ROUND(t0, 15, 10, 5, 0) + QUARTER_ROUND(t3, 11, 6, 1, 12) +#undef QUARTER_ROUND + + if (xbw) + { + obw[0] = tbw[0] ^ xbw[0] ^ rk[0]; + obw[1] = tbw[1] ^ xbw[1] ^ rk[1]; + obw[2] = tbw[2] ^ xbw[2] ^ rk[2]; + obw[3] = tbw[3] ^ xbw[3] ^ rk[3]; + } + else + { + obw[0] = tbw[0] ^ rk[0]; + obw[1] = tbw[1] ^ rk[1]; + obw[2] = tbw[2] ^ rk[2]; + obw[3] = tbw[3] ^ rk[3]; + } +} + +NAMESPACE_END + +#endif +#endif diff --git a/CryptoPP/crypto/rijndael.dat b/CryptoPP/crypto/rijndael.dat new file mode 100644 index 0000000..cf97819 --- /dev/null +++ b/CryptoPP/crypto/rijndael.dat @@ -0,0 +1,9 @@ +000102030405060708090A0B0C0D0E0F 000102030405060708090A0B0C0D0E0F 0A940BB5416EF045F1C39458C653EA5A +00010203050607080A0B0C0D0F101112 506812A45F08C889B97F5980038B8359 D8F532538289EF7D06B506A4FD5BE9C9 +14151617191A1B1C1E1F202123242526 5C6D71CA30DE8B8B00549984D2EC7D4B 59AB30F4D4EE6E4FF9907EF65B1FB68C +28292A2B2D2E2F30323334353738393A 53F3F4C64F8616E4E7C56199F48F21F6 BF1ED2FCB2AF3FD41443B56D85025CB1 +00010203050607080A0B0C0D0F10111214151617191A1B1C 2D33EEF2C0430A8A9EBF45E809C40BB6 DFF4945E0336DF4C1C56BC700EFF837F +1E1F20212324252628292A2B2D2E2F30323334353738393A 6AA375D1FA155A61FB72353E0A5A8756 B6FDDEF4752765E347D5D2DC196D1252 +3C3D3E3F41424344464748494B4C4D4E5051525355565758 BC3736518B9490DCB8ED60EB26758ED4 D23684E3D963B3AFCF1A114ACA90CBD6 +00010203050607080A0B0C0D0F10111214151617191A1B1C1E1F202123242526 834EADFCCAC7E1B30664B1ABA44815AB 1946DABF6A03A2A2C3D0B05080AED6FC +28292A2B2D2E2F30323334353738393A3C3D3E3F41424344464748494B4C4D4E D9DC4DBA3021B05D67C0518F72B62BF1 5ED301D747D3CC715445EBDEC62F2FB4 diff --git a/CryptoPP/crypto/rijndael.h b/CryptoPP/crypto/rijndael.h new file mode 100644 index 0000000..8a2fa77 --- /dev/null +++ b/CryptoPP/crypto/rijndael.h @@ -0,0 +1,61 @@ +#ifndef CRYPTOPP_RIJNDAEL_H +#define CRYPTOPP_RIJNDAEL_H + +/** \file +*/ + +#include "seckey.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! _ +struct Rijndael_Info : public FixedBlockSize<16>, public VariableKeyLength<16, 16, 32, 8> +{ + CRYPTOPP_DLL static const char * CRYPTOPP_API StaticAlgorithmName() {return CRYPTOPP_RIJNDAEL_NAME;} +}; + +/// Rijndael +class CRYPTOPP_DLL Rijndael : public Rijndael_Info, public BlockCipherDocumentation +{ + class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + public: + void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); + + protected: + // VS2005 workaround: have to put these on seperate lines, or error C2487 is triggered in DLL build + static const byte Se[256]; + static const byte Sd[256]; + static const word32 Te[4*256]; + static const word32 Td[4*256]; + + static const word32 rcon[]; + + unsigned int m_rounds; + SecBlock m_key; + }; + + class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef Rijndael::Encryption RijndaelEncryption; +typedef Rijndael::Decryption RijndaelDecryption; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/ripemd.cpp b/CryptoPP/crypto/ripemd.cpp new file mode 100644 index 0000000..16d9778 --- /dev/null +++ b/CryptoPP/crypto/ripemd.cpp @@ -0,0 +1,803 @@ +// ripemd.cpp +// RIPEMD-160 written and placed in the public domain by Wei Dai +// RIPEMD-320, RIPEMD-128, RIPEMD-256 written by Kevin Springle +// and also placed in the public domain + +#include "pch.h" +#include "ripemd.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +#define F(x, y, z) (x ^ y ^ z) +#define G(x, y, z) (z ^ (x & (y^z))) +#define H(x, y, z) (z ^ (x | ~y)) +#define I(x, y, z) (y ^ (z & (x^y))) +#define J(x, y, z) (x ^ (y | ~z)) + +#define k0 0 +#define k1 0x5a827999UL +#define k2 0x6ed9eba1UL +#define k3 0x8f1bbcdcUL +#define k4 0xa953fd4eUL +#define k5 0x50a28be6UL +#define k6 0x5c4dd124UL +#define k7 0x6d703ef3UL +#define k8 0x7a6d76e9UL +#define k9 0 + +// ************************************************************* + +// for 160 and 320 +#define Subround(f, a, b, c, d, e, x, s, k) \ + a += f(b, c, d) + x + k;\ + a = rotlFixed((word32)a, s) + e;\ + c = rotlFixed((word32)c, 10U) + +void RIPEMD160::InitState(HashWordType *state) +{ + state[0] = 0x67452301L; + state[1] = 0xefcdab89L; + state[2] = 0x98badcfeL; + state[3] = 0x10325476L; + state[4] = 0xc3d2e1f0L; +} + +void RIPEMD160::Transform (word32 *digest, const word32 *X) +{ + unsigned long a1, b1, c1, d1, e1, a2, b2, c2, d2, e2; + a1 = a2 = digest[0]; + b1 = b2 = digest[1]; + c1 = c2 = digest[2]; + d1 = d2 = digest[3]; + e1 = e2 = digest[4]; + + Subround(F, a1, b1, c1, d1, e1, X[ 0], 11, k0); + Subround(F, e1, a1, b1, c1, d1, X[ 1], 14, k0); + Subround(F, d1, e1, a1, b1, c1, X[ 2], 15, k0); + Subround(F, c1, d1, e1, a1, b1, X[ 3], 12, k0); + Subround(F, b1, c1, d1, e1, a1, X[ 4], 5, k0); + Subround(F, a1, b1, c1, d1, e1, X[ 5], 8, k0); + Subround(F, e1, a1, b1, c1, d1, X[ 6], 7, k0); + Subround(F, d1, e1, a1, b1, c1, X[ 7], 9, k0); + Subround(F, c1, d1, e1, a1, b1, X[ 8], 11, k0); + Subround(F, b1, c1, d1, e1, a1, X[ 9], 13, k0); + Subround(F, a1, b1, c1, d1, e1, X[10], 14, k0); + Subround(F, e1, a1, b1, c1, d1, X[11], 15, k0); + Subround(F, d1, e1, a1, b1, c1, X[12], 6, k0); + Subround(F, c1, d1, e1, a1, b1, X[13], 7, k0); + Subround(F, b1, c1, d1, e1, a1, X[14], 9, k0); + Subround(F, a1, b1, c1, d1, e1, X[15], 8, k0); + + Subround(G, e1, a1, b1, c1, d1, X[ 7], 7, k1); + Subround(G, d1, e1, a1, b1, c1, X[ 4], 6, k1); + Subround(G, c1, d1, e1, a1, b1, X[13], 8, k1); + Subround(G, b1, c1, d1, e1, a1, X[ 1], 13, k1); + Subround(G, a1, b1, c1, d1, e1, X[10], 11, k1); + Subround(G, e1, a1, b1, c1, d1, X[ 6], 9, k1); + Subround(G, d1, e1, a1, b1, c1, X[15], 7, k1); + Subround(G, c1, d1, e1, a1, b1, X[ 3], 15, k1); + Subround(G, b1, c1, d1, e1, a1, X[12], 7, k1); + Subround(G, a1, b1, c1, d1, e1, X[ 0], 12, k1); + Subround(G, e1, a1, b1, c1, d1, X[ 9], 15, k1); + Subround(G, d1, e1, a1, b1, c1, X[ 5], 9, k1); + Subround(G, c1, d1, e1, a1, b1, X[ 2], 11, k1); + Subround(G, b1, c1, d1, e1, a1, X[14], 7, k1); + Subround(G, a1, b1, c1, d1, e1, X[11], 13, k1); + Subround(G, e1, a1, b1, c1, d1, X[ 8], 12, k1); + + Subround(H, d1, e1, a1, b1, c1, X[ 3], 11, k2); + Subround(H, c1, d1, e1, a1, b1, X[10], 13, k2); + Subround(H, b1, c1, d1, e1, a1, X[14], 6, k2); + Subround(H, a1, b1, c1, d1, e1, X[ 4], 7, k2); + Subround(H, e1, a1, b1, c1, d1, X[ 9], 14, k2); + Subround(H, d1, e1, a1, b1, c1, X[15], 9, k2); + Subround(H, c1, d1, e1, a1, b1, X[ 8], 13, k2); + Subround(H, b1, c1, d1, e1, a1, X[ 1], 15, k2); + Subround(H, a1, b1, c1, d1, e1, X[ 2], 14, k2); + Subround(H, e1, a1, b1, c1, d1, X[ 7], 8, k2); + Subround(H, d1, e1, a1, b1, c1, X[ 0], 13, k2); + Subround(H, c1, d1, e1, a1, b1, X[ 6], 6, k2); + Subround(H, b1, c1, d1, e1, a1, X[13], 5, k2); + Subround(H, a1, b1, c1, d1, e1, X[11], 12, k2); + Subround(H, e1, a1, b1, c1, d1, X[ 5], 7, k2); + Subround(H, d1, e1, a1, b1, c1, X[12], 5, k2); + + Subround(I, c1, d1, e1, a1, b1, X[ 1], 11, k3); + Subround(I, b1, c1, d1, e1, a1, X[ 9], 12, k3); + Subround(I, a1, b1, c1, d1, e1, X[11], 14, k3); + Subround(I, e1, a1, b1, c1, d1, X[10], 15, k3); + Subround(I, d1, e1, a1, b1, c1, X[ 0], 14, k3); + Subround(I, c1, d1, e1, a1, b1, X[ 8], 15, k3); + Subround(I, b1, c1, d1, e1, a1, X[12], 9, k3); + Subround(I, a1, b1, c1, d1, e1, X[ 4], 8, k3); + Subround(I, e1, a1, b1, c1, d1, X[13], 9, k3); + Subround(I, d1, e1, a1, b1, c1, X[ 3], 14, k3); + Subround(I, c1, d1, e1, a1, b1, X[ 7], 5, k3); + Subround(I, b1, c1, d1, e1, a1, X[15], 6, k3); + Subround(I, a1, b1, c1, d1, e1, X[14], 8, k3); + Subround(I, e1, a1, b1, c1, d1, X[ 5], 6, k3); + Subround(I, d1, e1, a1, b1, c1, X[ 6], 5, k3); + Subround(I, c1, d1, e1, a1, b1, X[ 2], 12, k3); + + Subround(J, b1, c1, d1, e1, a1, X[ 4], 9, k4); + Subround(J, a1, b1, c1, d1, e1, X[ 0], 15, k4); + Subround(J, e1, a1, b1, c1, d1, X[ 5], 5, k4); + Subround(J, d1, e1, a1, b1, c1, X[ 9], 11, k4); + Subround(J, c1, d1, e1, a1, b1, X[ 7], 6, k4); + Subround(J, b1, c1, d1, e1, a1, X[12], 8, k4); + Subround(J, a1, b1, c1, d1, e1, X[ 2], 13, k4); + Subround(J, e1, a1, b1, c1, d1, X[10], 12, k4); + Subround(J, d1, e1, a1, b1, c1, X[14], 5, k4); + Subround(J, c1, d1, e1, a1, b1, X[ 1], 12, k4); + Subround(J, b1, c1, d1, e1, a1, X[ 3], 13, k4); + Subround(J, a1, b1, c1, d1, e1, X[ 8], 14, k4); + Subround(J, e1, a1, b1, c1, d1, X[11], 11, k4); + Subround(J, d1, e1, a1, b1, c1, X[ 6], 8, k4); + Subround(J, c1, d1, e1, a1, b1, X[15], 5, k4); + Subround(J, b1, c1, d1, e1, a1, X[13], 6, k4); + + Subround(J, a2, b2, c2, d2, e2, X[ 5], 8, k5); + Subround(J, e2, a2, b2, c2, d2, X[14], 9, k5); + Subround(J, d2, e2, a2, b2, c2, X[ 7], 9, k5); + Subround(J, c2, d2, e2, a2, b2, X[ 0], 11, k5); + Subround(J, b2, c2, d2, e2, a2, X[ 9], 13, k5); + Subround(J, a2, b2, c2, d2, e2, X[ 2], 15, k5); + Subround(J, e2, a2, b2, c2, d2, X[11], 15, k5); + Subround(J, d2, e2, a2, b2, c2, X[ 4], 5, k5); + Subround(J, c2, d2, e2, a2, b2, X[13], 7, k5); + Subround(J, b2, c2, d2, e2, a2, X[ 6], 7, k5); + Subround(J, a2, b2, c2, d2, e2, X[15], 8, k5); + Subround(J, e2, a2, b2, c2, d2, X[ 8], 11, k5); + Subround(J, d2, e2, a2, b2, c2, X[ 1], 14, k5); + Subround(J, c2, d2, e2, a2, b2, X[10], 14, k5); + Subround(J, b2, c2, d2, e2, a2, X[ 3], 12, k5); + Subround(J, a2, b2, c2, d2, e2, X[12], 6, k5); + + Subround(I, e2, a2, b2, c2, d2, X[ 6], 9, k6); + Subround(I, d2, e2, a2, b2, c2, X[11], 13, k6); + Subround(I, c2, d2, e2, a2, b2, X[ 3], 15, k6); + Subround(I, b2, c2, d2, e2, a2, X[ 7], 7, k6); + Subround(I, a2, b2, c2, d2, e2, X[ 0], 12, k6); + Subround(I, e2, a2, b2, c2, d2, X[13], 8, k6); + Subround(I, d2, e2, a2, b2, c2, X[ 5], 9, k6); + Subround(I, c2, d2, e2, a2, b2, X[10], 11, k6); + Subround(I, b2, c2, d2, e2, a2, X[14], 7, k6); + Subround(I, a2, b2, c2, d2, e2, X[15], 7, k6); + Subround(I, e2, a2, b2, c2, d2, X[ 8], 12, k6); + Subround(I, d2, e2, a2, b2, c2, X[12], 7, k6); + Subround(I, c2, d2, e2, a2, b2, X[ 4], 6, k6); + Subround(I, b2, c2, d2, e2, a2, X[ 9], 15, k6); + Subround(I, a2, b2, c2, d2, e2, X[ 1], 13, k6); + Subround(I, e2, a2, b2, c2, d2, X[ 2], 11, k6); + + Subround(H, d2, e2, a2, b2, c2, X[15], 9, k7); + Subround(H, c2, d2, e2, a2, b2, X[ 5], 7, k7); + Subround(H, b2, c2, d2, e2, a2, X[ 1], 15, k7); + Subround(H, a2, b2, c2, d2, e2, X[ 3], 11, k7); + Subround(H, e2, a2, b2, c2, d2, X[ 7], 8, k7); + Subround(H, d2, e2, a2, b2, c2, X[14], 6, k7); + Subround(H, c2, d2, e2, a2, b2, X[ 6], 6, k7); + Subround(H, b2, c2, d2, e2, a2, X[ 9], 14, k7); + Subround(H, a2, b2, c2, d2, e2, X[11], 12, k7); + Subround(H, e2, a2, b2, c2, d2, X[ 8], 13, k7); + Subround(H, d2, e2, a2, b2, c2, X[12], 5, k7); + Subround(H, c2, d2, e2, a2, b2, X[ 2], 14, k7); + Subround(H, b2, c2, d2, e2, a2, X[10], 13, k7); + Subround(H, a2, b2, c2, d2, e2, X[ 0], 13, k7); + Subround(H, e2, a2, b2, c2, d2, X[ 4], 7, k7); + Subround(H, d2, e2, a2, b2, c2, X[13], 5, k7); + + Subround(G, c2, d2, e2, a2, b2, X[ 8], 15, k8); + Subround(G, b2, c2, d2, e2, a2, X[ 6], 5, k8); + Subround(G, a2, b2, c2, d2, e2, X[ 4], 8, k8); + Subround(G, e2, a2, b2, c2, d2, X[ 1], 11, k8); + Subround(G, d2, e2, a2, b2, c2, X[ 3], 14, k8); + Subround(G, c2, d2, e2, a2, b2, X[11], 14, k8); + Subround(G, b2, c2, d2, e2, a2, X[15], 6, k8); + Subround(G, a2, b2, c2, d2, e2, X[ 0], 14, k8); + Subround(G, e2, a2, b2, c2, d2, X[ 5], 6, k8); + Subround(G, d2, e2, a2, b2, c2, X[12], 9, k8); + Subround(G, c2, d2, e2, a2, b2, X[ 2], 12, k8); + Subround(G, b2, c2, d2, e2, a2, X[13], 9, k8); + Subround(G, a2, b2, c2, d2, e2, X[ 9], 12, k8); + Subround(G, e2, a2, b2, c2, d2, X[ 7], 5, k8); + Subround(G, d2, e2, a2, b2, c2, X[10], 15, k8); + Subround(G, c2, d2, e2, a2, b2, X[14], 8, k8); + + Subround(F, b2, c2, d2, e2, a2, X[12], 8, k9); + Subround(F, a2, b2, c2, d2, e2, X[15], 5, k9); + Subround(F, e2, a2, b2, c2, d2, X[10], 12, k9); + Subround(F, d2, e2, a2, b2, c2, X[ 4], 9, k9); + Subround(F, c2, d2, e2, a2, b2, X[ 1], 12, k9); + Subround(F, b2, c2, d2, e2, a2, X[ 5], 5, k9); + Subround(F, a2, b2, c2, d2, e2, X[ 8], 14, k9); + Subround(F, e2, a2, b2, c2, d2, X[ 7], 6, k9); + Subround(F, d2, e2, a2, b2, c2, X[ 6], 8, k9); + Subround(F, c2, d2, e2, a2, b2, X[ 2], 13, k9); + Subround(F, b2, c2, d2, e2, a2, X[13], 6, k9); + Subround(F, a2, b2, c2, d2, e2, X[14], 5, k9); + Subround(F, e2, a2, b2, c2, d2, X[ 0], 15, k9); + Subround(F, d2, e2, a2, b2, c2, X[ 3], 13, k9); + Subround(F, c2, d2, e2, a2, b2, X[ 9], 11, k9); + Subround(F, b2, c2, d2, e2, a2, X[11], 11, k9); + + c1 = digest[1] + c1 + d2; + digest[1] = digest[2] + d1 + e2; + digest[2] = digest[3] + e1 + a2; + digest[3] = digest[4] + a1 + b2; + digest[4] = digest[0] + b1 + c2; + digest[0] = c1; +} + +// ************************************************************* + +void RIPEMD320::InitState(HashWordType *state) +{ + state[0] = 0x67452301L; + state[1] = 0xefcdab89L; + state[2] = 0x98badcfeL; + state[3] = 0x10325476L; + state[4] = 0xc3d2e1f0L; + state[5] = 0x76543210L; + state[6] = 0xfedcba98L; + state[7] = 0x89abcdefL; + state[8] = 0x01234567L; + state[9] = 0x3c2d1e0fL; +} + +void RIPEMD320::Transform (word32 *digest, const word32 *X) +{ + unsigned long a1, b1, c1, d1, e1, a2, b2, c2, d2, e2, t; + a1 = digest[0]; + b1 = digest[1]; + c1 = digest[2]; + d1 = digest[3]; + e1 = digest[4]; + a2 = digest[5]; + b2 = digest[6]; + c2 = digest[7]; + d2 = digest[8]; + e2 = digest[9]; + + Subround(F, a1, b1, c1, d1, e1, X[ 0], 11, k0); + Subround(F, e1, a1, b1, c1, d1, X[ 1], 14, k0); + Subround(F, d1, e1, a1, b1, c1, X[ 2], 15, k0); + Subround(F, c1, d1, e1, a1, b1, X[ 3], 12, k0); + Subround(F, b1, c1, d1, e1, a1, X[ 4], 5, k0); + Subround(F, a1, b1, c1, d1, e1, X[ 5], 8, k0); + Subround(F, e1, a1, b1, c1, d1, X[ 6], 7, k0); + Subround(F, d1, e1, a1, b1, c1, X[ 7], 9, k0); + Subround(F, c1, d1, e1, a1, b1, X[ 8], 11, k0); + Subround(F, b1, c1, d1, e1, a1, X[ 9], 13, k0); + Subround(F, a1, b1, c1, d1, e1, X[10], 14, k0); + Subround(F, e1, a1, b1, c1, d1, X[11], 15, k0); + Subround(F, d1, e1, a1, b1, c1, X[12], 6, k0); + Subround(F, c1, d1, e1, a1, b1, X[13], 7, k0); + Subround(F, b1, c1, d1, e1, a1, X[14], 9, k0); + Subround(F, a1, b1, c1, d1, e1, X[15], 8, k0); + + Subround(J, a2, b2, c2, d2, e2, X[ 5], 8, k5); + Subround(J, e2, a2, b2, c2, d2, X[14], 9, k5); + Subround(J, d2, e2, a2, b2, c2, X[ 7], 9, k5); + Subround(J, c2, d2, e2, a2, b2, X[ 0], 11, k5); + Subround(J, b2, c2, d2, e2, a2, X[ 9], 13, k5); + Subround(J, a2, b2, c2, d2, e2, X[ 2], 15, k5); + Subround(J, e2, a2, b2, c2, d2, X[11], 15, k5); + Subround(J, d2, e2, a2, b2, c2, X[ 4], 5, k5); + Subround(J, c2, d2, e2, a2, b2, X[13], 7, k5); + Subround(J, b2, c2, d2, e2, a2, X[ 6], 7, k5); + Subround(J, a2, b2, c2, d2, e2, X[15], 8, k5); + Subround(J, e2, a2, b2, c2, d2, X[ 8], 11, k5); + Subround(J, d2, e2, a2, b2, c2, X[ 1], 14, k5); + Subround(J, c2, d2, e2, a2, b2, X[10], 14, k5); + Subround(J, b2, c2, d2, e2, a2, X[ 3], 12, k5); + Subround(J, a2, b2, c2, d2, e2, X[12], 6, k5); + + t = a1; a1 = a2; a2 = t; + + Subround(G, e1, a1, b1, c1, d1, X[ 7], 7, k1); + Subround(G, d1, e1, a1, b1, c1, X[ 4], 6, k1); + Subround(G, c1, d1, e1, a1, b1, X[13], 8, k1); + Subround(G, b1, c1, d1, e1, a1, X[ 1], 13, k1); + Subround(G, a1, b1, c1, d1, e1, X[10], 11, k1); + Subround(G, e1, a1, b1, c1, d1, X[ 6], 9, k1); + Subround(G, d1, e1, a1, b1, c1, X[15], 7, k1); + Subround(G, c1, d1, e1, a1, b1, X[ 3], 15, k1); + Subround(G, b1, c1, d1, e1, a1, X[12], 7, k1); + Subround(G, a1, b1, c1, d1, e1, X[ 0], 12, k1); + Subround(G, e1, a1, b1, c1, d1, X[ 9], 15, k1); + Subround(G, d1, e1, a1, b1, c1, X[ 5], 9, k1); + Subround(G, c1, d1, e1, a1, b1, X[ 2], 11, k1); + Subround(G, b1, c1, d1, e1, a1, X[14], 7, k1); + Subround(G, a1, b1, c1, d1, e1, X[11], 13, k1); + Subround(G, e1, a1, b1, c1, d1, X[ 8], 12, k1); + + Subround(I, e2, a2, b2, c2, d2, X[ 6], 9, k6); + Subround(I, d2, e2, a2, b2, c2, X[11], 13, k6); + Subround(I, c2, d2, e2, a2, b2, X[ 3], 15, k6); + Subround(I, b2, c2, d2, e2, a2, X[ 7], 7, k6); + Subround(I, a2, b2, c2, d2, e2, X[ 0], 12, k6); + Subround(I, e2, a2, b2, c2, d2, X[13], 8, k6); + Subround(I, d2, e2, a2, b2, c2, X[ 5], 9, k6); + Subround(I, c2, d2, e2, a2, b2, X[10], 11, k6); + Subround(I, b2, c2, d2, e2, a2, X[14], 7, k6); + Subround(I, a2, b2, c2, d2, e2, X[15], 7, k6); + Subround(I, e2, a2, b2, c2, d2, X[ 8], 12, k6); + Subround(I, d2, e2, a2, b2, c2, X[12], 7, k6); + Subround(I, c2, d2, e2, a2, b2, X[ 4], 6, k6); + Subround(I, b2, c2, d2, e2, a2, X[ 9], 15, k6); + Subround(I, a2, b2, c2, d2, e2, X[ 1], 13, k6); + Subround(I, e2, a2, b2, c2, d2, X[ 2], 11, k6); + + t = b1; b1 = b2; b2 = t; + + Subround(H, d1, e1, a1, b1, c1, X[ 3], 11, k2); + Subround(H, c1, d1, e1, a1, b1, X[10], 13, k2); + Subround(H, b1, c1, d1, e1, a1, X[14], 6, k2); + Subround(H, a1, b1, c1, d1, e1, X[ 4], 7, k2); + Subround(H, e1, a1, b1, c1, d1, X[ 9], 14, k2); + Subround(H, d1, e1, a1, b1, c1, X[15], 9, k2); + Subround(H, c1, d1, e1, a1, b1, X[ 8], 13, k2); + Subround(H, b1, c1, d1, e1, a1, X[ 1], 15, k2); + Subround(H, a1, b1, c1, d1, e1, X[ 2], 14, k2); + Subround(H, e1, a1, b1, c1, d1, X[ 7], 8, k2); + Subround(H, d1, e1, a1, b1, c1, X[ 0], 13, k2); + Subround(H, c1, d1, e1, a1, b1, X[ 6], 6, k2); + Subround(H, b1, c1, d1, e1, a1, X[13], 5, k2); + Subround(H, a1, b1, c1, d1, e1, X[11], 12, k2); + Subround(H, e1, a1, b1, c1, d1, X[ 5], 7, k2); + Subround(H, d1, e1, a1, b1, c1, X[12], 5, k2); + + Subround(H, d2, e2, a2, b2, c2, X[15], 9, k7); + Subround(H, c2, d2, e2, a2, b2, X[ 5], 7, k7); + Subround(H, b2, c2, d2, e2, a2, X[ 1], 15, k7); + Subround(H, a2, b2, c2, d2, e2, X[ 3], 11, k7); + Subround(H, e2, a2, b2, c2, d2, X[ 7], 8, k7); + Subround(H, d2, e2, a2, b2, c2, X[14], 6, k7); + Subround(H, c2, d2, e2, a2, b2, X[ 6], 6, k7); + Subround(H, b2, c2, d2, e2, a2, X[ 9], 14, k7); + Subround(H, a2, b2, c2, d2, e2, X[11], 12, k7); + Subround(H, e2, a2, b2, c2, d2, X[ 8], 13, k7); + Subround(H, d2, e2, a2, b2, c2, X[12], 5, k7); + Subround(H, c2, d2, e2, a2, b2, X[ 2], 14, k7); + Subround(H, b2, c2, d2, e2, a2, X[10], 13, k7); + Subround(H, a2, b2, c2, d2, e2, X[ 0], 13, k7); + Subround(H, e2, a2, b2, c2, d2, X[ 4], 7, k7); + Subround(H, d2, e2, a2, b2, c2, X[13], 5, k7); + + t = c1; c1 = c2; c2 = t; + + Subround(I, c1, d1, e1, a1, b1, X[ 1], 11, k3); + Subround(I, b1, c1, d1, e1, a1, X[ 9], 12, k3); + Subround(I, a1, b1, c1, d1, e1, X[11], 14, k3); + Subround(I, e1, a1, b1, c1, d1, X[10], 15, k3); + Subround(I, d1, e1, a1, b1, c1, X[ 0], 14, k3); + Subround(I, c1, d1, e1, a1, b1, X[ 8], 15, k3); + Subround(I, b1, c1, d1, e1, a1, X[12], 9, k3); + Subround(I, a1, b1, c1, d1, e1, X[ 4], 8, k3); + Subround(I, e1, a1, b1, c1, d1, X[13], 9, k3); + Subround(I, d1, e1, a1, b1, c1, X[ 3], 14, k3); + Subround(I, c1, d1, e1, a1, b1, X[ 7], 5, k3); + Subround(I, b1, c1, d1, e1, a1, X[15], 6, k3); + Subround(I, a1, b1, c1, d1, e1, X[14], 8, k3); + Subround(I, e1, a1, b1, c1, d1, X[ 5], 6, k3); + Subround(I, d1, e1, a1, b1, c1, X[ 6], 5, k3); + Subround(I, c1, d1, e1, a1, b1, X[ 2], 12, k3); + + Subround(G, c2, d2, e2, a2, b2, X[ 8], 15, k8); + Subround(G, b2, c2, d2, e2, a2, X[ 6], 5, k8); + Subround(G, a2, b2, c2, d2, e2, X[ 4], 8, k8); + Subround(G, e2, a2, b2, c2, d2, X[ 1], 11, k8); + Subround(G, d2, e2, a2, b2, c2, X[ 3], 14, k8); + Subround(G, c2, d2, e2, a2, b2, X[11], 14, k8); + Subround(G, b2, c2, d2, e2, a2, X[15], 6, k8); + Subround(G, a2, b2, c2, d2, e2, X[ 0], 14, k8); + Subround(G, e2, a2, b2, c2, d2, X[ 5], 6, k8); + Subround(G, d2, e2, a2, b2, c2, X[12], 9, k8); + Subround(G, c2, d2, e2, a2, b2, X[ 2], 12, k8); + Subround(G, b2, c2, d2, e2, a2, X[13], 9, k8); + Subround(G, a2, b2, c2, d2, e2, X[ 9], 12, k8); + Subround(G, e2, a2, b2, c2, d2, X[ 7], 5, k8); + Subround(G, d2, e2, a2, b2, c2, X[10], 15, k8); + Subround(G, c2, d2, e2, a2, b2, X[14], 8, k8); + + t = d1; d1 = d2; d2 = t; + + Subround(J, b1, c1, d1, e1, a1, X[ 4], 9, k4); + Subround(J, a1, b1, c1, d1, e1, X[ 0], 15, k4); + Subround(J, e1, a1, b1, c1, d1, X[ 5], 5, k4); + Subround(J, d1, e1, a1, b1, c1, X[ 9], 11, k4); + Subround(J, c1, d1, e1, a1, b1, X[ 7], 6, k4); + Subround(J, b1, c1, d1, e1, a1, X[12], 8, k4); + Subround(J, a1, b1, c1, d1, e1, X[ 2], 13, k4); + Subround(J, e1, a1, b1, c1, d1, X[10], 12, k4); + Subround(J, d1, e1, a1, b1, c1, X[14], 5, k4); + Subround(J, c1, d1, e1, a1, b1, X[ 1], 12, k4); + Subround(J, b1, c1, d1, e1, a1, X[ 3], 13, k4); + Subround(J, a1, b1, c1, d1, e1, X[ 8], 14, k4); + Subround(J, e1, a1, b1, c1, d1, X[11], 11, k4); + Subround(J, d1, e1, a1, b1, c1, X[ 6], 8, k4); + Subround(J, c1, d1, e1, a1, b1, X[15], 5, k4); + Subround(J, b1, c1, d1, e1, a1, X[13], 6, k4); + + Subround(F, b2, c2, d2, e2, a2, X[12], 8, k9); + Subround(F, a2, b2, c2, d2, e2, X[15], 5, k9); + Subround(F, e2, a2, b2, c2, d2, X[10], 12, k9); + Subround(F, d2, e2, a2, b2, c2, X[ 4], 9, k9); + Subround(F, c2, d2, e2, a2, b2, X[ 1], 12, k9); + Subround(F, b2, c2, d2, e2, a2, X[ 5], 5, k9); + Subround(F, a2, b2, c2, d2, e2, X[ 8], 14, k9); + Subround(F, e2, a2, b2, c2, d2, X[ 7], 6, k9); + Subround(F, d2, e2, a2, b2, c2, X[ 6], 8, k9); + Subround(F, c2, d2, e2, a2, b2, X[ 2], 13, k9); + Subround(F, b2, c2, d2, e2, a2, X[13], 6, k9); + Subround(F, a2, b2, c2, d2, e2, X[14], 5, k9); + Subround(F, e2, a2, b2, c2, d2, X[ 0], 15, k9); + Subround(F, d2, e2, a2, b2, c2, X[ 3], 13, k9); + Subround(F, c2, d2, e2, a2, b2, X[ 9], 11, k9); + Subround(F, b2, c2, d2, e2, a2, X[11], 11, k9); + + t = e1; e1 = e2; e2 = t; + + digest[0] += a1; + digest[1] += b1; + digest[2] += c1; + digest[3] += d1; + digest[4] += e1; + digest[5] += a2; + digest[6] += b2; + digest[7] += c2; + digest[8] += d2; + digest[9] += e2; +} + +#undef Subround + +// ************************************************************* + +// for 128 and 256 +#define Subround(f, a, b, c, d, x, s, k) \ + a += f(b, c, d) + x + k;\ + a = rotlFixed((word32)a, s); + +void RIPEMD128::InitState(HashWordType *state) +{ + state[0] = 0x67452301L; + state[1] = 0xefcdab89L; + state[2] = 0x98badcfeL; + state[3] = 0x10325476L; +} + +void RIPEMD128::Transform (word32 *digest, const word32 *X) +{ + unsigned long a1, b1, c1, d1, a2, b2, c2, d2; + a1 = a2 = digest[0]; + b1 = b2 = digest[1]; + c1 = c2 = digest[2]; + d1 = d2 = digest[3]; + + Subround(F, a1, b1, c1, d1, X[ 0], 11, k0); + Subround(F, d1, a1, b1, c1, X[ 1], 14, k0); + Subround(F, c1, d1, a1, b1, X[ 2], 15, k0); + Subround(F, b1, c1, d1, a1, X[ 3], 12, k0); + Subround(F, a1, b1, c1, d1, X[ 4], 5, k0); + Subround(F, d1, a1, b1, c1, X[ 5], 8, k0); + Subround(F, c1, d1, a1, b1, X[ 6], 7, k0); + Subround(F, b1, c1, d1, a1, X[ 7], 9, k0); + Subround(F, a1, b1, c1, d1, X[ 8], 11, k0); + Subround(F, d1, a1, b1, c1, X[ 9], 13, k0); + Subround(F, c1, d1, a1, b1, X[10], 14, k0); + Subround(F, b1, c1, d1, a1, X[11], 15, k0); + Subround(F, a1, b1, c1, d1, X[12], 6, k0); + Subround(F, d1, a1, b1, c1, X[13], 7, k0); + Subround(F, c1, d1, a1, b1, X[14], 9, k0); + Subround(F, b1, c1, d1, a1, X[15], 8, k0); + + Subround(G, a1, b1, c1, d1, X[ 7], 7, k1); + Subround(G, d1, a1, b1, c1, X[ 4], 6, k1); + Subround(G, c1, d1, a1, b1, X[13], 8, k1); + Subround(G, b1, c1, d1, a1, X[ 1], 13, k1); + Subround(G, a1, b1, c1, d1, X[10], 11, k1); + Subround(G, d1, a1, b1, c1, X[ 6], 9, k1); + Subround(G, c1, d1, a1, b1, X[15], 7, k1); + Subround(G, b1, c1, d1, a1, X[ 3], 15, k1); + Subround(G, a1, b1, c1, d1, X[12], 7, k1); + Subround(G, d1, a1, b1, c1, X[ 0], 12, k1); + Subround(G, c1, d1, a1, b1, X[ 9], 15, k1); + Subround(G, b1, c1, d1, a1, X[ 5], 9, k1); + Subround(G, a1, b1, c1, d1, X[ 2], 11, k1); + Subround(G, d1, a1, b1, c1, X[14], 7, k1); + Subround(G, c1, d1, a1, b1, X[11], 13, k1); + Subround(G, b1, c1, d1, a1, X[ 8], 12, k1); + + Subround(H, a1, b1, c1, d1, X[ 3], 11, k2); + Subround(H, d1, a1, b1, c1, X[10], 13, k2); + Subround(H, c1, d1, a1, b1, X[14], 6, k2); + Subround(H, b1, c1, d1, a1, X[ 4], 7, k2); + Subround(H, a1, b1, c1, d1, X[ 9], 14, k2); + Subround(H, d1, a1, b1, c1, X[15], 9, k2); + Subround(H, c1, d1, a1, b1, X[ 8], 13, k2); + Subround(H, b1, c1, d1, a1, X[ 1], 15, k2); + Subround(H, a1, b1, c1, d1, X[ 2], 14, k2); + Subround(H, d1, a1, b1, c1, X[ 7], 8, k2); + Subround(H, c1, d1, a1, b1, X[ 0], 13, k2); + Subround(H, b1, c1, d1, a1, X[ 6], 6, k2); + Subround(H, a1, b1, c1, d1, X[13], 5, k2); + Subround(H, d1, a1, b1, c1, X[11], 12, k2); + Subround(H, c1, d1, a1, b1, X[ 5], 7, k2); + Subround(H, b1, c1, d1, a1, X[12], 5, k2); + + Subround(I, a1, b1, c1, d1, X[ 1], 11, k3); + Subround(I, d1, a1, b1, c1, X[ 9], 12, k3); + Subround(I, c1, d1, a1, b1, X[11], 14, k3); + Subround(I, b1, c1, d1, a1, X[10], 15, k3); + Subround(I, a1, b1, c1, d1, X[ 0], 14, k3); + Subround(I, d1, a1, b1, c1, X[ 8], 15, k3); + Subround(I, c1, d1, a1, b1, X[12], 9, k3); + Subround(I, b1, c1, d1, a1, X[ 4], 8, k3); + Subround(I, a1, b1, c1, d1, X[13], 9, k3); + Subround(I, d1, a1, b1, c1, X[ 3], 14, k3); + Subround(I, c1, d1, a1, b1, X[ 7], 5, k3); + Subround(I, b1, c1, d1, a1, X[15], 6, k3); + Subround(I, a1, b1, c1, d1, X[14], 8, k3); + Subround(I, d1, a1, b1, c1, X[ 5], 6, k3); + Subround(I, c1, d1, a1, b1, X[ 6], 5, k3); + Subround(I, b1, c1, d1, a1, X[ 2], 12, k3); + + Subround(I, a2, b2, c2, d2, X[ 5], 8, k5); + Subround(I, d2, a2, b2, c2, X[14], 9, k5); + Subround(I, c2, d2, a2, b2, X[ 7], 9, k5); + Subround(I, b2, c2, d2, a2, X[ 0], 11, k5); + Subround(I, a2, b2, c2, d2, X[ 9], 13, k5); + Subround(I, d2, a2, b2, c2, X[ 2], 15, k5); + Subround(I, c2, d2, a2, b2, X[11], 15, k5); + Subround(I, b2, c2, d2, a2, X[ 4], 5, k5); + Subround(I, a2, b2, c2, d2, X[13], 7, k5); + Subround(I, d2, a2, b2, c2, X[ 6], 7, k5); + Subround(I, c2, d2, a2, b2, X[15], 8, k5); + Subround(I, b2, c2, d2, a2, X[ 8], 11, k5); + Subround(I, a2, b2, c2, d2, X[ 1], 14, k5); + Subround(I, d2, a2, b2, c2, X[10], 14, k5); + Subround(I, c2, d2, a2, b2, X[ 3], 12, k5); + Subround(I, b2, c2, d2, a2, X[12], 6, k5); + + Subround(H, a2, b2, c2, d2, X[ 6], 9, k6); + Subround(H, d2, a2, b2, c2, X[11], 13, k6); + Subround(H, c2, d2, a2, b2, X[ 3], 15, k6); + Subround(H, b2, c2, d2, a2, X[ 7], 7, k6); + Subround(H, a2, b2, c2, d2, X[ 0], 12, k6); + Subround(H, d2, a2, b2, c2, X[13], 8, k6); + Subround(H, c2, d2, a2, b2, X[ 5], 9, k6); + Subround(H, b2, c2, d2, a2, X[10], 11, k6); + Subround(H, a2, b2, c2, d2, X[14], 7, k6); + Subround(H, d2, a2, b2, c2, X[15], 7, k6); + Subround(H, c2, d2, a2, b2, X[ 8], 12, k6); + Subround(H, b2, c2, d2, a2, X[12], 7, k6); + Subround(H, a2, b2, c2, d2, X[ 4], 6, k6); + Subround(H, d2, a2, b2, c2, X[ 9], 15, k6); + Subround(H, c2, d2, a2, b2, X[ 1], 13, k6); + Subround(H, b2, c2, d2, a2, X[ 2], 11, k6); + + Subround(G, a2, b2, c2, d2, X[15], 9, k7); + Subround(G, d2, a2, b2, c2, X[ 5], 7, k7); + Subround(G, c2, d2, a2, b2, X[ 1], 15, k7); + Subround(G, b2, c2, d2, a2, X[ 3], 11, k7); + Subround(G, a2, b2, c2, d2, X[ 7], 8, k7); + Subround(G, d2, a2, b2, c2, X[14], 6, k7); + Subround(G, c2, d2, a2, b2, X[ 6], 6, k7); + Subround(G, b2, c2, d2, a2, X[ 9], 14, k7); + Subround(G, a2, b2, c2, d2, X[11], 12, k7); + Subround(G, d2, a2, b2, c2, X[ 8], 13, k7); + Subround(G, c2, d2, a2, b2, X[12], 5, k7); + Subround(G, b2, c2, d2, a2, X[ 2], 14, k7); + Subround(G, a2, b2, c2, d2, X[10], 13, k7); + Subround(G, d2, a2, b2, c2, X[ 0], 13, k7); + Subround(G, c2, d2, a2, b2, X[ 4], 7, k7); + Subround(G, b2, c2, d2, a2, X[13], 5, k7); + + Subround(F, a2, b2, c2, d2, X[ 8], 15, k9); + Subround(F, d2, a2, b2, c2, X[ 6], 5, k9); + Subround(F, c2, d2, a2, b2, X[ 4], 8, k9); + Subround(F, b2, c2, d2, a2, X[ 1], 11, k9); + Subround(F, a2, b2, c2, d2, X[ 3], 14, k9); + Subround(F, d2, a2, b2, c2, X[11], 14, k9); + Subround(F, c2, d2, a2, b2, X[15], 6, k9); + Subround(F, b2, c2, d2, a2, X[ 0], 14, k9); + Subround(F, a2, b2, c2, d2, X[ 5], 6, k9); + Subround(F, d2, a2, b2, c2, X[12], 9, k9); + Subround(F, c2, d2, a2, b2, X[ 2], 12, k9); + Subround(F, b2, c2, d2, a2, X[13], 9, k9); + Subround(F, a2, b2, c2, d2, X[ 9], 12, k9); + Subround(F, d2, a2, b2, c2, X[ 7], 5, k9); + Subround(F, c2, d2, a2, b2, X[10], 15, k9); + Subround(F, b2, c2, d2, a2, X[14], 8, k9); + + c1 = digest[1] + c1 + d2; + digest[1] = digest[2] + d1 + a2; + digest[2] = digest[3] + a1 + b2; + digest[3] = digest[0] + b1 + c2; + digest[0] = c1; +} + +// ************************************************************* + +void RIPEMD256::InitState(HashWordType *state) +{ + state[0] = 0x67452301L; + state[1] = 0xefcdab89L; + state[2] = 0x98badcfeL; + state[3] = 0x10325476L; + state[4] = 0x76543210L; + state[5] = 0xfedcba98L; + state[6] = 0x89abcdefL; + state[7] = 0x01234567L; +} + +void RIPEMD256::Transform (word32 *digest, const word32 *X) +{ + unsigned long a1, b1, c1, d1, a2, b2, c2, d2, t; + a1 = digest[0]; + b1 = digest[1]; + c1 = digest[2]; + d1 = digest[3]; + a2 = digest[4]; + b2 = digest[5]; + c2 = digest[6]; + d2 = digest[7]; + + Subround(F, a1, b1, c1, d1, X[ 0], 11, k0); + Subround(F, d1, a1, b1, c1, X[ 1], 14, k0); + Subround(F, c1, d1, a1, b1, X[ 2], 15, k0); + Subround(F, b1, c1, d1, a1, X[ 3], 12, k0); + Subround(F, a1, b1, c1, d1, X[ 4], 5, k0); + Subround(F, d1, a1, b1, c1, X[ 5], 8, k0); + Subround(F, c1, d1, a1, b1, X[ 6], 7, k0); + Subround(F, b1, c1, d1, a1, X[ 7], 9, k0); + Subround(F, a1, b1, c1, d1, X[ 8], 11, k0); + Subround(F, d1, a1, b1, c1, X[ 9], 13, k0); + Subround(F, c1, d1, a1, b1, X[10], 14, k0); + Subround(F, b1, c1, d1, a1, X[11], 15, k0); + Subround(F, a1, b1, c1, d1, X[12], 6, k0); + Subround(F, d1, a1, b1, c1, X[13], 7, k0); + Subround(F, c1, d1, a1, b1, X[14], 9, k0); + Subround(F, b1, c1, d1, a1, X[15], 8, k0); + + Subround(I, a2, b2, c2, d2, X[ 5], 8, k5); + Subround(I, d2, a2, b2, c2, X[14], 9, k5); + Subround(I, c2, d2, a2, b2, X[ 7], 9, k5); + Subround(I, b2, c2, d2, a2, X[ 0], 11, k5); + Subround(I, a2, b2, c2, d2, X[ 9], 13, k5); + Subround(I, d2, a2, b2, c2, X[ 2], 15, k5); + Subround(I, c2, d2, a2, b2, X[11], 15, k5); + Subround(I, b2, c2, d2, a2, X[ 4], 5, k5); + Subround(I, a2, b2, c2, d2, X[13], 7, k5); + Subround(I, d2, a2, b2, c2, X[ 6], 7, k5); + Subround(I, c2, d2, a2, b2, X[15], 8, k5); + Subround(I, b2, c2, d2, a2, X[ 8], 11, k5); + Subround(I, a2, b2, c2, d2, X[ 1], 14, k5); + Subround(I, d2, a2, b2, c2, X[10], 14, k5); + Subround(I, c2, d2, a2, b2, X[ 3], 12, k5); + Subround(I, b2, c2, d2, a2, X[12], 6, k5); + + t = a1; a1 = a2; a2 = t; + + Subround(G, a1, b1, c1, d1, X[ 7], 7, k1); + Subround(G, d1, a1, b1, c1, X[ 4], 6, k1); + Subround(G, c1, d1, a1, b1, X[13], 8, k1); + Subround(G, b1, c1, d1, a1, X[ 1], 13, k1); + Subround(G, a1, b1, c1, d1, X[10], 11, k1); + Subround(G, d1, a1, b1, c1, X[ 6], 9, k1); + Subround(G, c1, d1, a1, b1, X[15], 7, k1); + Subround(G, b1, c1, d1, a1, X[ 3], 15, k1); + Subround(G, a1, b1, c1, d1, X[12], 7, k1); + Subround(G, d1, a1, b1, c1, X[ 0], 12, k1); + Subround(G, c1, d1, a1, b1, X[ 9], 15, k1); + Subround(G, b1, c1, d1, a1, X[ 5], 9, k1); + Subround(G, a1, b1, c1, d1, X[ 2], 11, k1); + Subround(G, d1, a1, b1, c1, X[14], 7, k1); + Subround(G, c1, d1, a1, b1, X[11], 13, k1); + Subround(G, b1, c1, d1, a1, X[ 8], 12, k1); + + Subround(H, a2, b2, c2, d2, X[ 6], 9, k6); + Subround(H, d2, a2, b2, c2, X[11], 13, k6); + Subround(H, c2, d2, a2, b2, X[ 3], 15, k6); + Subround(H, b2, c2, d2, a2, X[ 7], 7, k6); + Subround(H, a2, b2, c2, d2, X[ 0], 12, k6); + Subround(H, d2, a2, b2, c2, X[13], 8, k6); + Subround(H, c2, d2, a2, b2, X[ 5], 9, k6); + Subround(H, b2, c2, d2, a2, X[10], 11, k6); + Subround(H, a2, b2, c2, d2, X[14], 7, k6); + Subround(H, d2, a2, b2, c2, X[15], 7, k6); + Subround(H, c2, d2, a2, b2, X[ 8], 12, k6); + Subround(H, b2, c2, d2, a2, X[12], 7, k6); + Subround(H, a2, b2, c2, d2, X[ 4], 6, k6); + Subround(H, d2, a2, b2, c2, X[ 9], 15, k6); + Subround(H, c2, d2, a2, b2, X[ 1], 13, k6); + Subround(H, b2, c2, d2, a2, X[ 2], 11, k6); + + t = b1; b1 = b2; b2 = t; + + Subround(H, a1, b1, c1, d1, X[ 3], 11, k2); + Subround(H, d1, a1, b1, c1, X[10], 13, k2); + Subround(H, c1, d1, a1, b1, X[14], 6, k2); + Subround(H, b1, c1, d1, a1, X[ 4], 7, k2); + Subround(H, a1, b1, c1, d1, X[ 9], 14, k2); + Subround(H, d1, a1, b1, c1, X[15], 9, k2); + Subround(H, c1, d1, a1, b1, X[ 8], 13, k2); + Subround(H, b1, c1, d1, a1, X[ 1], 15, k2); + Subround(H, a1, b1, c1, d1, X[ 2], 14, k2); + Subround(H, d1, a1, b1, c1, X[ 7], 8, k2); + Subround(H, c1, d1, a1, b1, X[ 0], 13, k2); + Subround(H, b1, c1, d1, a1, X[ 6], 6, k2); + Subround(H, a1, b1, c1, d1, X[13], 5, k2); + Subround(H, d1, a1, b1, c1, X[11], 12, k2); + Subround(H, c1, d1, a1, b1, X[ 5], 7, k2); + Subround(H, b1, c1, d1, a1, X[12], 5, k2); + + Subround(G, a2, b2, c2, d2, X[15], 9, k7); + Subround(G, d2, a2, b2, c2, X[ 5], 7, k7); + Subround(G, c2, d2, a2, b2, X[ 1], 15, k7); + Subround(G, b2, c2, d2, a2, X[ 3], 11, k7); + Subround(G, a2, b2, c2, d2, X[ 7], 8, k7); + Subround(G, d2, a2, b2, c2, X[14], 6, k7); + Subround(G, c2, d2, a2, b2, X[ 6], 6, k7); + Subround(G, b2, c2, d2, a2, X[ 9], 14, k7); + Subround(G, a2, b2, c2, d2, X[11], 12, k7); + Subround(G, d2, a2, b2, c2, X[ 8], 13, k7); + Subround(G, c2, d2, a2, b2, X[12], 5, k7); + Subround(G, b2, c2, d2, a2, X[ 2], 14, k7); + Subround(G, a2, b2, c2, d2, X[10], 13, k7); + Subround(G, d2, a2, b2, c2, X[ 0], 13, k7); + Subround(G, c2, d2, a2, b2, X[ 4], 7, k7); + Subround(G, b2, c2, d2, a2, X[13], 5, k7); + + t = c1; c1 = c2; c2 = t; + + Subround(I, a1, b1, c1, d1, X[ 1], 11, k3); + Subround(I, d1, a1, b1, c1, X[ 9], 12, k3); + Subround(I, c1, d1, a1, b1, X[11], 14, k3); + Subround(I, b1, c1, d1, a1, X[10], 15, k3); + Subround(I, a1, b1, c1, d1, X[ 0], 14, k3); + Subround(I, d1, a1, b1, c1, X[ 8], 15, k3); + Subround(I, c1, d1, a1, b1, X[12], 9, k3); + Subround(I, b1, c1, d1, a1, X[ 4], 8, k3); + Subround(I, a1, b1, c1, d1, X[13], 9, k3); + Subround(I, d1, a1, b1, c1, X[ 3], 14, k3); + Subround(I, c1, d1, a1, b1, X[ 7], 5, k3); + Subround(I, b1, c1, d1, a1, X[15], 6, k3); + Subround(I, a1, b1, c1, d1, X[14], 8, k3); + Subround(I, d1, a1, b1, c1, X[ 5], 6, k3); + Subround(I, c1, d1, a1, b1, X[ 6], 5, k3); + Subround(I, b1, c1, d1, a1, X[ 2], 12, k3); + + Subround(F, a2, b2, c2, d2, X[ 8], 15, k9); + Subround(F, d2, a2, b2, c2, X[ 6], 5, k9); + Subround(F, c2, d2, a2, b2, X[ 4], 8, k9); + Subround(F, b2, c2, d2, a2, X[ 1], 11, k9); + Subround(F, a2, b2, c2, d2, X[ 3], 14, k9); + Subround(F, d2, a2, b2, c2, X[11], 14, k9); + Subround(F, c2, d2, a2, b2, X[15], 6, k9); + Subround(F, b2, c2, d2, a2, X[ 0], 14, k9); + Subround(F, a2, b2, c2, d2, X[ 5], 6, k9); + Subround(F, d2, a2, b2, c2, X[12], 9, k9); + Subround(F, c2, d2, a2, b2, X[ 2], 12, k9); + Subround(F, b2, c2, d2, a2, X[13], 9, k9); + Subround(F, a2, b2, c2, d2, X[ 9], 12, k9); + Subround(F, d2, a2, b2, c2, X[ 7], 5, k9); + Subround(F, c2, d2, a2, b2, X[10], 15, k9); + Subround(F, b2, c2, d2, a2, X[14], 8, k9); + + t = d1; d1 = d2; d2 = t; + + digest[0] += a1; + digest[1] += b1; + digest[2] += c1; + digest[3] += d1; + digest[4] += a2; + digest[5] += b2; + digest[6] += c2; + digest[7] += d2; +} + +NAMESPACE_END diff --git a/CryptoPP/crypto/ripemd.h b/CryptoPP/crypto/ripemd.h new file mode 100644 index 0000000..fc7b54d --- /dev/null +++ b/CryptoPP/crypto/ripemd.h @@ -0,0 +1,49 @@ +#ifndef CRYPTOPP_RIPEMD_H +#define CRYPTOPP_RIPEMD_H + +#include "iterhash.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! RIPEMD-160 +/*! Digest Length = 160 bits */ +class RIPEMD160 : public IteratedHashWithStaticTransform +{ +public: + static void InitState(HashWordType *state); + static void Transform(word32 *digest, const word32 *data); + static const char * StaticAlgorithmName() {return "RIPEMD-160";} +}; + +/*! Digest Length = 320 bits, Security is similar to RIPEMD-160 */ +class RIPEMD320 : public IteratedHashWithStaticTransform +{ +public: + static void InitState(HashWordType *state); + static void Transform(word32 *digest, const word32 *data); + static const char * StaticAlgorithmName() {return "RIPEMD-320";} +}; + +/*! \warning RIPEMD-128 is considered insecure, and should not be used + unless you absolutely need it for compatibility. */ +class RIPEMD128 : public IteratedHashWithStaticTransform +{ +public: + static void InitState(HashWordType *state); + static void Transform(word32 *digest, const word32 *data); + static const char * StaticAlgorithmName() {return "RIPEMD-128";} +}; + +/*! \warning RIPEMD-256 is considered insecure, and should not be used + unless you absolutely need it for compatibility. */ +class RIPEMD256 : public IteratedHashWithStaticTransform +{ +public: + static void InitState(HashWordType *state); + static void Transform(word32 *digest, const word32 *data); + static const char * StaticAlgorithmName() {return "RIPEMD-256";} +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/rng.cpp b/CryptoPP/crypto/rng.cpp new file mode 100644 index 0000000..a27974e --- /dev/null +++ b/CryptoPP/crypto/rng.cpp @@ -0,0 +1,155 @@ +// rng.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" + +#include "rng.h" +#include "fips140.h" + +#include +#include + +NAMESPACE_BEGIN(CryptoPP) + +// linear congruential generator +// originally by William S. England + +// do not use for cryptographic purposes + +/* +** Original_numbers are the original published m and q in the +** ACM article above. John Burton has furnished numbers for +** a reportedly better generator. The new numbers are now +** used in this program by default. +*/ + +#ifndef LCRNG_ORIGINAL_NUMBERS +const word32 LC_RNG::m=2147483647L; +const word32 LC_RNG::q=44488L; + +const word16 LC_RNG::a=(unsigned int)48271L; +const word16 LC_RNG::r=3399; +#else +const word32 LC_RNG::m=2147483647L; +const word32 LC_RNG::q=127773L; + +const word16 LC_RNG::a=16807; +const word16 LC_RNG::r=2836; +#endif + +void LC_RNG::GenerateBlock(byte *output, size_t size) +{ + while (size--) + { + word32 hi = seed/q; + word32 lo = seed%q; + + long test = a*lo - r*hi; + + if (test > 0) + seed = test; + else + seed = test+ m; + + *output++ = (GETBYTE(seed, 0) ^ GETBYTE(seed, 1) ^ GETBYTE(seed, 2) ^ GETBYTE(seed, 3)); + } +} + +// ******************************************************** + +#ifndef CRYPTOPP_IMPORTS + +X917RNG::X917RNG(BlockTransformation *c, const byte *seed, const byte *deterministicTimeVector) + : cipher(c), + S(cipher->BlockSize()), + dtbuf(S), + randseed(seed, S), + m_lastBlock(S), + m_deterministicTimeVector(deterministicTimeVector, deterministicTimeVector ? S : 0) +{ + if (!deterministicTimeVector) + { + time_t tstamp1 = time(0); + xorbuf(dtbuf, (byte *)&tstamp1, UnsignedMin(sizeof(tstamp1), S)); + cipher->ProcessBlock(dtbuf); + clock_t tstamp2 = clock(); + xorbuf(dtbuf, (byte *)&tstamp2, UnsignedMin(sizeof(tstamp2), S)); + cipher->ProcessBlock(dtbuf); + } + + // for FIPS 140-2 + GenerateBlock(m_lastBlock, S); +} + +void X917RNG::GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword size) +{ + while (size > 0) + { + // calculate new enciphered timestamp + if (m_deterministicTimeVector.size()) + { + cipher->ProcessBlock(m_deterministicTimeVector, dtbuf); + IncrementCounterByOne(m_deterministicTimeVector, S); + } + else + { + clock_t c = clock(); + xorbuf(dtbuf, (byte *)&c, UnsignedMin(sizeof(c), S)); + time_t t = time(NULL); + xorbuf(dtbuf+S-UnsignedMin(sizeof(t), S), (byte *)&t, UnsignedMin(sizeof(t), S)); + cipher->ProcessBlock(dtbuf); + } + + // combine enciphered timestamp with seed + xorbuf(randseed, dtbuf, S); + + // generate a new block of random bytes + cipher->ProcessBlock(randseed); + if (memcmp(m_lastBlock, randseed, S) == 0) + throw SelfTestFailure("X917RNG: Continuous random number generator test failed."); + + // output random bytes + size_t len = UnsignedMin(S, size); + target.ChannelPut(channel, randseed, len); + size -= len; + + // compute new seed vector + memcpy(m_lastBlock, randseed, S); + xorbuf(randseed, dtbuf, S); + cipher->ProcessBlock(randseed); + } +} + +#endif + +MaurerRandomnessTest::MaurerRandomnessTest() + : sum(0.0), n(0) +{ + for (unsigned i=0; i= Q) + sum += log(double(n - tab[inByte])); + tab[inByte] = n; + n++; + } + return 0; +} + +double MaurerRandomnessTest::GetTestValue() const +{ + if (BytesNeeded() > 0) + throw Exception(Exception::OTHER_ERROR, "MaurerRandomnessTest: " + IntToString(BytesNeeded()) + " more bytes of input needed"); + + double fTu = (sum/(n-Q))/log(2.0); // this is the test value defined by Maurer + + double value = fTu * 0.1392; // arbitrarily normalize it to + return value > 1.0 ? 1.0 : value; // a number between 0 and 1 +} + +NAMESPACE_END diff --git a/CryptoPP/crypto/rng.h b/CryptoPP/crypto/rng.h new file mode 100644 index 0000000..ff4d626 --- /dev/null +++ b/CryptoPP/crypto/rng.h @@ -0,0 +1,77 @@ +// rng.h - misc RNG related classes, see also osrng.h, randpool.h + +#ifndef CRYPTOPP_RNG_H +#define CRYPTOPP_RNG_H + +#include "cryptlib.h" +#include "filters.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! linear congruential generator +/*! originally by William S. England, do not use for cryptographic purposes */ +class LC_RNG : public RandomNumberGenerator +{ +public: + LC_RNG(word32 init_seed) + : seed(init_seed) {} + + void GenerateBlock(byte *output, size_t size); + + word32 GetSeed() {return seed;} + +private: + word32 seed; + + static const word32 m; + static const word32 q; + static const word16 a; + static const word16 r; +}; + +//! RNG derived from ANSI X9.17 Appendix C + +class CRYPTOPP_DLL X917RNG : public RandomNumberGenerator, public NotCopyable +{ +public: + // cipher will be deleted by destructor, deterministicTimeVector = 0 means obtain time vector from system + X917RNG(BlockTransformation *cipher, const byte *seed, const byte *deterministicTimeVector = 0); + + void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword size); + +private: + member_ptr cipher; + unsigned int S; // blocksize of cipher + SecByteBlock dtbuf; // buffer for enciphered timestamp + SecByteBlock randseed, m_lastBlock, m_deterministicTimeVector; +}; + +/** This class implements Maurer's Universal Statistical Test for Random Bit Generators + it is intended for measuring the randomness of *PHYSICAL* RNGs. + For more details see his paper in Journal of Cryptology, 1992. */ + +class MaurerRandomnessTest : public Bufferless +{ +public: + MaurerRandomnessTest(); + + size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking); + + // BytesNeeded() returns how many more bytes of input is needed by the test + // GetTestValue() should not be called before BytesNeeded()==0 + unsigned int BytesNeeded() const {return n >= (Q+K) ? 0 : Q+K-n;} + + // returns a number between 0.0 and 1.0, describing the quality of the + // random numbers entered + double GetTestValue() const; + +private: + enum {L=8, V=256, Q=2000, K=2000}; + double sum; + unsigned int n; + unsigned int tab[V]; +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/rsa.cpp b/CryptoPP/crypto/rsa.cpp new file mode 100644 index 0000000..9793de5 --- /dev/null +++ b/CryptoPP/crypto/rsa.cpp @@ -0,0 +1,304 @@ +// rsa.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "rsa.h" +#include "asn.h" +#include "oids.h" +#include "modarith.h" +#include "nbtheory.h" +#include "sha.h" +#include "algparam.h" +#include "fips140.h" + +#if !defined(NDEBUG) && !defined(CRYPTOPP_IS_DLL) +#include "pssr.h" +NAMESPACE_BEGIN(CryptoPP) +void RSA_TestInstantiations() +{ + RSASS::Verifier x1(1, 1); + RSASS::Signer x2(NullRNG(), 1); + RSASS::Verifier x3(x2); + RSASS::Verifier x4(x2.GetKey()); + RSASS::Verifier x5(x3); +#ifndef __MWERKS__ + RSASS::Signer x6 = x2; + x3 = x2; + x6 = x2; +#endif + RSAES::Encryptor x7(x2); +#ifndef __GNUC__ + RSAES::Encryptor x8(x3); +#endif + RSAES >::Encryptor x9(x2); + + x4 = x2.GetKey(); +} +NAMESPACE_END +#endif + +#ifndef CRYPTOPP_IMPORTS + +NAMESPACE_BEGIN(CryptoPP) + +OID RSAFunction::GetAlgorithmID() const +{ + return ASN1::rsaEncryption(); +} + +void RSAFunction::BERDecodePublicKey(BufferedTransformation &bt, bool, size_t) +{ + BERSequenceDecoder seq(bt); + m_n.BERDecode(seq); + m_e.BERDecode(seq); + seq.MessageEnd(); +} + +void RSAFunction::DEREncodePublicKey(BufferedTransformation &bt) const +{ + DERSequenceEncoder seq(bt); + m_n.DEREncode(seq); + m_e.DEREncode(seq); + seq.MessageEnd(); +} + +Integer RSAFunction::ApplyFunction(const Integer &x) const +{ + DoQuickSanityCheck(); + return a_exp_b_mod_c(x, m_e, m_n); +} + +bool RSAFunction::Validate(RandomNumberGenerator &rng, unsigned int level) const +{ + bool pass = true; + pass = pass && m_n > Integer::One() && m_n.IsOdd(); + pass = pass && m_e > Integer::One() && m_e.IsOdd() && m_e < m_n; + return pass; +} + +bool RSAFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const +{ + return GetValueHelper(this, name, valueType, pValue).Assignable() + CRYPTOPP_GET_FUNCTION_ENTRY(Modulus) + CRYPTOPP_GET_FUNCTION_ENTRY(PublicExponent) + ; +} + +void RSAFunction::AssignFrom(const NameValuePairs &source) +{ + AssignFromHelper(this, source) + CRYPTOPP_SET_FUNCTION_ENTRY(Modulus) + CRYPTOPP_SET_FUNCTION_ENTRY(PublicExponent) + ; +} + +// ***************************************************************************** + +class RSAPrimeSelector : public PrimeSelector +{ +public: + RSAPrimeSelector(const Integer &e) : m_e(e) {} + bool IsAcceptable(const Integer &candidate) const {return RelativelyPrime(m_e, candidate-Integer::One());} + Integer m_e; +}; + +void InvertibleRSAFunction::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg) +{ + int modulusSize = 2048; + alg.GetIntValue(Name::ModulusSize(), modulusSize) || alg.GetIntValue(Name::KeySize(), modulusSize); + + if (modulusSize < 16) + throw InvalidArgument("InvertibleRSAFunction: specified modulus size is too small"); + + m_e = alg.GetValueWithDefault(Name::PublicExponent(), Integer(17)); + + if (m_e < 3 || m_e.IsEven()) + throw InvalidArgument("InvertibleRSAFunction: invalid public exponent"); + + RSAPrimeSelector selector(m_e); + const NameValuePairs &primeParam = MakeParametersForTwoPrimesOfEqualSize(modulusSize) + (Name::PointerToPrimeSelector(), selector.GetSelectorPointer()); + m_p.GenerateRandom(rng, primeParam); + m_q.GenerateRandom(rng, primeParam); + + m_d = EuclideanMultiplicativeInverse(m_e, LCM(m_p-1, m_q-1)); + assert(m_d.IsPositive()); + + m_dp = m_d % (m_p-1); + m_dq = m_d % (m_q-1); + m_n = m_p * m_q; + m_u = m_q.InverseMod(m_p); + + if (FIPS_140_2_ComplianceEnabled()) + { + RSASS::Signer signer(*this); + RSASS::Verifier verifier(signer); + SignaturePairwiseConsistencyTest_FIPS_140_Only(signer, verifier); + + RSAES >::Decryptor decryptor(*this); + RSAES >::Encryptor encryptor(decryptor); + EncryptionPairwiseConsistencyTest_FIPS_140_Only(encryptor, decryptor); + } +} + +void InvertibleRSAFunction::Initialize(RandomNumberGenerator &rng, unsigned int keybits, const Integer &e) +{ + GenerateRandom(rng, MakeParameters(Name::ModulusSize(), (int)keybits)(Name::PublicExponent(), e+e.IsEven())); +} + +void InvertibleRSAFunction::Initialize(const Integer &n, const Integer &e, const Integer &d) +{ + if (n.IsEven() || e.IsEven() | d.IsEven()) + throw InvalidArgument("InvertibleRSAFunction: input is not a valid RSA private key"); + + m_n = n; + m_e = e; + m_d = d; + + Integer r = --(d*e); + unsigned int s = 0; + while (r.IsEven()) + { + r >>= 1; + s++; + } + + ModularArithmetic modn(n); + for (Integer i = 2; ; ++i) + { + Integer a = modn.Exponentiate(i, r); + if (a == 1) + continue; + Integer b; + unsigned int j = 0; + while (a != n-1) + { + b = modn.Square(a); + if (b == 1) + { + m_p = GCD(a-1, n); + m_q = n/m_p; + m_dp = m_d % (m_p-1); + m_dq = m_d % (m_q-1); + m_u = m_q.InverseMod(m_p); + return; + } + if (++j == s) + throw InvalidArgument("InvertibleRSAFunction: input is not a valid RSA private key"); + a = b; + } + } +} + +void InvertibleRSAFunction::BERDecodePrivateKey(BufferedTransformation &bt, bool, size_t) +{ + BERSequenceDecoder privateKey(bt); + word32 version; + BERDecodeUnsigned(privateKey, version, INTEGER, 0, 0); // check version + m_n.BERDecode(privateKey); + m_e.BERDecode(privateKey); + m_d.BERDecode(privateKey); + m_p.BERDecode(privateKey); + m_q.BERDecode(privateKey); + m_dp.BERDecode(privateKey); + m_dq.BERDecode(privateKey); + m_u.BERDecode(privateKey); + privateKey.MessageEnd(); +} + +void InvertibleRSAFunction::DEREncodePrivateKey(BufferedTransformation &bt) const +{ + DERSequenceEncoder privateKey(bt); + DEREncodeUnsigned(privateKey, 0); // version + m_n.DEREncode(privateKey); + m_e.DEREncode(privateKey); + m_d.DEREncode(privateKey); + m_p.DEREncode(privateKey); + m_q.DEREncode(privateKey); + m_dp.DEREncode(privateKey); + m_dq.DEREncode(privateKey); + m_u.DEREncode(privateKey); + privateKey.MessageEnd(); +} + +Integer InvertibleRSAFunction::CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const +{ + DoQuickSanityCheck(); + ModularArithmetic modn(m_n); + Integer r, rInv; + do { // do this in a loop for people using small numbers for testing + r.Randomize(rng, Integer::One(), m_n - Integer::One()); + rInv = modn.MultiplicativeInverse(r); + } while (rInv.IsZero()); + Integer re = modn.Exponentiate(r, m_e); + re = modn.Multiply(re, x); // blind + // here we follow the notation of PKCS #1 and let u=q inverse mod p + // but in ModRoot, u=p inverse mod q, so we reverse the order of p and q + Integer y = ModularRoot(re, m_dq, m_dp, m_q, m_p, m_u); + y = modn.Multiply(y, rInv); // unblind + if (modn.Exponentiate(y, m_e) != x) // check + throw Exception(Exception::OTHER_ERROR, "InvertibleRSAFunction: computational error during private key operation"); + return y; +} + +bool InvertibleRSAFunction::Validate(RandomNumberGenerator &rng, unsigned int level) const +{ + bool pass = RSAFunction::Validate(rng, level); + pass = pass && m_p > Integer::One() && m_p.IsOdd() && m_p < m_n; + pass = pass && m_q > Integer::One() && m_q.IsOdd() && m_q < m_n; + pass = pass && m_d > Integer::One() && m_d.IsOdd() && m_d < m_n; + pass = pass && m_dp > Integer::One() && m_dp.IsOdd() && m_dp < m_p; + pass = pass && m_dq > Integer::One() && m_dq.IsOdd() && m_dq < m_q; + pass = pass && m_u.IsPositive() && m_u < m_p; + if (level >= 1) + { + pass = pass && m_p * m_q == m_n; + pass = pass && m_e*m_d % LCM(m_p-1, m_q-1) == 1; + pass = pass && m_dp == m_d%(m_p-1) && m_dq == m_d%(m_q-1); + pass = pass && m_u * m_q % m_p == 1; + } + if (level >= 2) + pass = pass && VerifyPrime(rng, m_p, level-2) && VerifyPrime(rng, m_q, level-2); + return pass; +} + +bool InvertibleRSAFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const +{ + return GetValueHelper(this, name, valueType, pValue).Assignable() + CRYPTOPP_GET_FUNCTION_ENTRY(Prime1) + CRYPTOPP_GET_FUNCTION_ENTRY(Prime2) + CRYPTOPP_GET_FUNCTION_ENTRY(PrivateExponent) + CRYPTOPP_GET_FUNCTION_ENTRY(ModPrime1PrivateExponent) + CRYPTOPP_GET_FUNCTION_ENTRY(ModPrime2PrivateExponent) + CRYPTOPP_GET_FUNCTION_ENTRY(MultiplicativeInverseOfPrime2ModPrime1) + ; +} + +void InvertibleRSAFunction::AssignFrom(const NameValuePairs &source) +{ + AssignFromHelper(this, source) + CRYPTOPP_SET_FUNCTION_ENTRY(Prime1) + CRYPTOPP_SET_FUNCTION_ENTRY(Prime2) + CRYPTOPP_SET_FUNCTION_ENTRY(PrivateExponent) + CRYPTOPP_SET_FUNCTION_ENTRY(ModPrime1PrivateExponent) + CRYPTOPP_SET_FUNCTION_ENTRY(ModPrime2PrivateExponent) + CRYPTOPP_SET_FUNCTION_ENTRY(MultiplicativeInverseOfPrime2ModPrime1) + ; +} + +// ***************************************************************************** + +Integer RSAFunction_ISO::ApplyFunction(const Integer &x) const +{ + Integer t = RSAFunction::ApplyFunction(x); + return t % 16 == 12 ? t : m_n - t; +} + +Integer InvertibleRSAFunction_ISO::CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const +{ + Integer t = InvertibleRSAFunction::CalculateInverse(rng, x); + return STDMIN(t, m_n-t); +} + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/rsa.h b/CryptoPP/crypto/rsa.h new file mode 100644 index 0000000..cc8a1bb --- /dev/null +++ b/CryptoPP/crypto/rsa.h @@ -0,0 +1,174 @@ +#ifndef CRYPTOPP_RSA_H +#define CRYPTOPP_RSA_H + +/** \file + This file contains classes that implement the RSA + ciphers and signature schemes as defined in PKCS #1 v2.0. +*/ + +#include "pubkey.h" +#include "asn.h" +#include "pkcspad.h" +#include "oaep.h" +#include "emsa2.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! _ +class CRYPTOPP_DLL RSAFunction : public TrapdoorFunction, public X509PublicKey +{ + typedef RSAFunction ThisClass; + +public: + void Initialize(const Integer &n, const Integer &e) + {m_n = n; m_e = e;} + + // X509PublicKey + OID GetAlgorithmID() const; + void BERDecodePublicKey(BufferedTransformation &bt, bool parametersPresent, size_t size); + void DEREncodePublicKey(BufferedTransformation &bt) const; + + // CryptoMaterial + bool Validate(RandomNumberGenerator &rng, unsigned int level) const; + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; + void AssignFrom(const NameValuePairs &source); + + // TrapdoorFunction + Integer ApplyFunction(const Integer &x) const; + Integer PreimageBound() const {return m_n;} + Integer ImageBound() const {return m_n;} + + // non-derived + const Integer & GetModulus() const {return m_n;} + const Integer & GetPublicExponent() const {return m_e;} + + void SetModulus(const Integer &n) {m_n = n;} + void SetPublicExponent(const Integer &e) {m_e = e;} + +protected: + Integer m_n, m_e; +}; + +//! _ +class CRYPTOPP_DLL InvertibleRSAFunction : public RSAFunction, public TrapdoorFunctionInverse, public PKCS8PrivateKey +{ + typedef InvertibleRSAFunction ThisClass; + +public: + void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits, const Integer &e = 17); + void Initialize(const Integer &n, const Integer &e, const Integer &d, const Integer &p, const Integer &q, const Integer &dp, const Integer &dq, const Integer &u) + {m_n = n; m_e = e; m_d = d; m_p = p; m_q = q; m_dp = dp; m_dq = dq; m_u = u;} + //! factor n given private exponent + void Initialize(const Integer &n, const Integer &e, const Integer &d); + + // PKCS8PrivateKey + void BERDecode(BufferedTransformation &bt) + {PKCS8PrivateKey::BERDecode(bt);} + void DEREncode(BufferedTransformation &bt) const + {PKCS8PrivateKey::DEREncode(bt);} + void Load(BufferedTransformation &bt) + {PKCS8PrivateKey::BERDecode(bt);} + void Save(BufferedTransformation &bt) const + {PKCS8PrivateKey::DEREncode(bt);} + OID GetAlgorithmID() const {return RSAFunction::GetAlgorithmID();} + void BERDecodePrivateKey(BufferedTransformation &bt, bool parametersPresent, size_t size); + void DEREncodePrivateKey(BufferedTransformation &bt) const; + + // TrapdoorFunctionInverse + Integer CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const; + + // GeneratableCryptoMaterial + bool Validate(RandomNumberGenerator &rng, unsigned int level) const; + /*! parameters: (ModulusSize, PublicExponent (default 17)) */ + void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg); + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; + void AssignFrom(const NameValuePairs &source); + + // non-derived interface + const Integer& GetPrime1() const {return m_p;} + const Integer& GetPrime2() const {return m_q;} + const Integer& GetPrivateExponent() const {return m_d;} + const Integer& GetModPrime1PrivateExponent() const {return m_dp;} + const Integer& GetModPrime2PrivateExponent() const {return m_dq;} + const Integer& GetMultiplicativeInverseOfPrime2ModPrime1() const {return m_u;} + + void SetPrime1(const Integer &p) {m_p = p;} + void SetPrime2(const Integer &q) {m_q = q;} + void SetPrivateExponent(const Integer &d) {m_d = d;} + void SetModPrime1PrivateExponent(const Integer &dp) {m_dp = dp;} + void SetModPrime2PrivateExponent(const Integer &dq) {m_dq = dq;} + void SetMultiplicativeInverseOfPrime2ModPrime1(const Integer &u) {m_u = u;} + +protected: + Integer m_d, m_p, m_q, m_dp, m_dq, m_u; +}; + +class CRYPTOPP_DLL RSAFunction_ISO : public RSAFunction +{ +public: + Integer ApplyFunction(const Integer &x) const; + Integer PreimageBound() const {return ++(m_n>>1);} +}; + +class CRYPTOPP_DLL InvertibleRSAFunction_ISO : public InvertibleRSAFunction +{ +public: + Integer CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const; + Integer PreimageBound() const {return ++(m_n>>1);} +}; + +//! RSA +struct CRYPTOPP_DLL RSA +{ + static const char * CRYPTOPP_API StaticAlgorithmName() {return "RSA";} + typedef RSAFunction PublicKey; + typedef InvertibleRSAFunction PrivateKey; +}; + +//! RSA cryptosystem +template +struct RSAES : public TF_ES +{ +}; + +//! RSA signature scheme with appendix +/*! See documentation of PKCS1v15 for a list of hash functions that can be used with it. */ +template +struct RSASS : public TF_SS +{ +}; + +struct CRYPTOPP_DLL RSA_ISO +{ + static const char * CRYPTOPP_API StaticAlgorithmName() {return "RSA-ISO";} + typedef RSAFunction_ISO PublicKey; + typedef InvertibleRSAFunction_ISO PrivateKey; +}; + +template +struct RSASS_ISO : public TF_SS +{ +}; + +// The two RSA encryption schemes defined in PKCS #1 v2.0 +typedef RSAES::Decryptor RSAES_PKCS1v15_Decryptor; +typedef RSAES::Encryptor RSAES_PKCS1v15_Encryptor; + +typedef RSAES >::Decryptor RSAES_OAEP_SHA_Decryptor; +typedef RSAES >::Encryptor RSAES_OAEP_SHA_Encryptor; + +// The three RSA signature schemes defined in PKCS #1 v2.0 +typedef RSASS::Signer RSASSA_PKCS1v15_SHA_Signer; +typedef RSASS::Verifier RSASSA_PKCS1v15_SHA_Verifier; + +namespace Weak { +typedef RSASS::Signer RSASSA_PKCS1v15_MD2_Signer; +typedef RSASS::Verifier RSASSA_PKCS1v15_MD2_Verifier; + +typedef RSASS::Signer RSASSA_PKCS1v15_MD5_Signer; +typedef RSASS::Verifier RSASSA_PKCS1v15_MD5_Verifier; +} + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/rsa1024.dat b/CryptoPP/crypto/rsa1024.dat new file mode 100644 index 0000000..92b99f4 --- /dev/null +++ b/CryptoPP/crypto/rsa1024.dat @@ -0,0 +1,32 @@ +30820274020100300D06092A864886F70D010101 +05000482025E3082025A02010002818100A39D4F +72D1BCFF65A47545C2897C0464CE9181E8703421 +2EC04407C4C24D569AA20C58B8138C85E17510BC +6B861CADA9034C3ECE3B050B546E97D2BDC07A07 +CF8A612F7D3646739633041893EF18C411264E45 +C9E033A1BD5EE5FA02D95E9A9ADA2D0C6DF480E3 +2FA3FCE02889798455CE53F084AAB4C5549266F7 +CE8C77DF1D0201110281800E6FC33ED64561D443 +378627C0D63C9F7BA36D584622B7A23E241ECD98 +AC78952C6A804C7A320BD020EAE372E62FB4F853 +1D50D5F6261796823A929845B06A19B35A5227CB +C819852A9CBE588CC2D1CEE07F426D13C2BF2FCA +1C99FDEEFDFE387859E2B3F654E85A71481A71E9 +D5256583B1200F29C1AA0F437CFDC2AEAF218102 +4100D5DDB104AD074F6C1B8192D9AC8AED4DE05C +F5C6509490DA8CCFC91FDF7B3A1323E03894DCAA +B2587716D652A56904F86244E10C1B8FA597C389 +2591C55DBD65024100C3D930B583B8AD9A349218 +795C988CF0004F09DA04FFEF6FDF7CB4FA654F74 +B262521FE185693CD6290A337589F62CDEECE24E +CCB5E79865275540F3B603FB59024064A48F89BA +D6437E2B0FCCA2AB8CABE86995285D5318BCA315 +167CC3B47639726B3C56DCA41417B128FBB026E4 +6DA7FC6A7AC441EEDA2FCEF29AE480D5594A1102 +40228FBD4D355CD35772B05EAC014818DF0F1D01 +BD0FF0EE04AEF7E3B3B7867E015CA514AF53C746 +F89DD49FAB5494DABDED9159332F28DEA8705A56 +C198974A79024100D1DCA40FBD19036F0E2A9438 +7D03C090DDF0A677CDE0B8634A81F247752A355E +C1CEA2482A4887767145C2BA703C9C10228FDA1E +BB2EBEA73D23AA9C34182179 diff --git a/CryptoPP/crypto/rsa2048.dat b/CryptoPP/crypto/rsa2048.dat new file mode 100644 index 0000000..9b39ea3 --- /dev/null +++ b/CryptoPP/crypto/rsa2048.dat @@ -0,0 +1,61 @@ +308204BB020100300D06092A864886F70D010101 +0500048204A5308204A10201000282010100BB25 +80EB6B368287A0A3BDDF6AAA9EDA2EEF15D92C5F +E0B1C21473175C39B685A6FB0B0DB611092C19B4 +FA3CA5BB20F311E35B2E1097F48B077DF7684BEB +9A34EB78C7B5F02ADFAEA3F3A66F1EF91B0C47DE +68F0501F80A7E9603F794E928949F152C049A011 +D7E58C72F9303781E4FE7129DD7B87B5448D440A +62CE8E9C801F245039E2724A9C37CB17457950B7 +B3C4C9BE4D17A29EFC1EA1EF464FBD21DABE9F10 +ED0EB132405D68E4304008083BB675DA97CB6219 +147A1EB93D38A9C4023540F871272A85B45447B3 +6DE9A708E412CD31B1CB6470E4A37CBEA6000F36 +632DF86FD3C34466C63BD80F1350E4DD5081597F +F34F94F07AE6430DCC0563B1F7CF020111028201 +00034D763A5DC03580E33616ED5ABABA855B2E62 +4495DD8D002009656B5473772C85F55F10CE81CE +77BE31E04657410B1F6535B4CF1E6914E152F4AB +84DA2FD409F81BBB3DF0A96A58EACC9501F60162 +5C1356BF97D139C78A7E18496708EA7DE7B47266 +C81363B3FF888085E7403A028901FF3BA04C2EDE +930EC0EFAC4DCF8FD054C1119562A1C7CA455D79 +36CB95A16CE611ABC97918961DE6720CE171CC69 +A590E9A041EC1DAC6FDCF2E04946C100E03DEFCA +29FF480C926CD48589EB832D4476CF38AB320754 +D97BE77FDB9E5F2DCA1A2ABBC33D0790FE8C22CF +694BB8E0265733A5A17CC5D07DB54515DC80216A +A23A43EB12783888FF424EDB26FAF7DCB9028181 +00EB4C87F67AEA3F2047BF9DF61947DF2BA7E1C1 +64A03A8E3ED5F3BC6CDEE99FC6251C6A28F9502F +0A4B5A0CFA8038A12A2270AAE2C9342EDBA207CE +0F170B6D07550670CFEAE730B9411E66CD2D485F +3FC3E9C5348D32C768F68A53C756E66BE0FAC7E8 +FDC9FBE22644961782DA5DDC19D75B64D2E8B660 +052DDC95AD186633E902818100CB9C7830223B78 +FC28A6D2B77C50C3D389F32FC4DEF33341741205 +5102F8D852663DB44E1EA5E5E58A71D30D33C168 +E94855D79CC19CC7DFBAFBDFF7710490064A1375 +1CD75466219956B9D4C0AF0CC13E7D075F54E6AF +8CD67FBE3F4AB90425B039410686A168421E2E24 +FF0319D9D3F1C685BB650BC7B5BD12090CBDC392 +F702818060E3470B238DA185C330C89282E15BE4 +CCA84092D89094ECB2736BB45BC99C2469A249D4 +A2E4C8134C34237634CC06206888BED5DA60C800 +158ABE4272E6964E502FD41960B98C888439B1DC +039645567DD8BA9D2B14E8B2BFDE9AF7BA5EE120 +674341D1E9C211D385A736DB871796DD76CB47A2 +239663C5E5B52E9291937EC902818053D704500E +187D1C8935A20F514E6EC08418D76F2EA060663E +DA3E6CA6DEEFA97564B3A7B2444F9AC08938C933 +6DC1C9782358C8137CCAC5893A8965E33E1D2FC4 +262129FE4FEDD1997E10488B935F9ADD7EC6CCE6 +B957581C167B83791F01B52A71ED99467EB27593 +F4E20EA6EC86DECCF7643E1A8C614AD561C77DB7 +8CC40B02818100AF950A287679E6C55020400E8A +AD0642DB1C11D9AD5AE85F1B6FD2829D869453C9 +F67C0210D0847A4BD47C57FAECD9BE540BD66989 +E6C43F62D725B3D841B4F1DB7C28A722337358C8 +D1CD55F5CA6E31FAD6F827756BA074944D345C8D +2FCE759F4244B948D06F5AC863DEAAEF279B2F69 +955ADAD1F39DEA9DA028B94EF22F11 diff --git a/CryptoPP/crypto/rsa400pb.dat b/CryptoPP/crypto/rsa400pb.dat new file mode 100644 index 0000000..08c69eb --- /dev/null +++ b/CryptoPP/crypto/rsa400pb.dat @@ -0,0 +1,10 @@ +30 4c 30 0d 06 09 2a 86 +48 86 f7 0d 01 01 01 05 +00 03 3b 00 30 38 02 33 +00 a3 07 9a 90 df 0d fd +72 ac 09 0c cc 2a 78 b8 +74 13 13 3e 40 75 9c 98 +fa f8 20 4f 35 8a 0b 26 +3c 67 70 e7 83 a9 3b 69 +71 b7 37 79 d2 71 7b e8 +34 77 cf 02 01 03 diff --git a/CryptoPP/crypto/rsa400pv.dat b/CryptoPP/crypto/rsa400pv.dat new file mode 100644 index 0000000..f49cf37 --- /dev/null +++ b/CryptoPP/crypto/rsa400pv.dat @@ -0,0 +1,41 @@ + 30 81 fb + 02 01 00 + 02 + 33 00 a3 07 9a 90 df 0d + fd 72 ac 09 0c cc 2a 78 + b8 74 13 13 3e 40 75 9c + 98 fa f8 20 4f 35 8a 0b + 26 3c 67 70 e7 83 a9 3b + 69 71 b7 37 79 d2 71 7b + e8 34 77 cf + 02 01 03 + 02 + 32 6c af bc 60 94 b3 fe + 4c 72 b0 b3 32 c6 fb 25 + a2 b7 62 29 80 4e 68 65 + fc a4 5a 74 df 0f 8f b8 + 41 3b 52 c0 d0 e5 3d 9b + 59 0f f1 9b e7 9f 49 dd + 21 e5 eb + 02 1a 00 cf 20 + 35 02 8b 9d 86 98 40 b4 + 16 66 b4 2e 92 ea 0d a3 + b4 32 04 b5 cf ce 91 + 02 + 1a 00 c9 7f b1 f0 27 f4 + 53 f6 34 12 33 ea aa d1 + d9 35 3f 6c 42 d0 88 66 + b1 d0 5f + 02 1a 00 8a 15 + 78 ac 5d 13 af 10 2b 22 + b9 99 cd 74 61 f1 5e 6d + 22 cc 03 23 df df 0b + 02 + 1a 00 86 55 21 4a c5 4d + 8d 4e cd 61 77 f1 c7 36 + 90 ce 2a 48 2c 8b 05 99 + cb e0 3f + 02 1a 00 83 ef + ef b8 a9 a4 0d 1d b6 ed + 98 ad 84 ed 13 35 dc c1 + 08 f3 22 d0 57 cf 8d \ No newline at end of file diff --git a/CryptoPP/crypto/rsa512a.dat b/CryptoPP/crypto/rsa512a.dat new file mode 100644 index 0000000..2cbc1e6 --- /dev/null +++ b/CryptoPP/crypto/rsa512a.dat @@ -0,0 +1,35 @@ +30 82 01 50 + 02 01 00 + 30 0d + 06 09 + 2a 86 48 86 f7 0d 01 01 01 + 05 00 + 04 82 01 3a + 30 82 01 36 + 02 01 00 + 02 40 + 0a 66 79 1d c6 98 81 68 de 7a b7 74 19 bb 7f b0 + c0 01 c6 27 10 27 00 75 14 29 42 e1 9a 8d 8c 51 + d0 53 b3 e3 78 2a 1d e5 dc 5a f4 eb e9 94 68 17 + 01 14 a1 df e6 7c dc 9a 9a f5 5d 65 56 20 bb ab + 02 03 01 00 01 + 02 40 + 01 23 c5 b6 1b a3 6e db 1d 36 79 90 41 99 a8 9e + a8 0c 09 b9 12 2e 14 00 c0 9a dc f7 78 46 76 d0 + 1d 23 35 6a 7d 44 d6 bd 8b d5 0e 94 bf c7 23 fa + 87 d8 86 2b 75 17 76 91 c1 1d 75 76 92 df 88 81 + 02 20 + 33 d4 84 45 c8 59 e5 23 40 de 70 4b cd da 06 5f + bb 40 58 d7 40 bd 1d 67 d2 9e 9c 14 6c 11 cf 61 + 02 20 + 33 5e 84 08 86 6b 0f d3 8d c7 00 2d 3f 97 2c 67 + 38 9a 65 d5 d8 30 65 66 d5 c4 f2 a5 aa 52 62 8b + 02 20 + 04 5e c9 00 71 52 53 25 d3 d4 6d b7 96 95 e9 af + ac c4 52 39 64 36 0e 02 b1 19 ba a3 66 31 62 41 + 02 20 + 15 eb 32 73 60 c7 b6 0d 12 e5 e2 d1 6b dc d9 79 + 81 d1 7f ba 6b 70 db 13 b2 0b 43 6e 24 ea da 59 + 02 20 + 2c a6 36 6d 72 78 1d fa 24 d3 4a 9a 24 cb c2 ae + 92 7a 99 58 af 42 65 63 ff 63 fb 11 65 8a 46 1d diff --git a/CryptoPP/crypto/rw.cpp b/CryptoPP/crypto/rw.cpp new file mode 100644 index 0000000..b8d1359 --- /dev/null +++ b/CryptoPP/crypto/rw.cpp @@ -0,0 +1,196 @@ +// rw.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "rw.h" +#include "nbtheory.h" +#include "asn.h" + +#ifndef CRYPTOPP_IMPORTS + +NAMESPACE_BEGIN(CryptoPP) + +void RWFunction::BERDecode(BufferedTransformation &bt) +{ + BERSequenceDecoder seq(bt); + m_n.BERDecode(seq); + seq.MessageEnd(); +} + +void RWFunction::DEREncode(BufferedTransformation &bt) const +{ + DERSequenceEncoder seq(bt); + m_n.DEREncode(seq); + seq.MessageEnd(); +} + +Integer RWFunction::ApplyFunction(const Integer &in) const +{ + DoQuickSanityCheck(); + + Integer out = in.Squared()%m_n; + const word r = 12; + // this code was written to handle both r = 6 and r = 12, + // but now only r = 12 is used in P1363 + const word r2 = r/2; + const word r3a = (16 + 5 - r) % 16; // n%16 could be 5 or 13 + const word r3b = (16 + 13 - r) % 16; + const word r4 = (8 + 5 - r/2) % 8; // n%8 == 5 + switch (out % 16) + { + case r: + break; + case r2: + case r2+8: + out <<= 1; + break; + case r3a: + case r3b: + out.Negate(); + out += m_n; + break; + case r4: + case r4+8: + out.Negate(); + out += m_n; + out <<= 1; + break; + default: + out = Integer::Zero(); + } + return out; +} + +bool RWFunction::Validate(RandomNumberGenerator &rng, unsigned int level) const +{ + bool pass = true; + pass = pass && m_n > Integer::One() && m_n%8 == 5; + return pass; +} + +bool RWFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const +{ + return GetValueHelper(this, name, valueType, pValue).Assignable() + CRYPTOPP_GET_FUNCTION_ENTRY(Modulus) + ; +} + +void RWFunction::AssignFrom(const NameValuePairs &source) +{ + AssignFromHelper(this, source) + CRYPTOPP_SET_FUNCTION_ENTRY(Modulus) + ; +} + +// ***************************************************************************** +// private key operations: + +// generate a random private key +void InvertibleRWFunction::GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg) +{ + int modulusSize = 2048; + alg.GetIntValue("ModulusSize", modulusSize) || alg.GetIntValue("KeySize", modulusSize); + + if (modulusSize < 16) + throw InvalidArgument("InvertibleRWFunction: specified modulus length is too small"); + + const NameValuePairs &primeParam = MakeParametersForTwoPrimesOfEqualSize(modulusSize); + m_p.GenerateRandom(rng, CombinedNameValuePairs(primeParam, MakeParameters("EquivalentTo", 3)("Mod", 8))); + m_q.GenerateRandom(rng, CombinedNameValuePairs(primeParam, MakeParameters("EquivalentTo", 7)("Mod", 8))); + + m_n = m_p * m_q; + m_u = m_q.InverseMod(m_p); +} + +void InvertibleRWFunction::BERDecode(BufferedTransformation &bt) +{ + BERSequenceDecoder seq(bt); + m_n.BERDecode(seq); + m_p.BERDecode(seq); + m_q.BERDecode(seq); + m_u.BERDecode(seq); + seq.MessageEnd(); +} + +void InvertibleRWFunction::DEREncode(BufferedTransformation &bt) const +{ + DERSequenceEncoder seq(bt); + m_n.DEREncode(seq); + m_p.DEREncode(seq); + m_q.DEREncode(seq); + m_u.DEREncode(seq); + seq.MessageEnd(); +} + +Integer InvertibleRWFunction::CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const +{ + DoQuickSanityCheck(); + ModularArithmetic modn(m_n); + Integer r, rInv; + do { // do this in a loop for people using small numbers for testing + r.Randomize(rng, Integer::One(), m_n - Integer::One()); + rInv = modn.MultiplicativeInverse(r); + } while (rInv.IsZero()); + Integer re = modn.Square(r); + re = modn.Multiply(re, x); // blind + + Integer cp=re%m_p, cq=re%m_q; + if (Jacobi(cp, m_p) * Jacobi(cq, m_q) != 1) + { + cp = cp.IsOdd() ? (cp+m_p) >> 1 : cp >> 1; + cq = cq.IsOdd() ? (cq+m_q) >> 1 : cq >> 1; + } + + #pragma omp parallel + #pragma omp sections + { + #pragma omp section + cp = ModularSquareRoot(cp, m_p); + #pragma omp section + cq = ModularSquareRoot(cq, m_q); + } + + Integer y = CRT(cq, m_q, cp, m_p, m_u); + y = modn.Multiply(y, rInv); // unblind + y = STDMIN(y, m_n-y); + if (ApplyFunction(y) != x) // check + throw Exception(Exception::OTHER_ERROR, "InvertibleRWFunction: computational error during private key operation"); + return y; +} + +bool InvertibleRWFunction::Validate(RandomNumberGenerator &rng, unsigned int level) const +{ + bool pass = RWFunction::Validate(rng, level); + pass = pass && m_p > Integer::One() && m_p%8 == 3 && m_p < m_n; + pass = pass && m_q > Integer::One() && m_q%8 == 7 && m_q < m_n; + pass = pass && m_u.IsPositive() && m_u < m_p; + if (level >= 1) + { + pass = pass && m_p * m_q == m_n; + pass = pass && m_u * m_q % m_p == 1; + } + if (level >= 2) + pass = pass && VerifyPrime(rng, m_p, level-2) && VerifyPrime(rng, m_q, level-2); + return pass; +} + +bool InvertibleRWFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const +{ + return GetValueHelper(this, name, valueType, pValue).Assignable() + CRYPTOPP_GET_FUNCTION_ENTRY(Prime1) + CRYPTOPP_GET_FUNCTION_ENTRY(Prime2) + CRYPTOPP_GET_FUNCTION_ENTRY(MultiplicativeInverseOfPrime2ModPrime1) + ; +} + +void InvertibleRWFunction::AssignFrom(const NameValuePairs &source) +{ + AssignFromHelper(this, source) + CRYPTOPP_SET_FUNCTION_ENTRY(Prime1) + CRYPTOPP_SET_FUNCTION_ENTRY(Prime2) + CRYPTOPP_SET_FUNCTION_ENTRY(MultiplicativeInverseOfPrime2ModPrime1) + ; +} + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/rw.h b/CryptoPP/crypto/rw.h new file mode 100644 index 0000000..e999f58 --- /dev/null +++ b/CryptoPP/crypto/rw.h @@ -0,0 +1,92 @@ +#ifndef CRYPTOPP_RW_H +#define CRYPTOPP_RW_H + +/** \file + This file contains classes that implement the + Rabin-Williams signature schemes as defined in IEEE P1363. +*/ + +#include "pubkey.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! _ +class CRYPTOPP_DLL RWFunction : public TrapdoorFunction, public PublicKey +{ + typedef RWFunction ThisClass; + +public: + void Initialize(const Integer &n) + {m_n = n;} + + void BERDecode(BufferedTransformation &bt); + void DEREncode(BufferedTransformation &bt) const; + + Integer ApplyFunction(const Integer &x) const; + Integer PreimageBound() const {return ++(m_n>>1);} + Integer ImageBound() const {return m_n;} + + bool Validate(RandomNumberGenerator &rng, unsigned int level) const; + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; + void AssignFrom(const NameValuePairs &source); + + const Integer& GetModulus() const {return m_n;} + void SetModulus(const Integer &n) {m_n = n;} + +protected: + Integer m_n; +}; + +//! _ +class CRYPTOPP_DLL InvertibleRWFunction : public RWFunction, public TrapdoorFunctionInverse, public PrivateKey +{ + typedef InvertibleRWFunction ThisClass; + +public: + void Initialize(const Integer &n, const Integer &p, const Integer &q, const Integer &u) + {m_n = n; m_p = p; m_q = q; m_u = u;} + // generate a random private key + void Initialize(RandomNumberGenerator &rng, unsigned int modulusBits) + {GenerateRandomWithKeySize(rng, modulusBits);} + + void BERDecode(BufferedTransformation &bt); + void DEREncode(BufferedTransformation &bt) const; + + Integer CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const; + + // GeneratibleCryptoMaterial + bool Validate(RandomNumberGenerator &rng, unsigned int level) const; + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; + void AssignFrom(const NameValuePairs &source); + /*! parameters: (ModulusSize) */ + void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &alg); + + const Integer& GetPrime1() const {return m_p;} + const Integer& GetPrime2() const {return m_q;} + const Integer& GetMultiplicativeInverseOfPrime2ModPrime1() const {return m_u;} + + void SetPrime1(const Integer &p) {m_p = p;} + void SetPrime2(const Integer &q) {m_q = q;} + void SetMultiplicativeInverseOfPrime2ModPrime1(const Integer &u) {m_u = u;} + +protected: + Integer m_p, m_q, m_u; +}; + +//! RW +struct RW +{ + static std::string StaticAlgorithmName() {return "RW";} + typedef RWFunction PublicKey; + typedef InvertibleRWFunction PrivateKey; +}; + +//! RWSS +template +struct RWSS : public TF_SS +{ +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/rw1024.dat b/CryptoPP/crypto/rw1024.dat new file mode 100644 index 0000000..dcd0209 --- /dev/null +++ b/CryptoPP/crypto/rw1024.dat @@ -0,0 +1 @@ +3082014D02818100BECF1F40456801F6965E603BEBB61F530F0B17BBCB00E3A8866EB9BC84AE3892A4CB040280F568FC650B1734014CA78A200D5E4AB394CBB75C0034DCC47643E6F576A39F850C5F4528048165B084C82E9BA6BA4CFBCB3980F1EB47EC2C348EF52A6225A85AF743DFCEF5CD4583EB0B9C0DA77ABEBEB5BCC513D81BD768B579AD024100F06CA9C1FBE20EE2440F3AB2F9A9787D820943EAF59B6B8D103CFAB1C2F595DDC99D05DC73F9D1DB780B6F8B26CF87E58EB870DD983A2515600DF80C3EBB7B1B024100CB2B9BDEB0D508E21E646C86D836442FC16910D68C8D1D18BB1327899A506C16C1162E93EA7C2CB576B750AEAB152255D5AB22632025CFFAD927A070CBAEA2D7024100C90A853BEC7C25D773FDDB95C11CEF9BB3F487953773F07E42DB9D011325AE2725663478FB7F0EC1A5608280D9656BF3B9F463FF8B23F1CA1B543508D51826E2 \ No newline at end of file diff --git a/CryptoPP/crypto/rw2048.dat b/CryptoPP/crypto/rw2048.dat new file mode 100644 index 0000000..5547c88 --- /dev/null +++ b/CryptoPP/crypto/rw2048.dat @@ -0,0 +1 @@ +3082029002820101008F2975B4DA54179A6C81764DB9E6B50AD925C91568DFE2C245DF9103AF39370BD5F25CD26BF6E41B6FEB0E24473BBFAE89343BC20743057B056BD2189C01258650567A3EC24040EED7EEAF94B77BDD39529807D1FCF5FF4A90E6B42BA58FF1FDCDACF981C641B8F077ABBB41BEFD53CCABF06745CD009A7F9DFAA61ED03F11466E4B5370DFA18C7DFEA1689B60F98012CDE9131FE86F74BFC6B93AC449DA73A2366EA2AE2233AFFBFF0CDE1899B1F852C179639B31CEE11991AA8D46DB5067B0C5FFB3D913612668F0C43CA134B11875F271C0BC8722AF4AD6CC93A43CE165EF31C1EB542ECC7CA1A38BFDF66F3A2175E4EA7159E168FFE3A549535B90C7BBDD02818100C5CEBA84E8B7C20BAA6F450000803F15C1160EB7E0875EBBC15F11DC7E3CAFE55973234FF4C74589406D2950B0C236ABE1B5A5B70D55C035F45D87AF089847C0E2A2DEF23EA4CC19FB5419DF43577523248BEF80B94C59F7342C717F12DE68FEEADAD97BA2DD436834D8559D0A7A31D6F9D9480F852C285EFC75BCA8AF32590302818100B947440D272629155C2B3E0E62B76124281155F7A189650D36C8F7D742F7DBC571ADDCC582ED2ED283C2E8A1CD8C996D3D8A50F33C56581285C5016A16DEDA533715DF519CAB7777F3DCB9F5335552F315B44FF8126DFDDF60B66850AA8FD108ED3A248D18E7473D7967F0F15C740C67476A75273DA254AE5C7B94FB059DD19F0281801EE99173837363981E0988DE22B2E36BFC9713EDC8454BF1CB764D767DFDA985B9DBAA346C0C39B1A9F83D849502AFDD80AE33F588C114BC4DE5FA949125FF56908F8C66CDFF6BF601F1CBF463B0C807DEABB1290C358FC0433ED74EBA074CB211C4D75538ED017F497C9722D8C3D3E082BB4A8A92D5768B5D5963BBDB1DB24D \ No newline at end of file diff --git a/CryptoPP/crypto/safer.cpp b/CryptoPP/crypto/safer.cpp new file mode 100644 index 0000000..1e66357 --- /dev/null +++ b/CryptoPP/crypto/safer.cpp @@ -0,0 +1,153 @@ +// safer.cpp - modified by by Wei Dai from Richard De Moliner's safer.c + +#include "pch.h" +#include "safer.h" +#include "misc.h" +#include "argnames.h" + +NAMESPACE_BEGIN(CryptoPP) + +const byte SAFER::Base::exp_tab[256] = + {1, 45, 226, 147, 190, 69, 21, 174, 120, 3, 135, 164, 184, 56, 207, 63, + 8, 103, 9, 148, 235, 38, 168, 107, 189, 24, 52, 27, 187, 191, 114, 247, + 64, 53, 72, 156, 81, 47, 59, 85, 227, 192, 159, 216, 211, 243, 141, 177, + 255, 167, 62, 220, 134, 119, 215, 166, 17, 251, 244, 186, 146, 145, 100, 131, + 241, 51, 239, 218, 44, 181, 178, 43, 136, 209, 153, 203, 140, 132, 29, 20, + 129, 151, 113, 202, 95, 163, 139, 87, 60, 130, 196, 82, 92, 28, 232, 160, + 4, 180, 133, 74, 246, 19, 84, 182, 223, 12, 26, 142, 222, 224, 57, 252, + 32, 155, 36, 78, 169, 152, 158, 171, 242, 96, 208, 108, 234, 250, 199, 217, + 0, 212, 31, 110, 67, 188, 236, 83, 137, 254, 122, 93, 73, 201, 50, 194, + 249, 154, 248, 109, 22, 219, 89, 150, 68, 233, 205, 230, 70, 66, 143, 10, + 193, 204, 185, 101, 176, 210, 198, 172, 30, 65, 98, 41, 46, 14, 116, 80, + 2, 90, 195, 37, 123, 138, 42, 91, 240, 6, 13, 71, 111, 112, 157, 126, + 16, 206, 18, 39, 213, 76, 79, 214, 121, 48, 104, 54, 117, 125, 228, 237, + 128, 106, 144, 55, 162, 94, 118, 170, 197, 127, 61, 175, 165, 229, 25, 97, + 253, 77, 124, 183, 11, 238, 173, 75, 34, 245, 231, 115, 35, 33, 200, 5, + 225, 102, 221, 179, 88, 105, 99, 86, 15, 161, 49, 149, 23, 7, 58, 40}; + +const byte SAFER::Base::log_tab[256] = + {128, 0, 176, 9, 96, 239, 185, 253, 16, 18, 159, 228, 105, 186, 173, 248, + 192, 56, 194, 101, 79, 6, 148, 252, 25, 222, 106, 27, 93, 78, 168, 130, + 112, 237, 232, 236, 114, 179, 21, 195, 255, 171, 182, 71, 68, 1, 172, 37, + 201, 250, 142, 65, 26, 33, 203, 211, 13, 110, 254, 38, 88, 218, 50, 15, + 32, 169, 157, 132, 152, 5, 156, 187, 34, 140, 99, 231, 197, 225, 115, 198, + 175, 36, 91, 135, 102, 39, 247, 87, 244, 150, 177, 183, 92, 139, 213, 84, + 121, 223, 170, 246, 62, 163, 241, 17, 202, 245, 209, 23, 123, 147, 131, 188, + 189, 82, 30, 235, 174, 204, 214, 53, 8, 200, 138, 180, 226, 205, 191, 217, + 208, 80, 89, 63, 77, 98, 52, 10, 72, 136, 181, 86, 76, 46, 107, 158, + 210, 61, 60, 3, 19, 251, 151, 81, 117, 74, 145, 113, 35, 190, 118, 42, + 95, 249, 212, 85, 11, 220, 55, 49, 22, 116, 215, 119, 167, 230, 7, 219, + 164, 47, 70, 243, 97, 69, 103, 227, 12, 162, 59, 28, 133, 24, 4, 29, + 41, 160, 143, 178, 90, 216, 166, 126, 238, 141, 83, 75, 161, 154, 193, 14, + 122, 73, 165, 44, 129, 196, 199, 54, 43, 127, 67, 149, 51, 242, 108, 104, + 109, 240, 2, 40, 206, 221, 155, 234, 94, 153, 124, 20, 134, 207, 229, 66, + 184, 64, 120, 45, 58, 233, 100, 31, 146, 144, 125, 57, 111, 224, 137, 48}; + +#define EXP(x) exp_tab[(x)] +#define LOG(x) log_tab[(x)] +#define PHT(x, y) { y += x; x += y; } +#define IPHT(x, y) { x -= y; y -= x; } + +static const unsigned int BLOCKSIZE = 8; +static const unsigned int MAX_ROUNDS = 13; + +void SAFER::Base::UncheckedSetKey(const byte *userkey_1, unsigned int length, const NameValuePairs ¶ms) +{ + bool strengthened = Strengthened(); + unsigned int nof_rounds = params.GetIntValueWithDefault(Name::Rounds(), length == 8 ? (strengthened ? 8 : 6) : 10); + + const byte *userkey_2 = length == 8 ? userkey_1 : userkey_1 + 8; + keySchedule.New(1 + BLOCKSIZE * (1 + 2 * nof_rounds)); + + unsigned int i, j; + byte *key = keySchedule; + SecByteBlock ka(BLOCKSIZE + 1), kb(BLOCKSIZE + 1); + + if (MAX_ROUNDS < nof_rounds) + nof_rounds = MAX_ROUNDS; + *key++ = (unsigned char)nof_rounds; + ka[BLOCKSIZE] = 0; + kb[BLOCKSIZE] = 0; + for (j = 0; j < BLOCKSIZE; j++) + { + ka[BLOCKSIZE] ^= ka[j] = rotlFixed(userkey_1[j], 5U); + kb[BLOCKSIZE] ^= kb[j] = *key++ = userkey_2[j]; + } + + for (i = 1; i <= nof_rounds; i++) + { + for (j = 0; j < BLOCKSIZE + 1; j++) + { + ka[j] = rotlFixed(ka[j], 6U); + kb[j] = rotlFixed(kb[j], 6U); + } + for (j = 0; j < BLOCKSIZE; j++) + if (strengthened) + *key++ = (ka[(j + 2 * i - 1) % (BLOCKSIZE + 1)] + + exp_tab[exp_tab[18 * i + j + 1]]) & 0xFF; + else + *key++ = (ka[j] + exp_tab[exp_tab[18 * i + j + 1]]) & 0xFF; + for (j = 0; j < BLOCKSIZE; j++) + if (strengthened) + *key++ = (kb[(j + 2 * i) % (BLOCKSIZE + 1)] + + exp_tab[exp_tab[18 * i + j + 10]]) & 0xFF; + else + *key++ = (kb[j] + exp_tab[exp_tab[18 * i + j + 10]]) & 0xFF; + } +} + +typedef BlockGetAndPut Block; + +void SAFER::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + byte a, b, c, d, e, f, g, h, t; + const byte *key = keySchedule+1; + unsigned int round = keySchedule[0]; + + Block::Get(inBlock)(a)(b)(c)(d)(e)(f)(g)(h); + while(round--) + { + a ^= key[0]; b += key[1]; c += key[2]; d ^= key[3]; + e ^= key[4]; f += key[5]; g += key[6]; h ^= key[7]; + a = EXP(a) + key[ 8]; b = LOG(b) ^ key[ 9]; + c = LOG(c) ^ key[10]; d = EXP(d) + key[11]; + e = EXP(e) + key[12]; f = LOG(f) ^ key[13]; + g = LOG(g) ^ key[14]; h = EXP(h) + key[15]; + key += 16; + PHT(a, b); PHT(c, d); PHT(e, f); PHT(g, h); + PHT(a, c); PHT(e, g); PHT(b, d); PHT(f, h); + PHT(a, e); PHT(b, f); PHT(c, g); PHT(d, h); + t = b; b = e; e = c; c = t; t = d; d = f; f = g; g = t; + } + a ^= key[0]; b += key[1]; c += key[2]; d ^= key[3]; + e ^= key[4]; f += key[5]; g += key[6]; h ^= key[7]; + Block::Put(xorBlock, outBlock)(a)(b)(c)(d)(e)(f)(g)(h); +} + +void SAFER::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + byte a, b, c, d, e, f, g, h, t; + unsigned int round = keySchedule[0]; + const byte *key = keySchedule + BLOCKSIZE * (1 + 2 * round) - 7; + + Block::Get(inBlock)(a)(b)(c)(d)(e)(f)(g)(h); + h ^= key[7]; g -= key[6]; f -= key[5]; e ^= key[4]; + d ^= key[3]; c -= key[2]; b -= key[1]; a ^= key[0]; + while (round--) + { + key -= 16; + t = e; e = b; b = c; c = t; t = f; f = d; d = g; g = t; + IPHT(a, e); IPHT(b, f); IPHT(c, g); IPHT(d, h); + IPHT(a, c); IPHT(e, g); IPHT(b, d); IPHT(f, h); + IPHT(a, b); IPHT(c, d); IPHT(e, f); IPHT(g, h); + h -= key[15]; g ^= key[14]; f ^= key[13]; e -= key[12]; + d -= key[11]; c ^= key[10]; b ^= key[9]; a -= key[8]; + h = LOG(h) ^ key[7]; g = EXP(g) - key[6]; + f = EXP(f) - key[5]; e = LOG(e) ^ key[4]; + d = LOG(d) ^ key[3]; c = EXP(c) - key[2]; + b = EXP(b) - key[1]; a = LOG(a) ^ key[0]; + } + Block::Put(xorBlock, outBlock)(a)(b)(c)(d)(e)(f)(g)(h); +} + +NAMESPACE_END diff --git a/CryptoPP/crypto/safer.h b/CryptoPP/crypto/safer.h new file mode 100644 index 0000000..60676c5 --- /dev/null +++ b/CryptoPP/crypto/safer.h @@ -0,0 +1,86 @@ +#ifndef CRYPTOPP_SAFER_H +#define CRYPTOPP_SAFER_H + +/** \file +*/ + +#include "seckey.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// base class, do not use directly +class SAFER +{ +public: + class CRYPTOPP_NO_VTABLE Base : public BlockCipher + { + public: + unsigned int GetAlignment() const {return 1;} + void UncheckedSetKey(const byte *userkey, unsigned int length, const NameValuePairs ¶ms); + + protected: + virtual bool Strengthened() const =0; + + SecByteBlock keySchedule; + static const byte exp_tab[256]; + static const byte log_tab[256]; + }; + + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; +}; + +template +class CRYPTOPP_NO_VTABLE SAFER_Impl : public BlockCipherImpl +{ +protected: + bool Strengthened() const {return STR;} +}; + +//! _ +struct SAFER_K_Info : public FixedBlockSize<8>, public VariableKeyLength<16, 8, 16, 8>, public VariableRounds<10, 1, 13> +{ + static const char *StaticAlgorithmName() {return "SAFER-K";} +}; + +/// SAFER-K +class SAFER_K : public SAFER_K_Info, public SAFER, public BlockCipherDocumentation +{ +public: + typedef BlockCipherFinal > Encryption; + typedef BlockCipherFinal > Decryption; +}; + +//! _ +struct SAFER_SK_Info : public FixedBlockSize<8>, public VariableKeyLength<16, 8, 16, 8>, public VariableRounds<10, 1, 13> +{ + static const char *StaticAlgorithmName() {return "SAFER-SK";} +}; + +/// SAFER-SK +class SAFER_SK : public SAFER_SK_Info, public SAFER, public BlockCipherDocumentation +{ +public: + typedef BlockCipherFinal > Encryption; + typedef BlockCipherFinal > Decryption; +}; + +typedef SAFER_K::Encryption SAFER_K_Encryption; +typedef SAFER_K::Decryption SAFER_K_Decryption; + +typedef SAFER_SK::Encryption SAFER_SK_Encryption; +typedef SAFER_SK::Decryption SAFER_SK_Decryption; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/saferval.dat b/CryptoPP/crypto/saferval.dat new file mode 100644 index 0000000..52ba4a2 --- /dev/null +++ b/CryptoPP/crypto/saferval.dat @@ -0,0 +1,16 @@ +0000000000000000 0000000000000000 032808C90EE7AB7F +0000000000000000 0102030405060708 7D28038633B92EB4 +0102030405060708 1011121314151617 71E5CF7F083A59C5 +0102030405060708 18191A1B1C1D1E1F 356F702CC7FA8161 +08070605040302010807060504030201 5051525354555657 38E64DBF6E0F896E +08070605040302010807060504030201 58595A5B5C5D5E5F 7D8F014A902480FE +01020304050607080807060504030201 6061626364656667 113511C22E7936DF +01020304050607080807060504030201 68696A6B6C6D6E6F 9EEB2D17C0581437 +0000000000000001 7071727374757677 9ABE2C85BE2D7614 +0000000000000001 78797A7B7C7D7E7F EBC4A9C6C25CF215 +0102030405060708 8081828384858687 54E72BA2D744C566 +0102030405060708 88898A8B8C8D8E8F 57F55D0F7EB6F8FE +00000000000000010000000000000001 9091929394959697 9EAA4DF1E0EFF445 +00000000000000010000000000000001 98999A9B9C9D9E9F 4CC14838399E532D +01020304050607080000000000000000 A0A1A2A3A4A5A6A7 41246B65F1DC6AFA +00000000000000000102030405060708 A0A1A2A3A4A5A6A7 5CBD77B03626FE3B diff --git a/CryptoPP/crypto/salsa.cpp b/CryptoPP/crypto/salsa.cpp new file mode 100644 index 0000000..ae10d4a --- /dev/null +++ b/CryptoPP/crypto/salsa.cpp @@ -0,0 +1,564 @@ +// salsa.cpp - written and placed in the public domain by Wei Dai + +// use "cl /EP /P /DCRYPTOPP_GENERATE_X64_MASM salsa.cpp" to generate MASM code + +#include "pch.h" + +#ifndef CRYPTOPP_GENERATE_X64_MASM + +#include "salsa.h" +#include "misc.h" +#include "argnames.h" +#include "cpu.h" + +#if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE +#include +#endif + +NAMESPACE_BEGIN(CryptoPP) + +void Salsa20_TestInstantiations() +{ + Salsa20::Encryption x; +} + +void Salsa20_Policy::CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length) +{ + m_rounds = params.GetIntValueWithDefault(Name::Rounds(), 20); + + if (!(m_rounds == 8 || m_rounds == 12 || m_rounds == 20)) + throw InvalidRounds(StaticAlgorithmName(), m_rounds); + + // m_state is reordered for SSE2 + GetBlock get1(key); + get1(m_state[13])(m_state[10])(m_state[7])(m_state[4]); + GetBlock get2(key + length - 16); + get2(m_state[15])(m_state[12])(m_state[9])(m_state[6]); + + // "expand 16-byte k" or "expand 32-byte k" + m_state[0] = 0x61707865; + m_state[1] = (length == 16) ? 0x3120646e : 0x3320646e; + m_state[2] = (length == 16) ? 0x79622d36 : 0x79622d32; + m_state[3] = 0x6b206574; +} + +void Salsa20_Policy::CipherResynchronize(byte *keystreamBuffer, const byte *IV) +{ + GetBlock get(IV); + get(m_state[14])(m_state[11]); + m_state[8] = m_state[5] = 0; +} + +void Salsa20_Policy::SeekToIteration(lword iterationCount) +{ + m_state[8] = (word32)iterationCount; + m_state[5] = (word32)SafeRightShift<32>(iterationCount); +} + +#if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X64 +unsigned int Salsa20_Policy::GetAlignment() const +{ +#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE + if (HasSSE2()) + return 16; + else +#endif + return 1; +} + +unsigned int Salsa20_Policy::GetOptimalBlockSize() const +{ +#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE + if (HasSSE2()) + return 4*BYTES_PER_ITERATION; + else +#endif + return BYTES_PER_ITERATION; +} +#endif + +#ifdef CRYPTOPP_X64_MASM_AVAILABLE +extern "C" { +void Salsa20_OperateKeystream(byte *output, const byte *input, size_t iterationCount, int rounds, void *state); +} +#endif + +#pragma warning(disable: 4731) // frame pointer register 'ebp' modified by inline assembly code + +void Salsa20_Policy::OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount) +{ +#endif // #ifdef CRYPTOPP_GENERATE_X64_MASM + +#ifdef CRYPTOPP_X64_MASM_AVAILABLE + Salsa20_OperateKeystream(output, input, iterationCount, m_rounds, m_state.data()); + return; +#endif + +#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE +#ifdef CRYPTOPP_GENERATE_X64_MASM + ALIGN 8 + Salsa20_OperateKeystream PROC FRAME + mov r10, [rsp + 5*8] ; state + alloc_stack(10*16 + 32*16 + 8) + save_xmm128 xmm6, 0200h + save_xmm128 xmm7, 0210h + save_xmm128 xmm8, 0220h + save_xmm128 xmm9, 0230h + save_xmm128 xmm10, 0240h + save_xmm128 xmm11, 0250h + save_xmm128 xmm12, 0260h + save_xmm128 xmm13, 0270h + save_xmm128 xmm14, 0280h + save_xmm128 xmm15, 0290h + .endprolog + + #define REG_output rcx + #define REG_input rdx + #define REG_iterationCount r8 + #define REG_state r10 + #define REG_rounds e9d + #define REG_roundsLeft eax + #define REG_temp32 r11d + #define REG_temp r11 + #define SSE2_WORKSPACE rsp +#else + if (HasSSE2()) + { + #if CRYPTOPP_BOOL_X64 + #define REG_output %4 + #define REG_input %1 + #define REG_iterationCount %2 + #define REG_state %3 + #define REG_rounds %0 + #define REG_roundsLeft eax + #define REG_temp32 edx + #define REG_temp rdx + #define SSE2_WORKSPACE %5 + + __m128i workspace[32]; + #else + #define REG_output edi + #define REG_input eax + #define REG_iterationCount ecx + #define REG_state esi + #define REG_rounds edx + #define REG_roundsLeft ebx + #define REG_temp32 ebp + #define REG_temp ebp + #define SSE2_WORKSPACE esp + WORD_SZ + #endif + + #ifdef __GNUC__ + __asm__ __volatile__ + ( + ".intel_syntax noprefix;" + AS_PUSH_IF86( bx) + #else + void *s = m_state.data(); + word32 r = m_rounds; + + AS2( mov REG_iterationCount, iterationCount) + AS2( mov REG_input, input) + AS2( mov REG_output, output) + AS2( mov REG_state, s) + AS2( mov REG_rounds, r) + #endif +#endif // #ifndef CRYPTOPP_GENERATE_X64_MASM + + AS_PUSH_IF86( bp) + AS2( cmp REG_iterationCount, 4) + ASJ( jl, 5, f) + +#if CRYPTOPP_BOOL_X86 + AS2( mov ebx, esp) + AS2( and esp, -16) + AS2( sub esp, 32*16) + AS1( push ebx) +#endif + +#define SSE2_EXPAND_S(i, j) \ + ASS( pshufd xmm4, xmm##i, j, j, j, j) \ + AS2( movdqa [SSE2_WORKSPACE + (i*4+j)*16 + 256], xmm4) + + AS2( movdqa xmm0, [REG_state + 0*16]) + AS2( movdqa xmm1, [REG_state + 1*16]) + AS2( movdqa xmm2, [REG_state + 2*16]) + AS2( movdqa xmm3, [REG_state + 3*16]) + SSE2_EXPAND_S(0, 0) + SSE2_EXPAND_S(0, 1) + SSE2_EXPAND_S(0, 2) + SSE2_EXPAND_S(0, 3) + SSE2_EXPAND_S(1, 0) + SSE2_EXPAND_S(1, 2) + SSE2_EXPAND_S(1, 3) + SSE2_EXPAND_S(2, 1) + SSE2_EXPAND_S(2, 2) + SSE2_EXPAND_S(2, 3) + SSE2_EXPAND_S(3, 0) + SSE2_EXPAND_S(3, 1) + SSE2_EXPAND_S(3, 2) + SSE2_EXPAND_S(3, 3) + +#define SSE2_EXPAND_S85(i) \ + AS2( mov dword ptr [SSE2_WORKSPACE + 8*16 + i*4 + 256], REG_roundsLeft) \ + AS2( mov dword ptr [SSE2_WORKSPACE + 5*16 + i*4 + 256], REG_temp32) \ + AS2( add REG_roundsLeft, 1) \ + AS2( adc REG_temp32, 0) + + ASL(1) + AS2( mov REG_roundsLeft, dword ptr [REG_state + 8*4]) + AS2( mov REG_temp32, dword ptr [REG_state + 5*4]) + SSE2_EXPAND_S85(0) + SSE2_EXPAND_S85(1) + SSE2_EXPAND_S85(2) + SSE2_EXPAND_S85(3) + AS2( mov dword ptr [REG_state + 8*4], REG_roundsLeft) + AS2( mov dword ptr [REG_state + 5*4], REG_temp32) + +#define SSE2_QUARTER_ROUND(a, b, d, i) \ + AS2( movdqa xmm4, xmm##d) \ + AS2( paddd xmm4, xmm##a) \ + AS2( movdqa xmm5, xmm4) \ + AS2( pslld xmm4, i) \ + AS2( psrld xmm5, 32-i) \ + AS2( pxor xmm##b, xmm4) \ + AS2( pxor xmm##b, xmm5) + +#define L01(A,B,C,D,a,b,c,d,i) AS2( movdqa xmm##A, [SSE2_WORKSPACE + d*16 + i*256]) /* y3 */ +#define L02(A,B,C,D,a,b,c,d,i) AS2( movdqa xmm##C, [SSE2_WORKSPACE + a*16 + i*256]) /* y0 */ +#define L03(A,B,C,D,a,b,c,d,i) AS2( paddd xmm##A, xmm##C) /* y0+y3 */ +#define L04(A,B,C,D,a,b,c,d,i) AS2( movdqa xmm##B, xmm##A) +#define L05(A,B,C,D,a,b,c,d,i) AS2( pslld xmm##A, 7) +#define L06(A,B,C,D,a,b,c,d,i) AS2( psrld xmm##B, 32-7) +#define L07(A,B,C,D,a,b,c,d,i) AS2( pxor xmm##A, [SSE2_WORKSPACE + b*16 + i*256]) +#define L08(A,B,C,D,a,b,c,d,i) AS2( pxor xmm##A, xmm##B) /* z1 */ +#define L09(A,B,C,D,a,b,c,d,i) AS2( movdqa [SSE2_WORKSPACE + b*16], xmm##A) +#define L10(A,B,C,D,a,b,c,d,i) AS2( movdqa xmm##B, xmm##A) +#define L11(A,B,C,D,a,b,c,d,i) AS2( paddd xmm##A, xmm##C) /* z1+y0 */ +#define L12(A,B,C,D,a,b,c,d,i) AS2( movdqa xmm##D, xmm##A) +#define L13(A,B,C,D,a,b,c,d,i) AS2( pslld xmm##A, 9) +#define L14(A,B,C,D,a,b,c,d,i) AS2( psrld xmm##D, 32-9) +#define L15(A,B,C,D,a,b,c,d,i) AS2( pxor xmm##A, [SSE2_WORKSPACE + c*16 + i*256]) +#define L16(A,B,C,D,a,b,c,d,i) AS2( pxor xmm##A, xmm##D) /* z2 */ +#define L17(A,B,C,D,a,b,c,d,i) AS2( movdqa [SSE2_WORKSPACE + c*16], xmm##A) +#define L18(A,B,C,D,a,b,c,d,i) AS2( movdqa xmm##D, xmm##A) +#define L19(A,B,C,D,a,b,c,d,i) AS2( paddd xmm##A, xmm##B) /* z2+z1 */ +#define L20(A,B,C,D,a,b,c,d,i) AS2( movdqa xmm##B, xmm##A) +#define L21(A,B,C,D,a,b,c,d,i) AS2( pslld xmm##A, 13) +#define L22(A,B,C,D,a,b,c,d,i) AS2( psrld xmm##B, 32-13) +#define L23(A,B,C,D,a,b,c,d,i) AS2( pxor xmm##A, [SSE2_WORKSPACE + d*16 + i*256]) +#define L24(A,B,C,D,a,b,c,d,i) AS2( pxor xmm##A, xmm##B) /* z3 */ +#define L25(A,B,C,D,a,b,c,d,i) AS2( movdqa [SSE2_WORKSPACE + d*16], xmm##A) +#define L26(A,B,C,D,a,b,c,d,i) AS2( paddd xmm##A, xmm##D) /* z3+z2 */ +#define L27(A,B,C,D,a,b,c,d,i) AS2( movdqa xmm##D, xmm##A) +#define L28(A,B,C,D,a,b,c,d,i) AS2( pslld xmm##A, 18) +#define L29(A,B,C,D,a,b,c,d,i) AS2( psrld xmm##D, 32-18) +#define L30(A,B,C,D,a,b,c,d,i) AS2( pxor xmm##A, xmm##C) /* xor y0 */ +#define L31(A,B,C,D,a,b,c,d,i) AS2( pxor xmm##A, xmm##D) /* z0 */ +#define L32(A,B,C,D,a,b,c,d,i) AS2( movdqa [SSE2_WORKSPACE + a*16], xmm##A) + +#define SSE2_QUARTER_ROUND_X8(i, a, b, c, d, e, f, g, h) \ + L01(0,1,2,3, a,b,c,d, i) L01(4,5,6,7, e,f,g,h, i) \ + L02(0,1,2,3, a,b,c,d, i) L02(4,5,6,7, e,f,g,h, i) \ + L03(0,1,2,3, a,b,c,d, i) L03(4,5,6,7, e,f,g,h, i) \ + L04(0,1,2,3, a,b,c,d, i) L04(4,5,6,7, e,f,g,h, i) \ + L05(0,1,2,3, a,b,c,d, i) L05(4,5,6,7, e,f,g,h, i) \ + L06(0,1,2,3, a,b,c,d, i) L06(4,5,6,7, e,f,g,h, i) \ + L07(0,1,2,3, a,b,c,d, i) L07(4,5,6,7, e,f,g,h, i) \ + L08(0,1,2,3, a,b,c,d, i) L08(4,5,6,7, e,f,g,h, i) \ + L09(0,1,2,3, a,b,c,d, i) L09(4,5,6,7, e,f,g,h, i) \ + L10(0,1,2,3, a,b,c,d, i) L10(4,5,6,7, e,f,g,h, i) \ + L11(0,1,2,3, a,b,c,d, i) L11(4,5,6,7, e,f,g,h, i) \ + L12(0,1,2,3, a,b,c,d, i) L12(4,5,6,7, e,f,g,h, i) \ + L13(0,1,2,3, a,b,c,d, i) L13(4,5,6,7, e,f,g,h, i) \ + L14(0,1,2,3, a,b,c,d, i) L14(4,5,6,7, e,f,g,h, i) \ + L15(0,1,2,3, a,b,c,d, i) L15(4,5,6,7, e,f,g,h, i) \ + L16(0,1,2,3, a,b,c,d, i) L16(4,5,6,7, e,f,g,h, i) \ + L17(0,1,2,3, a,b,c,d, i) L17(4,5,6,7, e,f,g,h, i) \ + L18(0,1,2,3, a,b,c,d, i) L18(4,5,6,7, e,f,g,h, i) \ + L19(0,1,2,3, a,b,c,d, i) L19(4,5,6,7, e,f,g,h, i) \ + L20(0,1,2,3, a,b,c,d, i) L20(4,5,6,7, e,f,g,h, i) \ + L21(0,1,2,3, a,b,c,d, i) L21(4,5,6,7, e,f,g,h, i) \ + L22(0,1,2,3, a,b,c,d, i) L22(4,5,6,7, e,f,g,h, i) \ + L23(0,1,2,3, a,b,c,d, i) L23(4,5,6,7, e,f,g,h, i) \ + L24(0,1,2,3, a,b,c,d, i) L24(4,5,6,7, e,f,g,h, i) \ + L25(0,1,2,3, a,b,c,d, i) L25(4,5,6,7, e,f,g,h, i) \ + L26(0,1,2,3, a,b,c,d, i) L26(4,5,6,7, e,f,g,h, i) \ + L27(0,1,2,3, a,b,c,d, i) L27(4,5,6,7, e,f,g,h, i) \ + L28(0,1,2,3, a,b,c,d, i) L28(4,5,6,7, e,f,g,h, i) \ + L29(0,1,2,3, a,b,c,d, i) L29(4,5,6,7, e,f,g,h, i) \ + L30(0,1,2,3, a,b,c,d, i) L30(4,5,6,7, e,f,g,h, i) \ + L31(0,1,2,3, a,b,c,d, i) L31(4,5,6,7, e,f,g,h, i) \ + L32(0,1,2,3, a,b,c,d, i) L32(4,5,6,7, e,f,g,h, i) + +#define SSE2_QUARTER_ROUND_X16(i, a, b, c, d, e, f, g, h, A, B, C, D, E, F, G, H) \ + L01(0,1,2,3, a,b,c,d, i) L01(4,5,6,7, e,f,g,h, i) L01(8,9,10,11, A,B,C,D, i) L01(12,13,14,15, E,F,G,H, i) \ + L02(0,1,2,3, a,b,c,d, i) L02(4,5,6,7, e,f,g,h, i) L02(8,9,10,11, A,B,C,D, i) L02(12,13,14,15, E,F,G,H, i) \ + L03(0,1,2,3, a,b,c,d, i) L03(4,5,6,7, e,f,g,h, i) L03(8,9,10,11, A,B,C,D, i) L03(12,13,14,15, E,F,G,H, i) \ + L04(0,1,2,3, a,b,c,d, i) L04(4,5,6,7, e,f,g,h, i) L04(8,9,10,11, A,B,C,D, i) L04(12,13,14,15, E,F,G,H, i) \ + L05(0,1,2,3, a,b,c,d, i) L05(4,5,6,7, e,f,g,h, i) L05(8,9,10,11, A,B,C,D, i) L05(12,13,14,15, E,F,G,H, i) \ + L06(0,1,2,3, a,b,c,d, i) L06(4,5,6,7, e,f,g,h, i) L06(8,9,10,11, A,B,C,D, i) L06(12,13,14,15, E,F,G,H, i) \ + L07(0,1,2,3, a,b,c,d, i) L07(4,5,6,7, e,f,g,h, i) L07(8,9,10,11, A,B,C,D, i) L07(12,13,14,15, E,F,G,H, i) \ + L08(0,1,2,3, a,b,c,d, i) L08(4,5,6,7, e,f,g,h, i) L08(8,9,10,11, A,B,C,D, i) L08(12,13,14,15, E,F,G,H, i) \ + L09(0,1,2,3, a,b,c,d, i) L09(4,5,6,7, e,f,g,h, i) L09(8,9,10,11, A,B,C,D, i) L09(12,13,14,15, E,F,G,H, i) \ + L10(0,1,2,3, a,b,c,d, i) L10(4,5,6,7, e,f,g,h, i) L10(8,9,10,11, A,B,C,D, i) L10(12,13,14,15, E,F,G,H, i) \ + L11(0,1,2,3, a,b,c,d, i) L11(4,5,6,7, e,f,g,h, i) L11(8,9,10,11, A,B,C,D, i) L11(12,13,14,15, E,F,G,H, i) \ + L12(0,1,2,3, a,b,c,d, i) L12(4,5,6,7, e,f,g,h, i) L12(8,9,10,11, A,B,C,D, i) L12(12,13,14,15, E,F,G,H, i) \ + L13(0,1,2,3, a,b,c,d, i) L13(4,5,6,7, e,f,g,h, i) L13(8,9,10,11, A,B,C,D, i) L13(12,13,14,15, E,F,G,H, i) \ + L14(0,1,2,3, a,b,c,d, i) L14(4,5,6,7, e,f,g,h, i) L14(8,9,10,11, A,B,C,D, i) L14(12,13,14,15, E,F,G,H, i) \ + L15(0,1,2,3, a,b,c,d, i) L15(4,5,6,7, e,f,g,h, i) L15(8,9,10,11, A,B,C,D, i) L15(12,13,14,15, E,F,G,H, i) \ + L16(0,1,2,3, a,b,c,d, i) L16(4,5,6,7, e,f,g,h, i) L16(8,9,10,11, A,B,C,D, i) L16(12,13,14,15, E,F,G,H, i) \ + L17(0,1,2,3, a,b,c,d, i) L17(4,5,6,7, e,f,g,h, i) L17(8,9,10,11, A,B,C,D, i) L17(12,13,14,15, E,F,G,H, i) \ + L18(0,1,2,3, a,b,c,d, i) L18(4,5,6,7, e,f,g,h, i) L18(8,9,10,11, A,B,C,D, i) L18(12,13,14,15, E,F,G,H, i) \ + L19(0,1,2,3, a,b,c,d, i) L19(4,5,6,7, e,f,g,h, i) L19(8,9,10,11, A,B,C,D, i) L19(12,13,14,15, E,F,G,H, i) \ + L20(0,1,2,3, a,b,c,d, i) L20(4,5,6,7, e,f,g,h, i) L20(8,9,10,11, A,B,C,D, i) L20(12,13,14,15, E,F,G,H, i) \ + L21(0,1,2,3, a,b,c,d, i) L21(4,5,6,7, e,f,g,h, i) L21(8,9,10,11, A,B,C,D, i) L21(12,13,14,15, E,F,G,H, i) \ + L22(0,1,2,3, a,b,c,d, i) L22(4,5,6,7, e,f,g,h, i) L22(8,9,10,11, A,B,C,D, i) L22(12,13,14,15, E,F,G,H, i) \ + L23(0,1,2,3, a,b,c,d, i) L23(4,5,6,7, e,f,g,h, i) L23(8,9,10,11, A,B,C,D, i) L23(12,13,14,15, E,F,G,H, i) \ + L24(0,1,2,3, a,b,c,d, i) L24(4,5,6,7, e,f,g,h, i) L24(8,9,10,11, A,B,C,D, i) L24(12,13,14,15, E,F,G,H, i) \ + L25(0,1,2,3, a,b,c,d, i) L25(4,5,6,7, e,f,g,h, i) L25(8,9,10,11, A,B,C,D, i) L25(12,13,14,15, E,F,G,H, i) \ + L26(0,1,2,3, a,b,c,d, i) L26(4,5,6,7, e,f,g,h, i) L26(8,9,10,11, A,B,C,D, i) L26(12,13,14,15, E,F,G,H, i) \ + L27(0,1,2,3, a,b,c,d, i) L27(4,5,6,7, e,f,g,h, i) L27(8,9,10,11, A,B,C,D, i) L27(12,13,14,15, E,F,G,H, i) \ + L28(0,1,2,3, a,b,c,d, i) L28(4,5,6,7, e,f,g,h, i) L28(8,9,10,11, A,B,C,D, i) L28(12,13,14,15, E,F,G,H, i) \ + L29(0,1,2,3, a,b,c,d, i) L29(4,5,6,7, e,f,g,h, i) L29(8,9,10,11, A,B,C,D, i) L29(12,13,14,15, E,F,G,H, i) \ + L30(0,1,2,3, a,b,c,d, i) L30(4,5,6,7, e,f,g,h, i) L30(8,9,10,11, A,B,C,D, i) L30(12,13,14,15, E,F,G,H, i) \ + L31(0,1,2,3, a,b,c,d, i) L31(4,5,6,7, e,f,g,h, i) L31(8,9,10,11, A,B,C,D, i) L31(12,13,14,15, E,F,G,H, i) \ + L32(0,1,2,3, a,b,c,d, i) L32(4,5,6,7, e,f,g,h, i) L32(8,9,10,11, A,B,C,D, i) L32(12,13,14,15, E,F,G,H, i) + +#if CRYPTOPP_BOOL_X64 + SSE2_QUARTER_ROUND_X16(1, 0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15) +#else + SSE2_QUARTER_ROUND_X8(1, 2, 6, 10, 14, 3, 7, 11, 15) + SSE2_QUARTER_ROUND_X8(1, 0, 4, 8, 12, 1, 5, 9, 13) +#endif + AS2( mov REG_roundsLeft, REG_rounds) + ASJ( jmp, 2, f) + + ASL(SSE2_Salsa_Output) + AS2( movdqa xmm0, xmm4) + AS2( punpckldq xmm4, xmm5) + AS2( movdqa xmm1, xmm6) + AS2( punpckldq xmm6, xmm7) + AS2( movdqa xmm2, xmm4) + AS2( punpcklqdq xmm4, xmm6) // e + AS2( punpckhqdq xmm2, xmm6) // f + AS2( punpckhdq xmm0, xmm5) + AS2( punpckhdq xmm1, xmm7) + AS2( movdqa xmm6, xmm0) + AS2( punpcklqdq xmm0, xmm1) // g + AS2( punpckhqdq xmm6, xmm1) // h + AS_XMM_OUTPUT4(SSE2_Salsa_Output_A, REG_input, REG_output, 4, 2, 0, 6, 1, 0, 4, 8, 12, 1) + AS1( ret) + + ASL(6) +#if CRYPTOPP_BOOL_X64 + SSE2_QUARTER_ROUND_X16(0, 0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15) + ASL(2) + SSE2_QUARTER_ROUND_X16(0, 0, 13, 10, 7, 1, 14, 11, 4, 2, 15, 8, 5, 3, 12, 9, 6) +#else + SSE2_QUARTER_ROUND_X8(0, 2, 6, 10, 14, 3, 7, 11, 15) + SSE2_QUARTER_ROUND_X8(0, 0, 4, 8, 12, 1, 5, 9, 13) + ASL(2) + SSE2_QUARTER_ROUND_X8(0, 2, 15, 8, 5, 3, 12, 9, 6) + SSE2_QUARTER_ROUND_X8(0, 0, 13, 10, 7, 1, 14, 11, 4) +#endif + AS2( sub REG_roundsLeft, 2) + ASJ( jnz, 6, b) + +#define SSE2_OUTPUT_4(a, b, c, d) \ + AS2( movdqa xmm4, [SSE2_WORKSPACE + a*16 + 256])\ + AS2( paddd xmm4, [SSE2_WORKSPACE + a*16])\ + AS2( movdqa xmm5, [SSE2_WORKSPACE + b*16 + 256])\ + AS2( paddd xmm5, [SSE2_WORKSPACE + b*16])\ + AS2( movdqa xmm6, [SSE2_WORKSPACE + c*16 + 256])\ + AS2( paddd xmm6, [SSE2_WORKSPACE + c*16])\ + AS2( movdqa xmm7, [SSE2_WORKSPACE + d*16 + 256])\ + AS2( paddd xmm7, [SSE2_WORKSPACE + d*16])\ + ASC( call, SSE2_Salsa_Output) + + SSE2_OUTPUT_4(0, 13, 10, 7) + SSE2_OUTPUT_4(4, 1, 14, 11) + SSE2_OUTPUT_4(8, 5, 2, 15) + SSE2_OUTPUT_4(12, 9, 6, 3) + AS2( test REG_input, REG_input) + ASJ( jz, 9, f) + AS2( add REG_input, 12*16) + ASL(9) + AS2( add REG_output, 12*16) + AS2( sub REG_iterationCount, 4) + AS2( cmp REG_iterationCount, 4) + ASJ( jge, 1, b) + AS_POP_IF86( sp) + + ASL(5) + AS2( sub REG_iterationCount, 1) + ASJ( jl, 4, f) + AS2( movdqa xmm0, [REG_state + 0*16]) + AS2( movdqa xmm1, [REG_state + 1*16]) + AS2( movdqa xmm2, [REG_state + 2*16]) + AS2( movdqa xmm3, [REG_state + 3*16]) + AS2( mov REG_roundsLeft, REG_rounds) + + ASL(0) + SSE2_QUARTER_ROUND(0, 1, 3, 7) + SSE2_QUARTER_ROUND(1, 2, 0, 9) + SSE2_QUARTER_ROUND(2, 3, 1, 13) + SSE2_QUARTER_ROUND(3, 0, 2, 18) + ASS( pshufd xmm1, xmm1, 2, 1, 0, 3) + ASS( pshufd xmm2, xmm2, 1, 0, 3, 2) + ASS( pshufd xmm3, xmm3, 0, 3, 2, 1) + SSE2_QUARTER_ROUND(0, 3, 1, 7) + SSE2_QUARTER_ROUND(3, 2, 0, 9) + SSE2_QUARTER_ROUND(2, 1, 3, 13) + SSE2_QUARTER_ROUND(1, 0, 2, 18) + ASS( pshufd xmm1, xmm1, 0, 3, 2, 1) + ASS( pshufd xmm2, xmm2, 1, 0, 3, 2) + ASS( pshufd xmm3, xmm3, 2, 1, 0, 3) + AS2( sub REG_roundsLeft, 2) + ASJ( jnz, 0, b) + + AS2( paddd xmm0, [REG_state + 0*16]) + AS2( paddd xmm1, [REG_state + 1*16]) + AS2( paddd xmm2, [REG_state + 2*16]) + AS2( paddd xmm3, [REG_state + 3*16]) + + AS2( add dword ptr [REG_state + 8*4], 1) + AS2( adc dword ptr [REG_state + 5*4], 0) + + AS2( pcmpeqb xmm6, xmm6) // all ones + AS2( psrlq xmm6, 32) // lo32 mask + ASS( pshufd xmm7, xmm6, 0, 1, 2, 3) // hi32 mask + AS2( movdqa xmm4, xmm0) + AS2( movdqa xmm5, xmm3) + AS2( pand xmm0, xmm7) + AS2( pand xmm4, xmm6) + AS2( pand xmm3, xmm6) + AS2( pand xmm5, xmm7) + AS2( por xmm4, xmm5) // 0,13,2,15 + AS2( movdqa xmm5, xmm1) + AS2( pand xmm1, xmm7) + AS2( pand xmm5, xmm6) + AS2( por xmm0, xmm5) // 4,1,6,3 + AS2( pand xmm6, xmm2) + AS2( pand xmm2, xmm7) + AS2( por xmm1, xmm6) // 8,5,10,7 + AS2( por xmm2, xmm3) // 12,9,14,11 + + AS2( movdqa xmm5, xmm4) + AS2( movdqa xmm6, xmm0) + AS3( shufpd xmm4, xmm1, 2) // 0,13,10,7 + AS3( shufpd xmm0, xmm2, 2) // 4,1,14,11 + AS3( shufpd xmm1, xmm5, 2) // 8,5,2,15 + AS3( shufpd xmm2, xmm6, 2) // 12,9,6,3 + + // output keystream + AS_XMM_OUTPUT4(SSE2_Salsa_Output_B, REG_input, REG_output, 4, 0, 1, 2, 3, 0, 1, 2, 3, 4) + ASJ( jmp, 5, b) + ASL(4) + + AS_POP_IF86( bp) +#ifdef __GNUC__ + AS_POP_IF86( bx) + ".att_syntax prefix;" + : + #if CRYPTOPP_BOOL_X64 + : "r" (m_rounds), "r" (input), "r" (iterationCount), "r" (m_state.data()), "r" (output), "r" (workspace) + : "%eax", "%edx", "memory", "cc", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7", "%xmm8", "%xmm9", "%xmm10", "%xmm11", "%xmm12", "%xmm13", "%xmm14", "%xmm15" + #else + : "d" (m_rounds), "a" (input), "c" (iterationCount), "S" (m_state.data()), "D" (output) + : "memory", "cc" + #endif + ); +#endif +#ifdef CRYPTOPP_GENERATE_X64_MASM + movdqa xmm6, [rsp + 0200h] + movdqa xmm7, [rsp + 0210h] + movdqa xmm8, [rsp + 0220h] + movdqa xmm9, [rsp + 0230h] + movdqa xmm10, [rsp + 0240h] + movdqa xmm11, [rsp + 0250h] + movdqa xmm12, [rsp + 0260h] + movdqa xmm13, [rsp + 0270h] + movdqa xmm14, [rsp + 0280h] + movdqa xmm15, [rsp + 0290h] + add rsp, 10*16 + 32*16 + 8 + ret +Salsa20_OperateKeystream ENDP +#else + } + else +#endif +#endif +#ifndef CRYPTOPP_GENERATE_X64_MASM + { + word32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; + + while (iterationCount--) + { + x0 = m_state[0]; + x1 = m_state[1]; + x2 = m_state[2]; + x3 = m_state[3]; + x4 = m_state[4]; + x5 = m_state[5]; + x6 = m_state[6]; + x7 = m_state[7]; + x8 = m_state[8]; + x9 = m_state[9]; + x10 = m_state[10]; + x11 = m_state[11]; + x12 = m_state[12]; + x13 = m_state[13]; + x14 = m_state[14]; + x15 = m_state[15]; + + for (int i=m_rounds; i>0; i-=2) + { + #define QUARTER_ROUND(a, b, c, d) \ + b = b ^ rotlFixed(a + d, 7); \ + c = c ^ rotlFixed(b + a, 9); \ + d = d ^ rotlFixed(c + b, 13); \ + a = a ^ rotlFixed(d + c, 18); + + QUARTER_ROUND(x0, x4, x8, x12) + QUARTER_ROUND(x1, x5, x9, x13) + QUARTER_ROUND(x2, x6, x10, x14) + QUARTER_ROUND(x3, x7, x11, x15) + + QUARTER_ROUND(x0, x13, x10, x7) + QUARTER_ROUND(x1, x14, x11, x4) + QUARTER_ROUND(x2, x15, x8, x5) + QUARTER_ROUND(x3, x12, x9, x6) + } + + #define SALSA_OUTPUT(x) {\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 0, x0 + m_state[0]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 1, x13 + m_state[13]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 2, x10 + m_state[10]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 3, x7 + m_state[7]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 4, x4 + m_state[4]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 5, x1 + m_state[1]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 6, x14 + m_state[14]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 7, x11 + m_state[11]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 8, x8 + m_state[8]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 9, x5 + m_state[5]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 10, x2 + m_state[2]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 11, x15 + m_state[15]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 12, x12 + m_state[12]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 13, x9 + m_state[9]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 14, x6 + m_state[6]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 15, x3 + m_state[3]);} + +#ifndef CRYPTOPP_DOXYGEN_PROCESSING + CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(SALSA_OUTPUT, BYTES_PER_ITERATION); +#endif + + if (++m_state[8] == 0) + ++m_state[5]; + } + } +} // see comment above if an internal compiler error occurs here + +NAMESPACE_END + +#endif // #ifndef CRYPTOPP_GENERATE_X64_MASM diff --git a/CryptoPP/crypto/salsa.h b/CryptoPP/crypto/salsa.h new file mode 100644 index 0000000..ea3ed24 --- /dev/null +++ b/CryptoPP/crypto/salsa.h @@ -0,0 +1,43 @@ +// salsa.h - written and placed in the public domain by Wei Dai + +#ifndef CRYPTOPP_SALSA_H +#define CRYPTOPP_SALSA_H + +#include "strciphr.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! _ +struct Salsa20_Info : public VariableKeyLength<32, 16, 32, 16, SimpleKeyingInterface::UNIQUE_IV, 8> +{ + static const char *StaticAlgorithmName() {return "Salsa20";} +}; + +class CRYPTOPP_NO_VTABLE Salsa20_Policy : public AdditiveCipherConcretePolicy, public Salsa20_Info +{ +protected: + void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length); + void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount); + void CipherResynchronize(byte *keystreamBuffer, const byte *IV); + bool IsRandomAccess() const {return true;} + void SeekToIteration(lword iterationCount); +#if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X64 + unsigned int GetAlignment() const; + unsigned int GetOptimalBlockSize() const; +#endif + +private: + FixedSizeAlignedSecBlock m_state; + int m_rounds; +}; + +/// Salsa20, variable rounds: 8, 12 or 20 (default 20) +struct Salsa20 : public Salsa20_Info, public SymmetricCipherDocumentation +{ + typedef SymmetricCipherFinal >, Salsa20_Info> Encryption; + typedef Encryption Decryption; +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/seal.cpp b/CryptoPP/crypto/seal.cpp new file mode 100644 index 0000000..0af3375 --- /dev/null +++ b/CryptoPP/crypto/seal.cpp @@ -0,0 +1,217 @@ +// seal.cpp - written and placed in the public domain by Wei Dai +// updated to SEAL 3.0 by Leonard Janke + +#include "pch.h" + +// prevent Sun's CC compiler from including this file automatically +#if !(defined(__SUNPRO_CC) && defined(CRYPTOPP_ITERHASH_H)) + +#include "seal.h" +#include "sha.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +void SEAL_TestInstantiations() +{ + SEAL<>::Encryption x; +} + +struct SEAL_Gamma +{ + SEAL_Gamma(const byte *key) + : H(5), Z(5), D(16), lastIndex(0xffffffff) + { + GetUserKey(BIG_ENDIAN_ORDER, H.begin(), 5, key, 20); + memset(D, 0, 64); + } + + word32 Apply(word32 i); + + SecBlock H, Z, D; + word32 lastIndex; +}; + +word32 SEAL_Gamma::Apply(word32 i) +{ + word32 shaIndex = i/5; + if (shaIndex != lastIndex) + { + memcpy(Z, H, 20); + D[0] = shaIndex; + SHA::Transform(Z, D); + lastIndex = shaIndex; + } + return Z[i%5]; +} + +template +void SEAL_Policy::CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length) +{ + m_insideCounter = m_outsideCounter = m_startCount = 0; + + unsigned int L = params.GetIntValueWithDefault("NumberOfOutputBitsPerPositionIndex", 32*1024); + m_iterationsPerCount = L / 8192; + + SEAL_Gamma gamma(key); + unsigned int i; + + for (i=0; i<512; i++) + m_T[i] = gamma.Apply(i); + + for (i=0; i<256; i++) + m_S[i] = gamma.Apply(0x1000+i); + + m_R.New(4*(L/8192)); + + for (i=0; i +void SEAL_Policy::CipherResynchronize(byte *keystreamBuffer, const byte *IV) +{ + m_outsideCounter = IV ? GetWord(false, BIG_ENDIAN_ORDER, IV) : 0; + m_startCount = m_outsideCounter; + m_insideCounter = 0; +} + +template +void SEAL_Policy::SeekToIteration(lword iterationCount) +{ + m_outsideCounter = m_startCount + (unsigned int)(iterationCount / m_iterationsPerCount); + m_insideCounter = (unsigned int)(iterationCount % m_iterationsPerCount); +} + +template +void SEAL_Policy::OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount) +{ + word32 a, b, c, d, n1, n2, n3, n4; + unsigned int p, q; + + for (size_t iteration = 0; iteration < iterationCount; ++iteration) + { +#define Ttab(x) *(word32 *)((byte *)m_T.begin()+x) + + a = m_outsideCounter ^ m_R[4*m_insideCounter]; + b = rotrFixed(m_outsideCounter, 8U) ^ m_R[4*m_insideCounter+1]; + c = rotrFixed(m_outsideCounter, 16U) ^ m_R[4*m_insideCounter+2]; + d = rotrFixed(m_outsideCounter, 24U) ^ m_R[4*m_insideCounter+3]; + + for (unsigned int j=0; j<2; j++) + { + p = a & 0x7fc; + b += Ttab(p); + a = rotrFixed(a, 9U); + + p = b & 0x7fc; + c += Ttab(p); + b = rotrFixed(b, 9U); + + p = c & 0x7fc; + d += Ttab(p); + c = rotrFixed(c, 9U); + + p = d & 0x7fc; + a += Ttab(p); + d = rotrFixed(d, 9U); + } + + n1 = d, n2 = b, n3 = a, n4 = c; + + p = a & 0x7fc; + b += Ttab(p); + a = rotrFixed(a, 9U); + + p = b & 0x7fc; + c += Ttab(p); + b = rotrFixed(b, 9U); + + p = c & 0x7fc; + d += Ttab(p); + c = rotrFixed(c, 9U); + + p = d & 0x7fc; + a += Ttab(p); + d = rotrFixed(d, 9U); + + // generate 8192 bits + for (unsigned int i=0; i<64; i++) + { + p = a & 0x7fc; + a = rotrFixed(a, 9U); + b += Ttab(p); + b ^= a; + + q = b & 0x7fc; + b = rotrFixed(b, 9U); + c ^= Ttab(q); + c += b; + + p = (p+c) & 0x7fc; + c = rotrFixed(c, 9U); + d += Ttab(p); + d ^= c; + + q = (q+d) & 0x7fc; + d = rotrFixed(d, 9U); + a ^= Ttab(q); + a += d; + + p = (p+a) & 0x7fc; + b ^= Ttab(p); + a = rotrFixed(a, 9U); + + q = (q+b) & 0x7fc; + c += Ttab(q); + b = rotrFixed(b, 9U); + + p = (p+c) & 0x7fc; + d ^= Ttab(p); + c = rotrFixed(c, 9U); + + q = (q+d) & 0x7fc; + d = rotrFixed(d, 9U); + a += Ttab(q); + +#define SEAL_OUTPUT(x) \ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 0, b + m_S[4*i+0]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 1, c ^ m_S[4*i+1]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 2, d + m_S[4*i+2]);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 3, a ^ m_S[4*i+3]); + + CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(SEAL_OUTPUT, 4*4); + + if (i & 1) + { + a += n3; + b += n4; + c ^= n3; + d ^= n4; + } + else + { + a += n1; + b += n2; + c ^= n1; + d ^= n2; + } + } + + if (++m_insideCounter == m_iterationsPerCount) + { + ++m_outsideCounter; + m_insideCounter = 0; + } + } + + a = b = c = d = n1 = n2 = n3 = n4 = 0; + p = q = 0; +} + +template class SEAL_Policy; +template class SEAL_Policy; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/seal.h b/CryptoPP/crypto/seal.h new file mode 100644 index 0000000..c8b7ff4 --- /dev/null +++ b/CryptoPP/crypto/seal.h @@ -0,0 +1,44 @@ +#ifndef CRYPTOPP_SEAL_H +#define CRYPTOPP_SEAL_H + +#include "strciphr.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! _ +template +struct SEAL_Info : public FixedKeyLength<20, SimpleKeyingInterface::INTERNALLY_GENERATED_IV, 4> +{ + static const char *StaticAlgorithmName() {return B::ToEnum() == LITTLE_ENDIAN_ORDER ? "SEAL-3.0-LE" : "SEAL-3.0-BE";} +}; + +template +class CRYPTOPP_NO_VTABLE SEAL_Policy : public AdditiveCipherConcretePolicy, public SEAL_Info +{ +protected: + void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length); + void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount); + void CipherResynchronize(byte *keystreamBuffer, const byte *IV); + bool IsRandomAccess() const {return true;} + void SeekToIteration(lword iterationCount); + +private: + FixedSizeSecBlock m_T; + FixedSizeSecBlock m_S; + SecBlock m_R; + + word32 m_startCount, m_iterationsPerCount; + word32 m_outsideCounter, m_insideCounter; +}; + +//! SEAL +template +struct SEAL : public SEAL_Info, public SymmetricCipherDocumentation +{ + typedef SymmetricCipherFinal, AdditiveCipherTemplate<> >, SEAL_Info > Encryption; + typedef Encryption Decryption; +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/secblock.h b/CryptoPP/crypto/secblock.h new file mode 100644 index 0000000..4c2b27b --- /dev/null +++ b/CryptoPP/crypto/secblock.h @@ -0,0 +1,500 @@ +// secblock.h - written and placed in the public domain by Wei Dai + +#ifndef CRYPTOPP_SECBLOCK_H +#define CRYPTOPP_SECBLOCK_H + +#include "config.h" +#include "misc.h" +#include + +#if defined(CRYPTOPP_MEMALIGN_AVAILABLE) || defined(CRYPTOPP_MM_MALLOC_AVAILABLE) || defined(QNX) + #include +#else + #include +#endif + +NAMESPACE_BEGIN(CryptoPP) + +// ************** secure memory allocation *************** + +template +class AllocatorBase +{ +public: + typedef T value_type; + typedef size_t size_type; +#ifdef CRYPTOPP_MSVCRT6 + typedef ptrdiff_t difference_type; +#else + typedef std::ptrdiff_t difference_type; +#endif + typedef T * pointer; + typedef const T * const_pointer; + typedef T & reference; + typedef const T & const_reference; + + pointer address(reference r) const {return (&r);} + const_pointer address(const_reference r) const {return (&r); } + void construct(pointer p, const T& val) {new (p) T(val);} + void destroy(pointer p) {p->~T();} + size_type max_size() const {return ~size_type(0)/sizeof(T);} // switch to std::numeric_limits::max later + +protected: + static void CheckSize(size_t n) + { + if (n > ~size_t(0) / sizeof(T)) + throw InvalidArgument("AllocatorBase: requested size would cause integer overflow"); + } +}; + +#define CRYPTOPP_INHERIT_ALLOCATOR_TYPES \ +typedef typename AllocatorBase::value_type value_type;\ +typedef typename AllocatorBase::size_type size_type;\ +typedef typename AllocatorBase::difference_type difference_type;\ +typedef typename AllocatorBase::pointer pointer;\ +typedef typename AllocatorBase::const_pointer const_pointer;\ +typedef typename AllocatorBase::reference reference;\ +typedef typename AllocatorBase::const_reference const_reference; + +#if defined(_MSC_VER) && (_MSC_VER < 1300) +// this pragma causes an internal compiler error if placed immediately before std::swap(a, b) +#pragma warning(push) +#pragma warning(disable: 4700) // VC60 workaround: don't know how to get rid of this warning +#endif + +template +typename A::pointer StandardReallocate(A& a, T *p, typename A::size_type oldSize, typename A::size_type newSize, bool preserve) +{ + if (oldSize == newSize) + return p; + + if (preserve) + { + typename A::pointer newPointer = a.allocate(newSize, NULL); + memcpy_s(newPointer, sizeof(T)*newSize, p, sizeof(T)*STDMIN(oldSize, newSize)); + a.deallocate(p, oldSize); + return newPointer; + } + else + { + a.deallocate(p, oldSize); + return a.allocate(newSize, NULL); + } +} + +#if defined(_MSC_VER) && (_MSC_VER < 1300) +#pragma warning(pop) +#endif + +template +class AllocatorWithCleanup : public AllocatorBase +{ +public: + CRYPTOPP_INHERIT_ALLOCATOR_TYPES + + pointer allocate(size_type n, const void * = NULL) + { + CheckSize(n); + if (n == 0) + return NULL; + + if (T_Align16 && n*sizeof(T) >= 16) + { + byte *p; + #ifdef CRYPTOPP_MM_MALLOC_AVAILABLE + while (!(p = (byte *)_mm_malloc(sizeof(T)*n, 16))) + #elif defined(CRYPTOPP_MEMALIGN_AVAILABLE) + while (!(p = (byte *)memalign(16, sizeof(T)*n))) + #elif defined(CRYPTOPP_MALLOC_ALIGNMENT_IS_16) + while (!(p = (byte *)malloc(sizeof(T)*n))) + #else + while (!(p = (byte *)malloc(sizeof(T)*n + 16))) + #endif + CallNewHandler(); + + #ifdef CRYPTOPP_NO_ALIGNED_ALLOC + size_t adjustment = 16-((size_t)p%16); + p += adjustment; + p[-1] = (byte)adjustment; + #endif + + assert(IsAlignedOn(p, 16)); + return (pointer)p; + } + + pointer p; + while (!(p = (pointer)malloc(sizeof(T)*n))) + CallNewHandler(); + return p; + } + + void deallocate(void *p, size_type n) + { + memset(p, 0, n*sizeof(T)); + + if (T_Align16 && n*sizeof(T) >= 16) + { + #ifdef CRYPTOPP_MM_MALLOC_AVAILABLE + _mm_free(p); + #elif defined(CRYPTOPP_NO_ALIGNED_ALLOC) + p = (byte *)p - ((byte *)p)[-1]; + free(p); + #else + free(p); + #endif + return; + } + + free(p); + } + + pointer reallocate(T *p, size_type oldSize, size_type newSize, bool preserve) + { + return StandardReallocate(*this, p, oldSize, newSize, preserve); + } + + // VS.NET STL enforces the policy of "All STL-compliant allocators have to provide a + // template class member called rebind". + template struct rebind { typedef AllocatorWithCleanup other; }; +#if _MSC_VER >= 1500 + AllocatorWithCleanup() {} + template AllocatorWithCleanup(const AllocatorWithCleanup &) {} +#endif +}; + +CRYPTOPP_DLL_TEMPLATE_CLASS AllocatorWithCleanup; +CRYPTOPP_DLL_TEMPLATE_CLASS AllocatorWithCleanup; +CRYPTOPP_DLL_TEMPLATE_CLASS AllocatorWithCleanup; +CRYPTOPP_DLL_TEMPLATE_CLASS AllocatorWithCleanup; +#if CRYPTOPP_BOOL_X86 +CRYPTOPP_DLL_TEMPLATE_CLASS AllocatorWithCleanup; // for Integer +#endif + +template +class NullAllocator : public AllocatorBase +{ +public: + CRYPTOPP_INHERIT_ALLOCATOR_TYPES + + pointer allocate(size_type n, const void * = NULL) + { + assert(false); + return NULL; + } + + void deallocate(void *p, size_type n) + { + assert(false); + } + + size_type max_size() const {return 0;} +}; + +// This allocator can't be used with standard collections because +// they require that all objects of the same allocator type are equivalent. +// So this is for use with SecBlock only. +template , bool T_Align16 = false> +class FixedSizeAllocatorWithCleanup : public AllocatorBase +{ +public: + CRYPTOPP_INHERIT_ALLOCATOR_TYPES + + FixedSizeAllocatorWithCleanup() : m_allocated(false) {} + + pointer allocate(size_type n) + { + assert(IsAlignedOn(m_array, 8)); + + if (n <= S && !m_allocated) + { + m_allocated = true; + return GetAlignedArray(); + } + else + return m_fallbackAllocator.allocate(n); + } + + pointer allocate(size_type n, const void *hint) + { + if (n <= S && !m_allocated) + { + m_allocated = true; + return GetAlignedArray(); + } + else + return m_fallbackAllocator.allocate(n, hint); + } + + void deallocate(void *p, size_type n) + { + if (p == GetAlignedArray()) + { + assert(n <= S); + assert(m_allocated); + m_allocated = false; + memset(p, 0, n*sizeof(T)); + } + else + m_fallbackAllocator.deallocate(p, n); + } + + pointer reallocate(pointer p, size_type oldSize, size_type newSize, bool preserve) + { + if (p == GetAlignedArray() && newSize <= S) + { + assert(oldSize <= S); + if (oldSize > newSize) + memset(p + newSize, 0, (oldSize-newSize)*sizeof(T)); + return p; + } + + pointer newPointer = allocate(newSize, NULL); + if (preserve) + memcpy(newPointer, p, sizeof(T)*STDMIN(oldSize, newSize)); + deallocate(p, oldSize); + return newPointer; + } + + size_type max_size() const {return STDMAX(m_fallbackAllocator.max_size(), S);} + +private: +#ifdef __BORLANDC__ + T* GetAlignedArray() {return m_array;} + T m_array[S]; +#else + T* GetAlignedArray() {return T_Align16 ? (T*)(((byte *)m_array) + (0-(size_t)m_array)%16) : m_array;} + CRYPTOPP_ALIGN_DATA(8) T m_array[T_Align16 ? S+8/sizeof(T) : S]; +#endif + A m_fallbackAllocator; + bool m_allocated; +}; + +//! a block of memory allocated using A +template > +class SecBlock +{ +public: + typedef typename A::value_type value_type; + typedef typename A::pointer iterator; + typedef typename A::const_pointer const_iterator; + typedef typename A::size_type size_type; + + explicit SecBlock(size_type size=0) + : m_size(size) {m_ptr = m_alloc.allocate(size, NULL);} + SecBlock(const SecBlock &t) + : m_size(t.m_size) {m_ptr = m_alloc.allocate(m_size, NULL); memcpy_s(m_ptr, m_size*sizeof(T), t.m_ptr, m_size*sizeof(T));} + SecBlock(const T *t, size_type len) + : m_size(len) + { + m_ptr = m_alloc.allocate(len, NULL); + if (t == NULL) + memset(m_ptr, 0, len*sizeof(T)); + else + memcpy(m_ptr, t, len*sizeof(T)); + } + + ~SecBlock() + {m_alloc.deallocate(m_ptr, m_size);} + +#ifdef __BORLANDC__ + operator T *() const + {return (T*)m_ptr;} +#else + operator const void *() const + {return m_ptr;} + operator void *() + {return m_ptr;} + + operator const T *() const + {return m_ptr;} + operator T *() + {return m_ptr;} +#endif + +// T *operator +(size_type offset) +// {return m_ptr+offset;} + +// const T *operator +(size_type offset) const +// {return m_ptr+offset;} + +// T& operator[](size_type index) +// {assert(index >= 0 && index < m_size); return m_ptr[index];} + +// const T& operator[](size_type index) const +// {assert(index >= 0 && index < m_size); return m_ptr[index];} + + iterator begin() + {return m_ptr;} + const_iterator begin() const + {return m_ptr;} + iterator end() + {return m_ptr+m_size;} + const_iterator end() const + {return m_ptr+m_size;} + + typename A::pointer data() {return m_ptr;} + typename A::const_pointer data() const {return m_ptr;} + + size_type size() const {return m_size;} + bool empty() const {return m_size == 0;} + + byte * BytePtr() {return (byte *)m_ptr;} + const byte * BytePtr() const {return (const byte *)m_ptr;} + size_type SizeInBytes() const {return m_size*sizeof(T);} + + //! set contents and size + void Assign(const T *t, size_type len) + { + New(len); + memcpy_s(m_ptr, m_size*sizeof(T), t, len*sizeof(T)); + } + + //! copy contents and size from another SecBlock + void Assign(const SecBlock &t) + { + New(t.m_size); + memcpy_s(m_ptr, m_size*sizeof(T), t.m_ptr, m_size*sizeof(T)); + } + + SecBlock& operator=(const SecBlock &t) + { + Assign(t); + return *this; + } + + // append to this object + SecBlock& operator+=(const SecBlock &t) + { + size_type oldSize = m_size; + Grow(m_size+t.m_size); + memcpy_s(m_ptr+oldSize, m_size*sizeof(T), t.m_ptr, t.m_size*sizeof(T)); + return *this; + } + + // append operator + SecBlock operator+(const SecBlock &t) + { + SecBlock result(m_size+t.m_size); + memcpy_s(result.m_ptr, result.m_size*sizeof(T), m_ptr, m_size*sizeof(T)); + memcpy_s(result.m_ptr+m_size, t.m_size*sizeof(T), t.m_ptr, t.m_size*sizeof(T)); + return result; + } + + bool operator==(const SecBlock &t) const + { + return m_size == t.m_size && memcmp(m_ptr, t.m_ptr, m_size*sizeof(T)) == 0; + } + + bool operator!=(const SecBlock &t) const + { + return !operator==(t); + } + + //! change size, without preserving contents + void New(size_type newSize) + { + m_ptr = m_alloc.reallocate(m_ptr, m_size, newSize, false); + m_size = newSize; + } + + //! change size and set contents to 0 + void CleanNew(size_type newSize) + { + New(newSize); + memset(m_ptr, 0, m_size*sizeof(T)); + } + + //! change size only if newSize > current size. contents are preserved + void Grow(size_type newSize) + { + if (newSize > m_size) + { + m_ptr = m_alloc.reallocate(m_ptr, m_size, newSize, true); + m_size = newSize; + } + } + + //! change size only if newSize > current size. contents are preserved and additional area is set to 0 + void CleanGrow(size_type newSize) + { + if (newSize > m_size) + { + m_ptr = m_alloc.reallocate(m_ptr, m_size, newSize, true); + memset(m_ptr+m_size, 0, (newSize-m_size)*sizeof(T)); + m_size = newSize; + } + } + + //! change size and preserve contents + void resize(size_type newSize) + { + m_ptr = m_alloc.reallocate(m_ptr, m_size, newSize, true); + m_size = newSize; + } + + //! swap contents and size with another SecBlock + void swap(SecBlock &b) + { + std::swap(m_alloc, b.m_alloc); + std::swap(m_size, b.m_size); + std::swap(m_ptr, b.m_ptr); + } + +//private: + A m_alloc; + size_type m_size; + T *m_ptr; +}; + +typedef SecBlock SecByteBlock; +typedef SecBlock > AlignedSecByteBlock; +typedef SecBlock SecWordBlock; + +//! a SecBlock with fixed size, allocated statically +template > +class FixedSizeSecBlock : public SecBlock +{ +public: + explicit FixedSizeSecBlock() : SecBlock(S) {} +}; + +template +class FixedSizeAlignedSecBlock : public FixedSizeSecBlock, T_Align16> > +{ +}; + +//! a SecBlock that preallocates size S statically, and uses the heap when this size is exceeded +template > > +class SecBlockWithHint : public SecBlock +{ +public: + explicit SecBlockWithHint(size_t size) : SecBlock(size) {} +}; + +template +inline bool operator==(const CryptoPP::AllocatorWithCleanup&, const CryptoPP::AllocatorWithCleanup&) {return (true);} +template +inline bool operator!=(const CryptoPP::AllocatorWithCleanup&, const CryptoPP::AllocatorWithCleanup&) {return (false);} + +NAMESPACE_END + +NAMESPACE_BEGIN(std) +template +inline void swap(CryptoPP::SecBlock &a, CryptoPP::SecBlock &b) +{ + a.swap(b); +} + +#if defined(_STLP_DONT_SUPPORT_REBIND_MEMBER_TEMPLATE) || (defined(_STLPORT_VERSION) && !defined(_STLP_MEMBER_TEMPLATE_CLASSES)) +// working for STLport 5.1.3 and MSVC 6 SP5 +template +inline CryptoPP::AllocatorWithCleanup<_Tp2>& +__stl_alloc_rebind(CryptoPP::AllocatorWithCleanup<_Tp1>& __a, const _Tp2*) +{ + return (CryptoPP::AllocatorWithCleanup<_Tp2>&)(__a); +} +#endif + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/seckey.h b/CryptoPP/crypto/seckey.h new file mode 100644 index 0000000..5bd8f9a --- /dev/null +++ b/CryptoPP/crypto/seckey.h @@ -0,0 +1,211 @@ +// seckey.h - written and placed in the public domain by Wei Dai + +// This file contains helper classes/functions for implementing secret key algorithms. + +#ifndef CRYPTOPP_SECKEY_H +#define CRYPTOPP_SECKEY_H + +#include "cryptlib.h" +#include "misc.h" +#include "simple.h" + +NAMESPACE_BEGIN(CryptoPP) + +inline CipherDir ReverseCipherDir(CipherDir dir) +{ + return (dir == ENCRYPTION) ? DECRYPTION : ENCRYPTION; +} + +//! to be inherited by block ciphers with fixed block size +template +class FixedBlockSize +{ +public: + CRYPTOPP_CONSTANT(BLOCKSIZE = N) +}; + +// ************** rounds *************** + +//! to be inherited by ciphers with fixed number of rounds +template +class FixedRounds +{ +public: + CRYPTOPP_CONSTANT(ROUNDS = R) +}; + +//! to be inherited by ciphers with variable number of rounds +template // use INT_MAX here because enums are treated as signed ints +class VariableRounds +{ +public: + CRYPTOPP_CONSTANT(DEFAULT_ROUNDS = D) + CRYPTOPP_CONSTANT(MIN_ROUNDS = N) + CRYPTOPP_CONSTANT(MAX_ROUNDS = M) + static unsigned int StaticGetDefaultRounds(size_t keylength) {return DEFAULT_ROUNDS;} + +protected: + inline void ThrowIfInvalidRounds(int rounds, const Algorithm *alg) + { + if (rounds < MIN_ROUNDS || rounds > MAX_ROUNDS) + throw InvalidRounds(alg->AlgorithmName(), rounds); + } + + inline unsigned int GetRoundsAndThrowIfInvalid(const NameValuePairs ¶m, const Algorithm *alg) + { + int rounds = param.GetIntValueWithDefault("Rounds", DEFAULT_ROUNDS); + ThrowIfInvalidRounds(rounds, alg); + return (unsigned int)rounds; + } +}; + +// ************** key length *************** + +//! to be inherited by keyed algorithms with fixed key length +template +class FixedKeyLength +{ +public: + CRYPTOPP_CONSTANT(KEYLENGTH=N) + CRYPTOPP_CONSTANT(MIN_KEYLENGTH=N) + CRYPTOPP_CONSTANT(MAX_KEYLENGTH=N) + CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH=N) + CRYPTOPP_CONSTANT(IV_REQUIREMENT = IV_REQ) + CRYPTOPP_CONSTANT(IV_LENGTH = IV_L) + static size_t CRYPTOPP_API StaticGetValidKeyLength(size_t) {return KEYLENGTH;} +}; + +/// support query of variable key length, template parameters are default, min, max, multiple (default multiple 1) +template +class VariableKeyLength +{ + // make these private to avoid Doxygen documenting them in all derived classes + CRYPTOPP_COMPILE_ASSERT(Q > 0); + CRYPTOPP_COMPILE_ASSERT(N % Q == 0); + CRYPTOPP_COMPILE_ASSERT(M % Q == 0); + CRYPTOPP_COMPILE_ASSERT(N < M); + CRYPTOPP_COMPILE_ASSERT(D >= N); + CRYPTOPP_COMPILE_ASSERT(M >= D); + +public: + CRYPTOPP_CONSTANT(MIN_KEYLENGTH=N) + CRYPTOPP_CONSTANT(MAX_KEYLENGTH=M) + CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH=D) + CRYPTOPP_CONSTANT(KEYLENGTH_MULTIPLE=Q) + CRYPTOPP_CONSTANT(IV_REQUIREMENT=IV_REQ) + CRYPTOPP_CONSTANT(IV_LENGTH=IV_L) + + static size_t CRYPTOPP_API StaticGetValidKeyLength(size_t n) + { + if (n < (size_t)MIN_KEYLENGTH) + return MIN_KEYLENGTH; + else if (n > (size_t)MAX_KEYLENGTH) + return (size_t)MAX_KEYLENGTH; + else + { + n += KEYLENGTH_MULTIPLE-1; + return n - n%KEYLENGTH_MULTIPLE; + } + } +}; + +/// support query of key length that's the same as another class +template +class SameKeyLengthAs +{ +public: + CRYPTOPP_CONSTANT(MIN_KEYLENGTH=T::MIN_KEYLENGTH) + CRYPTOPP_CONSTANT(MAX_KEYLENGTH=T::MAX_KEYLENGTH) + CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH=T::DEFAULT_KEYLENGTH) + CRYPTOPP_CONSTANT(IV_REQUIREMENT=IV_REQ) + CRYPTOPP_CONSTANT(IV_LENGTH=IV_L) + + static size_t CRYPTOPP_API StaticGetValidKeyLength(size_t keylength) + {return T::StaticGetValidKeyLength(keylength);} +}; + +// ************** implementation helper for SimpleKeyed *************** + +//! _ +template +class CRYPTOPP_NO_VTABLE SimpleKeyingInterfaceImpl : public BASE +{ +public: + size_t MinKeyLength() const {return INFO::MIN_KEYLENGTH;} + size_t MaxKeyLength() const {return (size_t)INFO::MAX_KEYLENGTH;} + size_t DefaultKeyLength() const {return INFO::DEFAULT_KEYLENGTH;} + size_t GetValidKeyLength(size_t n) const {return INFO::StaticGetValidKeyLength(n);} + SimpleKeyingInterface::IV_Requirement IVRequirement() const {return (SimpleKeyingInterface::IV_Requirement)INFO::IV_REQUIREMENT;} + unsigned int IVSize() const {return INFO::IV_LENGTH;} +}; + +template +class CRYPTOPP_NO_VTABLE BlockCipherImpl : public AlgorithmImpl > > +{ +public: + unsigned int BlockSize() const {return this->BLOCKSIZE;} +}; + +//! _ +template +class BlockCipherFinal : public ClonableImpl, BASE> +{ +public: + BlockCipherFinal() {} + BlockCipherFinal(const byte *key) + {this->SetKey(key, this->DEFAULT_KEYLENGTH);} + BlockCipherFinal(const byte *key, size_t length) + {this->SetKey(key, length);} + BlockCipherFinal(const byte *key, size_t length, unsigned int rounds) + {this->SetKeyWithRounds(key, length, rounds);} + + bool IsForwardTransformation() const {return DIR == ENCRYPTION;} +}; + +//! _ +template +class MessageAuthenticationCodeImpl : public AlgorithmImpl, INFO> +{ +}; + +//! _ +template +class MessageAuthenticationCodeFinal : public ClonableImpl, MessageAuthenticationCodeImpl > +{ +public: + MessageAuthenticationCodeFinal() {} + MessageAuthenticationCodeFinal(const byte *key) + {this->SetKey(key, this->DEFAULT_KEYLENGTH);} + MessageAuthenticationCodeFinal(const byte *key, size_t length) + {this->SetKey(key, length);} +}; + +// ************** documentation *************** + +//! These objects usually should not be used directly. See CipherModeDocumentation instead. +/*! Each class derived from this one defines two types, Encryption and Decryption, + both of which implement the BlockCipher interface. */ +struct BlockCipherDocumentation +{ + //! implements the BlockCipher interface + typedef BlockCipher Encryption; + //! implements the BlockCipher interface + typedef BlockCipher Decryption; +}; + +/*! \brief Each class derived from this one defines two types, Encryption and Decryption, + both of which implement the SymmetricCipher interface. Two types of classes derive + from this class: stream ciphers and block cipher modes. Stream ciphers can be used + alone, cipher mode classes need to be used with a block cipher. See CipherModeDocumentation + for more for information about using cipher modes and block ciphers. */ +struct SymmetricCipherDocumentation +{ + //! implements the SymmetricCipher interface + typedef SymmetricCipher Encryption; + //! implements the SymmetricCipher interface + typedef SymmetricCipher Decryption; +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/serpent.cpp b/CryptoPP/crypto/serpent.cpp new file mode 100644 index 0000000..068e642 --- /dev/null +++ b/CryptoPP/crypto/serpent.cpp @@ -0,0 +1,123 @@ +// serpent.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "serpent.h" +#include "misc.h" + +#include "serpentp.h" + +NAMESPACE_BEGIN(CryptoPP) + +void Serpent_KeySchedule(word32 *k, unsigned int rounds, const byte *userKey, size_t keylen) +{ + FixedSizeSecBlock k0; + GetUserKey(LITTLE_ENDIAN_ORDER, k0.begin(), 8, userKey, keylen); + if (keylen < 32) + k0[keylen/4] |= word32(1) << ((keylen%4)*8); + + word32 t = k0[7]; + unsigned int i; + for (i = 0; i < 8; ++i) + k[i] = k0[i] = t = rotlFixed(k0[i] ^ k0[(i+3)%8] ^ k0[(i+5)%8] ^ t ^ 0x9e3779b9 ^ i, 11); + for (i = 8; i < 4*(rounds+1); ++i) + k[i] = t = rotlFixed(k[i-8] ^ k[i-5] ^ k[i-3] ^ t ^ 0x9e3779b9 ^ i, 11); + k -= 20; + + word32 a,b,c,d,e; + for (i=0; i Block; + +void Serpent::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word32 a, b, c, d, e; + + Block::Get(inBlock)(a)(b)(c)(d); + + const word32 *k = m_key; + unsigned int i=1; + + do + { + beforeS0(KX); beforeS0(S0); afterS0(LT); + afterS0(KX); afterS0(S1); afterS1(LT); + afterS1(KX); afterS1(S2); afterS2(LT); + afterS2(KX); afterS2(S3); afterS3(LT); + afterS3(KX); afterS3(S4); afterS4(LT); + afterS4(KX); afterS4(S5); afterS5(LT); + afterS5(KX); afterS5(S6); afterS6(LT); + afterS6(KX); afterS6(S7); + + if (i == 4) + break; + + ++i; + c = b; + b = e; + e = d; + d = a; + a = e; + k += 32; + beforeS0(LT); + } + while (true); + + afterS7(KX); + + Block::Put(xorBlock, outBlock)(d)(e)(b)(a); +} + +void Serpent::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word32 a, b, c, d, e; + + Block::Get(inBlock)(a)(b)(c)(d); + + const word32 *k = m_key + 96; + unsigned int i=4; + + beforeI7(KX); + goto start; + + do + { + c = b; + b = d; + d = e; + k -= 32; + beforeI7(ILT); +start: + beforeI7(I7); afterI7(KX); + afterI7(ILT); afterI7(I6); afterI6(KX); + afterI6(ILT); afterI6(I5); afterI5(KX); + afterI5(ILT); afterI5(I4); afterI4(KX); + afterI4(ILT); afterI4(I3); afterI3(KX); + afterI3(ILT); afterI3(I2); afterI2(KX); + afterI2(ILT); afterI2(I1); afterI1(KX); + afterI1(ILT); afterI1(I0); afterI0(KX); + } + while (--i != 0); + + Block::Put(xorBlock, outBlock)(a)(d)(b)(e); +} + +NAMESPACE_END diff --git a/CryptoPP/crypto/serpent.h b/CryptoPP/crypto/serpent.h new file mode 100644 index 0000000..900ea76 --- /dev/null +++ b/CryptoPP/crypto/serpent.h @@ -0,0 +1,52 @@ +#ifndef CRYPTOPP_SERPENT_H +#define CRYPTOPP_SERPENT_H + +/** \file +*/ + +#include "seckey.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! _ +struct Serpent_Info : public FixedBlockSize<16>, public VariableKeyLength<16, 1, 32>, public FixedRounds<32> +{ + static const char *StaticAlgorithmName() {return "Serpent";} +}; + +/// Serpent +class Serpent : public Serpent_Info, public BlockCipherDocumentation +{ + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + public: + void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); + + protected: + FixedSizeSecBlock m_key; + }; + + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef Serpent::Encryption SerpentEncryption; +typedef Serpent::Decryption SerpentDecryption; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/serpentp.h b/CryptoPP/crypto/serpentp.h new file mode 100644 index 0000000..4416b5d --- /dev/null +++ b/CryptoPP/crypto/serpentp.h @@ -0,0 +1,434 @@ +// private header for Serpent and Sosemanuk + +NAMESPACE_BEGIN(CryptoPP) + +// linear transformation +#define LT(i,a,b,c,d,e) {\ + a = rotlFixed(a, 13); \ + c = rotlFixed(c, 3); \ + d = rotlFixed(d ^ c ^ (a << 3), 7); \ + b = rotlFixed(b ^ a ^ c, 1); \ + a = rotlFixed(a ^ b ^ d, 5); \ + c = rotlFixed(c ^ d ^ (b << 7), 22);} + +// inverse linear transformation +#define ILT(i,a,b,c,d,e) {\ + c = rotrFixed(c, 22); \ + a = rotrFixed(a, 5); \ + c ^= d ^ (b << 7); \ + a ^= b ^ d; \ + b = rotrFixed(b, 1); \ + d = rotrFixed(d, 7) ^ c ^ (a << 3); \ + b ^= a ^ c; \ + c = rotrFixed(c, 3); \ + a = rotrFixed(a, 13);} + +// order of output from S-box functions +#define beforeS0(f) f(0,a,b,c,d,e) +#define afterS0(f) f(1,b,e,c,a,d) +#define afterS1(f) f(2,c,b,a,e,d) +#define afterS2(f) f(3,a,e,b,d,c) +#define afterS3(f) f(4,e,b,d,c,a) +#define afterS4(f) f(5,b,a,e,c,d) +#define afterS5(f) f(6,a,c,b,e,d) +#define afterS6(f) f(7,a,c,d,b,e) +#define afterS7(f) f(8,d,e,b,a,c) + +// order of output from inverse S-box functions +#define beforeI7(f) f(8,a,b,c,d,e) +#define afterI7(f) f(7,d,a,b,e,c) +#define afterI6(f) f(6,a,b,c,e,d) +#define afterI5(f) f(5,b,d,e,c,a) +#define afterI4(f) f(4,b,c,e,a,d) +#define afterI3(f) f(3,a,b,e,c,d) +#define afterI2(f) f(2,b,d,e,c,a) +#define afterI1(f) f(1,a,b,c,e,d) +#define afterI0(f) f(0,a,d,b,e,c) + +// The instruction sequences for the S-box functions +// come from Dag Arne Osvik's paper "Speeding up Serpent". + +#define S0(i, r0, r1, r2, r3, r4) \ + { \ + r3 ^= r0; \ + r4 = r1; \ + r1 &= r3; \ + r4 ^= r2; \ + r1 ^= r0; \ + r0 |= r3; \ + r0 ^= r4; \ + r4 ^= r3; \ + r3 ^= r2; \ + r2 |= r1; \ + r2 ^= r4; \ + r4 = ~r4; \ + r4 |= r1; \ + r1 ^= r3; \ + r1 ^= r4; \ + r3 |= r0; \ + r1 ^= r3; \ + r4 ^= r3; \ + } + +#define I0(i, r0, r1, r2, r3, r4) \ + { \ + r2 = ~r2; \ + r4 = r1; \ + r1 |= r0; \ + r4 = ~r4; \ + r1 ^= r2; \ + r2 |= r4; \ + r1 ^= r3; \ + r0 ^= r4; \ + r2 ^= r0; \ + r0 &= r3; \ + r4 ^= r0; \ + r0 |= r1; \ + r0 ^= r2; \ + r3 ^= r4; \ + r2 ^= r1; \ + r3 ^= r0; \ + r3 ^= r1; \ + r2 &= r3; \ + r4 ^= r2; \ + } + +#define S1(i, r0, r1, r2, r3, r4) \ + { \ + r0 = ~r0; \ + r2 = ~r2; \ + r4 = r0; \ + r0 &= r1; \ + r2 ^= r0; \ + r0 |= r3; \ + r3 ^= r2; \ + r1 ^= r0; \ + r0 ^= r4; \ + r4 |= r1; \ + r1 ^= r3; \ + r2 |= r0; \ + r2 &= r4; \ + r0 ^= r1; \ + r1 &= r2; \ + r1 ^= r0; \ + r0 &= r2; \ + r0 ^= r4; \ + } + +#define I1(i, r0, r1, r2, r3, r4) \ + { \ + r4 = r1; \ + r1 ^= r3; \ + r3 &= r1; \ + r4 ^= r2; \ + r3 ^= r0; \ + r0 |= r1; \ + r2 ^= r3; \ + r0 ^= r4; \ + r0 |= r2; \ + r1 ^= r3; \ + r0 ^= r1; \ + r1 |= r3; \ + r1 ^= r0; \ + r4 = ~r4; \ + r4 ^= r1; \ + r1 |= r0; \ + r1 ^= r0; \ + r1 |= r4; \ + r3 ^= r1; \ + } + +#define S2(i, r0, r1, r2, r3, r4) \ + { \ + r4 = r0; \ + r0 &= r2; \ + r0 ^= r3; \ + r2 ^= r1; \ + r2 ^= r0; \ + r3 |= r4; \ + r3 ^= r1; \ + r4 ^= r2; \ + r1 = r3; \ + r3 |= r4; \ + r3 ^= r0; \ + r0 &= r1; \ + r4 ^= r0; \ + r1 ^= r3; \ + r1 ^= r4; \ + r4 = ~r4; \ + } + +#define I2(i, r0, r1, r2, r3, r4) \ + { \ + r2 ^= r3; \ + r3 ^= r0; \ + r4 = r3; \ + r3 &= r2; \ + r3 ^= r1; \ + r1 |= r2; \ + r1 ^= r4; \ + r4 &= r3; \ + r2 ^= r3; \ + r4 &= r0; \ + r4 ^= r2; \ + r2 &= r1; \ + r2 |= r0; \ + r3 = ~r3; \ + r2 ^= r3; \ + r0 ^= r3; \ + r0 &= r1; \ + r3 ^= r4; \ + r3 ^= r0; \ + } + +#define S3(i, r0, r1, r2, r3, r4) \ + { \ + r4 = r0; \ + r0 |= r3; \ + r3 ^= r1; \ + r1 &= r4; \ + r4 ^= r2; \ + r2 ^= r3; \ + r3 &= r0; \ + r4 |= r1; \ + r3 ^= r4; \ + r0 ^= r1; \ + r4 &= r0; \ + r1 ^= r3; \ + r4 ^= r2; \ + r1 |= r0; \ + r1 ^= r2; \ + r0 ^= r3; \ + r2 = r1; \ + r1 |= r3; \ + r1 ^= r0; \ + } + +#define I3(i, r0, r1, r2, r3, r4) \ + { \ + r4 = r2; \ + r2 ^= r1; \ + r1 &= r2; \ + r1 ^= r0; \ + r0 &= r4; \ + r4 ^= r3; \ + r3 |= r1; \ + r3 ^= r2; \ + r0 ^= r4; \ + r2 ^= r0; \ + r0 |= r3; \ + r0 ^= r1; \ + r4 ^= r2; \ + r2 &= r3; \ + r1 |= r3; \ + r1 ^= r2; \ + r4 ^= r0; \ + r2 ^= r4; \ + } + +#define S4(i, r0, r1, r2, r3, r4) \ + { \ + r1 ^= r3; \ + r3 = ~r3; \ + r2 ^= r3; \ + r3 ^= r0; \ + r4 = r1; \ + r1 &= r3; \ + r1 ^= r2; \ + r4 ^= r3; \ + r0 ^= r4; \ + r2 &= r4; \ + r2 ^= r0; \ + r0 &= r1; \ + r3 ^= r0; \ + r4 |= r1; \ + r4 ^= r0; \ + r0 |= r3; \ + r0 ^= r2; \ + r2 &= r3; \ + r0 = ~r0; \ + r4 ^= r2; \ + } + +#define I4(i, r0, r1, r2, r3, r4) \ + { \ + r4 = r2; \ + r2 &= r3; \ + r2 ^= r1; \ + r1 |= r3; \ + r1 &= r0; \ + r4 ^= r2; \ + r4 ^= r1; \ + r1 &= r2; \ + r0 = ~r0; \ + r3 ^= r4; \ + r1 ^= r3; \ + r3 &= r0; \ + r3 ^= r2; \ + r0 ^= r1; \ + r2 &= r0; \ + r3 ^= r0; \ + r2 ^= r4; \ + r2 |= r3; \ + r3 ^= r0; \ + r2 ^= r1; \ + } + +#define S5(i, r0, r1, r2, r3, r4) \ + { \ + r0 ^= r1; \ + r1 ^= r3; \ + r3 = ~r3; \ + r4 = r1; \ + r1 &= r0; \ + r2 ^= r3; \ + r1 ^= r2; \ + r2 |= r4; \ + r4 ^= r3; \ + r3 &= r1; \ + r3 ^= r0; \ + r4 ^= r1; \ + r4 ^= r2; \ + r2 ^= r0; \ + r0 &= r3; \ + r2 = ~r2; \ + r0 ^= r4; \ + r4 |= r3; \ + r2 ^= r4; \ + } + +#define I5(i, r0, r1, r2, r3, r4) \ + { \ + r1 = ~r1; \ + r4 = r3; \ + r2 ^= r1; \ + r3 |= r0; \ + r3 ^= r2; \ + r2 |= r1; \ + r2 &= r0; \ + r4 ^= r3; \ + r2 ^= r4; \ + r4 |= r0; \ + r4 ^= r1; \ + r1 &= r2; \ + r1 ^= r3; \ + r4 ^= r2; \ + r3 &= r4; \ + r4 ^= r1; \ + r3 ^= r0; \ + r3 ^= r4; \ + r4 = ~r4; \ + } + +#define S6(i, r0, r1, r2, r3, r4) \ + { \ + r2 = ~r2; \ + r4 = r3; \ + r3 &= r0; \ + r0 ^= r4; \ + r3 ^= r2; \ + r2 |= r4; \ + r1 ^= r3; \ + r2 ^= r0; \ + r0 |= r1; \ + r2 ^= r1; \ + r4 ^= r0; \ + r0 |= r3; \ + r0 ^= r2; \ + r4 ^= r3; \ + r4 ^= r0; \ + r3 = ~r3; \ + r2 &= r4; \ + r2 ^= r3; \ + } + +#define I6(i, r0, r1, r2, r3, r4) \ + { \ + r0 ^= r2; \ + r4 = r2; \ + r2 &= r0; \ + r4 ^= r3; \ + r2 = ~r2; \ + r3 ^= r1; \ + r2 ^= r3; \ + r4 |= r0; \ + r0 ^= r2; \ + r3 ^= r4; \ + r4 ^= r1; \ + r1 &= r3; \ + r1 ^= r0; \ + r0 ^= r3; \ + r0 |= r2; \ + r3 ^= r1; \ + r4 ^= r0; \ + } + +#define S7(i, r0, r1, r2, r3, r4) \ + { \ + r4 = r2; \ + r2 &= r1; \ + r2 ^= r3; \ + r3 &= r1; \ + r4 ^= r2; \ + r2 ^= r1; \ + r1 ^= r0; \ + r0 |= r4; \ + r0 ^= r2; \ + r3 ^= r1; \ + r2 ^= r3; \ + r3 &= r0; \ + r3 ^= r4; \ + r4 ^= r2; \ + r2 &= r0; \ + r4 = ~r4; \ + r2 ^= r4; \ + r4 &= r0; \ + r1 ^= r3; \ + r4 ^= r1; \ + } + +#define I7(i, r0, r1, r2, r3, r4) \ + { \ + r4 = r2; \ + r2 ^= r0; \ + r0 &= r3; \ + r2 = ~r2; \ + r4 |= r3; \ + r3 ^= r1; \ + r1 |= r0; \ + r0 ^= r2; \ + r2 &= r4; \ + r1 ^= r2; \ + r2 ^= r0; \ + r0 |= r2; \ + r3 &= r4; \ + r0 ^= r3; \ + r4 ^= r1; \ + r3 ^= r4; \ + r4 |= r0; \ + r3 ^= r2; \ + r4 ^= r2; \ + } + +// key xor +#define KX(r, a, b, c, d, e) {\ + a ^= k[4 * r + 0]; \ + b ^= k[4 * r + 1]; \ + c ^= k[4 * r + 2]; \ + d ^= k[4 * r + 3];} + +#define LK(r, a, b, c, d, e) {\ + a = k[(8-r)*4 + 0]; \ + b = k[(8-r)*4 + 1]; \ + c = k[(8-r)*4 + 2]; \ + d = k[(8-r)*4 + 3];} + +#define SK(r, a, b, c, d, e) {\ + k[(8-r)*4 + 4] = a; \ + k[(8-r)*4 + 5] = b; \ + k[(8-r)*4 + 6] = c; \ + k[(8-r)*4 + 7] = d;} + +void Serpent_KeySchedule(word32 *k, unsigned int rounds, const byte *userKey, size_t keylen); + +NAMESPACE_END diff --git a/CryptoPP/crypto/serpentv.dat b/CryptoPP/crypto/serpentv.dat new file mode 100644 index 0000000..38ee88b --- /dev/null +++ b/CryptoPP/crypto/serpentv.dat @@ -0,0 +1,9 @@ +00000000000000000000000000000000 d29d576fcea3a3a7ed9099f29273d78e b2288b968ae8b08648d1ce9606fd992d +00000000000000000000000000000000 d29d576fcea3a3a7ed9099f26d8c2871 563a8403ff5309d62370b1dcf5a11edd +ffeeddccbbaa99887766554433221100 1032547698badcfeefcdab8967452301 d5baa00a4bb9d8a7c981c8dc90d89d92 +ffeeddccbbaa99887766554433221100 145f0b8b663176b95dcab7e9dcd5cc24 1032547698badcfeefcdab8967452301 +000000000000000000000000000000000000000000000000 d29d576fceaba3a7ed9899f2927bd78e 130e353e1037c22405e8faefb2c3c3e9 +8899aabbccddeeffffeeddccbbaa99887766554433221100 1032547698badcfeefcdab8967452301 da860842b720802bf404a4c71034879a +8899aabbccddeeffffeeddccbbaa99887766554433221100 b2696bd0d98c17953e4239225d27202c 1032547698badcfeefcdab8967452301 +0000000000000000000000000000000000000000000000000000000000000000 92074732d84e1841a013a0034c52bf50 81c4eb7b8ad9a8d0f2aa5d7bd626b560 +00112233445566778899aabbccddeeffffeeddccbbaa99887766554433221100 1032547698badcfeefcdab8967452301 93df9a3cafe387bd999eebe393a17fca diff --git a/CryptoPP/crypto/sha.cpp b/CryptoPP/crypto/sha.cpp new file mode 100644 index 0000000..ba20fc0 --- /dev/null +++ b/CryptoPP/crypto/sha.cpp @@ -0,0 +1,553 @@ +// sha.cpp - modified by Wei Dai from Steve Reid's public domain sha1.c + +// Steve Reid implemented SHA-1. Wei Dai implemented SHA-2. +// Both are in the public domain. + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "sha.h" +#include "misc.h" +#include "cpu.h" + +NAMESPACE_BEGIN(CryptoPP) + +// start of Steve Reid's code + +#define blk0(i) (W[i] = data[i]) +#define blk1(i) (W[i&15] = rotlFixed(W[(i+13)&15]^W[(i+8)&15]^W[(i+2)&15]^W[i&15],1)) + +void SHA1::InitState(HashWordType *state) +{ + state[0] = 0x67452301L; + state[1] = 0xEFCDAB89L; + state[2] = 0x98BADCFEL; + state[3] = 0x10325476L; + state[4] = 0xC3D2E1F0L; +} + +#define f1(x,y,z) (z^(x&(y^z))) +#define f2(x,y,z) (x^y^z) +#define f3(x,y,z) ((x&y)|(z&(x|y))) +#define f4(x,y,z) (x^y^z) + +/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ +#define R0(v,w,x,y,z,i) z+=f1(w,x,y)+blk0(i)+0x5A827999+rotlFixed(v,5);w=rotlFixed(w,30); +#define R1(v,w,x,y,z,i) z+=f1(w,x,y)+blk1(i)+0x5A827999+rotlFixed(v,5);w=rotlFixed(w,30); +#define R2(v,w,x,y,z,i) z+=f2(w,x,y)+blk1(i)+0x6ED9EBA1+rotlFixed(v,5);w=rotlFixed(w,30); +#define R3(v,w,x,y,z,i) z+=f3(w,x,y)+blk1(i)+0x8F1BBCDC+rotlFixed(v,5);w=rotlFixed(w,30); +#define R4(v,w,x,y,z,i) z+=f4(w,x,y)+blk1(i)+0xCA62C1D6+rotlFixed(v,5);w=rotlFixed(w,30); + +void SHA1::Transform(word32 *state, const word32 *data) +{ + word32 W[16]; + /* Copy context->state[] to working vars */ + word32 a = state[0]; + word32 b = state[1]; + word32 c = state[2]; + word32 d = state[3]; + word32 e = state[4]; + /* 4 rounds of 20 operations each. Loop unrolled. */ + R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); + R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); + R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); + R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); + R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); + R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); + R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); + R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); + R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); + R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); + R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); + R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); + R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); + R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); + R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); + R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); + R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); + R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); + R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); + R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); + /* Add the working vars back into context.state[] */ + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; +} + +// end of Steve Reid's code + +// ************************************************************* + +void SHA224::InitState(HashWordType *state) +{ + static const word32 s[8] = {0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4}; + memcpy(state, s, sizeof(s)); +} + +void SHA256::InitState(HashWordType *state) +{ + static const word32 s[8] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}; + memcpy(state, s, sizeof(s)); +} + +static const word32 SHA256_K[64] = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, + 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, + 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, + 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, + 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +}; + +#define blk2(i) (W[i&15]+=s1(W[(i-2)&15])+W[(i-7)&15]+s0(W[(i-15)&15])) + +#define Ch(x,y,z) (z^(x&(y^z))) +#define Maj(x,y,z) ((x&y)|(z&(x|y))) + +#define a(i) T[(0-i)&7] +#define b(i) T[(1-i)&7] +#define c(i) T[(2-i)&7] +#define d(i) T[(3-i)&7] +#define e(i) T[(4-i)&7] +#define f(i) T[(5-i)&7] +#define g(i) T[(6-i)&7] +#define h(i) T[(7-i)&7] + +#define R(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+SHA256_K[i+j]+(j?blk2(i):blk0(i));\ + d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i)) + +// for SHA256 +#define S0(x) (rotrFixed(x,2)^rotrFixed(x,13)^rotrFixed(x,22)) +#define S1(x) (rotrFixed(x,6)^rotrFixed(x,11)^rotrFixed(x,25)) +#define s0(x) (rotrFixed(x,7)^rotrFixed(x,18)^(x>>3)) +#define s1(x) (rotrFixed(x,17)^rotrFixed(x,19)^(x>>10)) + +void SHA256::Transform(word32 *state, const word32 *data) +{ + word32 W[16]; + word32 T[8]; + /* Copy context->state[] to working vars */ + memcpy(T, state, sizeof(T)); + /* 64 operations, partially loop unrolled */ + for (unsigned int j=0; j<64; j+=16) + { + R( 0); R( 1); R( 2); R( 3); + R( 4); R( 5); R( 6); R( 7); + R( 8); R( 9); R(10); R(11); + R(12); R(13); R(14); R(15); + } + /* Add the working vars back into context.state[] */ + state[0] += a(0); + state[1] += b(0); + state[2] += c(0); + state[3] += d(0); + state[4] += e(0); + state[5] += f(0); + state[6] += g(0); + state[7] += h(0); +} + +/* +// smaller but slower +void SHA256_Transform(word32 *state, const word32 *data) +{ + word32 T[20]; + word32 W[32]; + unsigned int i = 0, j = 0; + word32 *t = T+8; + + memcpy(t, state, 8*4); + word32 e = t[4], a = t[0]; + + do + { + word32 w = data[j]; + W[j] = w; + w += K[j]; + w += t[7]; + w += S1(e); + w += Ch(e, t[5], t[6]); + e = t[3] + w; + t[3] = t[3+8] = e; + w += S0(t[0]); + a = w + Maj(a, t[1], t[2]); + t[-1] = t[7] = a; + --t; + ++j; + if (j%8 == 0) + t += 8; + } while (j<16); + + do + { + i = j&0xf; + word32 w = s1(W[i+16-2]) + s0(W[i+16-15]) + W[i] + W[i+16-7]; + W[i+16] = W[i] = w; + w += K[j]; + w += t[7]; + w += S1(e); + w += Ch(e, t[5], t[6]); + e = t[3] + w; + t[3] = t[3+8] = e; + w += S0(t[0]); + a = w + Maj(a, t[1], t[2]); + t[-1] = t[7] = a; + + w = s1(W[(i+1)+16-2]) + s0(W[(i+1)+16-15]) + W[(i+1)] + W[(i+1)+16-7]; + W[(i+1)+16] = W[(i+1)] = w; + w += K[j+1]; + w += (t-1)[7]; + w += S1(e); + w += Ch(e, (t-1)[5], (t-1)[6]); + e = (t-1)[3] + w; + (t-1)[3] = (t-1)[3+8] = e; + w += S0((t-1)[0]); + a = w + Maj(a, (t-1)[1], (t-1)[2]); + (t-1)[-1] = (t-1)[7] = a; + + t-=2; + j+=2; + if (j%8 == 0) + t += 8; + } while (j<64); + + state[0] += a; + state[1] += t[1]; + state[2] += t[2]; + state[3] += t[3]; + state[4] += e; + state[5] += t[5]; + state[6] += t[6]; + state[7] += t[7]; +} +*/ + +#undef S0 +#undef S1 +#undef s0 +#undef s1 +#undef R + +// ************************************************************* + +#ifdef WORD64_AVAILABLE + +void SHA384::InitState(HashWordType *state) +{ + static const word64 s[8] = { + W64LIT(0xcbbb9d5dc1059ed8), W64LIT(0x629a292a367cd507), + W64LIT(0x9159015a3070dd17), W64LIT(0x152fecd8f70e5939), + W64LIT(0x67332667ffc00b31), W64LIT(0x8eb44a8768581511), + W64LIT(0xdb0c2e0d64f98fa7), W64LIT(0x47b5481dbefa4fa4)}; + memcpy(state, s, sizeof(s)); +} + +void SHA512::InitState(HashWordType *state) +{ + static const word64 s[8] = { + W64LIT(0x6a09e667f3bcc908), W64LIT(0xbb67ae8584caa73b), + W64LIT(0x3c6ef372fe94f82b), W64LIT(0xa54ff53a5f1d36f1), + W64LIT(0x510e527fade682d1), W64LIT(0x9b05688c2b3e6c1f), + W64LIT(0x1f83d9abfb41bd6b), W64LIT(0x5be0cd19137e2179)}; + memcpy(state, s, sizeof(s)); +} + +CRYPTOPP_ALIGN_DATA(16) static const word64 SHA512_K[80] CRYPTOPP_SECTION_ALIGN16 = { + W64LIT(0x428a2f98d728ae22), W64LIT(0x7137449123ef65cd), + W64LIT(0xb5c0fbcfec4d3b2f), W64LIT(0xe9b5dba58189dbbc), + W64LIT(0x3956c25bf348b538), W64LIT(0x59f111f1b605d019), + W64LIT(0x923f82a4af194f9b), W64LIT(0xab1c5ed5da6d8118), + W64LIT(0xd807aa98a3030242), W64LIT(0x12835b0145706fbe), + W64LIT(0x243185be4ee4b28c), W64LIT(0x550c7dc3d5ffb4e2), + W64LIT(0x72be5d74f27b896f), W64LIT(0x80deb1fe3b1696b1), + W64LIT(0x9bdc06a725c71235), W64LIT(0xc19bf174cf692694), + W64LIT(0xe49b69c19ef14ad2), W64LIT(0xefbe4786384f25e3), + W64LIT(0x0fc19dc68b8cd5b5), W64LIT(0x240ca1cc77ac9c65), + W64LIT(0x2de92c6f592b0275), W64LIT(0x4a7484aa6ea6e483), + W64LIT(0x5cb0a9dcbd41fbd4), W64LIT(0x76f988da831153b5), + W64LIT(0x983e5152ee66dfab), W64LIT(0xa831c66d2db43210), + W64LIT(0xb00327c898fb213f), W64LIT(0xbf597fc7beef0ee4), + W64LIT(0xc6e00bf33da88fc2), W64LIT(0xd5a79147930aa725), + W64LIT(0x06ca6351e003826f), W64LIT(0x142929670a0e6e70), + W64LIT(0x27b70a8546d22ffc), W64LIT(0x2e1b21385c26c926), + W64LIT(0x4d2c6dfc5ac42aed), W64LIT(0x53380d139d95b3df), + W64LIT(0x650a73548baf63de), W64LIT(0x766a0abb3c77b2a8), + W64LIT(0x81c2c92e47edaee6), W64LIT(0x92722c851482353b), + W64LIT(0xa2bfe8a14cf10364), W64LIT(0xa81a664bbc423001), + W64LIT(0xc24b8b70d0f89791), W64LIT(0xc76c51a30654be30), + W64LIT(0xd192e819d6ef5218), W64LIT(0xd69906245565a910), + W64LIT(0xf40e35855771202a), W64LIT(0x106aa07032bbd1b8), + W64LIT(0x19a4c116b8d2d0c8), W64LIT(0x1e376c085141ab53), + W64LIT(0x2748774cdf8eeb99), W64LIT(0x34b0bcb5e19b48a8), + W64LIT(0x391c0cb3c5c95a63), W64LIT(0x4ed8aa4ae3418acb), + W64LIT(0x5b9cca4f7763e373), W64LIT(0x682e6ff3d6b2b8a3), + W64LIT(0x748f82ee5defb2fc), W64LIT(0x78a5636f43172f60), + W64LIT(0x84c87814a1f0ab72), W64LIT(0x8cc702081a6439ec), + W64LIT(0x90befffa23631e28), W64LIT(0xa4506cebde82bde9), + W64LIT(0xbef9a3f7b2c67915), W64LIT(0xc67178f2e372532b), + W64LIT(0xca273eceea26619c), W64LIT(0xd186b8c721c0c207), + W64LIT(0xeada7dd6cde0eb1e), W64LIT(0xf57d4f7fee6ed178), + W64LIT(0x06f067aa72176fba), W64LIT(0x0a637dc5a2c898a6), + W64LIT(0x113f9804bef90dae), W64LIT(0x1b710b35131c471b), + W64LIT(0x28db77f523047d84), W64LIT(0x32caab7b40c72493), + W64LIT(0x3c9ebe0a15c9bebc), W64LIT(0x431d67c49c100d4c), + W64LIT(0x4cc5d4becb3e42b6), W64LIT(0x597f299cfc657e2a), + W64LIT(0x5fcb6fab3ad6faec), W64LIT(0x6c44198c4a475817) +}; + +#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86 +// put assembly version in separate function, otherwise MSVC 2005 SP1 doesn't generate correct code for the non-assembly version +CRYPTOPP_NAKED static void CRYPTOPP_FASTCALL SHA512_SSE2_Transform(word64 *state, const word64 *data) +{ +#ifdef __GNUC__ + __asm__ __volatile__ + ( + ".intel_syntax noprefix;" + AS1( push ebx) + AS2( mov ebx, eax) +#else + AS1( push ebx) + AS1( push esi) + AS1( push edi) + AS2( lea ebx, SHA512_K) +#endif + + AS2( mov eax, esp) + AS2( and esp, 0xfffffff0) + AS2( sub esp, 27*16) // 17*16 for expanded data, 20*8 for state + AS1( push eax) + AS2( xor eax, eax) + AS2( lea edi, [esp+4+8*8]) // start at middle of state buffer. will decrement pointer each round to avoid copying + AS2( lea esi, [esp+4+20*8+8]) // 16-byte alignment, then add 8 + + AS2( movq mm4, [ecx+0*8]) + AS2( movq [edi+0*8], mm4) + AS2( movq mm0, [ecx+1*8]) + AS2( movq [edi+1*8], mm0) + AS2( movq mm0, [ecx+2*8]) + AS2( movq [edi+2*8], mm0) + AS2( movq mm0, [ecx+3*8]) + AS2( movq [edi+3*8], mm0) + AS2( movq mm5, [ecx+4*8]) + AS2( movq [edi+4*8], mm5) + AS2( movq mm0, [ecx+5*8]) + AS2( movq [edi+5*8], mm0) + AS2( movq mm0, [ecx+6*8]) + AS2( movq [edi+6*8], mm0) + AS2( movq mm0, [ecx+7*8]) + AS2( movq [edi+7*8], mm0) + ASJ( jmp, 0, f) + +#define SSE2_S0_S1(r, a, b, c) \ + AS2( movq mm6, r)\ + AS2( psrlq r, a)\ + AS2( movq mm7, r)\ + AS2( psllq mm6, 64-c)\ + AS2( pxor mm7, mm6)\ + AS2( psrlq r, b-a)\ + AS2( pxor mm7, r)\ + AS2( psllq mm6, c-b)\ + AS2( pxor mm7, mm6)\ + AS2( psrlq r, c-b)\ + AS2( pxor r, mm7)\ + AS2( psllq mm6, b-a)\ + AS2( pxor r, mm6) + +#define SSE2_s0(r, a, b, c) \ + AS2( movdqa xmm6, r)\ + AS2( psrlq r, a)\ + AS2( movdqa xmm7, r)\ + AS2( psllq xmm6, 64-c)\ + AS2( pxor xmm7, xmm6)\ + AS2( psrlq r, b-a)\ + AS2( pxor xmm7, r)\ + AS2( psrlq r, c-b)\ + AS2( pxor r, xmm7)\ + AS2( psllq xmm6, c-a)\ + AS2( pxor r, xmm6) + +#define SSE2_s1(r, a, b, c) \ + AS2( movdqa xmm6, r)\ + AS2( psrlq r, a)\ + AS2( movdqa xmm7, r)\ + AS2( psllq xmm6, 64-c)\ + AS2( pxor xmm7, xmm6)\ + AS2( psrlq r, b-a)\ + AS2( pxor xmm7, r)\ + AS2( psllq xmm6, c-b)\ + AS2( pxor xmm7, xmm6)\ + AS2( psrlq r, c-b)\ + AS2( pxor r, xmm7) + + ASL(SHA512_Round) + // k + w is in mm0, a is in mm4, e is in mm5 + AS2( paddq mm0, [edi+7*8]) // h + AS2( movq mm2, [edi+5*8]) // f + AS2( movq mm3, [edi+6*8]) // g + AS2( pxor mm2, mm3) + AS2( pand mm2, mm5) + SSE2_S0_S1(mm5,14,18,41) + AS2( pxor mm2, mm3) + AS2( paddq mm0, mm2) // h += Ch(e,f,g) + AS2( paddq mm5, mm0) // h += S1(e) + AS2( movq mm2, [edi+1*8]) // b + AS2( movq mm1, mm2) + AS2( por mm2, mm4) + AS2( pand mm2, [edi+2*8]) // c + AS2( pand mm1, mm4) + AS2( por mm1, mm2) + AS2( paddq mm1, mm5) // temp = h + Maj(a,b,c) + AS2( paddq mm5, [edi+3*8]) // e = d + h + AS2( movq [edi+3*8], mm5) + AS2( movq [edi+11*8], mm5) + SSE2_S0_S1(mm4,28,34,39) // S0(a) + AS2( paddq mm4, mm1) // a = temp + S0(a) + AS2( movq [edi-8], mm4) + AS2( movq [edi+7*8], mm4) + AS1( ret) + + // first 16 rounds + ASL(0) + AS2( movq mm0, [edx+eax*8]) + AS2( movq [esi+eax*8], mm0) + AS2( movq [esi+eax*8+16*8], mm0) + AS2( paddq mm0, [ebx+eax*8]) + ASC( call, SHA512_Round) + AS1( inc eax) + AS2( sub edi, 8) + AS2( test eax, 7) + ASJ( jnz, 0, b) + AS2( add edi, 8*8) + AS2( cmp eax, 16) + ASJ( jne, 0, b) + + // rest of the rounds + AS2( movdqu xmm0, [esi+(16-2)*8]) + ASL(1) + // data expansion, W[i-2] already in xmm0 + AS2( movdqu xmm3, [esi]) + AS2( paddq xmm3, [esi+(16-7)*8]) + AS2( movdqa xmm2, [esi+(16-15)*8]) + SSE2_s1(xmm0, 6, 19, 61) + AS2( paddq xmm0, xmm3) + SSE2_s0(xmm2, 1, 7, 8) + AS2( paddq xmm0, xmm2) + AS2( movdq2q mm0, xmm0) + AS2( movhlps xmm1, xmm0) + AS2( paddq mm0, [ebx+eax*8]) + AS2( movlps [esi], xmm0) + AS2( movlps [esi+8], xmm1) + AS2( movlps [esi+8*16], xmm0) + AS2( movlps [esi+8*17], xmm1) + // 2 rounds + ASC( call, SHA512_Round) + AS2( sub edi, 8) + AS2( movdq2q mm0, xmm1) + AS2( paddq mm0, [ebx+eax*8+8]) + ASC( call, SHA512_Round) + // update indices and loop + AS2( add esi, 16) + AS2( add eax, 2) + AS2( sub edi, 8) + AS2( test eax, 7) + ASJ( jnz, 1, b) + // do housekeeping every 8 rounds + AS2( mov esi, 0xf) + AS2( and esi, eax) + AS2( lea esi, [esp+4+20*8+8+esi*8]) + AS2( add edi, 8*8) + AS2( cmp eax, 80) + ASJ( jne, 1, b) + +#define SSE2_CombineState(i) \ + AS2( movq mm0, [edi+i*8])\ + AS2( paddq mm0, [ecx+i*8])\ + AS2( movq [ecx+i*8], mm0) + + SSE2_CombineState(0) + SSE2_CombineState(1) + SSE2_CombineState(2) + SSE2_CombineState(3) + SSE2_CombineState(4) + SSE2_CombineState(5) + SSE2_CombineState(6) + SSE2_CombineState(7) + + AS1( pop esp) + AS1( emms) + +#if defined(__GNUC__) + AS1( pop ebx) + ".att_syntax prefix;" + : + : "a" (SHA512_K), "c" (state), "d" (data) + : "%esi", "%edi", "memory", "cc" + ); +#else + AS1( pop edi) + AS1( pop esi) + AS1( pop ebx) + AS1( ret) +#endif +} +#endif // #if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE + +void SHA512::Transform(word64 *state, const word64 *data) +{ +#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86 + if (HasSSE2()) + { + SHA512_SSE2_Transform(state, data); + return; + } +#endif + +#define S0(x) (rotrFixed(x,28)^rotrFixed(x,34)^rotrFixed(x,39)) +#define S1(x) (rotrFixed(x,14)^rotrFixed(x,18)^rotrFixed(x,41)) +#define s0(x) (rotrFixed(x,1)^rotrFixed(x,8)^(x>>7)) +#define s1(x) (rotrFixed(x,19)^rotrFixed(x,61)^(x>>6)) + +#define R(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+SHA512_K[i+j]+(j?blk2(i):blk0(i));\ + d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i)) + + word64 W[16]; + word64 T[8]; + /* Copy context->state[] to working vars */ + memcpy(T, state, sizeof(T)); + /* 80 operations, partially loop unrolled */ + for (unsigned int j=0; j<80; j+=16) + { + R( 0); R( 1); R( 2); R( 3); + R( 4); R( 5); R( 6); R( 7); + R( 8); R( 9); R(10); R(11); + R(12); R(13); R(14); R(15); + } + /* Add the working vars back into context.state[] */ + state[0] += a(0); + state[1] += b(0); + state[2] += c(0); + state[3] += d(0); + state[4] += e(0); + state[5] += f(0); + state[6] += g(0); + state[7] += h(0); +} + +#endif + +NAMESPACE_END + +#endif // #ifndef CRYPTOPP_IMPORTS diff --git a/CryptoPP/crypto/sha.h b/CryptoPP/crypto/sha.h new file mode 100644 index 0000000..ff05827 --- /dev/null +++ b/CryptoPP/crypto/sha.h @@ -0,0 +1,61 @@ +#ifndef CRYPTOPP_SHA_H +#define CRYPTOPP_SHA_H + +#include "iterhash.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// SHA-1 +class CRYPTOPP_DLL SHA1 : public IteratedHashWithStaticTransform +{ +public: + static void CRYPTOPP_API InitState(HashWordType *state); + static void CRYPTOPP_API Transform(word32 *digest, const word32 *data); + static const char * CRYPTOPP_API StaticAlgorithmName() {return "SHA-1";} +}; + +typedef SHA1 SHA; // for backwards compatibility + +//! implements the SHA-256 standard +class CRYPTOPP_DLL SHA256 : public IteratedHashWithStaticTransform +{ +public: + static void CRYPTOPP_API InitState(HashWordType *state); + static void CRYPTOPP_API Transform(word32 *digest, const word32 *data); + static const char * CRYPTOPP_API StaticAlgorithmName() {return "SHA-256";} +}; + +//! implements the SHA-224 standard +class CRYPTOPP_DLL SHA224 : public IteratedHashWithStaticTransform +{ +public: + static void CRYPTOPP_API InitState(HashWordType *state); + static void CRYPTOPP_API Transform(word32 *digest, const word32 *data) {SHA256::Transform(digest, data);} + static const char * CRYPTOPP_API StaticAlgorithmName() {return "SHA-224";} +}; + +#ifdef WORD64_AVAILABLE + +//! implements the SHA-512 standard +class CRYPTOPP_DLL SHA512 : public IteratedHashWithStaticTransform +{ +public: + static void CRYPTOPP_API InitState(HashWordType *state); + static void CRYPTOPP_API Transform(word64 *digest, const word64 *data); + static const char * CRYPTOPP_API StaticAlgorithmName() {return "SHA-512";} +}; + +//! implements the SHA-384 standard +class CRYPTOPP_DLL SHA384 : public IteratedHashWithStaticTransform +{ +public: + static void CRYPTOPP_API InitState(HashWordType *state); + static void CRYPTOPP_API Transform(word64 *digest, const word64 *data) {SHA512::Transform(digest, data);} + static const char * CRYPTOPP_API StaticAlgorithmName() {return "SHA-384";} +}; + +#endif + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/shacal2.cpp b/CryptoPP/crypto/shacal2.cpp new file mode 100644 index 0000000..7ddc94d --- /dev/null +++ b/CryptoPP/crypto/shacal2.cpp @@ -0,0 +1,140 @@ +// shacal2.cpp - by Kevin Springle, 2003 +// +// Portions of this code were derived from +// Wei Dai's implementation of SHA-2 +// +// The original code and all modifications are in the public domain. + +#include "pch.h" +#include "shacal2.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +// SHACAL-2 function and round definitions + +#define S0(x) (rotrFixed(x,2)^rotrFixed(x,13)^rotrFixed(x,22)) +#define S1(x) (rotrFixed(x,6)^rotrFixed(x,11)^rotrFixed(x,25)) +#define s0(x) (rotrFixed(x,7)^rotrFixed(x,18)^(x>>3)) +#define s1(x) (rotrFixed(x,17)^rotrFixed(x,19)^(x>>10)) + +#define Ch(x,y,z) (z^(x&(y^z))) +#define Maj(x,y,z) ((x&y)|(z&(x|y))) + +/* R is the SHA-256 round function. */ +/* This macro increments the k argument as a side effect. */ +#define R(a,b,c,d,e,f,g,h,k) \ + h+=S1(e)+Ch(e,f,g)+*k++;d+=h;h+=S0(a)+Maj(a,b,c); + +/* P is the inverse of the SHA-256 round function. */ +/* This macro decrements the k argument as a side effect. */ +#define P(a,b,c,d,e,f,g,h,k) \ + h-=S0(a)+Maj(a,b,c);d-=h;h-=S1(e)+Ch(e,f,g)+*--k; + +void SHACAL2::Base::UncheckedSetKey(const byte *userKey, unsigned int keylen, const NameValuePairs &) +{ + AssertValidKeyLength(keylen); + + word32 *rk = m_key; + unsigned int i; + + GetUserKey(BIG_ENDIAN_ORDER, rk, m_key.size(), userKey, keylen); + for (i = 0; i < 48; i++, rk++) + { + rk[16] = rk[0] + s0(rk[1]) + rk[9] + s1(rk[14]); + rk[0] += K[i]; + } + for (i = 48; i < 64; i++, rk++) + { + rk[0] += K[i]; + } +} + +typedef BlockGetAndPut Block; + +void SHACAL2::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word32 a, b, c, d, e, f, g, h; + const word32 *rk = m_key; + + /* + * map byte array block to cipher state: + */ + Block::Get(inBlock)(a)(b)(c)(d)(e)(f)(g)(h); + + // Perform SHA-256 transformation. + + /* 64 operations, partially loop unrolled */ + for (unsigned int j=0; j<64; j+=8) + { + R(a,b,c,d,e,f,g,h,rk); + R(h,a,b,c,d,e,f,g,rk); + R(g,h,a,b,c,d,e,f,rk); + R(f,g,h,a,b,c,d,e,rk); + R(e,f,g,h,a,b,c,d,rk); + R(d,e,f,g,h,a,b,c,rk); + R(c,d,e,f,g,h,a,b,rk); + R(b,c,d,e,f,g,h,a,rk); + } + + /* + * map cipher state to byte array block: + */ + + Block::Put(xorBlock, outBlock)(a)(b)(c)(d)(e)(f)(g)(h); +} + +void SHACAL2::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word32 a, b, c, d, e, f, g, h; + const word32 *rk = m_key + 64; + + /* + * map byte array block to cipher state: + */ + Block::Get(inBlock)(a)(b)(c)(d)(e)(f)(g)(h); + + // Perform inverse SHA-256 transformation. + + /* 64 operations, partially loop unrolled */ + for (unsigned int j=0; j<64; j+=8) + { + P(b,c,d,e,f,g,h,a,rk); + P(c,d,e,f,g,h,a,b,rk); + P(d,e,f,g,h,a,b,c,rk); + P(e,f,g,h,a,b,c,d,rk); + P(f,g,h,a,b,c,d,e,rk); + P(g,h,a,b,c,d,e,f,rk); + P(h,a,b,c,d,e,f,g,rk); + P(a,b,c,d,e,f,g,h,rk); + } + + /* + * map cipher state to byte array block: + */ + + Block::Put(xorBlock, outBlock)(a)(b)(c)(d)(e)(f)(g)(h); +} + +// The SHACAL-2 round constants are identical to the SHA-256 round constants. +const word32 SHACAL2::Base::K[64] = +{ + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, + 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, + 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, + 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, + 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +}; + +NAMESPACE_END diff --git a/CryptoPP/crypto/shacal2.h b/CryptoPP/crypto/shacal2.h new file mode 100644 index 0000000..5a95f8b --- /dev/null +++ b/CryptoPP/crypto/shacal2.h @@ -0,0 +1,54 @@ +#ifndef CRYPTOPP_SHACAL2_H +#define CRYPTOPP_SHACAL2_H + +/** \file +*/ + +#include "seckey.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! _ +struct SHACAL2_Info : public FixedBlockSize<32>, public VariableKeyLength<16, 16, 64> +{ + static const char *StaticAlgorithmName() {return "SHACAL-2";} +}; + +/// SHACAL-2 +class SHACAL2 : public SHACAL2_Info, public BlockCipherDocumentation +{ + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + public: + void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); + + protected: + FixedSizeSecBlock m_key; + + static const word32 K[64]; + }; + + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef SHACAL2::Encryption SHACAL2Encryption; +typedef SHACAL2::Decryption SHACAL2Decryption; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/shacal2v.dat b/CryptoPP/crypto/shacal2v.dat new file mode 100644 index 0000000..325d606 --- /dev/null +++ b/CryptoPP/crypto/shacal2v.dat @@ -0,0 +1,14 @@ +80000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 361AB6322FA9E7A7BB23818D839E01BDDAFDF47305426EDD297AEDB9F6202BAE +00000000000000000000000000000001 0000000000000000000000000000000000000000000000000000000000000000 7308AEC23D25A231B26448AFE78D5047804C5011B9B5F95C16DF2670551F0001 +00000000000000000000000000000000 8000000000000000000000000000000000000000000000000000000000000000 2CAE7C0460EE2FC3200923A1B6C2ABEEA746C8B44F6C3FB941BD3AF02A3E6E3E +00000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000001 45D43E9288738C5AD1A683D8DE59CEDD22D666A2B7078EB1301B532A272D570B +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 7CA51614425C3BA8CE54DD2FC2020AE7B6E574D198136D0FAE7E26CCBF0BE7A6 +01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101 0101010101010101010101010101010101010101010101010101010101010101 C4B7C6A9738C77EE28F7E685C8358E0AF88FB6D23955EE6DF49FE3F5DA16F826 +02020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202 0202020202020202020202020202020202020202020202020202020202020202 CD108DD9EC1000B79C75AA3DCC88F913E6F52773853035A5C44F3245B134CBFF +04040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404 0404040404040404040404040404040404040404040404040404040404040404 6AA777340200C1B65AB25193A8BB267C233DAC7E1B3C523D406FC5B567B7B586 +08080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808 0808080808080808080808080808080808080808080808080808080808080808 A23BE32D37FA4054EC45D6A9CC643AF9124EDAA4AD9ABC7FAAB449D39D11B128 +10101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010 1010101010101010101010101010101010101010101010101010101010101010 F64819DFBEBE0A6DB650E7072CE28EA606586418B317785FF0AD44212A84C82C +20202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020202020 2020202020202020202020202020202020202020202020202020202020202020 E267D6113C27170A3EE6DF496E801A6131BBD3444365D7C03791E25610F1A0E4 +40404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040404040 4040404040404040404040404040404040404040404040404040404040404040 C97909916EE86FFDCE8A92903046109B53F788A53039434DF1A394DAD6F697A2 +80808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080808080 8080808080808080808080808080808080808080808080808080808080808080 C3C1CD5F3060B3EC4E6ABC0818B68449E1750FB482368C8F3305270E16F98735 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 0598127BAF11706F77402000D730C54A0B84C868A98C6CA4D7F3C0FA06A78B7A diff --git a/CryptoPP/crypto/shark.cpp b/CryptoPP/crypto/shark.cpp new file mode 100644 index 0000000..1692a88 --- /dev/null +++ b/CryptoPP/crypto/shark.cpp @@ -0,0 +1,141 @@ +// shark.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifdef WORD64_AVAILABLE + +#include "shark.h" +#include "misc.h" +#include "modes.h" +#include "gf256.h" + +NAMESPACE_BEGIN(CryptoPP) + +static word64 SHARKTransform(word64 a) +{ + static const byte iG[8][8] = { + 0xe7, 0x30, 0x90, 0x85, 0xd0, 0x4b, 0x91, 0x41, + 0x53, 0x95, 0x9b, 0xa5, 0x96, 0xbc, 0xa1, 0x68, + 0x02, 0x45, 0xf7, 0x65, 0x5c, 0x1f, 0xb6, 0x52, + 0xa2, 0xca, 0x22, 0x94, 0x44, 0x63, 0x2a, 0xa2, + 0xfc, 0x67, 0x8e, 0x10, 0x29, 0x75, 0x85, 0x71, + 0x24, 0x45, 0xa2, 0xcf, 0x2f, 0x22, 0xc1, 0x0e, + 0xa1, 0xf1, 0x71, 0x40, 0x91, 0x27, 0x18, 0xa5, + 0x56, 0xf4, 0xaf, 0x32, 0xd2, 0xa4, 0xdc, 0x71, + }; + + word64 result=0; + GF256 gf256(0xf5); + for (unsigned int i=0; i<8; i++) + for(unsigned int j=0; j<8; j++) + result ^= word64(gf256.Multiply(iG[i][j], GF256::Element(a>>(56-8*j)))) << (56-8*i); + return result; +} + +void SHARK::Base::UncheckedSetKey(const byte *key, unsigned int keyLen, const NameValuePairs ¶ms) +{ + AssertValidKeyLength(keyLen); + + m_rounds = GetRoundsAndThrowIfInvalid(params, this); + m_roundKeys.New(m_rounds+1); + + // concatenate key enought times to fill a + for (unsigned int i=0; i<(m_rounds+1)*8; i++) + ((byte *)m_roundKeys.begin())[i] = key[i%keyLen]; + + SHARK::Encryption e; + e.InitForKeySetup(); + byte IV[8] = {0,0,0,0,0,0,0,0}; + CFB_Mode_ExternalCipher::Encryption cfb(e, IV); + + cfb.ProcessString((byte *)m_roundKeys.begin(), (m_rounds+1)*8); + + ConditionalByteReverse(BIG_ENDIAN_ORDER, m_roundKeys.begin(), m_roundKeys.begin(), (m_rounds+1)*8); + + m_roundKeys[m_rounds] = SHARKTransform(m_roundKeys[m_rounds]); + + if (!IsForwardTransformation()) + { + unsigned int i; + + // transform encryption round keys into decryption round keys + for (i=0; i +struct SharkProcessAndXorBlock{ // VC60 workaround: problem with template functions +inline SharkProcessAndXorBlock(const word64 *roundKeys, unsigned int rounds, const byte *inBlock, const byte *xorBlock, byte *outBlock) +{ + word64 tmp = *(word64 *)inBlock ^ roundKeys[0]; + + ByteOrder order = GetNativeByteOrder(); + tmp = cbox[0][GetByte(order, tmp, 0)] ^ cbox[1][GetByte(order, tmp, 1)] + ^ cbox[2][GetByte(order, tmp, 2)] ^ cbox[3][GetByte(order, tmp, 3)] + ^ cbox[4][GetByte(order, tmp, 4)] ^ cbox[5][GetByte(order, tmp, 5)] + ^ cbox[6][GetByte(order, tmp, 6)] ^ cbox[7][GetByte(order, tmp, 7)] + ^ roundKeys[1]; + + for(unsigned int i=2; i(xorBlock, outBlock) + (sbox[GETBYTE(tmp, 7)]) + (sbox[GETBYTE(tmp, 6)]) + (sbox[GETBYTE(tmp, 5)]) + (sbox[GETBYTE(tmp, 4)]) + (sbox[GETBYTE(tmp, 3)]) + (sbox[GETBYTE(tmp, 2)]) + (sbox[GETBYTE(tmp, 1)]) + (sbox[GETBYTE(tmp, 0)]); + + *(word64 *)outBlock ^= roundKeys[rounds]; +}}; + +void SHARK::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + SharkProcessAndXorBlock(m_roundKeys, m_rounds, inBlock, xorBlock, outBlock); +} + +void SHARK::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + SharkProcessAndXorBlock(m_roundKeys, m_rounds, inBlock, xorBlock, outBlock); +} + +NAMESPACE_END + +#endif // WORD64_AVAILABLE diff --git a/CryptoPP/crypto/shark.h b/CryptoPP/crypto/shark.h new file mode 100644 index 0000000..a4acd21 --- /dev/null +++ b/CryptoPP/crypto/shark.h @@ -0,0 +1,69 @@ +#ifndef CRYPTOPP_SHARK_H +#define CRYPTOPP_SHARK_H + +/** \file +*/ + +#include "config.h" + +#ifdef WORD64_AVAILABLE + +#include "seckey.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! _ +struct SHARK_Info : public FixedBlockSize<8>, public VariableKeyLength<16, 1, 16>, public VariableRounds<6, 2> +{ + static const char *StaticAlgorithmName() {return "SHARK-E";} +}; + +/// SHARK-E +class SHARK : public SHARK_Info, public BlockCipherDocumentation +{ + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + public: + void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶m); + + protected: + unsigned int m_rounds; + SecBlock m_roundKeys; + }; + + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + + // used by Base to do key setup + void InitForKeySetup(); + + private: + static const byte sbox[256]; + static const word64 cbox[8][256]; + }; + + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + + private: + static const byte sbox[256]; + static const word64 cbox[8][256]; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef SHARK::Encryption SHARKEncryption; +typedef SHARK::Decryption SHARKDecryption; + +NAMESPACE_END + +#endif +#endif diff --git a/CryptoPP/crypto/sharkbox.cpp b/CryptoPP/crypto/sharkbox.cpp new file mode 100644 index 0000000..bbe65b5 --- /dev/null +++ b/CryptoPP/crypto/sharkbox.cpp @@ -0,0 +1,4166 @@ +#include "pch.h" +#include "shark.h" + +#ifdef WORD64_AVAILABLE + +NAMESPACE_BEGIN(CryptoPP) + +const byte SHARK::Enc::sbox[256] = { +177, 206, 195, 149, 90, 173, 231, 2, 77, 68, 251, 145, 12, 135, 161, 80, +203, 103, 84, 221, 70, 143, 225, 78, 240, 253, 252, 235, 249, 196, 26, 110, + 94, 245, 204, 141, 28, 86, 67, 254, 7, 97, 248, 117, 89, 255, 3, 34, +138, 209, 19, 238, 136, 0, 14, 52, 21, 128, 148, 227, 237, 181, 83, 35, + 75, 71, 23, 167, 144, 53, 171, 216, 184, 223, 79, 87, 154, 146, 219, 27, + 60, 200, 153, 4, 142, 224, 215, 125, 133, 187, 64, 44, 58, 69, 241, 66, +101, 32, 65, 24, 114, 37, 147, 112, 54, 5, 242, 11, 163, 121, 236, 8, + 39, 49, 50, 182, 124, 176, 10, 115, 91, 123, 183, 129, 210, 13, 106, 38, +158, 88, 156, 131, 116, 179, 172, 48, 122, 105, 119, 15, 174, 33, 222, 208, + 46, 151, 16, 164, 152, 168, 212, 104, 45, 98, 41, 109, 22, 73, 118, 199, +232, 193, 150, 55, 229, 202, 244, 233, 99, 18, 194, 166, 20, 188, 211, 40, +175, 47, 230, 36, 82, 198, 160, 9, 189, 140, 207, 93, 17, 95, 1, 197, +159, 61, 162, 155, 201, 59, 190, 81, 25, 31, 63, 92, 178, 239, 74, 205, +191, 186, 111, 100, 217, 243, 62, 180, 170, 220, 213, 6, 192, 126, 246, 102, +108, 132, 113, 56, 185, 29, 127, 157, 72, 139, 42, 218, 165, 51, 130, 57, +214, 120, 134, 250, 228, 43, 169, 30, 137, 96, 107, 234, 85, 76, 247, 226, +}; + +const byte SHARK::Dec::sbox[256] = { + 53, 190, 7, 46, 83, 105, 219, 40, 111, 183, 118, 107, 12, 125, 54, 139, +146, 188, 169, 50, 172, 56, 156, 66, 99, 200, 30, 79, 36, 229, 247, 201, + 97, 141, 47, 63, 179, 101, 127, 112, 175, 154, 234, 245, 91, 152, 144, 177, +135, 113, 114, 237, 55, 69, 104, 163, 227, 239, 92, 197, 80, 193, 214, 202, + 90, 98, 95, 38, 9, 93, 20, 65, 232, 157, 206, 64, 253, 8, 23, 74, + 15, 199, 180, 62, 18, 252, 37, 75, 129, 44, 4, 120, 203, 187, 32, 189, +249, 41, 153, 168, 211, 96, 223, 17, 151, 137, 126, 250, 224, 155, 31, 210, +103, 226, 100, 119, 132, 43, 158, 138, 241, 109, 136, 121, 116, 87, 221, 230, + 57, 123, 238, 131, 225, 88, 242, 13, 52, 248, 48, 233, 185, 35, 84, 21, + 68, 11, 77, 102, 58, 3, 162, 145, 148, 82, 76, 195, 130, 231, 128, 192, +182, 14, 194, 108, 147, 236, 171, 67, 149, 246, 216, 70, 134, 5, 140, 176, +117, 0, 204, 133, 215, 61, 115, 122, 72, 228, 209, 89, 173, 184, 198, 208, +220, 161, 170, 2, 29, 191, 181, 159, 81, 196, 165, 16, 34, 207, 1, 186, +143, 49, 124, 174, 150, 218, 240, 86, 71, 212, 235, 78, 217, 19, 142, 73, + 85, 22, 255, 59, 244, 164, 178, 6, 160, 167, 251, 27, 110, 60, 51, 205, + 24, 94, 106, 213, 166, 33, 222, 254, 42, 28, 243, 10, 26, 25, 39, 45, +}; + +const word64 SHARK::Enc::cbox[8][256] = { +/* box 0 */ +W64LIT(0x060d838f16f3a365), +W64LIT(0xa68857ee5cae56f6), +W64LIT(0xebf516353c2c4d89), +W64LIT(0x652174be88e85bdc), +W64LIT(0x0d4e9a8086c17921), +W64LIT(0x27ba7d33cffa58a1), +W64LIT(0x88d9e104a237b530), +W64LIT(0x693b8755a4fbe816), +W64LIT(0xdac9591826b254a0), +W64LIT(0x45c2e369fb336af3), +W64LIT(0xa96e1fb87b3e4ef4), +W64LIT(0xb7578f1435eb7ef0), +W64LIT(0x839af80b32056f74), +W64LIT(0xae37f55cc71f277a), +W64LIT(0xa4208538fdff37d5), +W64LIT(0x35991e74ad3cdb6f), +W64LIT(0xba191594b32a07d1), +W64LIT(0x5344d1772e572b7b), +W64LIT(0xe7efe5de103ffe43), +W64LIT(0xa3796fdc41de5e5b), +W64LIT(0x2cf9643c5fc882e5), +W64LIT(0xffdbf6fd48196d22), +W64LIT(0x33949dfbbbcf780a), +W64LIT(0x7d15679dd0cec8bd), +W64LIT(0x5f5e229c024498b1), +W64LIT(0x1223634762c683ce), +W64LIT(0xdcc4da973041f7c5), +W64LIT(0x0b43190f9032da44), +W64LIT(0xc05598eddfc5a6e2), +W64LIT(0x9e5fd31a7753f4b8), +W64LIT(0x9afa8243c0f136fe), +W64LIT(0xcc4f6b06f3d61528), +W64LIT(0xdf38612a3bc25c0d), +W64LIT(0x43cf60e6edc0c996), +W64LIT(0xcfb3d0bbf855bee0), +W64LIT(0x96e071a8ece28534), +W64LIT(0x21b7febcd909fbc4), +W64LIT(0x8ed4628bb4c41655), +W64LIT(0x30682646b04cd3c2), +W64LIT(0xb5ff5dc294ba1fd3), +W64LIT(0x75aac52f4b7fb931), +W64LIT(0xe809ad8837afe641), +W64LIT(0x0eb2213d8d42d2e9), +W64LIT(0x9852509561a057dd), +W64LIT(0xaa92a40570bde53c), +W64LIT(0x7b18e412c63d6bd8), +W64LIT(0xa7dc3e85f67c9c1d), +W64LIT(0xd8618bce87e33583), +W64LIT(0xe34ab487a79d3c05), +W64LIT(0x20e397d773db312f), +W64LIT(0x05f138321d7008ad), +W64LIT(0x17d25b757fb68b63), +W64LIT(0x8a7133d20366d413), +W64LIT(0x0000000000000000), +W64LIT(0xeaa17f5e96fe8762), +W64LIT(0xc101f18675176c09), +W64LIT(0xbebc44cd0488c597), +W64LIT(0xdb9d30738c609e4b), +W64LIT(0xabc6cd6eda6f2fd7), +W64LIT(0x5aaf1aae1f34901c), +W64LIT(0xb00e65f089ca177e), +W64LIT(0xd47b7825abf08649), +W64LIT(0x924520f15b404772), +W64LIT(0x1686321ed5644188), +W64LIT(0x618425e73f4a999a), +W64LIT(0xe21eddec0d4ff6ee), +W64LIT(0xd787c398a0732d81), +W64LIT(0x1f6df9c7e407faef), +W64LIT(0x79b036c4676c0afb), +W64LIT(0x0fe6485627901802), +W64LIT(0x9cf701ccd602959b), +W64LIT(0xbfe82da6ae5a0f7c), +W64LIT(0x990639fecb729d36), +W64LIT(0xca42e889e525b64d), +W64LIT(0xb3f2de4d8249bcb6), +W64LIT(0x4033db5be643625e), +W64LIT(0x4167b2304c91a8b5), +W64LIT(0x108bb191c397e2ed), +W64LIT(0x1834132358269361), +W64LIT(0x541d3b93927642f5), +W64LIT(0x90edf227fa112651), +W64LIT(0x1dc52b1145569bcc), +W64LIT(0xe6bb8cb5baed34a8), +W64LIT(0xd276fbaabd03252c), +W64LIT(0x313c4f2d1a9e1929), +W64LIT(0xfd73242be9480c01), +W64LIT(0x9baeeb286a23fc15), +W64LIT(0xc9be5334eea61d85), +W64LIT(0xc70c720963e4cf6c), +W64LIT(0x3eda077b3d0e012b), +W64LIT(0x97b418c346304fdf), +W64LIT(0x32c0f490111db2e1), +W64LIT(0x2ba08ed8e3e9eb6b), +W64LIT(0x8b255ab9a9b41ef8), +W64LIT(0x91b99b4c50c3ecba), +W64LIT(0xfe8f9f96e2cba7c9), +W64LIT(0x3a7f56228aacc36d), +W64LIT(0xb15a0c9b2318dd95), +W64LIT(0x5953a11314b73bd4), +W64LIT(0xf3c10516640adee8), +W64LIT(0xedf895ba2adfeeec), +W64LIT(0xadcb4ee1cc9c8cb2), +W64LIT(0xde6c0841911096e6), +W64LIT(0x84c312ef8e2406fa), +W64LIT(0xa83a76d3d1ec841f), +W64LIT(0x1c91427aef845127), +W64LIT(0x3665a5c9a6bf70a7), +W64LIT(0xf6303d24797ad645), +W64LIT(0xcd1b026d5904dfc3), +W64LIT(0x1bc8a89e53a538a9), +W64LIT(0x7ee9dc20db4d6375), +W64LIT(0x51ec03a18f064a58), +W64LIT(0xc4f0c9b4686764a4), +W64LIT(0xdd90b3fc9a933d2e), +W64LIT(0x7a4c8d796cefa133), +W64LIT(0x73a746a05d8c1a54), +W64LIT(0x0759eae4bc21698e), +W64LIT(0xc8ea3a5f4474d76e), +W64LIT(0x38d784f42bfda24e), +W64LIT(0x231f2c6a78589ae7), +W64LIT(0xc3a92350d4460d2a), +W64LIT(0x72f32fcbf75ed0bf), +W64LIT(0xbd40ff700f0b6e5f), +W64LIT(0x157a89a3dee7ea40), +W64LIT(0x873fa95285a7ad32), +W64LIT(0x4d7d41db60821b7f), +W64LIT(0x1e3990ac4ed53004), +W64LIT(0x0a1770643ae010af), +W64LIT(0x9311499af1928d99), +W64LIT(0x64751dd5223a9137), +W64LIT(0xfa2acecf5569658f), +W64LIT(0x7c410ef67a1c0256), +W64LIT(0x56b5e945332723d6), +W64LIT(0x6f3604dab2084b73), +W64LIT(0xe95dc4e39d7d2caa), +W64LIT(0x13770a2cc8144925), +W64LIT(0xbc14961ba5d9a4b4), +W64LIT(0xb9e5ae29b8a9ac19), +W64LIT(0xf169d7c0c55bbfcb), +W64LIT(0x2446c68ec479f369), +W64LIT(0x806643b63986c4bc), +W64LIT(0x7fbdb54b719fa99e), +W64LIT(0x04a55159b7a2c246), +W64LIT(0xee042e07215c4524), +W64LIT(0x5bfb73c5b5e65af7), +W64LIT(0x0c1af3eb2c13b3ca), +W64LIT(0xa22d06b7eb0c94b0), +W64LIT(0xb8b1c742127b66f2), +W64LIT(0x285c3565e86a40a3), +W64LIT(0x3b2b3f49207e0986), +W64LIT(0x3c72d5ad9c5f6008), +W64LIT(0x770217f9ea2ed812), +W64LIT(0xfc274d40439ac6ea), +W64LIT(0x4fd5930dc1d37a5c), +W64LIT(0x2e51b6eafe99e3c6), +W64LIT(0x6b93558305aa8935), +W64LIT(0x19607a48f2f4598a), +W64LIT(0x08bfa2b29bb1718c), +W64LIT(0x3f8e6e1097dccbc0), +W64LIT(0x3983ed9f812f68a5), +W64LIT(0xac9f278a664e4659), +W64LIT(0x82ce916098d7a59f), +W64LIT(0xc2fd4a3b7e94c7c1), +W64LIT(0x66ddcf03836bf014), +W64LIT(0xe1e2665106cc5d26), +W64LIT(0x74feac44e1ad73da), +W64LIT(0x8d28d936bf47bd9d), +W64LIT(0x62789e5a34c93252), +W64LIT(0x81322add93540e57), +W64LIT(0xcb1681e24ff77ca6), +W64LIT(0x2512afe56eab3982), +W64LIT(0xd18a4017b6808ee4), +W64LIT(0x705bfd1d560fb19c), +W64LIT(0x4b70c2547671b81a), +W64LIT(0x49d81082d720d939), +W64LIT(0xe0b60f3aac1e97cd), +W64LIT(0x4e81fa666b01b0b7), +W64LIT(0x951cca15e7612efc), +W64LIT(0x463e58d4f0b0c13b), +W64LIT(0x632cf7319e1bf8b9), +W64LIT(0x5ca2992109c73379), +W64LIT(0xf764544fd3a81cae), +W64LIT(0x6ac73ce8af7843de), +W64LIT(0x9f0bba71dd813e53), +W64LIT(0x85977b8424f6cc11), +W64LIT(0x5807c878be65f13f), +W64LIT(0x686fee3e0e2922fd), +W64LIT(0x78e45fafcdbec010), +W64LIT(0x6ccabf67b98be0bb), +W64LIT(0x11dfd8fa69452806), +W64LIT(0xcee7b9d05287740b), +W64LIT(0x50b86aca25d480b3), +W64LIT(0x5df6f04aa315f992), +W64LIT(0x5e0a4bf7a896525a), +W64LIT(0x03fcbbbd0b83abc8), +W64LIT(0x8f800be01e16dcbe), +W64LIT(0xd32292c117d1efc7), +W64LIT(0xe5473708b16e9f60), +W64LIT(0x224b4501d28a500c), +W64LIT(0xfb7ea7a4ffbbaf64), +W64LIT(0x3d26bcc6368daae3), +W64LIT(0x866bc0392f7567d9), +W64LIT(0x3731cca20c6dba4c), +W64LIT(0xb603e67f9f39b41b), +W64LIT(0xa1d1bd0ae08f3f78), +W64LIT(0xd935e2a52d31ff68), +W64LIT(0xaf639c376dcded91), +W64LIT(0x0154696baad2caeb), +W64LIT(0xecacfcd1800d2407), +W64LIT(0xf03dbeab6f897520), +W64LIT(0x02a8d2d6a1516123), +W64LIT(0xf498eff2d82bb766), +W64LIT(0x710f9476fcdd7b77), +W64LIT(0xf8821c19f43804ac), +W64LIT(0xf9d675725eeace47), +W64LIT(0x1a9cc1f5f977f242), +W64LIT(0x5210b81c8485e190), +W64LIT(0x6d9ed60c13592a50), +W64LIT(0xf2956c7dced81403), +W64LIT(0xbb4d7cff19f8cd3a), +W64LIT(0x4c2928b0ca50d194), +W64LIT(0x6e626db118da8198), +W64LIT(0xe4135e631bbc558b), +W64LIT(0x9da368a77cd05f70), +W64LIT(0xa574ec53572dfd3e), +W64LIT(0x09ebcbd93163bb67), +W64LIT(0x4a24ab3fdca372f1), +W64LIT(0x429b098d4712037d), +W64LIT(0x57e1802e99f5e93d), +W64LIT(0xef50476c8b8e8fcf), +W64LIT(0xa085d4614a5df593), +W64LIT(0x34cd771f07ee1184), +W64LIT(0xc6581b62c9360587), +W64LIT(0x2dad0d57f51a480e), +W64LIT(0x898d886f08e57fdb), +W64LIT(0xd6d3aaf30aa1e76a), +W64LIT(0x76567e9240fc12f9), +W64LIT(0xb4ab34a93e68d538), +W64LIT(0xb2a6b726289b765d), +W64LIT(0x8c7cb05d15957776), +W64LIT(0x554952f838a4881e), +W64LIT(0xd52f114e01224ca2), +W64LIT(0x60d04c8c95985371), +W64LIT(0x6789a66829b93aff), +W64LIT(0x2f05df81544b292d), +W64LIT(0x476a31bf5a620bd0), +W64LIT(0xf5cc869972f97d8d), +W64LIT(0x488c79e97df213d2), +W64LIT(0x44968a0251e1a018), +W64LIT(0x26ee14586528924a), +W64LIT(0xd0de297c1c52440f), +W64LIT(0xc5a4a0dfc2b5ae4f), +W64LIT(0x29085c0e42b88a48), +W64LIT(0x142ee0c8743520ab), +W64LIT(0x2af4e7b3493b2180), +W64LIT(0x9448a37e4db3e417), +/* box 1 */ +W64LIT(0xe2795ba105ba30ce), +W64LIT(0x65b5d634f5e0fbdd), +W64LIT(0x2d7d7f1464dd8c55), +W64LIT(0xeefbf778add1c20b), +W64LIT(0x1eb0fbd1f11968e7), +W64LIT(0xe6073f45ce30cd8d), +W64LIT(0x21ffd3cdccb67e90), +W64LIT(0xdf0941cfa750a262), +W64LIT(0xc61df5b1b75ef18a), +W64LIT(0xc5c7defa9dc337c6), +W64LIT(0x2581b729073c83d3), +W64LIT(0xa5e97513167173cf), +W64LIT(0xdd3673bd381526b9), +W64LIT(0xe8baa1eef91ebb93), +W64LIT(0x3b314cf8f625eb34), +W64LIT(0x579d4bc8d5fc5df8), +W64LIT(0xbb598ec2e7681b28), +W64LIT(0xc8a06b1a80708794), +W64LIT(0x1c8fc9a36e5cec3c), +W64LIT(0xf60a5a3f0807d374), +W64LIT(0x1ace9f353a9395a4), +W64LIT(0x7e9e50387aab2cee), +W64LIT(0xb5e41069d0466d36), +W64LIT(0x8cea6ee3b92602d9), +W64LIT(0xf952ddad8af1e7fd), +W64LIT(0xb19a748d1bcc9075), +W64LIT(0x2464ae10b2e4c144), +W64LIT(0xfcc9a070f4a35829), +W64LIT(0xfa88f6e6a06c21b1), +W64LIT(0x2c98662dd105cec2), +W64LIT(0x9065a740d77aeee5), +W64LIT(0xcb7a4051aaed41d8), +W64LIT(0x55a279ba4ab9d923), +W64LIT(0x27be855b98790708), +W64LIT(0xbabc97fb52b059bf), +W64LIT(0xa19711f7ddfb8e8c), +W64LIT(0x047e64e4cb8afd43), +W64LIT(0xc386886cc90c4e5e), +W64LIT(0xc422c7c3281b7551), +W64LIT(0xfb6defdf15b46326), +W64LIT(0x01e51939b5d84297), +W64LIT(0x5cbba8be9c809432), +W64LIT(0x6f762c7b09447080), +W64LIT(0xcee13d8cd4bffe0c), +W64LIT(0x54476083ff619bb4), +W64LIT(0x6e933542bc9c3217), +W64LIT(0x4af79b520e78f353), +W64LIT(0x98996f7db49be163), +W64LIT(0xa07208ce6823cc1b), +W64LIT(0x2b3c29823012f5cd), +W64LIT(0x93bf8c0bfde728a9), +W64LIT(0x2225f886e62bb8dc), +W64LIT(0x7f7b4901cf736e79), +W64LIT(0x0000000000000000), +W64LIT(0x023f32729f4584db), +W64LIT(0xd5cabb805bf4293f), +W64LIT(0x07a44fafe1173b0f), +W64LIT(0xe95fb8d74cc6f904), +W64LIT(0x7b052de504f9933a), +W64LIT(0x6aed51a67716cf54), +W64LIT(0x68d263d4e8534b8f), +W64LIT(0xa96bd9cabe1a810a), +W64LIT(0x1d6ad09adb84aeab), +W64LIT(0x0d67b5e01db3b052), +W64LIT(0x52063615abaee22c), +W64LIT(0x8f3045a893bbc495), +W64LIT(0xd8ad0e604647996d), +W64LIT(0xaf2a8f5cead5f892), +W64LIT(0x3017af8ebf5922fe), +W64LIT(0x4034611df2dc780e), +W64LIT(0x721cfce1d2c0de2b), +W64LIT(0x28e602c91a8f3381), +W64LIT(0xe1a370ea2f27f682), +W64LIT(0x29031bf0af577116), +W64LIT(0x1914b47e100e53e8), +W64LIT(0x567852f160241f6f), +W64LIT(0x793a1f979bbc17e1), +W64LIT(0xef1eee411809809c), +W64LIT(0x6211999b14f7c0d2), +W64LIT(0x059b7ddd7e52bfd4), +W64LIT(0x43ee4a56d841be42), +W64LIT(0xf1ae1590e910e87b), +W64LIT(0x33cd84c595c4e4b2), +W64LIT(0x4b12826bbba0b1c4), +W64LIT(0xeb608aa5d3837ddf), +W64LIT(0x201acaf4796e3c07), +W64LIT(0xbf27ea262ce2e66b), +W64LIT(0x58c5cc5a570a6971), +W64LIT(0x37b3e0215e4e19f1), +W64LIT(0xab54ebb8215f05d1), +W64LIT(0x8ed55c9126638602), +W64LIT(0x9aa65d0f2bde65b8), +W64LIT(0xd7f589f2c4b1ade4), +W64LIT(0x5039046734eb66f7), +W64LIT(0x6cac073023d9b6cc), +W64LIT(0x51dc1d5e81332460), +W64LIT(0x17a92ad5272025f6), +W64LIT(0x47902eb213cb4301), +W64LIT(0x1b2b860c8f4bd733), +W64LIT(0x4f6ce68f702a4c87), +W64LIT(0xcf0424b56167bc9b), +W64LIT(0x997c76440143a3f4), +W64LIT(0x7ae034dcb121d1ad), +W64LIT(0x100d657ac6371ef9), +W64LIT(0x0ac3fa4ffca48b5d), +W64LIT(0xdeec58f61288e0f5), +W64LIT(0x265b9c622da1459f), +W64LIT(0xdcd36a848dcd642e), +W64LIT(0xe4380d3751754956), +W64LIT(0x13d74e31ecaad8b5), +W64LIT(0xfd2cb949417b1abe), +W64LIT(0x9624f1d683b5977d), +W64LIT(0x4675378ba6130196), +W64LIT(0x0b26e376497cc9ca), +W64LIT(0x41d1782447043a99), +W64LIT(0xe39c4298b0627259), +W64LIT(0xcd3b16c7fe223840), +W64LIT(0x7787813cac9261ff), +W64LIT(0x492db01924e5351f), +W64LIT(0x5afafe28c84fedaa), +W64LIT(0x8b4e214c583139d6), +W64LIT(0xccde0ffe4bfa7ad7), +W64LIT(0x76629805194a2368), +W64LIT(0x7ca1624ae5eea835), +W64LIT(0x61cbb2d03e6a069e), +W64LIT(0x48c8a920913d7788), +W64LIT(0x8068c23a114df01c), +W64LIT(0xd38bed160f3b50a7), +W64LIT(0x32289dfc201ca625), +W64LIT(0xc1b9ba1e5649ca85), +W64LIT(0xed21dc33874c0447), +W64LIT(0xa3a8238542be0a57), +W64LIT(0x5b1fe7117d97af3d), +W64LIT(0x3d701a6ea2ea92ac), +W64LIT(0x73f9e5d867189cbc), +W64LIT(0x9ed839ebe05498fb), +W64LIT(0x5920d563e2d22be6), +W64LIT(0xca9f59681f35034f), +W64LIT(0x11e87c4373ef5c6e), +W64LIT(0x97c1e8ef366dd5ea), +W64LIT(0xacf0a417c0483ede), +W64LIT(0xd26ef42fbae31230), +W64LIT(0xbcfdc16d067f2027), +W64LIT(0xbec2f31f993aa4fc), +W64LIT(0x45af1cc08c8ec7da), +W64LIT(0x31f2b6b70a816069), +W64LIT(0xd9481759f39fdbfa), +W64LIT(0xe5dd140ee4ad0bc1), +W64LIT(0xa6335e583cecb583), +W64LIT(0x38eb67b3dcb82d78), +W64LIT(0xf5d07174229a1538), +W64LIT(0x5f6183f5b61d527e), +W64LIT(0x0f58879282f63489), +W64LIT(0x164c33ec92f86761), +W64LIT(0x444a05f93956854d), +W64LIT(0x818ddb03a495b28b), +W64LIT(0x4d53d4fdef6fc85c), +W64LIT(0x8d0f77da0cfe404e), +W64LIT(0x8416a6dedac70d5f), +W64LIT(0x666ffd7fdf7d3d91), +W64LIT(0xb63e3b22fadbab7a), +W64LIT(0xf2743edbc38d2e37), +W64LIT(0xa40c6c2aa3a93158), +W64LIT(0x9f3d20d2558cda6c), +W64LIT(0xfef692026be6dcf2), +W64LIT(0x2ea7545f4e404a19), +W64LIT(0xb2405fc631515639), +W64LIT(0x23c0e1bf53f3fa4b), +W64LIT(0x83b2e9713bd03650), +W64LIT(0x0641569654cf7998), +W64LIT(0xb883a589cdf5dd64), +W64LIT(0x3ad455c143fda9a3), +W64LIT(0x925a9532483f6a3e), +W64LIT(0xaab1f28194874746), +W64LIT(0xf435684d974257af), +W64LIT(0xd1b4df64907ed47c), +W64LIT(0x390e7e8a69606fef), +W64LIT(0xd051c65d25a696eb), +W64LIT(0xb4010950659e2fa1), +W64LIT(0x0c82acd9a86bf2c5), +W64LIT(0x88940a0772acff9a), +W64LIT(0xf39127e276556ca0), +W64LIT(0xaecf96655f0dba05), +W64LIT(0x03da2b4b2a9dc64c), +W64LIT(0x3f4f281c3daf1677), +W64LIT(0x3469cb6a74d3dfbd), +W64LIT(0xf04b0ca95cc8aaec), +W64LIT(0x1f55e2e844c12a70), +W64LIT(0x4cb6cdc45ab78acb), +W64LIT(0xc05ca327e3918812), +W64LIT(0x95feda9da9285131), +W64LIT(0xb966bcb0782d9ff3), +W64LIT(0xa7d647618934f714), +W64LIT(0xd61090cb7169ef73), +W64LIT(0x71c6d7aaf85d1867), +W64LIT(0xecc4c50a329446d0), +W64LIT(0x6450cf0d4038b94a), +W64LIT(0x420b536f6d99fcd5), +W64LIT(0x75b8b34e33d7e524), +W64LIT(0xc26391557cd40cc9), +W64LIT(0xda923c12d9021db6), +W64LIT(0x4e89ffb6c5f20e10), +W64LIT(0x0919d104d6394d11), +W64LIT(0x8aab3875ede97b41), +W64LIT(0xa88ec0f30bc2c39d), +W64LIT(0xb7db221b4f03e9ed), +W64LIT(0xc7f8ec880286b31d), +W64LIT(0x2f424d66fb98088e), +W64LIT(0xe04669d39affb415), +W64LIT(0x3eaa3125887754e0), +W64LIT(0x5e849acc03c510e9), +W64LIT(0x8257f0488e0874c7), +W64LIT(0xbd18d854b3a762b0), +W64LIT(0xb3a546ff848914ae), +W64LIT(0x9ce70b997f111c20), +W64LIT(0x3c9503571732d03b), +W64LIT(0xe7e2267c7be88f1a), +W64LIT(0x63f480a2a12f8245), +W64LIT(0x602eabe98bb24409), +W64LIT(0x941bc3a41cf013a6), +W64LIT(0x678ae4466aa57f06), +W64LIT(0x1232570859729a22), +W64LIT(0x6d491e099601f45b), +W64LIT(0x5d5eb1872958d6a5), +W64LIT(0x1473019e0dbde3ba), +W64LIT(0xa24d3abcf76648c0), +W64LIT(0x85f3bfe76f1f4fc8), +W64LIT(0x08fcc83d63e10f86), +W64LIT(0x745daa77860fa7b3), +W64LIT(0x9180be7962a2ac72), +W64LIT(0x87cc8d95f05acb13), +W64LIT(0x78df06ae2e645576), +W64LIT(0x18f1ad47a5d6117f), +W64LIT(0x358cd253c10b9d2a), +W64LIT(0x0ebd9eab372e761e), +W64LIT(0xf7ef4306bddf91e3), +W64LIT(0x7023ce934d855af0), +W64LIT(0xd42fa2b9ee2c6ba8), +W64LIT(0x3656f918eb965b66), +W64LIT(0x9d0212a0cac95eb7), +W64LIT(0x2ad930bb85cab75a), +W64LIT(0x862994ac45828984), +W64LIT(0x7d447b735036eaa2), +W64LIT(0xb07f6db4ae14d2e2), +W64LIT(0x6b08489fc2ce8dc3), +W64LIT(0x9b4344369e06272f), +W64LIT(0xad15bd2e75907c49), +W64LIT(0xdb77252b6cda5f21), +W64LIT(0xea85939c665b3f48), +W64LIT(0xc945722335a8c503), +W64LIT(0x159618a7b865a12d), +W64LIT(0x69377aed5d8b0918), +W64LIT(0x8971133ec774bd0d), +W64LIT(0x53e32f2c1e76a0bb), +W64LIT(0xf8b7c4943f29a56a), +W64LIT(0xff138b3bde3e9e65), +/* box 2 */ +W64LIT(0x7c6a2eb5fdabecc6), +W64LIT(0x401cda0a752bbea0), +W64LIT(0x1925217156dc57c4), +W64LIT(0x56dec6d301d70787), +W64LIT(0x41c751ff73c6ac58), +W64LIT(0xc9067697a92cb5f9), +W64LIT(0x3391c917aaa0bc85), +W64LIT(0xae0a9a4c0e742afe), +W64LIT(0xaa8ca972162a62f4), +W64LIT(0x5aa193912935df99), +W64LIT(0x86fd9135fe27e5ba), +W64LIT(0xffca074b1d3f538e), +W64LIT(0x0e3cb65d24cdfc1b), +W64LIT(0x4384b2e07fe9885d), +W64LIT(0xc73ac0ca8de149e2), +W64LIT(0x48e5bc7645972eb4), +W64LIT(0xbe0d56b46ef9ffd6), +W64LIT(0x200e6d05c0ef5f50), +W64LIT(0xe1f17dee597f7abd), +W64LIT(0x0243e31f0c2f2405), +W64LIT(0xf4ab09dd2741f567), +W64LIT(0xe4acc52547cc204f), +W64LIT(0x348f92c3b83cc272), +W64LIT(0x53837e181f645d75), +W64LIT(0xd8da319acf4c7229), +W64LIT(0x81e3cae1ecbb9b4d), +W64LIT(0xd6e687c7eb818e32), +W64LIT(0x3dad7f4a8e6d409e), +W64LIT(0x28f70b79f053cf44), +W64LIT(0x493e3783437a3c4c), +W64LIT(0xb27203f6461b27c8), +W64LIT(0xd02357e6fff0e23d), +W64LIT(0xe8d390676f2ef851), +W64LIT(0x26cbbd24d49e335f), +W64LIT(0xee1640467b5f945e), +W64LIT(0x4aa65f6949b80ab1), +W64LIT(0xb56c58225487593f), +W64LIT(0x4ffbe7a2570b5043), +W64LIT(0x0aba85633c93b411), +W64LIT(0x78ec1d8be5f5a4cc), +W64LIT(0x501b16f215a66b88), +W64LIT(0x271036d1d27321a7), +W64LIT(0x7ff2465ff769da3b), +W64LIT(0x35541936bed1d08a), +W64LIT(0xb8c886957a8893d9), +W64LIT(0x2fe950ade2cfb1b3), +W64LIT(0xf90fd76a094e3f81), +W64LIT(0x2daab3b2eee095b6), +W64LIT(0x1abd499b5c1e6139), +W64LIT(0x0c7f554228e2d81e), +W64LIT(0x425f391579049aa5), +W64LIT(0xc3bcf3f495bf01e8), +W64LIT(0xb4b7d3d7526a4bc7), +W64LIT(0x0000000000000000), +W64LIT(0xa0362c112ab9d6e5), +W64LIT(0x91e406198c364e65), +W64LIT(0x454162c16b98e452), +W64LIT(0x139fa4126a4fe3d5), +W64LIT(0x01db8bf506ed12f8), +W64LIT(0x9a85088fb648e88c), +W64LIT(0x3ab3249e9cf13e69), +W64LIT(0xd57eef2de143b8cf), +W64LIT(0xb1ea6b1c4cd91135), +W64LIT(0x7aaffe94e9da80c9), +W64LIT(0xad92f2a604b61c03), +W64LIT(0xa3ae44fb207be018), +W64LIT(0xeb4bf88d65ecceac), +W64LIT(0xc0249b1e9f7d3715), +W64LIT(0xa8cf4a6d1a0546f1), +W64LIT(0xc6e14b3f8b0c5b1a), +W64LIT(0xce182d43bbb0cb0e), +W64LIT(0xfc526fa117fd6573), +W64LIT(0x8c471456c2b451ab), +W64LIT(0xac497953025b0efb), +W64LIT(0x0486333e185e480a), +W64LIT(0x18feaa845031453c), +W64LIT(0xa1eda7e42c54c41d), +W64LIT(0x06c5d02114716c0f), +W64LIT(0x055db8cb1eb35af2), +W64LIT(0xe5774ed0412132b7), +W64LIT(0x36cc71dcb413e677), +W64LIT(0x470281de67b7c057), +W64LIT(0x58e2708e251afb9c), +W64LIT(0xa914c1981ce85409), +W64LIT(0xb3a9880340f63530), +W64LIT(0x638adfe5bf06d70d), +W64LIT(0x0b610e963a7ea6e9), +W64LIT(0x927c6ef386f47898), +W64LIT(0xed8e28ac719da2a3), +W64LIT(0x7548c33ccbfa6e2a), +W64LIT(0xf3b5520935dd8b90), +W64LIT(0x8d9c9fa3c4594353), +W64LIT(0x31d22a08a68f9880), +W64LIT(0x0da4deb72e0fcae6), +W64LIT(0x8fdf7cbcc8766756), +W64LIT(0x5dbfc8453ba9a16e), +W64LIT(0x8e04f749ce9b75ae), +W64LIT(0x83a029fee094bf48), +W64LIT(0xa4b01f2f32e79eef), +W64LIT(0x1c7899ba486f0d36), +W64LIT(0x654f0fc4ab77bb02), +W64LIT(0x7db1a540fb46fe3e), +W64LIT(0x51c09d07134b7970), +W64LIT(0xcb459588a50391fc), +W64LIT(0x3fee9c558242649b), +W64LIT(0xfe118cbe1bd24176), +W64LIT(0x76d0abd6c13858d7), +W64LIT(0x5e27a0af316b9793), +W64LIT(0x69305a868395631c), +W64LIT(0x3b68af6b9a1c2c91), +W64LIT(0x6db669b89bcb2b16), +W64LIT(0xa72877c53825a812), +W64LIT(0xd3bb3f0cf532d4c0), +W64LIT(0x6ff58aa797e40f13), +W64LIT(0x96fa5dcd9eaa3092), +W64LIT(0x2c713847e80d874e), +W64LIT(0xc57923d581ce6de7), +W64LIT(0x2b6f6393fa91f9b9), +W64LIT(0x0922ed89365182ec), +W64LIT(0x324a42e2ac4dae7d), +W64LIT(0x16c21cd974fcb927), +W64LIT(0x956235279468066f), +W64LIT(0x7b747561ef379231), +W64LIT(0x449ae9346d75f6aa), +W64LIT(0xf570822821ace79f), +W64LIT(0x5939fb7b23f7e964), +W64LIT(0x7937967ee318b634), +W64LIT(0x84be722af208c1bf), +W64LIT(0x08f9667c30bc9014), +W64LIT(0xefcdcbb37db286a6), +W64LIT(0xa6f3fc303ec8baea), +W64LIT(0xea9073786301dc54), +W64LIT(0x62515410b9ebc5f5), +W64LIT(0xd260b4f9f3dfc638), +W64LIT(0x9e033bb1ae16a086), +W64LIT(0x38f0c78190de1a6c), +W64LIT(0xc267780193521310), +W64LIT(0x80384114ea5689b5), +W64LIT(0x9b5e837ab0a5fa74), +W64LIT(0xf73361372d83c39a), +W64LIT(0x3009a1fda0628a78), +W64LIT(0xd4a564d8e7aeaa37), +W64LIT(0xfb4c347505611b84), +W64LIT(0x5b7a18642fd8cd61), +W64LIT(0x239605efca2d69ad), +W64LIT(0xf8d45c9f0fa32d79), +W64LIT(0xbb50ee7f704aa524), +W64LIT(0x392b4c7496330894), +W64LIT(0x0fe73da82220eee3), +W64LIT(0x3717fa29b2fef48f), +W64LIT(0xf26ed9fc33309968), +W64LIT(0xd73d0c32ed6c9cca), +W64LIT(0xda99d285c363562c), +W64LIT(0xde1fe1bbdb3d1e26), +W64LIT(0x738d131ddf8b0225), +W64LIT(0x292c808cf6beddbc), +W64LIT(0xbc4eb5ab62d6dbd3), +W64LIT(0x039868ea0ac236fd), +W64LIT(0xcc5bce5cb79fef0b), +W64LIT(0xb031e0e94a3403cd), +W64LIT(0xc4a2a82087237f1f), +W64LIT(0xb72fbb3d58a87d3a), +W64LIT(0xafd111b908993806), +W64LIT(0x68ebd173857871e4), +W64LIT(0x9d9b535ba4d4967b), +W64LIT(0xe9081b9269c3eaa9), +W64LIT(0x71cef002d3a42620), +W64LIT(0x93a7e50680196a60), +W64LIT(0x891aac9ddc070b59), +W64LIT(0x155a74337e3e8fda), +W64LIT(0x4e206c5751e642bb), +W64LIT(0x9721d6389847226a), +W64LIT(0x12442fe76ca2f12d), +W64LIT(0x2553d5cede5c05a2), +W64LIT(0xa275cf0e2696f2e0), +W64LIT(0x24885e3bd8b1175a), +W64LIT(0x670cecdba7589f07), +W64LIT(0x749348c9cd177cd2), +W64LIT(0x64948431ad9aa9fa), +W64LIT(0x2ab4e866fc7ceb41), +W64LIT(0xe6ef263a4be3044a), +W64LIT(0xe734adcf4d0e16b2), +W64LIT(0x903f8dec8adb5c9d), +W64LIT(0xf02d3ae33f1fbd6d), +W64LIT(0x725698e8d96610dd), +W64LIT(0x1da3124f4e821fce), +W64LIT(0x1719972c7211abdf), +W64LIT(0x11dc470d6660c7d0), +W64LIT(0xec55a3597770b05b), +W64LIT(0xbfd6dd416814ed2e), +W64LIT(0x57054d26073a157f), +W64LIT(0x1e3b7aa544402933), +W64LIT(0x5ffc2b5a3786856b), +W64LIT(0x61c93cfab329f308), +W64LIT(0x3e3517a084af7663), +W64LIT(0xf6e8eac22b6ed162), +W64LIT(0x1007ccf8608dd528), +W64LIT(0x66d7672ea1b58dff), +W64LIT(0x8b594f82d0282f5c), +W64LIT(0x1fe0f15042ad3bcb), +W64LIT(0x4b7dd49c4f551849), +W64LIT(0x4c638f485dc966be), +W64LIT(0xcfc3a6b6bd5dd9f6), +W64LIT(0x46d90a2b615ad2af), +W64LIT(0x8565f9dff4e5d347), +W64LIT(0x94b9bed292851497), +W64LIT(0xfa97bf80038c097c), +W64LIT(0xb9130d607c658121), +W64LIT(0xdc5c02a4d7123a23), +W64LIT(0x224d8e1accc07b55), +W64LIT(0x87261ac0f8caf742), +W64LIT(0xd901ba6fc9a160d1), +W64LIT(0xab57228710c7700c), +W64LIT(0x21d5e6f0c6024da8), +W64LIT(0x98c6eb90ba67cc89), +W64LIT(0x827ba20be679adb0), +W64LIT(0x991d6065bc8ade71), +W64LIT(0x5546ae390b15317a), +W64LIT(0xa56b94da340a8c17), +W64LIT(0x071e5bd4129c7ef7), +W64LIT(0xe02af61b5f926845), +W64LIT(0x6b73b9998fba4719), +W64LIT(0xdfc46a4eddd00cde), +W64LIT(0x770b2023c7d54a2f), +W64LIT(0x7e29cdaaf184c8c3), +W64LIT(0xba8b658a76a7b7dc), +W64LIT(0x9c40d8aea2398483), +W64LIT(0x9fd8b044a8fbb27e), +W64LIT(0xdb425970c58e44d4), +W64LIT(0xe269150453bd4c40), +W64LIT(0x3c76f4bf88805266), +W64LIT(0xf1f6b11639f2af95), +W64LIT(0x549d25cc0df82382), +W64LIT(0x4db804bd5b247446), +W64LIT(0x8a82c477d6c53da4), +W64LIT(0x5258f5ed19894f8d), +W64LIT(0x6e2e015291091deb), +W64LIT(0xc1ff10eb999025ed), +W64LIT(0xbd953e5e643bc92b), +W64LIT(0xc8ddfd62afc1a701), +W64LIT(0x5c6443b03d44b396), +W64LIT(0x6c6de24d9d2639ee), +W64LIT(0x1481ffc678d39d22), +W64LIT(0xd1f8dc13f91df0c5), +W64LIT(0xca9e1e7da3ee8304), +W64LIT(0xdd878951d1ff28db), +W64LIT(0x6012b70fb5c4e1f0), +W64LIT(0x1b66c26e5af373c1), +W64LIT(0xe3b29ef155505eb8), +W64LIT(0x70157bf7d54934d8), +W64LIT(0x2e32db58e422a34b), +W64LIT(0x6aa8326c895755e1), +W64LIT(0xb6f430c85e456fc2), +W64LIT(0xfd89e4541110778b), +W64LIT(0x88c12768daea19a1), +W64LIT(0xcd8045a9b172fdf3), +/* box 3 */ +W64LIT(0x99183e616655b742), +W64LIT(0xb2872032a50d6860), +W64LIT(0x0946f63b060528ef), +W64LIT(0x36612b9a141ef07d), +W64LIT(0x0634da84dd49579b), +W64LIT(0xfc9c9e9b486c8a57), +W64LIT(0xa63fe3c0744e6fd0), +W64LIT(0xf1515758d8b46bf9), +W64LIT(0x3e82559fcd5197ff), +W64LIT(0x92e12d262bc40177), +W64LIT(0xc3bb433a5a7752c5), +W64LIT(0x21c3852a5183267a), +W64LIT(0x39130725cf528f09), +W64LIT(0x9ba7db1d2dc12998), +W64LIT(0xc58f99be873e055e), +W64LIT(0xd9d424498f32656c), +W64LIT(0x27f75fae8cca71e1), +W64LIT(0x59b91019a8fc3430), +W64LIT(0xce768af9caafb36b), +W64LIT(0x9d930199f0887e03), +W64LIT(0x63b07a7ef3706a8e), +W64LIT(0xb5167288a70e7096), +W64LIT(0x40cc1a28e967d22e), +W64LIT(0x4d01d3eb79bf3380), +W64LIT(0x9e896cdb6456afb4), +W64LIT(0x2548bad2c75eef3b), +W64LIT(0xa79a6bfeab0420bd), +W64LIT(0x9f2ce4e5bb1ce0d9), +W64LIT(0x32ea146282c3393c), +W64LIT(0x6d67defff7765a97), +W64LIT(0x83775912b31080eb), +W64LIT(0xf5da68a04e69a2b8), +W64LIT(0x1196743498d4819c), +W64LIT(0x0bf913474d91b635), +W64LIT(0x43d6776a7db90399), +W64LIT(0x444725d07fba1b6f), +W64LIT(0x6584a0fa2e393d15), +W64LIT(0x3f27dda1121bd892), +W64LIT(0xf6c005e2dab7730f), +W64LIT(0x56cb3ca673b04b44), +W64LIT(0x642128c4f1737278), +W64LIT(0xbf4ae9f135d589ce), +W64LIT(0xb038c54eee99f6ba), +W64LIT(0xf47fe09e9123edd5), +W64LIT(0x75b75cf069a7f3e4), +W64LIT(0xd419ed8a1fea84c2), +W64LIT(0x73838674b4eea47f), +W64LIT(0x498aec13ef62fac1), +W64LIT(0x20660d148ec96917), +W64LIT(0xa48006bc3fdaf10a), +W64LIT(0x2f1421ab55851663), +W64LIT(0x0a5c9b7992dbf958), +W64LIT(0xd1375a4c567d02ee), +W64LIT(0x0000000000000000), +W64LIT(0xc842507d17e6e4f0), +W64LIT(0xf3eeb2249320f523), +W64LIT(0xc9e7d843c8acab9d), +W64LIT(0xff86f3d9dcb25be0), +W64LIT(0xb4b3fab678443ffb), +W64LIT(0xb19d4d7031d3b9d7), +W64LIT(0x79df1d0d26355d27), +W64LIT(0x8eba90d123c86145), +W64LIT(0xaa57a23d3bdcc113), +W64LIT(0xcb583d3f83383547), +W64LIT(0xd871ac7750782a01), +W64LIT(0xe162ab529f2aa508), +W64LIT(0x38b68f1b1018c064), +W64LIT(0x237c60561a17b8a0), +W64LIT(0xa31154063dd9e9fc), +W64LIT(0x713c6308ff7a3aa5), +W64LIT(0x1a6f6773d54537a9), +W64LIT(0x08e37e05d94f6782), +W64LIT(0x357b46d880c021ca), +W64LIT(0x6cc256c1283c15fa), +W64LIT(0xcfd302c715e5fc06), +W64LIT(0xbdf50c8d7e411714), +W64LIT(0x7cf1aacb6fa2db0b), +W64LIT(0x5240035ee56d8205), +W64LIT(0x7b60f8716da1c3fd), +W64LIT(0x01a5883edf4a4f6d), +W64LIT(0xdd5f1bb119efac2d), +W64LIT(0x5474d9da3824d59e), +W64LIT(0x0f722cbfdb4c7f74), +W64LIT(0x17a2aeb0459dd607), +W64LIT(0x37c4a3a4cb54bf10), +W64LIT(0xc21ecb04853d1da8), +W64LIT(0x4273ff54a2f34cf4), +W64LIT(0xdace490b1becb4db), +W64LIT(0x6af68c45f5754261), +W64LIT(0x46f8c0ac342e85b5), +W64LIT(0x854383966e59d770), +W64LIT(0x81c8bc6ef8841e31), +W64LIT(0x3bace25984c611d3), +W64LIT(0x1033fc0a479ecef1), +W64LIT(0x1c5bbdf7080c6032), +W64LIT(0x7412d4ceb6edbc89), +W64LIT(0xa8e8474170485fc9), +W64LIT(0xb8dbbb4b37d69138), +W64LIT(0x079152ba020318f6), +W64LIT(0x72260e4a6ba4eb12), +W64LIT(0x905ec85a60509fad), +W64LIT(0x2dabc4d71e1188b9), +W64LIT(0xd092d27289374d83), +W64LIT(0x610f9f02b8e4f454), +W64LIT(0x02bfe57c4b949eda), +W64LIT(0x95707f9c29c71981), +W64LIT(0x6fd83b83bce2c44d), +W64LIT(0x5d322fe13e21fd71), +W64LIT(0x34decee65f8a6ea7), +W64LIT(0xcd6ce7bb5e7162dc), +W64LIT(0xfb0dcc214a6f92a1), +W64LIT(0x2eb1a9958acf590e), +W64LIT(0xdcfa938fc6a5e340), +W64LIT(0x669ecdb8bae7eca2), +W64LIT(0x151d4bcc0e0948dd), +W64LIT(0xfd3916a59726c53a), +W64LIT(0x581c982777b67b5d), +W64LIT(0x1bcaef4d0a0f78c4), +W64LIT(0xdfe0fecd527b32f7), +W64LIT(0x128c19760c0a502b), +W64LIT(0x84e60ba8b113981d), +W64LIT(0x3c3db0e386c50925), +W64LIT(0x7febc789fb7c0abc), +W64LIT(0x7d5422f5b0e89466), +W64LIT(0xd70380c88b345575), +W64LIT(0xbbc1d609a308408f), +W64LIT(0xe278c6100bf474bf), +W64LIT(0x5e2842a3aaff2cc6), +W64LIT(0x6b53047b2a3f0d0c), +W64LIT(0xf7658ddc05fd3c62), +W64LIT(0x9a025323f28b66f5), +W64LIT(0x8c0575ad685cff9f), +W64LIT(0x76ad31b2fd792253), +W64LIT(0x68496939bee1dcbb), +W64LIT(0x7e4e4fb7243645d1), +W64LIT(0xe44c1c94d6bd2324), +W64LIT(0xbeef61cfea9fc6a3), +W64LIT(0x91fb4064bf1ad0c0), +W64LIT(0x052eb7c64997862c), +W64LIT(0x4a9081517bbc2b76), +W64LIT(0x8f1f18effc822e28), +W64LIT(0x3a096a675b8c5ebe), +W64LIT(0xee1087ed4466da7c), +W64LIT(0x2652d79053803e8c), +W64LIT(0x7099eb36203075c8), +W64LIT(0xc7307cc2ccaa9b84), +W64LIT(0x5c97a7dfe16bb21c), +W64LIT(0x50ffe622aef91cdf), +W64LIT(0x8da0fd93b716b0f2), +W64LIT(0x69ece10761ab93d6), +W64LIT(0x31f07920161de88b), +W64LIT(0x13299148d3401f46), +W64LIT(0x031a6d4294ded1b7), +W64LIT(0xccc96f85813b2db1), +W64LIT(0x14b8c3f2d14307b0), +W64LIT(0x8659eed4fa8706c7), +W64LIT(0xba645e377c420fe2), +W64LIT(0x2920fb2f88cc41f8), +W64LIT(0x87fc66ea25cd49aa), +W64LIT(0x1ee4588b4398fee8), +W64LIT(0xecaf62910ff244a6), +W64LIT(0xf817a163deb14316), +W64LIT(0x45e2adeea0f05402), +W64LIT(0x806d345027ce515c), +W64LIT(0x576eb498acfa0429), +W64LIT(0xa5258e82e090be67), +W64LIT(0x892bc26b21cb79b3), +W64LIT(0x6e7db3bd63a88b20), +W64LIT(0x4e1bbea9ed61e237), +W64LIT(0xadc6f08739dfd9e5), +W64LIT(0x8b9427176a5fe769), +W64LIT(0xa1aeb17a764d7726), +W64LIT(0x4b35096fa4f6641b), +W64LIT(0x22d9e868c55df7cd), +W64LIT(0x55d151e4e76e9af3), +W64LIT(0x966a12debd19c836), +W64LIT(0x0dcdc9c390d8e1ae), +W64LIT(0xf24b3a1a4c6aba4e), +W64LIT(0x24ed32ec1814a056), +W64LIT(0xaf7915fb724b473f), +W64LIT(0x2885731157860e95), +W64LIT(0x9c3689a72fc2316e), +W64LIT(0x475d4892eb64cad8), +W64LIT(0xac6378b9e6959688), +W64LIT(0xa00b3944a907384b), +W64LIT(0xc695f4fc13e0d4e9), +W64LIT(0x3055f11ec957a7e6), +W64LIT(0x6215f2402c3a25e3), +W64LIT(0xde4576f38d317d9a), +W64LIT(0x9344a518f48e4e1a), +W64LIT(0x82d2d12c6c5acf86), +W64LIT(0xefb50fd39b2c9511), +W64LIT(0xe981d5574665c28a), +W64LIT(0x5f8dca9d75b563ab), +W64LIT(0xb60c1fca33d0a121), +W64LIT(0xfe237be703f8148d), +W64LIT(0xd6a608f6547e1a18), +W64LIT(0xb97e3375e89cde55), +W64LIT(0xd388bf301de99c34), +W64LIT(0x5b06f565e368aaea), +W64LIT(0xf0f4df6607fe2494), +W64LIT(0x1607268e9ad7996a), +W64LIT(0xaedc9dc5ad010852), +W64LIT(0xe0c7236c4060ea65), +W64LIT(0xea9bb815d2bb133d), +W64LIT(0x888e4a55fe8136de), +W64LIT(0x5aa37d5b3c22e587), +W64LIT(0xc104a64611e3cc1f), +W64LIT(0x515a6e1c71b353b2), +W64LIT(0xc42a118058744a33), +W64LIT(0x7708b98c22336d3e), +W64LIT(0x2a3a966d1c12904f), +W64LIT(0x8a31af29b515a804), +W64LIT(0xed0aeaafd0b80bcb), +W64LIT(0x2c0e4ce9c15bc7d4), +W64LIT(0x0c6841fd4f92aec3), +W64LIT(0x98bdb65fb91ff82f), +W64LIT(0x1f41d0b59cd2b185), +W64LIT(0xb322a80c7a47270d), +W64LIT(0xe6f3f9e89d29bdfe), +W64LIT(0x7ac5704fb2eb8c90), +W64LIT(0xa94dcf7faf0210a4), +W64LIT(0x787a9533f97f124a), +W64LIT(0xdb6bc135c4a6fbb6), +W64LIT(0x048b3ff896ddc941), +W64LIT(0xe8245d69992f8de7), +W64LIT(0xe3dd4e2ed4be3bd2), +W64LIT(0xcafdb5015c727a2a), +W64LIT(0xb7a997f4ec9aee4c), +W64LIT(0xe75671d64263f293), +W64LIT(0x2b9f1e53c358df22), +W64LIT(0x18d0820f9ed1a973), +W64LIT(0xabf22a03e4968e7e), +W64LIT(0xa2b4dc38e293a691), +W64LIT(0x673b458665ada3cf), +W64LIT(0xf9b2295d01fb0c7b), +W64LIT(0xd22d370ec2a3d359), +W64LIT(0x97cf9ae06253875b), +W64LIT(0x0ed7a48104063019), +W64LIT(0x482f642d3028b5ac), +W64LIT(0xc0a12e78cea98372), +W64LIT(0x4fbe3697322bad5a), +W64LIT(0x19750a31419be61e), +W64LIT(0x41699216362d9d43), +W64LIT(0xd5bc65b4c0a0cbaf), +W64LIT(0xe5e994aa09f76c49), +W64LIT(0xeb3e302b0df15c50), +W64LIT(0x94d5f7a2f68d56ec), +W64LIT(0x53e58b603a27cd68), +W64LIT(0x3d9838dd598f4648), +W64LIT(0x60aa173c67aebb39), +W64LIT(0x1dfe35c9d7462f5f), +W64LIT(0x4ca45bd5a6f57ced), +W64LIT(0xbc5084b3a10b5879), +W64LIT(0xfaa8441f9525ddcc), +W64LIT(0x334f9c5c5d897651), +/* box 4 */ +W64LIT(0xda1687a883adf27e), +W64LIT(0xe35c9378578d9f22), +W64LIT(0x303ca4531637fa40), +W64LIT(0xa088321f74b20375), +W64LIT(0xc9863f3a9acb95e9), +W64LIT(0x5fcf47c57d0b0ed4), +W64LIT(0x4aa211e4e1280b4b), +W64LIT(0xe1a4c9ba871d1289), +W64LIT(0x4926664759f03a4f), +W64LIT(0xadfb36ede3707bca), +W64LIT(0xcf7bd1891f8ef7e1), +W64LIT(0x9735559e8f882792), +W64LIT(0x5932a976f84e6cdc), +W64LIT(0x9dc792bef547818a), +W64LIT(0x06fdeeb385456208), +W64LIT(0x46ad38771ea2cf5b), +W64LIT(0x5eb36aa41543b27b), +W64LIT(0x8b2eb33cd1bcb511), +W64LIT(0x71105ff6e598ebbc), +W64LIT(0x5441ad846f8c1463), +W64LIT(0x4c5fff57646d6943), +W64LIT(0xf3485c49f633c9b1), +W64LIT(0x9cbbbfdf9d0f3d25), +W64LIT(0x22d031a067192178), +W64LIT(0xca0248992213a4ed), +W64LIT(0x19627fb263a9c18f), +W64LIT(0x9330e1efda5dc831), +W64LIT(0x1390b89219666797), +W64LIT(0x2edf18339893e568), +W64LIT(0x6c779435d3e4c590), +W64LIT(0x53c06e568281cac4), +W64LIT(0x6ff3e3966b3cf494), +W64LIT(0xfe3b58bb61f1b10e), +W64LIT(0x77edb14560dd89b4), +W64LIT(0x02f85ac2d0908dab), +W64LIT(0x12ec95f3712edb38), +W64LIT(0x85d9c06dfea6fcaa), +W64LIT(0x90b4964c6285f935), +W64LIT(0xf1b0068b26a3441a), +W64LIT(0x729428555d40dab8), +W64LIT(0x5c4b3066c5d33fd0), +W64LIT(0x5d371d07ad9b837f), +W64LIT(0xa48d866e2167ecd6), +W64LIT(0xb661139d504937ee), +W64LIT(0xa27068dda4228ede), +W64LIT(0xf8c6b608e4b4d306), +W64LIT(0x6bf657e73ee91b37), +W64LIT(0xac871b8c8b38c765), +W64LIT(0x4ea7a595b4fde4e8), +W64LIT(0x0d7304f297c278bf), +W64LIT(0xb71d3efc38018b41), +W64LIT(0xae7f414e5ba84ace), +W64LIT(0xaf036c2f33e0f661), +W64LIT(0x0000000000000000), +W64LIT(0xb89660cc7f537e55), +W64LIT(0xa675dcacf1f7617d), +W64LIT(0x610490c74426bd2f), +W64LIT(0xc18ca2d83094be5a), +W64LIT(0x2adaac42cd460acb), +W64LIT(0x7d1f76651a122fac), +W64LIT(0xc58916a9654151f9), +W64LIT(0xedabe0297897d699), +W64LIT(0x2d5b6f90204bd46c), +W64LIT(0x26d585d132cccedb), +W64LIT(0x9f3fc87c25d70c21), +W64LIT(0xc60d610add9960fd), +W64LIT(0x80a0597dc33bafa6), +W64LIT(0xd0e44088f9625466), +W64LIT(0x1d67cbc3367c2e2c), +W64LIT(0x2c2742f1480368c3), +W64LIT(0x89d6e9fe012c38ba), +W64LIT(0xe9ae54582d42393a), +W64LIT(0x3ecbd702392db3fb), +W64LIT(0xb5e5643ee89106ea), +W64LIT(0xa882affddeed28c6), +W64LIT(0x1ae60811db71f08b), +W64LIT(0x924ccc8eb215749e), +W64LIT(0xfcc30279b1613ca5), +W64LIT(0x825803bf13ab220d), +W64LIT(0xd992f00b3b75c37a), +W64LIT(0xc8fa125bf2832946), +W64LIT(0x35453d432baaa94c), +W64LIT(0xf9ba9b698cfc6fa9), +W64LIT(0x37bd6781fb3a24e7), +W64LIT(0x791ac2144fc7c00f), +W64LIT(0x16e9218224fb349b), +W64LIT(0xdb6aaac9ebe54ed1), +W64LIT(0xd8eedd6a533d7fd5), +W64LIT(0x7c635b04725a9303), +W64LIT(0x553d80e507c4a8cc), +W64LIT(0x9a46516c184a5f2d), +W64LIT(0x14117b40f46bb930), +W64LIT(0x1ee3bc608ea41f28), +W64LIT(0x27a9a8b05a847274), +W64LIT(0x4050d6c49be7ad53), +W64LIT(0x7be298d69f574da4), +W64LIT(0x6a8a7a8656a1a798), +W64LIT(0x4d23d2360c25d5ec), +W64LIT(0x1014cf31a1be5693), +W64LIT(0xb264a7ec059cd84d), +W64LIT(0xea2a23fb959a083e), +W64LIT(0xf0cc2bea4eebf8b5), +W64LIT(0x76919c240895351b), +W64LIT(0x0b8eea4112871ab7), +W64LIT(0x47d1151676ea73f4), +W64LIT(0xbdeff9dc42ce2d59), +W64LIT(0x2ba68123a50eb664), +W64LIT(0x057999103d9d530c), +W64LIT(0xe759270902587081), +W64LIT(0xef53baeba8075b32), +W64LIT(0x4fdb88f4dcb55847), +W64LIT(0x6e8fcef70374483b), +W64LIT(0x1168e250c9f6ea3c), +W64LIT(0x1b9a2570b3394c24), +W64LIT(0x706c72978dd05713), +W64LIT(0x865db7ce467ecdae), +W64LIT(0x52bc4337eac9766b), +W64LIT(0x504419f53a59fbc0), +W64LIT(0x8f2b074d84695ab2), +W64LIT(0x6078bda62c6e0180), +W64LIT(0x43d4a167233f9c57), +W64LIT(0x0ef773512f1a49bb), +W64LIT(0x0c0f2993ff8ac410), +W64LIT(0x4bde3c858960b7e4), +W64LIT(0x66855315a92b6388), +W64LIT(0xd360372b41ba6562), +W64LIT(0x584e84179006d073), +W64LIT(0x9b3a7c0d7002e382), +W64LIT(0xa5f1ab0f492f5079), +W64LIT(0x2822f6801dd68760), +W64LIT(0x445562b5ce3242f0), +W64LIT(0xaa7af53f0e7da56d), +W64LIT(0x3c338dc0e9bd3e50), +W64LIT(0x3bb24e1204b0e0f7), +W64LIT(0xd59dd998c4ff076a), +W64LIT(0x91c8bb2d0acd459a), +W64LIT(0x84a5ed0c96ee4005), +W64LIT(0x33b8d3f0aeefcb44), +W64LIT(0x57c5da27d7542567), +W64LIT(0x32c4fe91c6a777eb), +W64LIT(0x3439102243e215e3), +W64LIT(0xc7714c6bb5d1dc52), +W64LIT(0x3fb7fa6351650f54), +W64LIT(0x87219aaf2e367101), +W64LIT(0xf5b5b2fa7376abb9), +W64LIT(0x412cfba5f3af11fc), +W64LIT(0xdceb691b06e89076), +W64LIT(0xbb12176fc78b4f51), +W64LIT(0x73e8053435086617), +W64LIT(0xe220be193fc5238d), +W64LIT(0xb09cfd2ed50c55e6), +W64LIT(0xb9ea4dad171bc2fa), +W64LIT(0x9e43e51d4d9fb08e), +W64LIT(0x36c14ae093729848), +W64LIT(0xa9fe829cb6a59469), +W64LIT(0x0405b47155d5efa3), +W64LIT(0x0af2c7207acfa618), +W64LIT(0x7e9b01c6a2ca1ea8), +W64LIT(0xdd97447a6ea02cd9), +W64LIT(0x0781c3d2ed0ddea7), +W64LIT(0x7866ef75278f7ca0), +W64LIT(0xd1986de9912ae8c9), +W64LIT(0xcb7e65f84a5b1842), +W64LIT(0xcd838b4bcf1e7a4a), +W64LIT(0xab06d85e663519c2), +W64LIT(0xd4e1f4f9acb7bbc5), +W64LIT(0xfdbf2f18d929800a), +W64LIT(0xf23471289e7b751e), +W64LIT(0xbc93d4bd2a8691f6), +W64LIT(0x3d4fa0a181f582ff), +W64LIT(0xba6e3a0eafc3f3fe), +W64LIT(0x5ab6ded540965dd8), +W64LIT(0xeb560e9afdd2b491), +W64LIT(0x0976b083c217971c), +W64LIT(0xecd7cd4810df6a36), +W64LIT(0x23ac1cc10f519dd7), +W64LIT(0xbe6b8e7ffa161c5d), +W64LIT(0x7fe72ca7ca82a207), +W64LIT(0xc0f08fb958dc02f5), +W64LIT(0x7a9eb5b7f71ff10b), +W64LIT(0xa709f1cd99bfddd2), +W64LIT(0x8dd35d8f54f9d719), +W64LIT(0x8caf70ee3cb16bb6), +W64LIT(0xe4dd50aaba804185), +W64LIT(0x83242ede7be39ea2), +W64LIT(0x98be0baec8dad286), +W64LIT(0x690e0d25ee79969c), +W64LIT(0x95cd0f5c5f18aa39), +W64LIT(0x56b9f746bf1c99c8), +W64LIT(0x7469c6e6d805b8b0), +W64LIT(0x8a529e5db9f409be), +W64LIT(0xe6250a686a10cc2e), +W64LIT(0x2fa33552f0db59c7), +W64LIT(0x42a88c064b7720f8), +W64LIT(0x6d0bb954bbac793f), +W64LIT(0x181e52d30be17d20), +W64LIT(0xbf17a31e925ea0f2), +W64LIT(0x94b1223d37501696), +W64LIT(0xe8d27939450a8595), +W64LIT(0xccffa62aa756c6e5), +W64LIT(0x383639b1bc68d1f3), +W64LIT(0xee2f978ac04fe79d), +W64LIT(0xa30c45bccc6a3271), +W64LIT(0x1f9f9101e6eca387), +W64LIT(0xb1e0d04fbd44e949), +W64LIT(0x242ddf13e25c4370), +W64LIT(0x156d56219c23059f), +W64LIT(0x88aac49f69648415), +W64LIT(0x6280e764fcfe8c2b), +W64LIT(0xdf6f1eb8be30a172), +W64LIT(0xe5a17dcbd2c8fd2a), +W64LIT(0xe0d8e4dbef55ae26), +W64LIT(0x63fcca0594b63084), +W64LIT(0xa1f41f7e1cfabfda), +W64LIT(0x295edbe1759e3bcf), +W64LIT(0x67f97e74c163df27), +W64LIT(0x038477a3b8d83104), +W64LIT(0xde1333d9d6781ddd), +W64LIT(0x3ace63736cf85c58), +W64LIT(0xd619ae3b7c27366e), +W64LIT(0x5bcaf3b428dee177), +W64LIT(0xb3188a8d6dd464e2), +W64LIT(0x1c1be6a25e349283), +W64LIT(0x017c2d616848bcaf), +W64LIT(0x8e572a2cec21e61d), +W64LIT(0xf631c559cbae9abd), +W64LIT(0x81dc741cab731309), +W64LIT(0xff4775da09b90da1), +W64LIT(0xb499495f80d9ba45), +W64LIT(0x0f8b5e304752f514), +W64LIT(0x394a14d0d4206d5c), +W64LIT(0xce07fce877c64b4e), +W64LIT(0xf4c99f9b1b3e1716), +W64LIT(0xc4f53bc80d09ed56), +W64LIT(0xc208d57b884c8f5e), +W64LIT(0x080a9de2aa5f2bb3), +W64LIT(0x314089327e7f46ef), +W64LIT(0xfa3eecca34245ead), +W64LIT(0x20286b62b789acd3), +W64LIT(0x7515eb87b04d041f), +W64LIT(0x513834945211476f), +W64LIT(0x650124b611f3528c), +W64LIT(0x17950ce34cb38834), +W64LIT(0x45294fd4a67afe5f), +W64LIT(0x21544603dfc1107c), +W64LIT(0x485a4b2631b886e0), +W64LIT(0x6872204486312a33), +W64LIT(0x647d09d779bbee23), +W64LIT(0x2551f2728a14ffdf), +W64LIT(0xd765835a146f8ac1), +W64LIT(0xd21c1a4a29f2d9cd), +W64LIT(0x99c226cfa0926e29), +W64LIT(0xfb42c1ab5c6ce202), +W64LIT(0xc374f81ae00433f1), +W64LIT(0x964978ffe7c09b3d), +W64LIT(0xf74de838a3e62612), +/* box 5 */ +W64LIT(0x74b87b36b0592c6a), +W64LIT(0x3d82d75dffb4b81c), +W64LIT(0x8884246715267825), +W64LIT(0xdaf2d8a77ed4e5de), +W64LIT(0xfeb118650e53f9c7), +W64LIT(0xbd2d1aea59226b06), +W64LIT(0x26ce87f6dbabb191), +W64LIT(0x32772ecbeb66bd0a), +W64LIT(0xd4bbf82bc5104c8c), +W64LIT(0x055357720c4e03a1), +W64LIT(0xef5be62a32d0f6fd), +W64LIT(0xbe1c84c45d186aca), +W64LIT(0xacc7e4a565a1643c), +W64LIT(0x8dd7731519687b84), +W64LIT(0x11eafe4f3c830f3a), +W64LIT(0x04ef8e68a358afe5), +W64LIT(0x40ad9ca1534b930d), +W64LIT(0xe44191d4855a5c0e), +W64LIT(0x6001d20b809420f1), +W64LIT(0x73666b70173b8243), +W64LIT(0x372479b9e728beab), +W64LIT(0x45fecbd35f0590ac), +W64LIT(0x7057f55e1301838f), +W64LIT(0xff0dc17fa1455583), +W64LIT(0x0cc467b810e804da), +W64LIT(0xb9c29482fa7ac4e3), +W64LIT(0xa003831d754960e6), +W64LIT(0x8a096353be0ad5ad), +W64LIT(0xdd2cc8e1d9b64bf7), +W64LIT(0xc7dc415052bfee3e), +W64LIT(0x9f0c137421d17572), +W64LIT(0x35a93e8d4c041323), +W64LIT(0x9a5f44062d9f76d3), +W64LIT(0x71eb2c44bc172fcb), +W64LIT(0x0ff5f99614d20516), +W64LIT(0x7789e518b4632da6), +W64LIT(0xc99561dce97b476c), +W64LIT(0x5276fcc06bf29dfb), +W64LIT(0x4a0b32454bd795ba), +W64LIT(0x9274add69e2fddec), +W64LIT(0x4f5865374799961b), +W64LIT(0xb2d8e37c4df06e10), +W64LIT(0xc4eddf7e5685eff2), +W64LIT(0xb3643a66e2e6c254), +W64LIT(0xd50721316a06e0c8), +W64LIT(0x8bb5ba49111c79e9), +W64LIT(0x2bb639546455190f), +W64LIT(0xf8d3d1390627fbaa), +W64LIT(0x38d1802ff3fabbbd), +W64LIT(0xdfa18fd5729ae67f), +W64LIT(0x4ee4bc2de88f3a5f), +W64LIT(0xf72628af12f5febc), +W64LIT(0x0aa6aee4189c06b7), +W64LIT(0x0000000000000000), +W64LIT(0x9eb0ca6e8ec7d936), +W64LIT(0xcb1826e84257eae4), +W64LIT(0x187dce8520250841), +W64LIT(0xc28f16225ef1ed9f), +W64LIT(0xc333cf38f1e741db), +W64LIT(0x4220db95f8673e85), +W64LIT(0xdc9011fb76a0e7b3), +W64LIT(0x105627559395a37e), +W64LIT(0x2f59b73cc70db6ea), +W64LIT(0xe112c6a689145faf), +W64LIT(0x82228a830dba7e92), +W64LIT(0x2ee56e26681b1aae), +W64LIT(0x2a0ae04ecb43b54b), +W64LIT(0x47738ce7f4293d24), +W64LIT(0xa7dd935bd22bcecf), +W64LIT(0xd2d93177cd644ee1), +W64LIT(0xebb4684291885918), +W64LIT(0x0e49208cbbc4a952), +W64LIT(0xa550d46f79076347), +W64LIT(0x411145bbfc5d3f49), +W64LIT(0xe6ccd6e02e76f186), +W64LIT(0x4bb7eb5fe4c139fe), +W64LIT(0x5d8305567f2098ed), +W64LIT(0x95aabd90394d73c5), +W64LIT(0x25ff19d8df91b05d), +W64LIT(0x86cd04ebaee2d177), +W64LIT(0x03319e2e043a01cc), +W64LIT(0x6b1ba5f5371e8a02), +W64LIT(0x76353c021b7581e2), +W64LIT(0x64ee5c6323cc8f14), +W64LIT(0x5c3fdc4cd03634a9), +W64LIT(0x6996e2c19c32278a), +W64LIT(0x8938fd7dba30d461), +W64LIT(0x7b4d82a0a48b297c), +W64LIT(0xbfa05ddef20ec68e), +W64LIT(0x8ee6ed3b1d527a48), +W64LIT(0x61bd0b112f828cb5), +W64LIT(0x66631b5788e0229c), +W64LIT(0x55a8ec86cc9033d2), +W64LIT(0x1c9240ed837da7a4), +W64LIT(0x150570279fdba0df), +W64LIT(0x53ca25dac4e431bf), +W64LIT(0xd636bf1f6e3ce104), +W64LIT(0xcaa4fff2ed4146a0), +W64LIT(0x787c1c8ea0b128b0), +W64LIT(0xad7b3dbfcab7c878), +W64LIT(0xfc3c5f51a57f544f), +W64LIT(0xb78bb40e41be6db1), +W64LIT(0x8c6baa0fb67ed7c0), +W64LIT(0xce4b719a4e19e945), +W64LIT(0xf96f0823a93157ee), +W64LIT(0x7d2f4bfcacff2b11), +W64LIT(0x3eb34973fb8eb9d0), +W64LIT(0xe39f81922238f227), +W64LIT(0x239dd084d7e5b230), +W64LIT(0x1fa3dec38747a668), +W64LIT(0xc5510664f99343b6), +W64LIT(0xc829b8c6466deb28), +W64LIT(0x85fc9ac5aad8d0bb), +W64LIT(0xb6376d14eea8c1f5), +W64LIT(0x9d8154408afdd8fa), +W64LIT(0x3be01e01f7c0ba71), +W64LIT(0x628c953f2bb88d79), +W64LIT(0x6d796ca93f6a886f), +W64LIT(0xfa5e960dad0b5622), +W64LIT(0xe5fd48ce2a4cf04a), +W64LIT(0xe7700ffa81605dc2), +W64LIT(0x2dd4f0086c211b62), +W64LIT(0x2221099e78f31e74), +W64LIT(0xdb4e01bdd1c2499a), +W64LIT(0xf417b68116cfff70), +W64LIT(0xb506f33aea92c039), +W64LIT(0x514762ee6fc89c37), +W64LIT(0x9c3d8d5a25eb74be), +W64LIT(0x396d59355cec17f9), +W64LIT(0xccc636aee53544cd), +W64LIT(0x0b1a77feb78aaaf3), +W64LIT(0xe9392f763aa4f490), +W64LIT(0xaaa52df96dd56651), +W64LIT(0x46cf55fd5b3f9160), +W64LIT(0xa4ec0d75d611cf03), +W64LIT(0xaff67a8b619b65f0), +W64LIT(0x3415e797e312bf67), +W64LIT(0x7af15bba0b9d8538), +W64LIT(0x811314ad09807f5e), +W64LIT(0x8771ddf101f47d33), +W64LIT(0x969b23be3d777209), +W64LIT(0xd365e86d6272e2a5), +W64LIT(0x58d05224736e9b4c), +W64LIT(0xc660984afda9427a), +W64LIT(0x5414359c63869f96), +W64LIT(0xe885f66c95b258d4), +W64LIT(0x655285798cda2350), +W64LIT(0x6cc5b5b3907c242b), +W64LIT(0x6ff42b9d944625e7), +W64LIT(0xc0025116f5dd4017), +W64LIT(0xa28ec429de65cd6e), +W64LIT(0x63304c2584ae213d), +W64LIT(0x7fa20cc807d38699), +W64LIT(0x996eda2829a5771f), +W64LIT(0x1b4c50ab241f098d), +W64LIT(0x1e1f07d928510a2c), +W64LIT(0x33cbf7d14470114e), +W64LIT(0xb055a448e6dcc398), +W64LIT(0x98d2033286b3db5b), +W64LIT(0xec6a780436eaf731), +W64LIT(0xa1bf5a07da5fcca2), +W64LIT(0xbaf30aacfe40c52f), +W64LIT(0xf144e1f31a81fcd1), +W64LIT(0xe0ae1fbc2602f3eb), +W64LIT(0x14b9a93d30cd0c9b), +W64LIT(0x596c8b3edc783708), +W64LIT(0x682a3bdb33248bce), +W64LIT(0xb87e4d98556c68a7), +W64LIT(0x80afcdb7a696d31a), +W64LIT(0x5725abb267bc9e5a), +W64LIT(0x914533f89a15dc20), +W64LIT(0x5eb29b787b1a9921), +W64LIT(0x01bcd91aaf16ac44), +W64LIT(0xc1be880c5acbec53), +W64LIT(0xedd6a11e99fc5b75), +W64LIT(0x028d4734ab2cad88), +W64LIT(0x8f5a3421b244d60c), +W64LIT(0x4dd52203ecb53b93), +W64LIT(0x3f0f906954981594), +W64LIT(0xae4aa391ce8dc9b4), +W64LIT(0x3698a0a3483e12ef), +W64LIT(0xf5ab6f9bb9d95334), +W64LIT(0x082be9d0b3b0ab3f), +W64LIT(0xd1e8af59c95e4f2d), +W64LIT(0xd87f9f93d5f84856), +W64LIT(0x6e48f2873b5089a3), +W64LIT(0x2443c0c270871c19), +W64LIT(0xb1e97d5249ca6fdc), +W64LIT(0x7c9392e603e98755), +W64LIT(0x839e5399a2acd2d6), +W64LIT(0x19c1179f8f33a405), +W64LIT(0xde1d56cfdd8c4a3b), +W64LIT(0x20ac4eaad3dfb3fc), +W64LIT(0x1af089b18b09a5c9), +W64LIT(0x3a5cc71b58d61635), +W64LIT(0x444212c9f0133ce8), +W64LIT(0x72dab26ab82d2e07), +W64LIT(0x4c69fb1943a397d7), +W64LIT(0xf3c9a6c7b1ad5159), +W64LIT(0x1d2e99f72c6b0be0), +W64LIT(0xb4ba2a2045846c7d), +W64LIT(0xe22358888d2e5e63), +W64LIT(0x2887a77a606f18c3), +W64LIT(0xa8286acdc6f9cbd9), +W64LIT(0x5f0e4262d40c3565), +W64LIT(0xeee73f309dc65ab9), +W64LIT(0x9be39d1c8289da97), +W64LIT(0x1634ee099be1a113), +W64LIT(0xea08b1583e9ef55c), +W64LIT(0x9727faa49261de4d), +W64LIT(0x2c682912c337b726), +W64LIT(0xcff7a880e10f4501), +W64LIT(0x1788371334f70d57), +W64LIT(0x27725eec74bd1dd5), +W64LIT(0x3146b0e5ef5cbcc6), +W64LIT(0x099730ca1ca6077b), +W64LIT(0xf2757fdd1ebbfd1d), +W64LIT(0x6aa77cef98082646), +W64LIT(0xbb4fd3b65156696b), +W64LIT(0x569972a8c8aa321e), +W64LIT(0xa3321d337173612a), +W64LIT(0x50fbbbf4c0de3073), +W64LIT(0x5a5d1510d84236c4), +W64LIT(0xfd80864b0a69f80b), +W64LIT(0x07de1046a762ae29), +W64LIT(0xa6614a417d3d628b), +W64LIT(0xd78a6605c12a4d40), +W64LIT(0x67dfc24d27f68ed8), +W64LIT(0xbc91c3f0f634c742), +W64LIT(0xd05476436648e369), +W64LIT(0x493aac6b4fed9476), +W64LIT(0x12db606138b90ef6), +W64LIT(0xa994b3d769ef679d), +W64LIT(0x211097b07cc91fb8), +W64LIT(0x30fa69ff404a1082), +W64LIT(0x3c3e0e4750a21458), +W64LIT(0x7504a22c1f4f802e), +W64LIT(0x844043df05ce7cff), +W64LIT(0xf0f838e9b5975095), +W64LIT(0x7e1ed5d2a8c52add), +W64LIT(0x90f9eae235037064), +W64LIT(0x0662c95c0874026d), +W64LIT(0x9416648a965bdf81), +W64LIT(0xf69af1b5bde352f8), +W64LIT(0x0d78bea2bffea89e), +W64LIT(0x293b7e60cf79b487), +W64LIT(0xd9c346897aeee412), +W64LIT(0xfbe24f17021dfa66), +W64LIT(0x1367b97b97afa2b2), +W64LIT(0xab19f4e3c2c3ca15), +W64LIT(0x48867571e0fb3832), +W64LIT(0x93c874cc313971a8), +W64LIT(0x79c0c5940fa784f4), +W64LIT(0xcd7aefb44a23e889), +W64LIT(0x439c028f577192c1), +W64LIT(0x5be1cc0a77549a80), +/* box 6 */ +W64LIT(0x714d28d778656928), +W64LIT(0xc88a7c6b84f64f7c), +W64LIT(0xec43cac5ab89aaca), +W64LIT(0x777fa38110dc16a3), +W64LIT(0x0f7d5c87e4213b5c), +W64LIT(0x73f051e5f3a1ef51), +W64LIT(0xea714193c330d541), +W64LIT(0x95e5f3dae016c4f3), +W64LIT(0x63d3738095a0e173), +W64LIT(0x9825d66f8ff379d6), +W64LIT(0xe8cc38a148f45338), +W64LIT(0xa840b0c025f06bb0), +W64LIT(0x944135c35f748735), +W64LIT(0x74661caa247ad31c), +W64LIT(0xe7b16426acd56864), +W64LIT(0xd1e689df6e6f0589), +W64LIT(0xa73dec47c1d150ec), +W64LIT(0x64453ecf427bdd3e), +W64LIT(0x0ed99a9e5b43789a), +W64LIT(0x7b1b402dc05be840), +W64LIT(0x0dc025b56fe5bd25), +W64LIT(0x3f183a284e22293a), +W64LIT(0xa0aba108160a6ca1), +W64LIT(0x46be033705bd4703), +W64LIT(0x86df6e94b2b10f6e), +W64LIT(0xa216d83a9dceead8), +W64LIT(0x129e5b57edc5885b), +W64LIT(0x7e3074509c445274), +W64LIT(0x7d29cb7ba8e297cb), +W64LIT(0x1611a9330eb871a9), +W64LIT(0x486799a95efe3f99), +W64LIT(0x9fb39b205828459b), +W64LIT(0xd0424fc6d10d464f), +W64LIT(0xe968feb8f79610fe), +W64LIT(0x5d6f8fb164e08b8f), +W64LIT(0xaafdc9f2ae34edc9), +W64LIT(0x02bd79328bc48679), +W64LIT(0x9b3c6944bb55bc69), +W64LIT(0x6277b5992ac2a2b5), +W64LIT(0x877ba88d0dd34ca8), +W64LIT(0xfa5263f6a531db63), +W64LIT(0x2e9fde54974164de), +W64LIT(0xcda14816d8e9f548), +W64LIT(0x675c81e476dd1881), +W64LIT(0x2a102c30743c9d2c), +W64LIT(0x37f32be07dd82e2b), +W64LIT(0x256d70b7901da670), +W64LIT(0x4ce86bcdbd83c66b), +W64LIT(0x50afaa040b0536aa), +W64LIT(0xef5a75ee9f2f6f75), +W64LIT(0xb3913c4644ada73c), +W64LIT(0x1187e47cd9634de4), +W64LIT(0xc54a59deeb13f259), +W64LIT(0x0000000000000000), +W64LIT(0x01a4c619bf6243c6), +W64LIT(0x90cec7a7bc097ec7), +W64LIT(0xf94bdcdd91971edc), +W64LIT(0x8e347f5c814b087f), +W64LIT(0xc7f720ec60d77420), +W64LIT(0x354e52d2f61ca852), +W64LIT(0x34ea94cb497eeb94), +W64LIT(0xae723b964d49143b), +W64LIT(0xf48bf968fe72a3f9), +W64LIT(0xfc60e8a0cd88a4e8), +W64LIT(0x2909931b409a5893), +W64LIT(0xbd48a6d81feedfa6), +W64LIT(0x6cae2f077181da2f), +W64LIT(0xad6b84bd79efd184), +W64LIT(0x18c833ad55fb0933), +W64LIT(0x204644cacc021c44), +W64LIT(0x392ab17e269b56b1), +W64LIT(0x14acd001857cf7d0), +W64LIT(0x8abb8d386236f18d), +W64LIT(0xeefeb3f7204d2cb3), +W64LIT(0xf636805a75b62580), +W64LIT(0x2bb4ea29cb5edeea), +W64LIT(0xc653e6f5dfb537e6), +W64LIT(0x8d2dc077b5edcdc0), +W64LIT(0x31c1a0b6156151a0), +W64LIT(0xf8ef1ac42ef55d1a), +W64LIT(0xdbb0e125d65184e1), +W64LIT(0x82509cf051ccf69c), +W64LIT(0xe33e96424fa89196), +W64LIT(0xdf3f1341352c7d13), +W64LIT(0x8f90b9453e294bb9), +W64LIT(0x1023226566010e22), +W64LIT(0xa58095754a15d695), +W64LIT(0x2c22a7661c85e2a7), +W64LIT(0xe183ef70c46c17ef), +W64LIT(0xafd6fd8ff22b57fd), +W64LIT(0x471ac52ebadf04c5), +W64LIT(0x4d4cadd402e185ad), +W64LIT(0x916a01be036b3d01), +W64LIT(0x28ad5502fff81b55), +W64LIT(0x3657edf9c2ba6ded), +W64LIT(0xd2ff36f45ac9c036), +W64LIT(0xf1a0cd15a26d19cd), +W64LIT(0xd90d98175d950298), +W64LIT(0xf7924643cad46646), +W64LIT(0xdd826a73bee8fb6a), +W64LIT(0x9d0ee212d3ecc3e2), +W64LIT(0xb6ba083b18b21d08), +W64LIT(0x3da5431ac5e6af43), +W64LIT(0x08eb11c833fa0711), +W64LIT(0x052b347d5c1fba34), +W64LIT(0x6fb7902c45271f90), +W64LIT(0x133a9d4e52a7cb9d), +W64LIT(0x6e135635fa455c56), +W64LIT(0x725497fc4cc3ac97), +W64LIT(0xf31db42729a99fb4), +W64LIT(0x846217a639758917), +W64LIT(0x4b7e26826a58fa26), +W64LIT(0x235ffbe1f8a4d9fb), +W64LIT(0xff79578bf92e6157), +W64LIT(0xda14273c6933c727), +W64LIT(0x8b1f4b21dd54b24b), +W64LIT(0x9caa240b6c8e8024), +W64LIT(0xc1c5abba086e0bab), +W64LIT(0xde9bd5588a4e3ed5), +W64LIT(0x2d86617fa3e7a161), +W64LIT(0xbff5dfea942a59df), +W64LIT(0x66f847fdc9bf5b47), +W64LIT(0x3b97c84cad5fd0c8), +W64LIT(0x3ebcfc31f1406afc), +W64LIT(0xca3705590f32c905), +W64LIT(0x24c9b6ae2f7fe5b6), +W64LIT(0x408c88616d043888), +W64LIT(0x93d7788c88afbb78), +W64LIT(0x196cf5b4ea994af5), +W64LIT(0x9a98af5d0437ffaf), +W64LIT(0x8c89066e0a8f8e06), +W64LIT(0xab590feb1156ae0f), +W64LIT(0xd7d4028906d67a02), +W64LIT(0xe4a8db0d9873addb), +W64LIT(0xc378d28883aa8dd2), +W64LIT(0x4ff1d4e6892503d4), +W64LIT(0xd670c490b9b439c4), +W64LIT(0x65e1f8d6fd199ef8), +W64LIT(0xf2b9723e96cbdc72), +W64LIT(0xb12c4574cf692145), +W64LIT(0x569d215263bc4921), +W64LIT(0x69851b7a2d9e601b), +W64LIT(0x5e76309a50464e30), +W64LIT(0x5fd2f683ef240df6), +W64LIT(0xd8a95e0ee2f7415e), +W64LIT(0xe29a505bf0cad250), +W64LIT(0x96fc4cf1d4b0014c), +W64LIT(0x8806f40ae9f277f4), +W64LIT(0x53b6152f3fa3f315), +W64LIT(0x1c47c1c9b686f0c1), +W64LIT(0x80ede5c2da0870e5), +W64LIT(0xd5697bbb8d12fc7b), +W64LIT(0xfdc42eb972eae72e), +W64LIT(0x0bf2aee3075cc2ae), +W64LIT(0x22fb3df847c69a3d), +W64LIT(0xbadeeb97c835e3eb), +W64LIT(0xdc26ac6a018ab8ac), +W64LIT(0xbcec60c1a08c9c60), +W64LIT(0x4231f153e6c0bef1), +W64LIT(0x337cd9849ea5d7d9), +W64LIT(0x5b5d04e70c59f404), +W64LIT(0x79a6391f4b9f6e39), +W64LIT(0x5212d33680c1b0d3), +W64LIT(0xb5a3b7102c14d8b7), +W64LIT(0x7f94b249232611b2), +W64LIT(0x17b56f2ab1da326f), +W64LIT(0x59e07dd5879d727d), +W64LIT(0xebd5878a7c529687), +W64LIT(0xbb7a2d8e7757a02d), +W64LIT(0x0319bf2b34a6c5bf), +W64LIT(0x5ccb49a8db82c849), +W64LIT(0x1de307d009e4b307), +W64LIT(0x49c35fb0e19c7c5f), +W64LIT(0x55849e79571a8c9e), +W64LIT(0x7abf86347f39ab86), +W64LIT(0x9273be9537cdf8be), +W64LIT(0xe615a23f13b72ba2), +W64LIT(0x6821dd6392fc23dd), +W64LIT(0x5af9c2feb33bb7c2), +W64LIT(0x06328b5668b97f8b), +W64LIT(0x44037a058e79c17a), +W64LIT(0x83f45ae9eeaeb55a), +W64LIT(0x5739e74bdcde0ae7), +W64LIT(0xfbf6a5ef1a5398a5), +W64LIT(0xe50c1d142711ee1d), +W64LIT(0x1a754a9fde3f8f4a), +W64LIT(0x7802ff06f4fd2dff), +W64LIT(0xf52f3f714110e03f), +W64LIT(0x2674cf9ca4bb63cf), +W64LIT(0x60caccaba10624cc), +W64LIT(0xb088836d700b6283), +W64LIT(0xa6992a5e7eb3132a), +W64LIT(0xa9e476d99a922876), +W64LIT(0x6b386248a65ae662), +W64LIT(0xc2dc14913cc8ce14), +W64LIT(0x76db6598afbe5565), +W64LIT(0x32d81f9d21c7941f), +W64LIT(0x21e282d373605f82), +W64LIT(0xc0616da3b70c486d), +W64LIT(0x616e0ab21e64670a), +W64LIT(0x6d0ae91ecee399e9), +W64LIT(0x27d009851bd92009), +W64LIT(0xfedd9192464c2291), +W64LIT(0x45a7bc1c311b82bc), +W64LIT(0x54205860e878cf58), +W64LIT(0xa10f6711a9682f67), +W64LIT(0x9981107630913a10), +W64LIT(0xede70cdc14ebe90c), +W64LIT(0x70e9eecec7072aee), +W64LIT(0x1f5e7ee28220357e), +W64LIT(0x2f3b184d28232718), +W64LIT(0x41284e78d2667b4e), +W64LIT(0xa424536cf5779553), +W64LIT(0xa3b21e2322aca91e), +W64LIT(0x4e5512ff36474012), +W64LIT(0x1efab8fb3d4276b8), +W64LIT(0x89a2321356903432), +W64LIT(0xcb93c340b0508ac3), +W64LIT(0x306566afaa031266), +W64LIT(0x4adae09bd53ab9e0), +W64LIT(0xc92eba723b940cba), +W64LIT(0x094fd7d18c9844d7), +W64LIT(0xcc058e0f678bb68e), +W64LIT(0xd4cdbda23270bfbd), +W64LIT(0x0a5668fab83e8168), +W64LIT(0x510b6c1db467756c), +W64LIT(0xb86392a543f16592), +W64LIT(0x048ff264e37df9f2), +W64LIT(0x3a330e55123d930e), +W64LIT(0xb235fa5ffbcfe4fa), +W64LIT(0xb9c754bcfc932654), +W64LIT(0x3c0185037a84ec85), +W64LIT(0x0c64e3acd087fee3), +W64LIT(0xe02729697b0e5429), +W64LIT(0x07964d4fd7db3c4d), +W64LIT(0x814923db656a3323), +W64LIT(0x388e776799f91577), +W64LIT(0x6a9ca4511938a5a4), +W64LIT(0x1bd18c86615dcc8c), +W64LIT(0xb407710993769b71), +W64LIT(0x150816183a1eb416), +W64LIT(0x4395374a59a2fd37), +W64LIT(0xc4ee9fc75471b19f), +W64LIT(0x5844bbcc38ff31bb), +W64LIT(0xcf1c3124532d7331), +W64LIT(0xb71ece22a7d05ece), +W64LIT(0xaccf42a4c68d9242), +W64LIT(0x97588ae86bd2428a), +W64LIT(0x75c2dab39b1890da), +W64LIT(0x9e175d39e74a065d), +W64LIT(0xf0040b0c1d0f5a0b), +W64LIT(0xceb8f73dec4f30f7), +W64LIT(0xbe5119f32b481a19), +W64LIT(0xd35bf0ede5ab83f0), +W64LIT(0x7c8d0d621780d40d), +W64LIT(0x85c6d1bf8617cad1), +/* box 7 */ +W64LIT(0xb1c742127b66f2a4), +W64LIT(0xce916098d7a59fc1), +W64LIT(0xc312ef8e2406fa70), +W64LIT(0x956c7dced81403d5), +W64LIT(0x5a0c9b2318dd9520), +W64LIT(0xad0d57f51a480e8b), +W64LIT(0xe7b9d05287740b01), +W64LIT(0x0217f9ea2ed81268), +W64LIT(0x4d7cff19f8cd3a06), +W64LIT(0x44d1772e572b7b67), +W64LIT(0xfb73c5b5e65af72e), +W64LIT(0x91427aef84512705), +W64LIT(0x0c720963e4cf6c85), +W64LIT(0x87c398a0732d8117), +W64LIT(0xa17f5e96fe87620e), +W64LIT(0x50476c8b8e8fcf1d), +W64LIT(0xcb4ee1cc9c8cb225), +W64LIT(0x67b2304c91a8b59a), +W64LIT(0x54696baad2caebcd), +W64LIT(0xddcf03836bf01437), +W64LIT(0x46c68ec479f3690f), +W64LIT(0x8f9f96e2cba7c942), +W64LIT(0xe1802e99f5e93db9), +W64LIT(0x4e9a8086c179215a), +W64LIT(0xf0c9b4686764a427), +W64LIT(0xfd4a3b7e94c7c196), +W64LIT(0xfcbbbd0b83abc8a2), +W64LIT(0xebcbd93163bb6784), +W64LIT(0xf9643c5fc882e546), +W64LIT(0xc4da973041f7c5fc), +W64LIT(0x1af3eb2c13b3ca97), +W64LIT(0x6e1fb87b3e4ef4fb), +W64LIT(0x5e229c024498b1f0), +W64LIT(0xf516353c2c4d89c3), +W64LIT(0xcc869972f97d8da9), +W64LIT(0x8d886f08e57fdb2a), +W64LIT(0x1cca15e7612efc2f), +W64LIT(0x567e9240fc12f9a5), +W64LIT(0x43190f9032da44eb), +W64LIT(0xfeac44e1ad73daca), +W64LIT(0x07c878be65f13f8c), +W64LIT(0x618bce87e3358322), +W64LIT(0xf895ba2adfeeec72), +W64LIT(0x751dd5223a913758), +W64LIT(0x59eae4bc21698e7c), +W64LIT(0xff5dc294ba1fd3fe), +W64LIT(0x03e67f9f39b41b5c), +W64LIT(0x2292c117d1efc7c9), +W64LIT(0x8a4017b6808ee4a6), +W64LIT(0xd1bd0ae08f3f78b2), +W64LIT(0x135e631bbc558bf6), +W64LIT(0xee14586528924a60), +W64LIT(0x8857ee5cae56f6ce), +W64LIT(0x0000000000000000), +W64LIT(0x0e65f089ca177eed), +W64LIT(0x34132358269361db), +W64LIT(0x15679dd0cec8bd4e), +W64LIT(0x800be01e16dcbe9b), +W64LIT(0x949dfbbbcf780ae1), +W64LIT(0xe397d773db312fd1), +W64LIT(0xedf227fa1126513c), +W64LIT(0xb5e945332723d674), +W64LIT(0x53a11314b73bd441), +W64LIT(0x23634762c683cefd), +W64LIT(0x4b4501d28a500cbe), +W64LIT(0x473708b16e9f603b), +W64LIT(0x1770643ae010af26), +W64LIT(0xa746a05d8c1a54b6), +W64LIT(0x90b3fc9a933d2e31), +W64LIT(0x35e2a52d31ff68ef), +W64LIT(0xab34a93e68d53833), +W64LIT(0xd81082d720d939d3), +W64LIT(0xb86aca25d480b3c5), +W64LIT(0xdfd8fa694528065f), +W64LIT(0x4f6b06f3d615286e), +W64LIT(0x578f1435eb7ef091), +W64LIT(0x9af80b32056f740c), +W64LIT(0x92a40570bde53c59), +W64LIT(0xdbf6fd48196d228f), +W64LIT(0x1b026d5904dfc3a3), +W64LIT(0x3c4f2d1a9e19298e), +W64LIT(0xc8a89e53a538a979), +W64LIT(0x991e74ad3cdb6f50), +W64LIT(0x042e07215c4524d0), +W64LIT(0x8e6e1097dccbc076), +W64LIT(0xe071a8ece285348d), +W64LIT(0xd784f42bfda24e0a), +W64LIT(0x7d41db60821b7f0d), +W64LIT(0x85d4614a5df5937f), +W64LIT(0xbb8cb5baed34a899), +W64LIT(0x40ff700f0b6e5fb7), +W64LIT(0x2cf7319e1bf8b924), +W64LIT(0x3a76d3d1ec841f36), +W64LIT(0x4520f15b40477253), +W64LIT(0xf138321d7008ad13), +W64LIT(0x42e889e525b64ddf), +W64LIT(0x65a5c9a6bf70a7f2), +W64LIT(0x208538fdff37d5a1), +W64LIT(0x410ef67a1c025683), +W64LIT(0x18e412c63d6bd8ff), +W64LIT(0x72d5ad9c5f6008d4), +W64LIT(0x255ab9a9b41ef845), +W64LIT(0x93558305aa89356d), +W64LIT(0x70c2547671b81abc), +W64LIT(0x3604dab2084b73b3), +W64LIT(0x05df81544b292de4), +W64LIT(0xf2de4d8249bcb64f), +W64LIT(0x0bba71dd813e5309), +W64LIT(0xa368a77cd05f7066), +W64LIT(0x796fdc41de5e5bdd), +W64LIT(0xec03a18f064a5808), +W64LIT(0x085c0e42b88a4855), +W64LIT(0x274d40439ac6ea2d), +W64LIT(0x31cca20c6dba4c3f), +W64LIT(0x322add93540e5763), +W64LIT(0xb60f3aac1e97cd28), +W64LIT(0x7cb05d1595777639), +W64LIT(0xb036c4676c0afb90), +W64LIT(0x0a4bf7a896525a3d), +W64LIT(0x73242be9480c01e0), +W64LIT(0x5bfd1d560fb19c14), +W64LIT(0x7b7825abf08649b5), +W64LIT(0xb7febcd909fbc41c), +W64LIT(0x81fa666b01b0b7af), +W64LIT(0xd25b757fb68b63ee), +W64LIT(0x0d838f16f3a365b1), +W64LIT(0x6a31bf5a620bd02b), +W64LIT(0x26bcc6368daae319), +W64LIT(0x9ed60c13592a50dc), +W64LIT(0x581b62c936058748), +W64LIT(0x9cc1f5f977f242b4), +W64LIT(0x83ed9f812f68a5c7), +W64LIT(0x74ec53572dfd3e6c), +W64LIT(0xb3d0bbf855bee0cc), +W64LIT(0xacfcd1800d2407bf), +W64LIT(0x303d24797ad6450b), +W64LIT(0x7a89a3dee7ea4081), +W64LIT(0x69d7c0c55bbfcb77), +W64LIT(0x770a2cc814492530), +W64LIT(0x0f9476fcdd7b77d9), +W64LIT(0xaeeb286a23fc15d7), +W64LIT(0x2174be88e85bdc95), +W64LIT(0xde297c1c52440f6b), +W64LIT(0xd04c8c9598537186), +W64LIT(0x2ee0c8743520ab4c), +W64LIT(0x977b8424f6cc11bd), +W64LIT(0x10b81c8485e190aa), +W64LIT(0xa4a0dfc2b5ae4fea), +W64LIT(0x98eff2d82bb76664), +W64LIT(0xa8d2d6a15161236f), +W64LIT(0xd4628bb4c4165556), +W64LIT(0x682646b04cd3c243), +W64LIT(0x2d06b7eb0c94b010), +W64LIT(0x626db118da81987e), +W64LIT(0x2928b0ca50d194c0), +W64LIT(0x6df9c7e407faefa7), +W64LIT(0x1681e24ff77ca612), +W64LIT(0x4952f838a4881ed6), +W64LIT(0x76fbaabd03252c04), +W64LIT(0xc73ce8af7843dea0), +W64LIT(0xe82da6ae5a0f7cd8), +W64LIT(0xc10516640adee818), +W64LIT(0x968a0251e1a01889), +W64LIT(0x37f55cc71f277a87), +W64LIT(0xe5ae29b8a9ac1969), +W64LIT(0xcabf67b98be0bb11), +W64LIT(0xf4e7b3493b2180f7), +W64LIT(0xe9dc20db4d6375ec), +W64LIT(0x639c376dcded914a), +W64LIT(0x12afe56eab3982c2), +W64LIT(0xc2e369fb336af344), +W64LIT(0xa6b726289b765d82), +W64LIT(0x14961ba5d9a4b47a), +W64LIT(0xbc44cd0488c59715), +W64LIT(0xd3aaf30aa1e76ada), +W64LIT(0x28d936bf47bd9df4), +W64LIT(0xaf1aae1f34901ce3), +W64LIT(0x2f114e01224ca278), +W64LIT(0xe648562790180235), +W64LIT(0x24ab3fdca372f171), +W64LIT(0x52509561a057dd75), +W64LIT(0xc6cd6eda6f2fd794), +W64LIT(0xa08ed8e3e9eb6b3a), +W64LIT(0x09ad8837afe64161), +W64LIT(0xbdb54b719fa99e21), +W64LIT(0x8c79e97df213d21e), +W64LIT(0xcf60e6edc0c996f5), +W64LIT(0x5dc4e39d7d2caaac), +W64LIT(0x11499af1928d999e), +W64LIT(0x5fd31a7753f4b8c4), +W64LIT(0x01f18675176c0934), +W64LIT(0xc52b1145569bccc8), +W64LIT(0x9f278a664e4659e8), +W64LIT(0x3dbeab6f897520ba), +W64LIT(0xa2992109c7337952), +W64LIT(0x9b098d4712037d38), +W64LIT(0xc9591826b254a04d), +W64LIT(0x3b8755a4fbe81602), +W64LIT(0xbe5334eea61d857d), +W64LIT(0x51b6eafe99e3c629), +W64LIT(0x191594b32a07d1cb), +W64LIT(0x1f2c6a78589ae773), +W64LIT(0x3fa95285a7ad32d2), +W64LIT(0x5c3565e86a40a398), +W64LIT(0xb2213d8d42d2e9f8), +W64LIT(0xefe5de103ffe4354), +W64LIT(0x4ab487a79d3c058a), +W64LIT(0xcd771f07ee11849d), +W64LIT(0xbfa2b29bb1718c49), +W64LIT(0xba7d33cffa58a1ad), +W64LIT(0x6fee3e0e2922fdcf), +W64LIT(0x64544fd3a81caec6), +W64LIT(0xd9e104a237b530e7), +W64LIT(0xf32fcbf75ed0bf7b), +W64LIT(0x3e58d4f0b0c13be6), +W64LIT(0xb418c346304fdf40), +W64LIT(0xaac52f4b7fb93107), +W64LIT(0xdc3e85f67c9c1d03), +W64LIT(0xd5930dc1d37a5c62), +W64LIT(0x0639fecb729d36b8), +W64LIT(0xc0f490111db2e12c), +W64LIT(0x7ea7a4ffbbaf6451), +W64LIT(0xf6f04aa315f9929f), +W64LIT(0x6643b63986c4bcae), +W64LIT(0x6c0841911096e693), +W64LIT(0x8425e73f4a999a4b), +W64LIT(0x7133d20366d41388), +W64LIT(0x38612a3bc25c0d5e), +W64LIT(0xb99b4c50c3ecbaf1), +W64LIT(0x1d3b93927642f51b), +W64LIT(0x7f56228aacc36d65), +W64LIT(0x9d30738c609e4b80), +W64LIT(0x48a37e4db3e417e2), +W64LIT(0x8bb191c397e2ed92), +W64LIT(0x2acecf5569658f9c), +W64LIT(0xda077b3d0e012bbb), +W64LIT(0xa55159b7a2c246de), +W64LIT(0x33db5be643625e57), +W64LIT(0x821c19f43804acf3), +W64LIT(0x3990ac4ed530046a), +W64LIT(0xd675725eeace473e), +W64LIT(0x789e5a34c93252e9), +W64LIT(0x86321ed564418823), +W64LIT(0xfa8243c0f136fe1a), +W64LIT(0xe45fafcdbec0105d), +W64LIT(0x2b3f49207e0986a8), +W64LIT(0xa92350d4460d2a5b), +W64LIT(0x1eddec0d4ff6ee47), +W64LIT(0x89a66829b93afffa), +W64LIT(0x607a48f2f4598a16), +W64LIT(0x6bc0392f7567d91f), +W64LIT(0xea3a5f4474d76eb0), +W64LIT(0x5598eddfc5a6e2f9), +W64LIT(0x4c8d796cefa13332), +W64LIT(0xf701ccd602959bab), +W64LIT(0xe2665106cc5d26e5), +}; + +const word64 SHARK::Dec::cbox[8][256] = { +/* box 0 */ +W64LIT(0xe6126af05e55aff3), +W64LIT(0x4b6c893f310b0835), +W64LIT(0xaa4c0e84ebfc8d57), +W64LIT(0xfb9b5c7bf3b3090d), +W64LIT(0x4508a6a9ccba5ce2), +W64LIT(0xe5d1d2064dc6bde9), +W64LIT(0x348343755288edde), +W64LIT(0xb684505de46b250c), +W64LIT(0xa8cede205a1e91e8), +W64LIT(0x40b89b46f9fa6acc), +W64LIT(0x8ee1ec1afab080ba), +W64LIT(0xde77d6b7408e0a45), +W64LIT(0x9a3e184c2e455802), +W64LIT(0xbe93fad23f0955ef), +W64LIT(0x3ae76ce3af39b909), +W64LIT(0xad7ee3cf6f5ea7c6), +W64LIT(0x8b51d1f5cff0b694), +W64LIT(0x70ca8d8e3c43bf99), +W64LIT(0xccdba7f8b2a8f6c9), +W64LIT(0x4c5e6474b5a922a4), +W64LIT(0x5d31adcd541ccc32), +W64LIT(0x9b7f701e8c3456a7), +W64LIT(0x2ac9cd08ecfd593a), +W64LIT(0x8fa0844858c18e1f), +W64LIT(0x32f0c66c745bc9ea), +W64LIT(0xc58d6525cbbb888f), +W64LIT(0x8c633cbe4b529c05), +W64LIT(0xf2cd9ea68aa0774b), +W64LIT(0x2cba4811ca2e7d0e), +W64LIT(0xe2e33f4dc9649778), +W64LIT(0xf4be1bbfac73537f), +W64LIT(0x22de6787379f29d9), +W64LIT(0x0956c2dd79137e46), +W64LIT(0xe061efe978868bc7), +W64LIT(0x1cc85ed90f97a85b), +W64LIT(0x31337e9a67c8dbf0), +W64LIT(0x360193d1e36af161), +W64LIT(0x7fefca4a6383e5eb), +W64LIT(0x8535fe633241e243), +W64LIT(0xc3fee03ced68acbb), +W64LIT(0x81c4abdea570dac8), +W64LIT(0x67d6c12efb25753b), +W64LIT(0xa4282112164dd980), +W64LIT(0xcf181f0ea13be4d3), +W64LIT(0xa98fb672f86f9f4d), +W64LIT(0x5c70c59ff66dc297), +W64LIT(0xb0f7d544c2b80138), +W64LIT(0x0da79760ee2246cd), +W64LIT(0x3740fb83411bffc4), +W64LIT(0x24ade29e114c0ded), +W64LIT(0xf858e48de0201b17), +W64LIT(0x0e642f96fdb154d7), +W64LIT(0xddb46e41531d185f), +W64LIT(0x25ec8accb33d0348), +W64LIT(0x0282d0a4b1e21cbf), +W64LIT(0x1bfab3928b3582ca), +W64LIT(0xaffc336bdebcbb79), +W64LIT(0x35c22b27f0f9e37b), +W64LIT(0x03c3b8f61393121a), +W64LIT(0xb8e07fcb19da71db), +W64LIT(0x99fda0ba3dd64a18), +W64LIT(0xce59775c034aea76), +W64LIT(0x49ee599b80e9148a), +W64LIT(0xfe2b6194c6f33f23), +W64LIT(0x4edcb4d0044b3e1b), +W64LIT(0xd5a3c4ce887f68bc), +W64LIT(0xdf36bee5e2ff04e0), +W64LIT(0x171c4ca0c766caa2), +W64LIT(0x0bd41279c8f162f9), +W64LIT(0xe490ba54efb7b34c), +W64LIT(0x5b4228d472cfe806), +W64LIT(0x5355825ba9ad98e5), +W64LIT(0x9f8e25a31b056e2c), +W64LIT(0xcd9acfaa10d9f86c), +W64LIT(0x88926903dc63a48e), +W64LIT(0xb40680f9558939b3), +W64LIT(0x239f0fd595ee277c), +W64LIT(0xec8710db34d5c3af), +W64LIT(0x87b72ec783a3fefc), +W64LIT(0x632794936c144db0), +W64LIT(0x46cb1e5fdf294ef8), +W64LIT(0x83467b7a1492c677), +W64LIT(0x9c4d9d5508967c36), +W64LIT(0xd6607c389bec7aa6), +W64LIT(0x165d24f26517c407), +W64LIT(0xc4cc0d7769ca862a), +W64LIT(0xcbe94ab3360adc58), +W64LIT(0x847496319030ece6), +W64LIT(0x7a5ff7a556c3d3c5), +W64LIT(0xc03d58cafefbbea1), +W64LIT(0x76b908971a909bad), +W64LIT(0x2f79f0e7d9bd6f14), +W64LIT(0x197863363ad79e75), +W64LIT(0xda86830ad7bf32ce), +W64LIT(0x5a034086d0bee6a3), +W64LIT(0x97998f2cc0671ecf), +W64LIT(0x552607428f7ebcd1), +W64LIT(0x51d752ff184f845a), +W64LIT(0xbb23c73d0a4963c1), +W64LIT(0x2b88a55a4e8c579f), +W64LIT(0xd80453ae665d2e71), +W64LIT(0xee05c07f8537df10), +W64LIT(0x423a4be248187673), +W64LIT(0xcaa822e1947bd2fd), +W64LIT(0x1abbdbc029448c6f), +W64LIT(0x96d8e77e6216106a), +W64LIT(0x6266fcc1ce654315), +W64LIT(0x89d301517e12aa2b), +W64LIT(0x730935782fd0ad83), +W64LIT(0x8085c38c0701d46d), +W64LIT(0x6b303e1cb7763d53), +W64LIT(0x3f57510c9a798f27), +W64LIT(0x4449cefb6ecb5247), +W64LIT(0x48af31c922981a2f), +W64LIT(0x98bcc8e89fa744bd), +W64LIT(0x69b2eeb8069421ec), +W64LIT(0xebb5fd90b077e93e), +W64LIT(0x6a71564e150733f6), +W64LIT(0x116fc9b9e1b5ee96), +W64LIT(0x4a2de16d937a0690), +W64LIT(0xb9a11799bbab7f7e), +W64LIT(0x9368da9157562644), +W64LIT(0x718be5dc9e32b13c), +W64LIT(0xc82af2452599ce42), +W64LIT(0xb547e8abf7f83716), +W64LIT(0x33b1ae3ed62ac74f), +W64LIT(0x799c4f534550c1df), +W64LIT(0x3e16395e38088182), +W64LIT(0x7c2c72bc7010f7f1), +W64LIT(0xf38cf6f428d179ee), +W64LIT(0xd29129850cdd422d), +W64LIT(0x41f9f3145b8b6469), +W64LIT(0x945a37dad3f40cd5), +W64LIT(0x757ab061090389b7), +W64LIT(0x6554118a4ac76984), +W64LIT(0x7d6d1aeed261f954), +W64LIT(0x01416852a2710ea5), +W64LIT(0xb27505e0735a1d87), +W64LIT(0x77f860c5b8e19508), +W64LIT(0x78dd2701e721cf7a), +W64LIT(0xe12087bbdaf78562), +W64LIT(0x86f6469521d2f059), +W64LIT(0xef44a82d2746d1b5), +W64LIT(0xbc112a768eeb4950), +W64LIT(0xc2bf886e4f19a21e), +W64LIT(0x307216c8c5b9d555), +W64LIT(0xc96b9a1787e8c0e7), +W64LIT(0xa31acc5992eff311), +W64LIT(0xa0d974af817ce10b), +W64LIT(0xdcf50613f16c16fa), +W64LIT(0xfca9b1307711239c), +W64LIT(0x57a4d7e63e9ca06e), +W64LIT(0xc64eddd3d8289a95), +W64LIT(0xa25ba40b309efdb4), +W64LIT(0x2e3898b57bcc61b1), +W64LIT(0xf5ff73ed0e025dda), +W64LIT(0xa6aaf1b6a7afc53f), +W64LIT(0xd9453bfcc42c20d4), +W64LIT(0x9d0cf507aae77293), +W64LIT(0x290a75feff6e4b20), +W64LIT(0xa7eb99e405decb9a), +W64LIT(0xa1981cfd230defae), +W64LIT(0x12ac714ff226fc8c), +W64LIT(0x743bd833ab728712), +W64LIT(0x6c02d35733d417c2), +W64LIT(0xe9372d340195f581), +W64LIT(0xf77da349bfe04165), +W64LIT(0x68f386eaa4e52f49), +W64LIT(0x211ddf71240c3bc3), +W64LIT(0x13ed191d5057f229), +W64LIT(0xe8764566a3e4fb24), +W64LIT(0xf9198cdf425115b2), +W64LIT(0xd013f921bd3f5e92), +W64LIT(0x91ea0a35e6b43afb), +W64LIT(0x0732ed4b84a22a91), +W64LIT(0xeaf495c21206e79b), +W64LIT(0x5214ea090bdc9640), +W64LIT(0x0000000000000000), +W64LIT(0xb3346db2d12b1322), +W64LIT(0x0ce6ff324c534868), +W64LIT(0xaebd5b397ccdb5dc), +W64LIT(0x0a957a2b6a806c5c), +W64LIT(0x1f0be62f1c04ba41), +W64LIT(0x14dff456d4f5d8b8), +W64LIT(0x58819022615cfa1c), +W64LIT(0x05b03def3540362e), +W64LIT(0xe3a2571f6b1599dd), +W64LIT(0x9229b2c3f52728e1), +W64LIT(0xba62af6fa8386d64), +W64LIT(0x0673851926d32434), +W64LIT(0x641579d8e8b66721), +W64LIT(0x04f155bd9731388b), +W64LIT(0x9ecf4df1b9746089), +W64LIT(0x205cb723867d3566), +W64LIT(0x102ea1eb43c4e033), +W64LIT(0x3ba604b10d48b7ac), +W64LIT(0x50963aadba3e8aff), +W64LIT(0xac3f8b9dcd2fa963), +W64LIT(0x7b1e9ff7f4b2dd60), +W64LIT(0xf63ccb1b1d914fc0), +W64LIT(0x7eaea218c1f2eb4e), +W64LIT(0x5fb37d69e5fed08d), +W64LIT(0x56e5bfb49cedaecb), +W64LIT(0x2dfb2043685f73ab), +W64LIT(0x61a54437ddf6510f), +W64LIT(0x6fc16ba1204705d8), +W64LIT(0xe75302a2fc24a156), +W64LIT(0x3dd581a82b9b9398), +W64LIT(0xdbc7eb5875ce3c6b), +W64LIT(0x90ab626744c5345e), +W64LIT(0x59c0f870c32df4b9), +W64LIT(0x6697a97c59547b9e), +W64LIT(0xfde8d962d5602d39), +W64LIT(0xd3d041d7aeac4c88), +W64LIT(0x5ef2153b478fde28), +W64LIT(0xd4e2ac9c2a0e6619), +W64LIT(0x1e4a8e7dbe75b4e4), +W64LIT(0x72485d2a8da1a326), +W64LIT(0x437b23b0ea6978d6), +W64LIT(0x159e9c047684d61d), +W64LIT(0x0f2547c45fc05a72), +W64LIT(0xf10e265099336551), +W64LIT(0x3c94e9fa89ea9d3d), +W64LIT(0xbfd292809d785b4a), +W64LIT(0x0817aa8fdb6270e3), +W64LIT(0x60e42c657f875faa), +W64LIT(0x18390b6498a690d0), +W64LIT(0x478a760d7d58405d), +W64LIT(0x284b1dac5d1f4585), +W64LIT(0xb1b6bd1660c90f9d), +W64LIT(0xd15291731f4e5037), +W64LIT(0x4d1f0c2617d82c01), +W64LIT(0xc70fb5817a599430), +W64LIT(0x6d43bb0591a51967), +W64LIT(0x6e8003f382360b7d), +W64LIT(0x1d89368bade6a6fe), +W64LIT(0x4f9ddc82a63a30be), +W64LIT(0xedc6788996a4cd0a), +W64LIT(0xab0d66d6498d83f2), +W64LIT(0x54676f102d0fb274), +W64LIT(0xc17c30985c8ab004), +W64LIT(0x3865bc471edba5b6), +W64LIT(0x3924d415bcaaab13), +W64LIT(0x951b5f8871850270), +W64LIT(0x8a10b9a76d81b831), +W64LIT(0xbd5042242c9a47f5), +W64LIT(0xa5694940b43cd725), +W64LIT(0xff6a09c664823186), +W64LIT(0x8d2254ece92392a0), +W64LIT(0xb7c5380f461a2ba9), +W64LIT(0x82071328b6e3c8d2), +W64LIT(0xd721146a399d7403), +W64LIT(0xfada342951c207a8), +W64LIT(0x262f323aa0ae1152), +W64LIT(0xf04f4e023b426bf4), +W64LIT(0x276e5a6802df1ff7), +/* box 1 */ +W64LIT(0x3b4016dbfd16e203), +W64LIT(0x9a7574c51174530a), +W64LIT(0x90012e69c02ec8d3), +W64LIT(0xf44580e3d780e076), +W64LIT(0xf81dec2b49eca14b), +W64LIT(0x26cae3e8a6e3d7ef), +W64LIT(0x0962419e0c41f6ab), +W64LIT(0x54d1eb4070ebd951), +W64LIT(0x865e884b0188eec8), +W64LIT(0xdf76067ea406fe8a), +W64LIT(0x29849412e594fba0), +W64LIT(0x461569896869c0f2), +W64LIT(0xb5ddd6b3bbd6724e), +W64LIT(0x0c586cc89e6c413d), +W64LIT(0x6b0ad97054d904ea), +W64LIT(0xa135621eec62b109), +W64LIT(0x0eef7e47087ea461), +W64LIT(0xfaaafea4dffe4417), +W64LIT(0xe0ad344e80342331), +W64LIT(0xab4138b23d382ad0), +W64LIT(0x107390468e90fcff), +W64LIT(0xbe0885a2218561b9), +W64LIT(0xdbed22957d22c132), +W64LIT(0x2251c7037fc7e857), +W64LIT(0x33835ef8ba5e9c86), +W64LIT(0xb3f1e0d7f4e0a8aa), +W64LIT(0x3fdb32302432ddbb), +W64LIT(0xa719547aa3546bed), +W64LIT(0xe10c3df3cb3dab1f), +W64LIT(0x17feaf9f8aafae35), +W64LIT(0x9df84b1c154b01c0), +W64LIT(0x8364a51d93a5595e), +W64LIT(0x535cd49974d48b9b), +W64LIT(0x01a109bd4b09882e), +W64LIT(0xc4d0c529b0c51182), +W64LIT(0x2e09abcbe1aba96a), +W64LIT(0x1f3de7bccde7d0b0), +W64LIT(0x9317355b1d35a5a1), +W64LIT(0x6c87e6a950e65620), +W64LIT(0x8910ffb142ffc287), +W64LIT(0x40395fed275f1a16), +W64LIT(0x7b794936da49f815), +W64LIT(0xf269b68798b63a92), +W64LIT(0xfd27c17ddbc116dd), +W64LIT(0x8d8bdb5a9bdbfd3f), +W64LIT(0x1ba6c35714c3ef08), +W64LIT(0x6e30f426c6f4b37c), +W64LIT(0x7fe26ddd036dc7ad), +W64LIT(0x14e8b4ad57b4c347), +W64LIT(0xb985ba7b25ba3373), +W64LIT(0xe9cf75d08c75d59a), +W64LIT(0x626898ee5898f241), +W64LIT(0x5b9f9cba339cf51e), +W64LIT(0xb250e96abfe92084), +W64LIT(0x165fa622c1a6261b), +W64LIT(0xf5e4895e9c896858), +W64LIT(0xb76ac43c2dc49712), +W64LIT(0x02b7128f9612e55c), +W64LIT(0x1d8af5335bf535ec), +W64LIT(0x36b973ae28732b10), +W64LIT(0xa8572380e02347a2), +W64LIT(0xf6f2926c4192052a), +W64LIT(0x8c2ad2e7d0d27511), +W64LIT(0xd32e6ab63a6abfb7), +W64LIT(0xbd1e9e90fc9e0ccb), +W64LIT(0x03161b32dd1b6d72), +W64LIT(0x4dc03a98f23ad305), +W64LIT(0x81d3b79205b7bc02), +W64LIT(0x450372bbb572ad80), +W64LIT(0x2d1fb0f93cb0c418), +W64LIT(0x2a928f20388f96d2), +W64LIT(0x721b08a8d6080ebe), +W64LIT(0x92b63ce6563c2d8f), +W64LIT(0xeb78675f1a6730c6), +W64LIT(0x13658b74538b918d), +W64LIT(0x428e4d62b14dff4a), +W64LIT(0x88b1f60c09f64aa9), +W64LIT(0x75963771d2375c74), +W64LIT(0x7ad8408b9140703b), +W64LIT(0x57c7f072adf0b423), +W64LIT(0xe5971918121994a7), +W64LIT(0x5666f9cfe6f93c0d), +W64LIT(0x8f3cc9d50dc91863), +W64LIT(0x1e9cee0186ee589e), +W64LIT(0x8a06e4839fe4aff5), +W64LIT(0xb824b3c66eb3bb5d), +W64LIT(0xd1997839ac785aeb), +W64LIT(0x6752b5b8cab545d7), +W64LIT(0xb47cdf0ef0dffa60), +W64LIT(0x949a0a82190af76b), +W64LIT(0xc04be1c269e12e3a), +W64LIT(0xfc86c8c090c89ef3), +W64LIT(0xe3bb2f7c5d2f4e43), +W64LIT(0x6aabd0cd1fd08cc4), +W64LIT(0x2147dc31a2dc8525), +W64LIT(0xca3fbb6eb8bbb5e3), +W64LIT(0x48fa17ce60176493), +W64LIT(0x6444ae8a17ae28a5), +W64LIT(0x2b33869d73861efc), +W64LIT(0xd0387184e771d2c5), +W64LIT(0x7cf476efde76aadf), +W64LIT(0x63c9915313917a6f), +W64LIT(0xc929a05c65a0d891), +W64LIT(0xda4c2b28362b491c), +W64LIT(0xfe31da4f06da7baf), +W64LIT(0xc1eae87f22e8a614), +W64LIT(0x5c12a36337a3a7d4), +W64LIT(0x18b0d865c9d8827a), +W64LIT(0xe7200b97840b71fb), +W64LIT(0x4bec0cfcbd0c09e1), +W64LIT(0x0f4e77fa43772c4f), +W64LIT(0x4c613325b9335b2b), +W64LIT(0xf3c8bf3ad3bfb2bc), +W64LIT(0x87ff81f64a8166e6), +W64LIT(0xa38270917a705455), +W64LIT(0x1911d1d882d10a54), +W64LIT(0x44a27b06fe7b25ae), +W64LIT(0x049b24ebd9243fb8), +W64LIT(0xbb32a8f4b3a8d62f), +W64LIT(0x91a027d48b2740fd), +W64LIT(0x3d6c20bfb22038e7), +W64LIT(0xe681022acf02f9d5), +W64LIT(0xf17fadb545ad57e0), +W64LIT(0xcc138d0af78d6f07), +W64LIT(0x495b1e732b1eecbd), +W64LIT(0x38560de9200d8f71), +W64LIT(0xa9f62a3dab2acf8c), +W64LIT(0x47b46034236048dc), +W64LIT(0x8e9dc06846c0904d), +W64LIT(0xaccc076b3907781a), +W64LIT(0x32225745f15714a8), +W64LIT(0xd4a3556f3e55ed7d), +W64LIT(0xd7b54e5de34e800f), +W64LIT(0xddc114f132141bd6), +W64LIT(0x6d26ef141befde0e), +W64LIT(0x85489379dc9383ba), +W64LIT(0x0bd553119a5313f7), +W64LIT(0x786f520407529567), +W64LIT(0xcb9eb2d3f3b23dcd), +W64LIT(0xa223792c3179dc7b), +W64LIT(0x0a745aacd15a9bd9), +W64LIT(0x710d139a0b1363cc), +W64LIT(0x681cc24289c26998), +W64LIT(0x1a07caea5fca6726), +W64LIT(0x82c5aca0d8acd170), +W64LIT(0x25dcf8da7bf8ba9d), +W64LIT(0xc7c6de1b6dde7cf0), +W64LIT(0xc35dfaf0b4fa4348), +W64LIT(0xded70fc3ef0f76a4), +W64LIT(0x504acfaba9cfe6e9), +W64LIT(0xc571cc94fbcc99ac), +W64LIT(0x5ea5b1eca1b14288), +W64LIT(0xae7b15e4af159d46), +W64LIT(0xc888a9e12ea950bf), +W64LIT(0xf7539bd10a9b8d04), +W64LIT(0x962d180d8f181237), +W64LIT(0xe43610a559101c89), +W64LIT(0x772125fe4425b928), +W64LIT(0x84e99ac4979a0b94), +W64LIT(0xc667d7a626d7f4de), +W64LIT(0xefe343b4c3430f7e), +W64LIT(0xd5025cd2755c6553), +W64LIT(0xa6b85dc7e85de3c3), +W64LIT(0xd61447e0a8470821), +W64LIT(0x3e7a3b8d6f3b5595), +W64LIT(0x52fddd243fdd03b5), +W64LIT(0x8072be2f4ebe342c), +W64LIT(0x12c482c9188219a3), +W64LIT(0x9eee502ec8506cb2), +W64LIT(0xad6d0ed6720ef034), +W64LIT(0x59288e35a58e1042), +W64LIT(0xe21a26c11626c66d), +W64LIT(0x247df16730f132b3), +W64LIT(0xf0dea4080ea4dfce), +W64LIT(0x31344c772c4c79da), +W64LIT(0x4f77281764283659), +W64LIT(0x79ce5bb94c5b1d49), +W64LIT(0x0000000000000000), +W64LIT(0x73ba01159d018690), +W64LIT(0x74373ecc993ed45a), +W64LIT(0xbcbf972db79784e5), +W64LIT(0x4ed621aa2f21be77), +W64LIT(0xd95a301aeb30246e), +W64LIT(0x9c5942a15e4289ee), +W64LIT(0x37187a13637aa33e), +W64LIT(0x276bea55edea5fc1), +W64LIT(0x1c2bfc8e10fcbdc2), +W64LIT(0xed54513b5551ea22), +W64LIT(0x20e6d58ce9d50d0b), +W64LIT(0x3ae11f66b61f6a2d), +W64LIT(0x66f3bc0581bccdf9), +W64LIT(0x2cbeb94477b94c36), +W64LIT(0x99636ff7cc6f3e78), +W64LIT(0x953b033f52037f45), +W64LIT(0xb0e7fbe529fbc5d8), +W64LIT(0x60df8a61ce8a171d), +W64LIT(0x6f91fd9b8dfd3b52), +W64LIT(0xaae0310f7631a2fe), +W64LIT(0xbfa98c1f6a8ce997), +W64LIT(0x8ba7ed3ed4ed27db), +W64LIT(0x98c2664a8766b656), +W64LIT(0x062c36644f36dae4), +W64LIT(0x5570e2fd3be2517f), +W64LIT(0xead96ee2516eb8e8), +W64LIT(0x419856506c569238), +W64LIT(0x23f0cebe34ce6079), +W64LIT(0x309545ca6745f1f4), +W64LIT(0x5a3e950778957d30), +W64LIT(0x617e83dc85839f33), +W64LIT(0xfb0bf71994f7cc39), +W64LIT(0x3ccd2902f929b0c9), +W64LIT(0x70ac1a27401aebe2), +W64LIT(0xcea49f85619f8a5b), +W64LIT(0x39f704546b04075f), +W64LIT(0x0df96575d565c913), +W64LIT(0x08c3482347487e85), +W64LIT(0xd28f630b71633799), +W64LIT(0xecf558861e58620c), +W64LIT(0xc2fcf34dfff3cb66), +W64LIT(0x978c11b0c4119a19), +W64LIT(0x69bdcbffc2cbe1b6), +W64LIT(0xba93a149f8a15e01), +W64LIT(0x51ebc616e2c66ec7), +W64LIT(0x078d3fd9043f52ca), +W64LIT(0x58898788ee87986c), +W64LIT(0x4a4d0541f60581cf), +W64LIT(0xe86e7c6dc77c5db4), +W64LIT(0xee424a09884a8750), +W64LIT(0xcdb284b7bc84e729), +W64LIT(0x65e5a7375ca7a08b), +W64LIT(0x2fa8a276aaa22144), +W64LIT(0xa0946ba3a76b3927), +W64LIT(0xa5ae46f535468eb1), +W64LIT(0x35af689cf5684662), +W64LIT(0x28259dafae9d738e), +W64LIT(0xcf0596382a960275), +W64LIT(0xb6cbcd8166cd1f3c), +W64LIT(0x7e43646048644f83), +W64LIT(0x9bd47d785a7ddb24), +W64LIT(0x432f44dffa447764), +W64LIT(0x9f4f59938359e49c), +W64LIT(0x7d557f52957f22f1), +W64LIT(0x76802c430f2c3106), +W64LIT(0xdc601d4c791d93f8), +W64LIT(0x053a2d56922db796), +W64LIT(0x11d299fbc59974d1), +W64LIT(0xf9bce59602e52965), +W64LIT(0xd8fb39a7a039ac40), +W64LIT(0x340e6121be61ce4c), +W64LIT(0x5f04b851eab8caa6), +W64LIT(0x5db3aade7caa2ffa), +W64LIT(0x1549bd101cbd4b69), +W64LIT(0xff90d3f24dd3f381), +W64LIT(0xafda1c59e41c1568), +W64LIT(0xb146f25862f24df6), +W64LIT(0xa40f4f487e4f069f), +/* box 2 */ +W64LIT(0xa1a35cebf8f0f94c), +W64LIT(0x2c203d650f3f095d), +W64LIT(0x1a2bdaee4084a2a7), +W64LIT(0xd32404574d7bcc68), +W64LIT(0xf785bea594a9adc4), +W64LIT(0xf2eb54456206949c), +W64LIT(0x3f5e334d0475ced1), +W64LIT(0x5994299b835d1f60), +W64LIT(0x785b7989ac204794), +W64LIT(0x025da6a2cf461a41), +W64LIT(0xdf1f3a71f01a901b), +W64LIT(0x27284f018bb77637), +W64LIT(0xe1955a6d694c5310), +W64LIT(0x24a1baf2d9d261ac), +W64LIT(0xe4fbb08d9fe36a48), +W64LIT(0x8d83618ef7cff011), +W64LIT(0x2ac72276abf5279e), +W64LIT(0xf9e32621e68eebf6), +W64LIT(0xbf323fb4d3f86f69), +W64LIT(0xbb888605b8745beb), +W64LIT(0x70dafe1e7acd2f65), +W64LIT(0xd0adf1a41f1edbf3), +W64LIT(0x1e91635f2b089625), +W64LIT(0xee2791b8864818f8), +W64LIT(0x99ce23e4c56c1484), +W64LIT(0xf33f0714ff259946), +W64LIT(0xbd6f99161cbe7528), +W64LIT(0x9f293cf761a63a47), +W64LIT(0xb80173f6ea114c70), +W64LIT(0x6543ef25d54dc62a), +W64LIT(0x39b92c5ea0bfe012), +W64LIT(0x63a4f0367187e8e9), +W64LIT(0x4c0d38a02cddf62f), +W64LIT(0x07334c4239e92319), +W64LIT(0x43bff375c3d9bdc7), +W64LIT(0xca862b4a5f9a7954), +W64LIT(0x5d2e902ae8d12be2), +W64LIT(0x137e0e280b4ac78c), +W64LIT(0xf162a1b630638307), +W64LIT(0x55af17bd3e3c4313), +W64LIT(0x358212781ddebc61), +W64LIT(0x94214e93e52e452d), +W64LIT(0xc18e592edb12063e), +W64LIT(0xec7a371a490e02b9), +W64LIT(0x4963d240da72cf77), +W64LIT(0x41e255d70c9fa786), +W64LIT(0xff0439324244c535), +W64LIT(0x88ed8b6e0160c949), +W64LIT(0x6c163be39e83a301), +W64LIT(0xc534e09fb09e32bc), +W64LIT(0x806c0cf9d78da1b8), +W64LIT(0xdba583c09b96a499), +W64LIT(0x746047af11411be7), +W64LIT(0xf40c4b56c6ccba5f), +W64LIT(0x6270a367eca4e533), +W64LIT(0xd41748157492ef71), +W64LIT(0xeff3c2e91b6b1522), +W64LIT(0x0e66988472274632), +W64LIT(0x534808ae9af66dd0), +W64LIT(0x8231aa5b18cbbbf9), +W64LIT(0xb2dd52c3f3ba3ec0), +W64LIT(0xdd429cd33f5c8a5a), +W64LIT(0x4e509e02e39bec6e), +W64LIT(0x26fc1c5016947bed), +W64LIT(0xd9f8256254d0bed8), +W64LIT(0x0955d4c64bce652b), +W64LIT(0x1610e4c8fde5fed4), +W64LIT(0x6dc268b203a0aedb), +W64LIT(0x2e7d9bc7c079131c), +W64LIT(0xc3d3ff8c14541c7f), +W64LIT(0xd64aeeb7bbd4f530), +W64LIT(0xab7f7ddee15b8bfc), +W64LIT(0x144d426a32a3e495), +W64LIT(0x8e0a947da5aae78a), +W64LIT(0x798f2ad831034a4e), +W64LIT(0x3be48afc6ff9fa53), +W64LIT(0x529c5bff07d5600a), +W64LIT(0xbee66ce54edb62b3), +W64LIT(0x931202d1dcc76634), +W64LIT(0x50c1fd5dc8937a4b), +W64LIT(0xa4cdb60b0e5fc014), +W64LIT(0x57f2b11ff17a5952), +W64LIT(0x47054ac4a8558945), +W64LIT(0x5a1ddc68d13808fb), +W64LIT(0x5cfac37b75f22638), +W64LIT(0xc207acdd897711a5), +W64LIT(0x289a84d464b33ddf), +W64LIT(0xc05a0a7f46310be4), +W64LIT(0xe6a6162f50a57009), +W64LIT(0x06e71f13a4ca2ec3), +W64LIT(0x5f733688279731a3), +W64LIT(0xeb497b5870e721a0), +W64LIT(0xb667eb7298360a42), +W64LIT(0xe3c8fccfa60a4951), +W64LIT(0xe772457ecd867dd3), +W64LIT(0x6978d103682c9a59), +W64LIT(0x0def6d77204251a9), +W64LIT(0xc90fdeb90dff6ecf), +W64LIT(0xd179a2f5823dd629), +W64LIT(0x2fa9c8965d5a1ec6), +W64LIT(0x81b85fa84aaeac62), +W64LIT(0xdc96cf82a27f8780), +W64LIT(0x602d05c523e2ff72), +W64LIT(0x19a22f1d12e1b53c), +W64LIT(0xe52fe3dc02c06792), +W64LIT(0x58407aca1e7e12ba), +W64LIT(0x61f95694bec1f2a8), +W64LIT(0x48b781114751c2ad), +W64LIT(0xaaab2e8f7c788626), +W64LIT(0x04bab9b16b8c3482), +W64LIT(0x2df46e34921c0487), +W64LIT(0x1123a88ac40cddcd), +W64LIT(0xc6bd156ce2fb2527), +W64LIT(0x7f6835cb95c9648d), +W64LIT(0x83e5f90a85e8b623), +W64LIT(0x4f84cd537eb8e1b4), +W64LIT(0x294ed785f9903005), +W64LIT(0x1cccc5fde44e8c64), +W64LIT(0xcb52781bc2b9748e), +W64LIT(0x1d1896ac796d81be), +W64LIT(0xb30901926e99331a), +W64LIT(0xad9862cd4591a53f), +W64LIT(0xc8db8de890dc6315), +W64LIT(0x7bd28c7afe45500f), +W64LIT(0x0adc213519ab72b0), +W64LIT(0xa8f6882db33e9c67), +W64LIT(0xb5ee1e81ca531dd9), +W64LIT(0x201b0343b25e552e), +W64LIT(0x4036068691bcaa5c), +W64LIT(0xae11973e17f4b2a4), +W64LIT(0x9efd6fa6fc85379d), +W64LIT(0x33650d6bb91492a2), +W64LIT(0x3a30d9adf2daf789), +W64LIT(0x0c3b3e26bd615c73), +W64LIT(0xf651edf4098aa01e), +W64LIT(0x710ead4fe7ee22bf), +W64LIT(0x3138abc9765288e3), +W64LIT(0x9d749a55aee02006), +W64LIT(0x6e4b9d4151c5b940), +W64LIT(0x84d6b548bc01953a), +W64LIT(0x360be78b4fbbabfa), +W64LIT(0xa22aa918aa95eed7), +W64LIT(0xedae644bd42d0f63), +W64LIT(0x46d119953576849f), +W64LIT(0x6497bc74486ecbf0), +W64LIT(0xfbbe808329c8f1b7), +W64LIT(0x4aea27b38817d8ec), +W64LIT(0x5626e24e6c595488), +W64LIT(0x056eeae0f6af3958), +W64LIT(0x4558ec6667139304), +W64LIT(0x448cbf37fa309ede), +W64LIT(0x6f9fce10cce6b49a), +W64LIT(0xa0770fba65d3f496), +W64LIT(0x671e49871a0bdc6b), +W64LIT(0xda71d09106b5a943), +W64LIT(0x08818797d6ed68f1), +W64LIT(0xa3fefa4937b6e30d), +W64LIT(0xb080f4613cfc2481), +W64LIT(0x763de10dde0701a6), +W64LIT(0x4dd96bf1b1fefbf5), +W64LIT(0x92c6518041e46bee), +W64LIT(0x3456412980fdb1bb), +W64LIT(0x981a70b5584f195e), +W64LIT(0x3d0395efcb33d490), +W64LIT(0xba5cd55425575631), +W64LIT(0x4b3e74e21534d536), +W64LIT(0x6af124f03a498dc2), +W64LIT(0x7ebc669a08ea6957), +W64LIT(0x30ecf898eb718539), +W64LIT(0xa922db7c2e1d91bd), +W64LIT(0x7a06df2b63665dd5), +W64LIT(0xb154a730a1df295b), +W64LIT(0xfc8dccc11021d2ae), +W64LIT(0xcfe8c1aaa935400c), +W64LIT(0x97a8bb60b74b52b6), +W64LIT(0x18767c4c8fc2b8e6), +W64LIT(0x9a47d6179709031f), +W64LIT(0x0000000000000000), +W64LIT(0xac4c319cd8b2a8e5), +W64LIT(0xb9d520a7773241aa), +W64LIT(0xdecb69206d399dc1), +W64LIT(0x1f45300eb62b9bff), +W64LIT(0x10f7fbdb592fd017), +W64LIT(0x3e8a601c9956c30b), +W64LIT(0x8502e619212298e0), +W64LIT(0xf5d818075befb785), +W64LIT(0x547b44eca31f4ec9), +W64LIT(0x9ca0c90433c32ddc), +W64LIT(0xe041093cf46f5eca), +W64LIT(0xa69010a9c119da55), +W64LIT(0xc769463d7fd828fd), +W64LIT(0xc4e0b3ce2dbd3f66), +W64LIT(0x2575e9a344f16c76), +W64LIT(0x01d453519d230dda), +W64LIT(0xfa6ad3d2b4ebfc6d), +W64LIT(0xd5c31b44e9b1e2ab), +W64LIT(0xf83775707bade62c), +W64LIT(0xbcbbca47819d78f2), +W64LIT(0xd79ebde626f7f8ea), +W64LIT(0x5bc98f394c1b0521), +W64LIT(0x2246a5e17d184f6f), +W64LIT(0x12aa5d799669ca56), +W64LIT(0x5ea765d9bab43c79), +W64LIT(0x8939d83f9c43c493), +W64LIT(0x32b15e3a24379f78), +W64LIT(0xe914ddfabfa13be1), +W64LIT(0x909bf7228ea271af), +W64LIT(0x73530bed28a838fe), +W64LIT(0xd2f05706d058c1b2), +W64LIT(0xfed06a63df67c8ef), +W64LIT(0xb43a4dd057701003), +W64LIT(0xa519e55a937ccdce), +W64LIT(0x75b414fe8c62163d), +W64LIT(0xafc5c46f8ad7bf7e), +W64LIT(0x2392f6b0e03b42b5), +W64LIT(0x386d7f0f3d9cedc8), +W64LIT(0x21cf50122f7d58f4), +W64LIT(0x9b9385460a2a0ec5), +W64LIT(0x5115ae0c55b07791), +W64LIT(0x0fb2cbd5ef044be8), +W64LIT(0xea9d2809edc42c7a), +W64LIT(0xcc613459fb505797), +W64LIT(0x426ba0245efab01d), +W64LIT(0x1599113baf80e94f), +W64LIT(0x7d3593695a8f7ecc), +W64LIT(0x0389f5f35265179b), +W64LIT(0x875f40bbee6482a1), +W64LIT(0x95f51dc2780d48f7), +W64LIT(0x7ce1c038c7ac7316), +W64LIT(0xce3c92fb34164dd6), +W64LIT(0xcdb5670866735a4d), +W64LIT(0x8ab02dccce26d308), +W64LIT(0x914fa47313817c75), +W64LIT(0x8b647e9d5305ded2), +W64LIT(0xd82c7633c9f3b302), +W64LIT(0x728758bcb58b3524), +W64LIT(0xe8c08eab2282363b), +W64LIT(0x8fdec72c3889ea50), +W64LIT(0x2b13712736d62a44), +W64LIT(0x3cd7c6be5610d94a), +W64LIT(0x37dfb4dad298a620), +W64LIT(0x868b13ea73478f7b), +W64LIT(0xb7b3b82305150798), +W64LIT(0x0b08726484887f6a), +W64LIT(0x1bff89bfdda7af7d), +W64LIT(0x77e9b25c43240c7c), +W64LIT(0xf0b6f2e7ad408edd), +W64LIT(0x17c4b79960c6f30e), +W64LIT(0x8c5732df6aecfdcb), +W64LIT(0x68ac8252f50f9783), +W64LIT(0x66ca1ad68728d1b1), +W64LIT(0x6b2577a1a76a8018), +W64LIT(0xe21caf9e3b29448b), +W64LIT(0xa74443f85c3ad78f), +W64LIT(0xfd599f908d02df74), +W64LIT(0x967ce8312a685f6c), +/* box 3 */ +W64LIT(0xfa7b9775ba3af751), +W64LIT(0x03ef98cb769c2d13), +W64LIT(0x7191ce067072359e), +W64LIT(0xbab18b6bff7516a8), +W64LIT(0xe6e5ef4efbc1065e), +W64LIT(0x7bec74a3b1d0dbf4), +W64LIT(0x656b4fb907c31c4a), +W64LIT(0x4e8520f99fc86304), +W64LIT(0x8fd8df31d16dae58), +W64LIT(0x90a93fc1e60a7244), +W64LIT(0x30ad09f2b449cfc5), +W64LIT(0x8453be7e91bb5b90), +W64LIT(0x1d68a3d1c08feaad), +W64LIT(0x5c54642504b410f6), +W64LIT(0x8061383c8a9e3707), +W64LIT(0xf9940fbecca6da42), +W64LIT(0x46e1d97da982bbdf), +W64LIT(0xfc50521656f7ad77), +W64LIT(0x5e4d2704f35c2647), +W64LIT(0x8bea5973ca48c2cf), +W64LIT(0xd06323dfa34593bd), +W64LIT(0x62b651306a7a5dce), +W64LIT(0xa436b0714966d116), +W64LIT(0x4f73fb131ebc78a6), +W64LIT(0x92b07ce011e244f5), +W64LIT(0x33429139c2d5e2d6), +W64LIT(0xcee418c515565403), +W64LIT(0xd7be3d56cefcd239), +W64LIT(0x53ed83285f4789a9), +W64LIT(0xf3e9b51b0d043428), +W64LIT(0x20650e0fd8dd8a86), +W64LIT(0xb6e7f4add21aa2e4), +W64LIT(0x6d0fb63d3189c491), +W64LIT(0x0da0a42cac1bafee), +W64LIT(0x3f14eeffefba569a), +W64LIT(0x13279f361a086850), +W64LIT(0x9b225e8ea6dc878c), +W64LIT(0x6684d772715f3159), +W64LIT(0xa3ebaef824df9092), +W64LIT(0xc499a260d4f4ba69), +W64LIT(0xaa798c9693e153eb), +W64LIT(0x50021be329dba4ba), +W64LIT(0x949bb983fd2f1ed3), +W64LIT(0xdfdac4d2f8b60ae2), +W64LIT(0xf0062dd07b98193b), +W64LIT(0xafbdd13e09b024de), +W64LIT(0xb95e13a089e93bbb), +W64LIT(0x649d945386b707e8), +W64LIT(0xe4fcac6f0c2930ef), +W64LIT(0x413cc7f4c43bfa5b), +W64LIT(0x3b2668bdf49f3a0d), +W64LIT(0xe50a77858d5d2b4d), +W64LIT(0x05c45da89a517735), +W64LIT(0x3ee235156ece4d38), +W64LIT(0xfe491137a11f9bc6), +W64LIT(0xb7112f47536eb946), +W64LIT(0x07dd1e896db94184), +W64LIT(0x1ab5bd58ad36ab29), +W64LIT(0x8197e3d60bea2ca5), +W64LIT(0xab8f577c12954849), +W64LIT(0x9cff4007cb65c608), +W64LIT(0xa00436335243bd81), +W64LIT(0xfda689fcd783b6d5), +W64LIT(0xccfd5be4e2be62b2), +W64LIT(0x75a348446b575909), +W64LIT(0x17151974012d04c7), +W64LIT(0xfb8d4c9f3b4eecf3), +W64LIT(0xac5249f57f2c09cd), +W64LIT(0x9346a70a90965f57), +W64LIT(0x043286421b256c97), +W64LIT(0x27b81086b564cb02), +W64LIT(0x3569545a2e18b8f0), +W64LIT(0x6b24735edd449eb7), +W64LIT(0x2193d5e559a99124), +W64LIT(0xc7763aaba268977a), +W64LIT(0xb0cc31ce3ed7f8c2), +W64LIT(0xc939064c78ef1587), +W64LIT(0x16e3c29e80591f65), +W64LIT(0x5da2bfcf85c00b54), +W64LIT(0x5990398d9ee567c3), +W64LIT(0x67720c98f02b2afb), +W64LIT(0x54309da132fec82d), +W64LIT(0xeab39088d6aeb212), +W64LIT(0x9682faa20ac72862), +W64LIT(0xd38cbb14d5d9beae), +W64LIT(0x4c9c63d8682055b5), +W64LIT(0xd648e6bc4f88c99b), +W64LIT(0xdc355c198e2a27f1), +W64LIT(0x10c807fd6c944543), +W64LIT(0x450e41b6df1e96cc), +W64LIT(0x0b8b614f40d6f5c8), +W64LIT(0xd27a60fe54ada50c), +W64LIT(0x49583e70f2712280), +W64LIT(0x8dc19c10268598e9), +W64LIT(0x5866e2671f917c61), +W64LIT(0x79f537824638ed45), +W64LIT(0xc2b267033839e04f), +W64LIT(0xcb20456d8f072336), +W64LIT(0x2a18b4aa197f64ec), +W64LIT(0xdbe84290e3936675), +W64LIT(0x73888d27879a032f), +W64LIT(0xe8aad3a9214684a3), +W64LIT(0x6ee02ef64715e982), +W64LIT(0xa996145de57d7ef8), +W64LIT(0xc8cfdda6f99b0e25), +W64LIT(0x062bc563eccd5a26), +W64LIT(0x264ecb6c3410d0a0), +W64LIT(0xb8a8c84a089d2019), +W64LIT(0x7dc7b1c05d1d81d2), +W64LIT(0xd5a77e773914e488), +W64LIT(0x4b417d5105991431), +W64LIT(0xf62de8b39755431d), +W64LIT(0x993b1daf5134b13d), +W64LIT(0x82787b1d7d7601b6), +W64LIT(0xe321b2e66190716b), +W64LIT(0xb5086c66a4868ff7), +W64LIT(0x9ee603263c8df0b9), +W64LIT(0x349f8fb0af6ca352), +W64LIT(0x5b897aac690d5172), +W64LIT(0x7c316a2adc699a70), +W64LIT(0xd451a59db860ff2a), +W64LIT(0x706715ecf1062e3c), +W64LIT(0x838ea0f7fc021a14), +W64LIT(0x57df056a4462e53e), +W64LIT(0xcf12c32f94224fa1), +W64LIT(0xed6e8e01bb17f396), +W64LIT(0x915fe42b677e69e6), +W64LIT(0x89f31a523da0f47e), +W64LIT(0xe71334a47ab51dfc), +W64LIT(0xa860cfb76409655a), +W64LIT(0x9f10d8ccbdf9eb1b), +W64LIT(0xef77cd204cffc527), +W64LIT(0xf862d4544dd2c1e0), +W64LIT(0x8a1c82994b3cd96d), +W64LIT(0xae4b0ad488c43f7c), +W64LIT(0x98cdc645d040aa9f), +W64LIT(0x7fdef2e1aaf5b763), +W64LIT(0x4717029728f6a07d), +W64LIT(0x745593aeea2342ab), +W64LIT(0xee8116cacd8bde85), +W64LIT(0x727e56cd06ee188d), +W64LIT(0x227c4d2e2f35bc37), +W64LIT(0x977421488bb333c0), +W64LIT(0xa21d7512a5ab8b30), +W64LIT(0xbb4750817e010d0a), +W64LIT(0x6cf96dd7b0fddf33), +W64LIT(0x2801f78bee97525d), +W64LIT(0x1c9e783b41fbf10f), +W64LIT(0x9d099bed4a11ddaa), +W64LIT(0x7a1aaf4930a4c056), +W64LIT(0x32b44ad343a1f974), +W64LIT(0x3cfb763499267b89), +W64LIT(0xb2d572efc93fce73), +W64LIT(0x63408adaeb0e466c), +W64LIT(0xada4921ffe58126f), +W64LIT(0x5fbbfcee72283de5), +W64LIT(0x6ad2a8b45c308515), +W64LIT(0x0c567fc62d6fb44c), +W64LIT(0x956d62697c5b0571), +W64LIT(0x25a153a7428cfdb3), +W64LIT(0x150c5a55f6c53276), +W64LIT(0xe2d7690ce0e46ac9), +W64LIT(0xda1e997a62e77dd7), +W64LIT(0xf5c27078e1c96e0e), +W64LIT(0xc344bce9b94dfbed), +W64LIT(0x60af12119d926b7f), +W64LIT(0xa1f2edd9d337a623), +W64LIT(0xcad69e870e733894), +W64LIT(0x3770177bd9f08e41), +W64LIT(0xa5c06b9bc812cab4), +W64LIT(0x1f71e0f03767dc1c), +W64LIT(0x44f89a5c5e6a8d6e), +W64LIT(0x6159c9fb1ce670dd), +W64LIT(0x8e2e04db5019b5fa), +W64LIT(0x8805c1b8bcd4efdc), +W64LIT(0xe138f1c7967847da), +W64LIT(0x4ab7a6bb84ed0f93), +W64LIT(0x0000000000000000), +W64LIT(0x38c9f0768203171e), +W64LIT(0x1b4366b22c42b08b), +W64LIT(0x7803ec68c74cf6e7), +W64LIT(0xec9855eb3a63e834), +W64LIT(0xbe830d29e4507a3f), +W64LIT(0x2dc5aa2374c62568), +W64LIT(0xa62ff350be8ee7a7), +W64LIT(0x764cd08f1dcb741a), +W64LIT(0x8c3747faa7f1834b), +W64LIT(0x0fb9e70d5bf3995f), +W64LIT(0x55c6464bb38ad38f), +W64LIT(0xf7db3359162158bf), +W64LIT(0xd195f8352231881f), +W64LIT(0x0992226eb73ec379), +W64LIT(0x14fa81bf77b129d4), +W64LIT(0x48aee59a73053922), +W64LIT(0x2457884dc3f8e611), +W64LIT(0xffbfcadd206b8064), +W64LIT(0xb4feb78c25f29455), +W64LIT(0x864afd5f66536d21), +W64LIT(0x6f16f51cc661f220), +W64LIT(0xde2c1f3879c21140), +W64LIT(0x195a2593dbaa863a), +W64LIT(0x2e2a32e8025a087b), +W64LIT(0x432584d533d3ccea), +W64LIT(0x2c3371c9f5b23eca), +W64LIT(0xa7d928ba3ffafc05), +W64LIT(0x42d35f3fb2a7d748), +W64LIT(0x85a5659410cf4032), +W64LIT(0x0864f984364ad8db), +W64LIT(0xf21f6ef18c702f8a), +W64LIT(0xf1f0f63afaec0299), +W64LIT(0xd9f101b1147b50c4), +W64LIT(0x2fdce902832e13d9), +W64LIT(0x4d6ab832e9544e17), +W64LIT(0xe0ce2a2d170c5c78), +W64LIT(0x51f4c009a8afbf18), +W64LIT(0x68cbeb95abd8b3a4), +W64LIT(0xc15dffc84ea5cd5c), +W64LIT(0x02194321f7e836b1), +W64LIT(0x113edc17ede05ee1), +W64LIT(0x521b58c2de33920b), +W64LIT(0x9ad4856427a89c2e), +W64LIT(0x5629de80c516fe9c), +W64LIT(0x77ba0b659cbf6fb8), +W64LIT(0x238a96c4ae41a795), +W64LIT(0x12d144dc9b7c73f2), +W64LIT(0xd807da5b950f4b66), +W64LIT(0x3686cc91588495e3), +W64LIT(0x18acfe795ade9d98), +W64LIT(0x5a7fa146e8794ad0), +W64LIT(0xc680e141231c8cd8), +W64LIT(0x1e873b1ab613c7be), +W64LIT(0xf434ab9260bd75ac), +W64LIT(0xcd0b800e63ca7910), +W64LIT(0xbc9a4e0813b84c8e), +W64LIT(0x3d0dadde1852602b), +W64LIT(0x40ca1c1e454fe1f9), +W64LIT(0x0a7dbaa5c1a2ee6a), +W64LIT(0x693d307f2aaca806), +W64LIT(0x0e4f3ce7da8782fd), +W64LIT(0xbd6c95e292cc572c), +W64LIT(0x3ad0b35775eb21af), +W64LIT(0x7e28290b2b81acc1), +W64LIT(0x01f6dbea81741ba2), +W64LIT(0x87bc26b5e7277683), +W64LIT(0x393f2b9c03770cbc), +W64LIT(0xddc387f30f5e3c53), +W64LIT(0xeb454b6257daa9b0), +W64LIT(0xb323a905484bd5d1), +W64LIT(0xb13aea24bfa3e360), +W64LIT(0x315bd218353dd467), +W64LIT(0x2bee6f40980b7f4e), +W64LIT(0xe95c0843a0329f01), +W64LIT(0xc56f798a5580a1cb), +W64LIT(0xbf75d6c36524619d), +W64LIT(0x29f72c616fe349ff), +W64LIT(0xc0ab2422cfd1d6fe), +/* box 4 */ +W64LIT(0x561fc423e957943c), +W64LIT(0x014287ca69079288), +W64LIT(0x2f086129dfcd1d21), +W64LIT(0xc537d4aea044fd99), +W64LIT(0xf1e8c3bfd7c8a457), +W64LIT(0x2971998a5cdf9bfb), +W64LIT(0x23fa649a2ce9e460), +W64LIT(0x3aa9e9c356a6716a), +W64LIT(0xd6efa4e7aa3d1708), +W64LIT(0x705a24b1fda5b5eb), +W64LIT(0x101e0ce2b170a9fc), +W64LIT(0x7ca821020e814caa), +W64LIT(0x0bc97ada1931ed13), +W64LIT(0x34df1711778c59ce), +W64LIT(0xd35020ef9226d2bf), +W64LIT(0x575d43e9805006b4), +W64LIT(0x91acebec9b1db840), +W64LIT(0x549b3f423b5945d9), +W64LIT(0x99a3ed9d3925163e), +W64LIT(0x7917a50a369a891d), +W64LIT(0xe372343cb4b6dc4e), +W64LIT(0x8d40e2bdd949e8fd), +W64LIT(0xcfbc29bed0728202), +W64LIT(0x969794857108ac12), +W64LIT(0xdd26de3db30cfa1b), +W64LIT(0x115c8b28d8773b74), +W64LIT(0xe9f9c92cc480a3d5), +W64LIT(0x4dc8b21b4116d0d3), +W64LIT(0x316093194f979c79), +W64LIT(0x5124bb4a0342806e), +W64LIT(0xb31408bcdef3cea8), +W64LIT(0xc1cad76cf158aaa6), +W64LIT(0x88ff66b5e1522d4a), +W64LIT(0xa8c37e8476b28a47), +W64LIT(0x15a188ea896b6c4b), +W64LIT(0xa24883940684f5dc), +W64LIT(0xda1da1545919ee49), +W64LIT(0x22b8e35045ee76e8), +W64LIT(0x6106af9925d28e9f), +W64LIT(0xef80318f4792250f), +W64LIT(0x663dd0f0cfc79acd), +W64LIT(0x302214d326900ef1), +W64LIT(0xdfa2255c61022bfe), +W64LIT(0xe6cdb0348cad19f9), +W64LIT(0x50663c806a4512e6), +W64LIT(0x65fbac5b74ced9a0), +W64LIT(0xc4755364c9436f11), +W64LIT(0x8fc419dc0b473918), +W64LIT(0x5c9439339961eba7), +W64LIT(0x3f166dcb6ebdb4dd), +W64LIT(0xba59890715ccf25e), +W64LIT(0xf0aa4475becf36df), +W64LIT(0x03c67cabbb09436d), +W64LIT(0xb99ff5acaec5b133), +W64LIT(0xf9e7c5ce75f00a29), +W64LIT(0x6df4aa2ad6f677de), +W64LIT(0xaeba8627f5a00c9d), +W64LIT(0xa573fcfdec91e18e), +W64LIT(0x7f6e5da9b5880fc7), +W64LIT(0xca03adb6e86947b5), +W64LIT(0x74a72773acb9e2d4), +W64LIT(0x604428534cd51c17), +W64LIT(0xf8a542041cf798a1), +W64LIT(0x448533a08a29ec25), +W64LIT(0x80f060c4436a8334), +W64LIT(0x0db082799a236bc9), +W64LIT(0xfa21b965cef94944), +W64LIT(0x64b92b911dc94b28), +W64LIT(0x7118a37b94a22763), +W64LIT(0xaff801ed9ca79e15), +W64LIT(0x1dae8e9b2b53c235), +W64LIT(0x13d870490a79ea91), +W64LIT(0x8a7b9dd4335cfcaf), +W64LIT(0x1f2a75faf95d13d0), +W64LIT(0xeec2b6452e95b787), +W64LIT(0xc34e2c0d23567b43), +W64LIT(0x47434f0b3120af48), +W64LIT(0xa18eff3fbd8db6b1), +W64LIT(0x98e16a57502284b6), +W64LIT(0x37196bbacc851aa3), +W64LIT(0x8e869e166240ab90), +W64LIT(0x9fda153eba3790e4), +W64LIT(0xf515c07d86d4f368), +W64LIT(0x72dedfd02fab640e), +W64LIT(0xe230b3f6ddb14ec6), +W64LIT(0x97d5134f180f3e9a), +W64LIT(0xe1f6cf5d66b80dab), +W64LIT(0xe78f37fee5aa8b71), +W64LIT(0xa30a045e6f836754), +W64LIT(0x90ee6c26f21a2ac8), +W64LIT(0xaa4785e5a4bc5ba2), +W64LIT(0x4e0eceb0fa1f93be), +W64LIT(0x94136fe4a3067df7), +W64LIT(0x7b935e6be49458f8), +W64LIT(0x9b2716fceb2bc7db), +W64LIT(0x840d63061276d40b), +W64LIT(0xed04caee959cf4ea), +W64LIT(0xea3fb5877f89e0b8), +W64LIT(0xb56df01f5de14872), +W64LIT(0x4935b1d9100a87ec), +W64LIT(0x82749ba5916452d1), +W64LIT(0x58693af1c87dbc98), +W64LIT(0x89bde17f8855bfc2), +W64LIT(0x677f573aa6c00845), +W64LIT(0xeb7d324d168e7230), +W64LIT(0x0284fb61d20ed1e5), +W64LIT(0xb190f3dd0cfd1f4d), +W64LIT(0x684b2e22eeedb269), +W64LIT(0x2bf562eb8ed14a1e), +W64LIT(0xe0b448970fbf9f23), +W64LIT(0x396f9568edaf3207), +W64LIT(0x52e2c7e1b84bc303), +W64LIT(0x77615bd817b0a1b9), +W64LIT(0x7e2cda63dc8f9d4f), +W64LIT(0xf22ebf146cc1e73a), +W64LIT(0xc08850a6985f382e), +W64LIT(0xd9dbddffe210ad24), +W64LIT(0xbfe60d0f2dd737e9), +W64LIT(0x9a659136822c5553), +W64LIT(0x87cb1fada97f9766), +W64LIT(0x4c8a35d12811425b), +W64LIT(0x83361c6ff863c059), +W64LIT(0xd212a725fb214037), +W64LIT(0x9e9892f4d330026c), +W64LIT(0x45c7b46ae32e7ead), +W64LIT(0x5baf465a7374fff5), +W64LIT(0xdc6459f7da0b6893), +W64LIT(0xd46b5f867833c6ed), +W64LIT(0x5dd6bef9f066792f), +W64LIT(0xcb412a7c816ed53d), +W64LIT(0x75e5a0b9c5be705c), +W64LIT(0xf6d3bcd63dddb005), +W64LIT(0xfb633eafa7fedbcc), +W64LIT(0xd529d84c11345465), +W64LIT(0xc9c5d11d536004d8), +W64LIT(0xdb5f269e301e7cc1), +W64LIT(0x86899867c07805ee), +W64LIT(0x3d9296aabcb36538), +W64LIT(0x2cce1d8264c45e4c), +W64LIT(0x5aedc1901a736d7d), +W64LIT(0x2e4ae6e3b6ca8fa9), +W64LIT(0x1e68f230905a8158), +W64LIT(0xdee0a2960805b976), +W64LIT(0xcd38d2df027c53e7), +W64LIT(0x6909a9e887ea20e1), +W64LIT(0x24c11bf3c6fcf032), +W64LIT(0x18110a9313480782), +W64LIT(0xa7f7079c3e9f306b), +W64LIT(0xd8995a358b173fac), +W64LIT(0x854fe4cc7b714683), +W64LIT(0xbd62f66effd9e60c), +W64LIT(0x14e30f20e06cfec3), +W64LIT(0x6e32d6816dff34b3), +W64LIT(0x217e9ffbfee73585), +W64LIT(0xc88756d73a679650), +W64LIT(0x359d90db1e8bcb46), +W64LIT(0x2645e09214f221d7), +W64LIT(0x04fd03c2511c573f), +W64LIT(0x739c581a46acf686), +W64LIT(0xb0d2741765fa8dc5), +W64LIT(0xa0cc78f5d48a2439), +W64LIT(0x5e10c2524b6f3a42), +W64LIT(0xe50bcc9f37a45a94), +W64LIT(0x53a0402bd14c518b), +W64LIT(0x413ab7a8b2322992), +W64LIT(0x203c183197e0a70d), +W64LIT(0xcc7a55156b7bc16f), +W64LIT(0x4601c8c158273dc0), +W64LIT(0xbea48ac544d0a561), +W64LIT(0x638254f8f7dc5f7a), +W64LIT(0xa6b580565798a2e3), +W64LIT(0x3cd01160d5b4f7b0), +W64LIT(0x8c026577b04e7a75), +W64LIT(0x7ad1d9a18d93ca70), +W64LIT(0x785522c05f9d1b95), +W64LIT(0x5f5245982268a8ca), +W64LIT(0x9551e82eca01ef7f), +W64LIT(0x0000000000000000), +W64LIT(0xbb1b0ecd7ccb60d6), +W64LIT(0x094d81bbcb3f3cf6), +W64LIT(0x28331e4035d80973), +W64LIT(0xf7913b1c54da228d), +W64LIT(0x6acfd5433ce3638c), +W64LIT(0x1bd77638a84144ef), +W64LIT(0x62c0d3329edbcdf2), +W64LIT(0x81b2e70e2a6d11bc), +W64LIT(0xd7ad232dc33a8580), +W64LIT(0x05bf8408381bc5b7), +W64LIT(0x33e468789d994d9c), +W64LIT(0xfedcbaa79fe51e7b), +W64LIT(0x4f4c497a93180136), +W64LIT(0x073b7f69ea151452), +W64LIT(0x0cf205b3f324f941), +W64LIT(0x382d12a284a8a08f), +W64LIT(0x1cec0951425450bd), +W64LIT(0x55d9b888525ed751), +W64LIT(0x6cb62de0bff1e556), +W64LIT(0xd1d4db8e4028035a), +W64LIT(0x25839c39affb62ba), +W64LIT(0x4af3cd72ab03c481), +W64LIT(0xa4317b3785967306), +W64LIT(0x1a95f1f2c146d667), +W64LIT(0x926a97472014fb2d), +W64LIT(0xb7e90b7e8fef9997), +W64LIT(0xcefeae74b975108a), +W64LIT(0x3e54ea0107ba2655), +W64LIT(0xd0965c44292f91d2), +W64LIT(0xab05022fcdbbc92a), +W64LIT(0xfd1ac60c24ec5d16), +W64LIT(0xfc5841c64debcf9e), +W64LIT(0xe4494b555ea3c81c), +W64LIT(0xb6ab8cb4e6e80b1f), +W64LIT(0x3beb6e093fa1e3e2), +W64LIT(0xf36c38de05c675b2), +W64LIT(0x9c1c6995013ed389), +W64LIT(0x8b391a1e5a5b6e27), +W64LIT(0xec464d24fc9b6662), +W64LIT(0xad7cfa8c4ea94ff0), +W64LIT(0x0f347918482dba2c), +W64LIT(0x9d5eee5f68394101), +W64LIT(0x7623dc127eb73331), +W64LIT(0x32a6efb2f49edf14), +W64LIT(0x2d8c9a480dc3ccc4), +W64LIT(0xb2568f76b7f45c20), +W64LIT(0x0e76fed2212a28a4), +W64LIT(0x48773613790d1564), +W64LIT(0x129af783637e7819), +W64LIT(0x080f0671a238ae7e), +W64LIT(0x365bec70a582882b), +W64LIT(0x42fccb03093b6aff), +W64LIT(0x0a8bfd1070367f9b), +W64LIT(0xff9e3d6df6e28cf3), +W64LIT(0xe8bb4ee6ad87315d), +W64LIT(0xc7b32fcf724a2c7c), +W64LIT(0xb8dd7266c7c223bb), +W64LIT(0x9328108d491369a5), +W64LIT(0x0679f8a3831286da), +W64LIT(0x270767587df5b35f), +W64LIT(0xa981f94e1fb518cf), +W64LIT(0x6b8d528955e4f104), +W64LIT(0x1667f44132622f26), +W64LIT(0x2ab7e521e7d6d896), +W64LIT(0xac3e7d4627aedd78), +W64LIT(0x7deaa6c86786de22), +W64LIT(0x1725738b5b65bdae), +W64LIT(0x4bb14ab8c2045609), +W64LIT(0x592bbd3ba17a2e10), +W64LIT(0xc20cabc74a51e9cb), +W64LIT(0x6f70514b04f8a63b), +W64LIT(0xbc2071a496de7484), +W64LIT(0x19538d597a4f950a), +W64LIT(0xf45747b7efd361e0), +W64LIT(0x43be4cc9603cf877), +W64LIT(0xc6f1a8051b4dbef4), +W64LIT(0xb42f77d534e6dafa), +W64LIT(0x40783062db35bb1a), +/* box 5 */ +W64LIT(0xf5a96c292deb0a4e), +W64LIT(0x211c9df6ee653c51), +W64LIT(0x04de5ddcbeeef596), +W64LIT(0xe1e5b06f7457c19f), +W64LIT(0x74ca30f014a54fb6), +W64LIT(0xc296f9f7c5457d85), +W64LIT(0x7d4ee08a484d10b0), +W64LIT(0xae87f2d0bf9b13ad), +W64LIT(0x8df4bb480e89afb7), +W64LIT(0x2d8b7a67d9a2d61e), +W64LIT(0x0f3559c8bd712adb), +W64LIT(0x541bc7312f013338), +W64LIT(0x9ec4848b636d5164), +W64LIT(0x952f809f60f28e29), +W64LIT(0x28984d8cb28d6357), +W64LIT(0xd4b5f1dfc38e361f), +W64LIT(0x5674135f7076b373), +W64LIT(0xb791a330042172ec), +W64LIT(0xab94c53bd4b4a6e4), +W64LIT(0xf17731f59305ffd8), +W64LIT(0x39c7a621801e1dcf), +W64LIT(0x20d1f7c13ba47c8e), +W64LIT(0x5e3da912f95facaa), +W64LIT(0xb1202a82e5b80731), +W64LIT(0x13303fc36de4fed3), +W64LIT(0x2e29c43e5314168a), +W64LIT(0x861fbf5c0d1670fa), +W64LIT(0x6458b16af3f771f1), +W64LIT(0x3043765bdcf642c9), +W64LIT(0x12fd55f4b825be0c), +W64LIT(0x0a266e23d65e9f92), +W64LIT(0x6595db5d2636312e), +W64LIT(0x85bd010587a0b06e), +W64LIT(0x9bd7b3600842e42d), +W64LIT(0xaa59af0c0175e63b), +W64LIT(0x240faa1d854a8918), +W64LIT(0xf464061ef82a4a91), +W64LIT(0x5c527d7ca6282ce1), +W64LIT(0x03a2be598ab6c094), +W64LIT(0x40571b7776bdf8e9), +W64LIT(0xe4f687841f7874d6), +W64LIT(0x115febad32937e98), +W64LIT(0x5108f0da442e8671), +W64LIT(0x9cab50e53c1ad12f), +W64LIT(0x33e1c8025640825d), +W64LIT(0x87d2d56bd8d73025), +W64LIT(0xc0f92d999a32fdce), +W64LIT(0x62e938d8126e042c), +W64LIT(0x4a717554a0e3677b), +W64LIT(0x0beb0414039fdf4d), +W64LIT(0xd6da25b19cf9b654), +W64LIT(0x55d6ad06fac073e7), +W64LIT(0x632452efc7af44f3), +W64LIT(0xb5fe775e5b56f2a7), +W64LIT(0x892ae694b0675a21), +W64LIT(0x7a32030f7c1525b2), +W64LIT(0x5d9f174b73e96c3e), +W64LIT(0xc35b93c010843d5a), +W64LIT(0x373f95dee8ae77cb), +W64LIT(0xfb515fd6455b604a), +W64LIT(0xa9fb11558bc326af), +W64LIT(0x22be23af64d3fcc5), +W64LIT(0xa8367b625e026670), +W64LIT(0xb8a4faf8b9505837), +W64LIT(0x785dd7612362a5f9), +W64LIT(0x588c20a018c6d977), +W64LIT(0xea0eb47b77c81ed2), +W64LIT(0xa6ce489d36b20c74), +W64LIT(0x0c97e79137c7ea4f), +W64LIT(0x7c838abd9d8c506f), +W64LIT(0x57b97968a5b7f3ac), +W64LIT(0x6c110b277ade6e28), +W64LIT(0xc785ce1cae6ac8cc), +W64LIT(0x1581b6718c7d8b0e), +W64LIT(0x614b868198d8c4b8), +W64LIT(0x27ad14440ffc498c), +W64LIT(0xdb80a8177eff1cc4), +W64LIT(0x472bf8f242e5cdeb), +W64LIT(0x8a8858cd3ad19ab5), +W64LIT(0xf60bd270a75dcada), +W64LIT(0x43f5a52efc0b387d), +W64LIT(0x6ddc6110af1f2ef7), +W64LIT(0xf0ba5bc246c4bf07), +W64LIT(0x6fb3b57ef068aebc), +W64LIT(0x18db3bd76e7b219e), +W64LIT(0x903cb7740bdd3b60), +W64LIT(0x7bff6938a9d4656d), +W64LIT(0xbdb7cd13d27fed7e), +W64LIT(0x051337eb6b2fb549), +W64LIT(0x77688ea99e138f22), +W64LIT(0xd9ef7c7921889c8f), +W64LIT(0x077ce38534583502), +W64LIT(0xf318e59bcc727f93), +W64LIT(0xb34ffeecbacf877a), +W64LIT(0xe9ac0a22fd7ede46), +W64LIT(0xfc2dbc5371035548), +W64LIT(0x026fd46e5f77804b), +W64LIT(0xe53bedb3cab93409), +W64LIT(0xcc6eca08adf51781), +W64LIT(0xe028da58a1968140), +W64LIT(0x3a6518780aa8dd5b), +W64LIT(0xce011e66f28297ca), +W64LIT(0xa4a19cf369c58c3f), +W64LIT(0xc5ea1a72f11d4887), +W64LIT(0xc427704524dc0858), +W64LIT(0x4238cf1929ca78a2), +W64LIT(0x481ea13aff94e730), +W64LIT(0xdf5ef5cbc011e952), +W64LIT(0x80ae36eeec8f0527), +W64LIT(0x5ae3f4ce47b1593c), +W64LIT(0xcda3a03f7834575e), +W64LIT(0x71d9071b7f8afaff), +W64LIT(0xcadf43ba4c6c625c), +W64LIT(0x1623082806cb4b9a), +W64LIT(0x17ee621fd30a0b45), +W64LIT(0x448946abc8530d7f), +W64LIT(0x974054f13f850e62), +W64LIT(0x73b6d37520fd7ab4), +W64LIT(0xc8b097d4131be217), +W64LIT(0x9f09eebcb6ac11bb), +W64LIT(0x45442c9c1d924da0), +W64LIT(0x1b79858ee4cde10a), +W64LIT(0x0984d07a5ce85f06), +W64LIT(0x4cc0fce6417a12a6), +W64LIT(0x99b8670e57356466), +W64LIT(0xad254c89352dd339), +W64LIT(0x322ca2358381c282), +W64LIT(0xcfcc74512743d715), +W64LIT(0x6b6de8a24e865b2a), +W64LIT(0xda4dc220ab3e5c1b), +W64LIT(0x88e78ca365a61afe), +W64LIT(0x939e092d816bfbf4), +W64LIT(0xcb12298d99ad2283), +W64LIT(0xeed0e9a7c926eb44), +W64LIT(0x98750d3982f424b9), +W64LIT(0xd5789be8164f76c0), +W64LIT(0xbe15734a58c92dea), +W64LIT(0x49d3cb0d2a55a7ef), +W64LIT(0x67fa0f337941b165), +W64LIT(0x8c39d17fdb48ef68), +W64LIT(0x25c2c02a508bc9c7), +W64LIT(0x349d2b876218b75f), +W64LIT(0x70146d2caa4bba20), +W64LIT(0x1c05660bd095d408), +W64LIT(0xfe42683d2e74d503), +W64LIT(0x9a1ad957dd83a4f2), +W64LIT(0xf2d58fac19b33f4c), +W64LIT(0x81635cd9394e45f8), +W64LIT(0xb65cc907d1e03233), +W64LIT(0xdd3121a59f666919), +W64LIT(0x318e1c6c09370216), +W64LIT(0x8b4532faef10da6a), +W64LIT(0x191651e0bbba6141), +W64LIT(0x3f762f9361876812), +W64LIT(0xb96990cf6c9118e8), +W64LIT(0xb4331d698e97b278), +W64LIT(0xd822164ef449dc50), +W64LIT(0x84706b325261f0b1), +W64LIT(0x4eaf28881e0d92ed), +W64LIT(0x69023ccc11f1db61), +W64LIT(0x66376504ac80f1ba), +W64LIT(0x0849ba4d89291fd9), +W64LIT(0xff8f020afbb595dc), +W64LIT(0x50c59aed91efc6ae), +W64LIT(0x1dc80c3c055494d7), +W64LIT(0x1e6ab2658fe25443), +W64LIT(0x3d19fbfd3ef0e859), +W64LIT(0xfa9c35e1909a2095), +W64LIT(0x52aa4e83ce9846e5), +W64LIT(0x419a7140a37cb836), +W64LIT(0xa07fc12fd72b79a9), +W64LIT(0x68cf56fbc4309bbe), +W64LIT(0x01cd6a37d5c140df), +W64LIT(0x9253631a54aabb2b), +W64LIT(0xd06bac037d60c389), +W64LIT(0x295527bb674c2388), +W64LIT(0xd204786d221743c2), +W64LIT(0x0000000000000000), +W64LIT(0xf7c6b847729c8a05), +W64LIT(0xdcfc4b924aa729c6), +W64LIT(0xe38a64012b2041d4), +W64LIT(0xb28294db6f0ec7a5), +W64LIT(0x9d663ad2e9db91f0), +W64LIT(0x91f1dd43de1c7bbf), +W64LIT(0x6086ecb64d198467), +W64LIT(0x59414a97cd0799a8), +W64LIT(0xace826bee0ec93e6), +W64LIT(0xa56cf6c4bc04cce0), +W64LIT(0x727bb942f53c3a6b), +W64LIT(0x6e7edf4925a9ee63), +W64LIT(0x26607e73da3d0953), +W64LIT(0xe75439dd95ceb442), +W64LIT(0x7990bd56f6a3e526), +W64LIT(0xecbf3dc996516b0f), +W64LIT(0x76a5e49e4bd2cffd), +W64LIT(0x968d3ec6ea444ebd), +W64LIT(0x5b2e9ef9927019e3), +W64LIT(0x6aa082959b471bf5), +W64LIT(0xbb0644a133e698a3), +W64LIT(0x830c88b76639c5b3), +W64LIT(0xe2470e36fee1010b), +W64LIT(0xb0ed40b5307947ee), +W64LIT(0x355041b0b7d9f780), +W64LIT(0x8e560511843f6f23), +W64LIT(0x7f2134e4173a90fb), +W64LIT(0x2af799e2edfae31c), +W64LIT(0x4bbc1f63752227a4), +W64LIT(0xf8f3e18fcfeda0de), +W64LIT(0x0d5a8da6e206aa90), +W64LIT(0x2c4610500c6396c1), +W64LIT(0xde939ffc15d0a98d), +W64LIT(0xaf4a98e76a5a5372), +W64LIT(0x8f9b6f2651fe2ffc), +W64LIT(0x36f2ffe93d6f3714), +W64LIT(0x0ef833ff68b06a04), +W64LIT(0xe69953ea400ff49d), +W64LIT(0x23734998b112bc1a), +W64LIT(0x3ebb45a4b44628cd), +W64LIT(0x1ab4efb9310ca1d5), +W64LIT(0x2fe4ae0986d55655), +W64LIT(0xebc3de4ca2095e0d), +W64LIT(0x536724b41b59063a), +W64LIT(0x46e692c597248d34), +W64LIT(0x2b3af3d5383ba3c3), +W64LIT(0x3ba8724fdf699d84), +W64LIT(0xc13447ae4ff3bd11), +W64LIT(0x4d0d96d194bb5279), +W64LIT(0xfde0d664a4c21597), +W64LIT(0xd7174f864938f68b), +W64LIT(0x7eec5ed3c2fbd024), +W64LIT(0xbfd8197d8d086d35), +W64LIT(0x4f6242bfcbccd232), +W64LIT(0xa70322aae3734cab), +W64LIT(0xa3dd7f765d9db93d), +W64LIT(0x94e2eaa8b533cef6), +W64LIT(0x144cdc4659bccbd1), +W64LIT(0xc648a42b7bab8813), +W64LIT(0xf93e8bb81a2ce001), +W64LIT(0xbacb2e96e627d87c), +W64LIT(0xbc7aa72407beada1), +W64LIT(0xc97dfde3c6daa2c8), +W64LIT(0xa1b2ab1802ea3976), +W64LIT(0x1fa7d8525a23149c), +W64LIT(0x75075ac7c1640f69), +W64LIT(0xe861601528bf9e99), +W64LIT(0xa2101541885cf9e2), +W64LIT(0xef1d83901ce7ab9b), +W64LIT(0x06b189b2e19975dd), +W64LIT(0x380acc1655df5d10), +W64LIT(0x1092819ae7523e47), +W64LIT(0xd3c9125af7d6031d), +W64LIT(0xd1a6c634a8a18356), +W64LIT(0x5ff0c3252c9eec75), +W64LIT(0x82c1e280b3f8856c), +W64LIT(0xed7257fe43902bd0), +W64LIT(0x3cd491caeb31a886), +/* box 6 */ +W64LIT(0x94af9eb6fad9e7df), +W64LIT(0x9208ae5e03c94ddd), +W64LIT(0x1d8de8d67158480b), +W64LIT(0xfd093cd2ba147af8), +W64LIT(0xa45ceb22e6597ccf), +W64LIT(0x9bbde6e77bf113da), +W64LIT(0xe4edf4b465fffe5c), +W64LIT(0x7125622e4e8d2a2f), +W64LIT(0x1791b81b8f68430d), +W64LIT(0xb56a63d1902195c0), +W64LIT(0xa980832b30d2ee67), +W64LIT(0x4c0a7fb384862397), +W64LIT(0xed58bc0d1dc7a05b), +W64LIT(0x5955d7f05c4d0637), +W64LIT(0xd2b9b1c8806fcf4e), +W64LIT(0x06a730e8f910aa02), +W64LIT(0xb8b60bd846aa0768), +W64LIT(0x45bf370afcbe7d90), +W64LIT(0x16f6b0375ec370a1), +W64LIT(0x892276608b81afd4), +W64LIT(0xdcccc1b5d0ec08e7), +W64LIT(0xe856949162df5f58), +W64LIT(0x82592e81a41a977e), +W64LIT(0xac8eabb74fca1164), +W64LIT(0xfac9041692afe356), +W64LIT(0x3b882d75331ba3ba), +W64LIT(0xa39cd3e6cee2e561), +W64LIT(0xd077a190d7cca9e3), +W64LIT(0x9c7dde23534a8a74), +W64LIT(0x80973ed9f3b9f1d3), +W64LIT(0xce535132209cb4e9), +W64LIT(0xaa299b5fb6dabb66), +W64LIT(0x2d7e9d426dd8d31b), +W64LIT(0x8a8b6e140d89fad5), +W64LIT(0x6ca88af83fd56224), +W64LIT(0xf5db7c4713871753), +W64LIT(0xeef1a4799bcff55a), +W64LIT(0x76e55aea6636b381), +W64LIT(0x8ee24ea4a33a367a), +W64LIT(0x25acddd7c44bbeb0), +W64LIT(0x9adaeecbaa5a2076), +W64LIT(0x0e75707d5083c7a9), +W64LIT(0x2bd9adaa94c87919), +W64LIT(0x19e4c866dfeb84a4), +W64LIT(0x129f9087f070bc0e), +W64LIT(0xd9c2e929aff4f7e4), +W64LIT(0x6f01928cb9dd3725), +W64LIT(0x39463d2d64b8c517), +W64LIT(0xebff8ce5e4d70a59), +W64LIT(0xb40d6bfd418aa66c), +W64LIT(0xf21b44833b3c8efd), +W64LIT(0x3654457ce5903112), +W64LIT(0x431807e205aed792), +W64LIT(0xb10343613e92596f), +W64LIT(0x0a1c50cdfe300b06), +W64LIT(0x778252c6b79d802d), +W64LIT(0x0cbb60250720a104), +W64LIT(0xe1e3dc281ae7015f), +W64LIT(0x0f1278518128f405), +W64LIT(0x47712752ab1d1b3d), +W64LIT(0xe24ac45c9cef545e), +W64LIT(0x1ceae0faa0f37ba7), +W64LIT(0x9814fe93fdf946db), +W64LIT(0xec3fb421cc6c93f7), +W64LIT(0x833e26ad75b1a4d2), +W64LIT(0x6b68b23c176efb8a), +W64LIT(0x4904572ffb9edc94), +W64LIT(0x4bca4777ac3dba39), +W64LIT(0x2762cd8f93e8d81d), +W64LIT(0x9eb3ce7b04e9ecd9), +W64LIT(0xc2e8311727bc15ed), +W64LIT(0xea9884c9357c39f5), +W64LIT(0xfc6e34fe6bbf4954), +W64LIT(0x13f898ab21db8fa2), +W64LIT(0xb7a47389c782f36d), +W64LIT(0x7b3932e3b0bd2129), +W64LIT(0xaf27b3c3c9c24465), +W64LIT(0xb6c37ba51629c0c1), +W64LIT(0x84fe1e695d0a3d7c), +W64LIT(0x1a4dd01259e3d1a5), +W64LIT(0xab4e9373677188ca), +W64LIT(0x90c6be06546a2b70), +W64LIT(0xf37c4cafea97bd51), +W64LIT(0x647aca6d96460f8f), +W64LIT(0x4ec46febd325453a), +W64LIT(0x3e8605e94c035cb9), +W64LIT(0x0ddc6809d68b92a8), +W64LIT(0x8bec6638dc22c979), +W64LIT(0x67d3d219104e5a8e), +W64LIT(0x2abea58645634ab5), +W64LIT(0x5b9bc7a80bee609a), +W64LIT(0x936fa672d2627e71), +W64LIT(0x7d9e020b49ad8b2b), +W64LIT(0x5832dfdc8de6359b), +W64LIT(0xc7e6198b58a4eaee), +W64LIT(0xd41e8120797f654c), +W64LIT(0xf4bc746bc22c24ff), +W64LIT(0xe084d404cb4c32f3), +W64LIT(0x48635f032a35ef38), +W64LIT(0x8757061ddb02687d), +W64LIT(0x522e8f1173d63e9d), +W64LIT(0xbcdf2b68e819cbc7), +W64LIT(0xbf76331c6e119ec6), +W64LIT(0x08d24095a9936dab), +W64LIT(0x728c7a5ac8857f2e), +W64LIT(0xd110a9bc06679a4f), +W64LIT(0x1f43f88e26fb2ea6), +W64LIT(0xb2aa5b15b89a0c6e), +W64LIT(0x4aad4f5b7d968995), +W64LIT(0x9fd4c657d542df75), +W64LIT(0x323d65cc4b23fdbd), +W64LIT(0xc38f393bf6172641), +W64LIT(0xa152c3be994183cc), +W64LIT(0x9d1ad60f82e1b9d8), +W64LIT(0xe744ecc0e3f7ab5d), +W64LIT(0x38213501b513f6bb), +W64LIT(0xade9a39b9e6122c8), +W64LIT(0x37334d50343b02be), +W64LIT(0x55eeb7d55b6da733), +W64LIT(0x970686c27cd1b2de), +W64LIT(0x427f0fced405e43e), +W64LIT(0xc026214f701f7340), +W64LIT(0x40b11f9683a68293), +W64LIT(0x02ce105857a366ad), +W64LIT(0x7e371a7fcfa5de2a), +W64LIT(0xffc72c8aedb71c55), +W64LIT(0x68c1aa489166ae8b), +W64LIT(0xc68111a7890fd942), +W64LIT(0x79f722bbe71e4784), +W64LIT(0xd579890ca8d456e0), +W64LIT(0x70426a029f261983), +W64LIT(0xb0644b4def396ac3), +W64LIT(0xdb0cf971f8579149), +W64LIT(0x5489bff98ac6949f), +W64LIT(0x046920b0aeb3ccaf), +W64LIT(0x7cf90a279806b887), +W64LIT(0x050e289c7f18ff03), +W64LIT(0x651dc24147ed3c23), +W64LIT(0x5e95ef3474f69f99), +W64LIT(0x6dcf82d4ee7e5188), +W64LIT(0x8f854688729105d6), +W64LIT(0x81f036f52212c27f), +W64LIT(0xb9d103f4970134c4), +W64LIT(0x5349873da27d0d31), +W64LIT(0x20a2f54bbb5341b3), +W64LIT(0xf0d554db6c9fe850), +W64LIT(0x07c038c428bb99ae), +W64LIT(0x30f375941c809b10), +W64LIT(0x3fe10dc59da86f15), +W64LIT(0x46162f7e7ab62891), +W64LIT(0xe623e4ec325c98f1), +W64LIT(0xfea024a63c1c2ff9), +W64LIT(0x349a5524b23357bf), +W64LIT(0x35fd5d0863986413), +W64LIT(0x96618eeead7a8172), +W64LIT(0xcb5d79ae5f844bea), +W64LIT(0x21c5fd676af8721f), +W64LIT(0x5720a78d0ccec19e), +W64LIT(0xf6726433958f4252), +W64LIT(0x8d4b56d02532637b), +W64LIT(0x24cbd5fb15e08d1c), +W64LIT(0x3aef2559e2b09016), +W64LIT(0x5afccf84da455336), +W64LIT(0x51879765f5de6b9c), +W64LIT(0x2917bdf2c36b1fb4), +W64LIT(0xa7f5f356605129ce), +W64LIT(0xc1412963a1b440ec), +W64LIT(0x3d2f1d9dca0b09b8), +W64LIT(0xa53be30e37f24f63), +W64LIT(0x5ff2e718a55dac35), +W64LIT(0xa2fbdbca1f49d6cd), +W64LIT(0xf7156c1f442471fe), +W64LIT(0x7a5e3acf61161285), +W64LIT(0xca3a71828e2f7846), +W64LIT(0x1b2ad83e8848e209), +W64LIT(0xa8e78b07e179ddcb), +W64LIT(0xef96ac554a64c6f6), +W64LIT(0x0000000000000000), +W64LIT(0x6013eadd38f5c320), +W64LIT(0x3c4815b11ba03a14), +W64LIT(0x09b548b978385e07), +W64LIT(0x226ce513ecf0271e), +W64LIT(0x63baf2a9befd9621), +W64LIT(0x44d83f262d154e3c), +W64LIT(0xcdfa4946a694e1e8), +W64LIT(0x113688f37678e90f), +W64LIT(0x859916458ca10ed0), +W64LIT(0xc52809d30f078c43), +W64LIT(0x4d6d779f552d103b), +W64LIT(0x1e24f0a2f7501d0a), +W64LIT(0x0167082cd1ab33ac), +W64LIT(0x1438a06f0960160c), +W64LIT(0xf9601c6214a7b657), +W64LIT(0xa035cb9248eab060), +W64LIT(0x50e09f4924755830), +W64LIT(0xd7b79954ff77304d), +W64LIT(0xe58afc98b454cdf0), +W64LIT(0x03a9187486085501), +W64LIT(0x62ddfa856f56a58d), +W64LIT(0xc44f01ffdeacbfef), +W64LIT(0x73eb7276192e4c82), +W64LIT(0xd6d091782edc03e1), +W64LIT(0xfbae0c3a4304d0fa), +W64LIT(0x9973f6bf2c527577), +W64LIT(0x105180dfa7d3daa3), +W64LIT(0x2605c5a34243ebb1), +W64LIT(0x91a1b62a85c118dc), +W64LIT(0xc99369f608272d47), +W64LIT(0x5d3cf740f2feca98), +W64LIT(0xcf34591ef1378745), +W64LIT(0xc8f461dad98c1eeb), +W64LIT(0x0b7b58e12f9b38aa), +W64LIT(0xe32dcc704d4467f2), +W64LIT(0x754c429ee03ee680), +W64LIT(0xd3deb9e451c4fce2), +W64LIT(0x6e669aa068760489), +W64LIT(0x66b4da35c1e56922), +W64LIT(0x4fa367c7028e7696), +W64LIT(0xba781b80110961c5), +W64LIT(0x41d617ba520db13f), +W64LIT(0x335a6de09a88ce11), +W64LIT(0xdf65d9c156e45de6), +W64LIT(0xcc9d416a773fd244), +W64LIT(0x5c5bff6c2355f934), +W64LIT(0x2870b5de12c02c18), +W64LIT(0x155fa843d8cb25a0), +W64LIT(0x78902a9736b57428), +W64LIT(0xae40bbef186977c9), +W64LIT(0x88457e4c5a2a9c78), +W64LIT(0x6a0fba10c6c5c826), +W64LIT(0x7f5012531e0eed86), +W64LIT(0x8c2c5efcf49950d7), +W64LIT(0x31947db8cd2ba8bc), +W64LIT(0x2c19956ebc73e0b7), +W64LIT(0x230bed3f3d5b14b2), +W64LIT(0x69a6a26440cd9d27), +W64LIT(0x86300e310aa95bd1), +W64LIT(0xb3cd533969313fc2), +W64LIT(0x1883c04a0e40b708), +W64LIT(0xf1b25cf7bd34dbfc), +W64LIT(0x2fb08d1a3a7bb5b6), +W64LIT(0xd8a5e1057e5fc448), +W64LIT(0xddabc99901473b4b), +W64LIT(0xde02d1ed874f6e4a), +W64LIT(0xbdb8234439b2f86b), +W64LIT(0x5647afa1dd65f232), +W64LIT(0x2ed78536ebd0861a), +W64LIT(0xe9319cbdb3746cf4), +W64LIT(0xa692fb7ab1fa1a62), +W64LIT(0x742b4ab23195d52c), +W64LIT(0x95c8969a2b72d473), +W64LIT(0x6174e2f1e95ef08c), +W64LIT(0xf807144ec50c85fb), +W64LIT(0xbe113b30bfbaad6a), +W64LIT(0xda6bf15d29fca2e5), +W64LIT(0xbb1f13acc0a25269), +/* box 7 */ +W64LIT(0xc22b27f0f9e37bf9), +W64LIT(0x93fad23f0955ef09), +W64LIT(0x32ed4b84a22a91a2), +W64LIT(0x3898b57bcc61b1cc), +W64LIT(0x55825ba9ad98e5ad), +W64LIT(0xb2eeb8069421ec94), +W64LIT(0xc7eb5875ce3c6bce), +W64LIT(0x4b1dac5d1f45851f), +W64LIT(0xc16ba1204705d847), +W64LIT(0xc5380f461a2ba91a), +W64LIT(0xb908971a909bad90), +W64LIT(0x303e1cb7763d5376), +W64LIT(0xe6ff324c53486853), +W64LIT(0x6d1aeed261f95461), +W64LIT(0x0193d1e36af1616a), +W64LIT(0x51d1f5cff0b694f0), +W64LIT(0x29b2c3f52728e127), +W64LIT(0x112a768eeb4950eb), +W64LIT(0x8fb672f86f9f4d6f), +W64LIT(0xf0c66c745bc9ea5b), +W64LIT(0x3f8b9dcd2fa9632f), +W64LIT(0x65bc471edba5b6db), +W64LIT(0x4d9d5508967c3696), +W64LIT(0x3a4be24818767318), +W64LIT(0x2794936c144db014), +W64LIT(0x2af2452599ce4299), +W64LIT(0x4a8e7dbe75b4e475), +W64LIT(0x9ddc82a63a30be3a), +W64LIT(0xade29e114c0ded4c), +W64LIT(0xd1d2064dc6bde9c6), +W64LIT(0x7da349bfe04165e0), +W64LIT(0x6b9a1787e8c0e7e8), +W64LIT(0xa54437ddf6510ff6), +W64LIT(0x2254ece92392a023), +W64LIT(0x79f0e7d9bd6f14bd), +W64LIT(0x57510c9a798f2779), +W64LIT(0x346db2d12b13222b), +W64LIT(0x54118a4ac76984c7), +W64LIT(0xefca4a6383e5eb83), +W64LIT(0xca8d8e3c43bf9943), +W64LIT(0xfc336bdebcbb79bc), +W64LIT(0x3e184c2e45580245), +W64LIT(0xf495c21206e79b06), +W64LIT(0xff73ed0e025dda02), +W64LIT(0x4228d472cfe806cf), +W64LIT(0xbcc8e89fa744bda7), +W64LIT(0xab626744c5345ec5), +W64LIT(0xb6bd1660c90f9dc9), +W64LIT(0xb72ec783a3fefca3), +W64LIT(0x8be5dc9e32b13c32), +W64LIT(0x485d2a8da1a326a1), +W64LIT(0xc6788996a4cd0aa4), +W64LIT(0x40fb83411bffc41b), +W64LIT(0x08a6a9ccba5ce2ba), +W64LIT(0xf386eaa4e52f49e5), +W64LIT(0x1acc5992eff311ef), +W64LIT(0xa2571f6b1599dd15), +W64LIT(0x44a82d2746d1b546), +W64LIT(0x70c59ff66dc2976d), +W64LIT(0x8d6525cbbb888fbb), +W64LIT(0x963aadba3e8aff3e), +W64LIT(0x7c30985c8ab0048a), +W64LIT(0x607c389bec7aa6ec), +W64LIT(0xa822e1947bd2fd7b), +W64LIT(0x034086d0bee6a3be), +W64LIT(0x66fcc1ce65431565), +W64LIT(0xb37d69e5fed08dfe), +W64LIT(0x2f323aa0ae1152ae), +W64LIT(0x56c2dd79137e4613), +W64LIT(0x31adcd541ccc321c), +W64LIT(0xdff456d4f5d8b8f5), +W64LIT(0xf9f3145b8b64698b), +W64LIT(0x764566a3e4fb24e4), +W64LIT(0x0cf507aae77293e7), +W64LIT(0x59775c034aea764a), +W64LIT(0xb89b46f9fa6accfa), +W64LIT(0xe8d962d5602d3960), +W64LIT(0x17aa8fdb6270e362), +W64LIT(0x1c4ca0c766caa266), +W64LIT(0x2de16d937a06907a), +W64LIT(0x2547c45fc05a72c0), +W64LIT(0x0fb5817a59943059), +W64LIT(0x0680f9558939b389), +W64LIT(0x16395e3808818208), +W64LIT(0xac714ff226fc8c26), +W64LIT(0xa9b1307711239c11), +W64LIT(0xec8accb33d03483d), +W64LIT(0x6c893f310b08350b), +W64LIT(0xc4abdea570dac870), +W64LIT(0xba4811ca2e7d0e2e), +W64LIT(0xf155bd9731388b31), +W64LIT(0xdd2701e721cf7a21), +W64LIT(0xe94ab3360adc580a), +W64LIT(0x23c73d0a4963c149), +W64LIT(0x5cb723867d35667d), +W64LIT(0x5042242c9a47f59a), +W64LIT(0x198cdf425115b251), +W64LIT(0x0a75feff6e4b206e), +W64LIT(0xfda0ba3dd64a18d6), +W64LIT(0xcede205a1e91e81e), +W64LIT(0xd041d7aeac4c88ac), +W64LIT(0xe42c657f875faa87), +W64LIT(0x36bee5e2ff04e0ff), +W64LIT(0x6fc9b9e1b5ee96b5), +W64LIT(0x998f2cc0671ecf67), +W64LIT(0xd301517e12aa2b12), +W64LIT(0xaea218c1f2eb4ef2), +W64LIT(0xda342951c207a8c2), +W64LIT(0x61efe978868bc786), +W64LIT(0x7f701e8c3456a734), +W64LIT(0x0be62f1c04ba4104), +W64LIT(0x9129850cdd422ddd), +W64LIT(0xd6c12efb25753b25), +W64LIT(0xe33f4dc964977864), +W64LIT(0x1579d8e8b66721b6), +W64LIT(0xf860c5b8e19508e1), +W64LIT(0x7496319030ece630), +W64LIT(0x88a55a4e8c579f8c), +W64LIT(0xcf4df1b974608974), +W64LIT(0x10b9a76d81b83181), +W64LIT(0x0e26509933655133), +W64LIT(0x43bb0591a51967a5), +W64LIT(0x926903dc63a48e63), +W64LIT(0x9c4f534550c1df50), +W64LIT(0x3bd833ab72871272), +W64LIT(0xa4d7e63e9ca06e9c), +W64LIT(0xb46e41531d185f1d), +W64LIT(0x126af05e55aff355), +W64LIT(0x24d415bcaaab13aa), +W64LIT(0x1e9ff7f4b2dd60b2), +W64LIT(0x05c07f8537df1037), +W64LIT(0x467b7a1492c67792), +W64LIT(0x2087bbdaf78562f7), +W64LIT(0x819022615cfa1c5c), +W64LIT(0xcd9ea68aa0774ba0), +W64LIT(0xa79760ee2246cd22), +W64LIT(0x8343755288edde88), +W64LIT(0x58e48de0201b1720), +W64LIT(0x7216c8c5b9d555b9), +W64LIT(0x372d340195f58195), +W64LIT(0xa11799bbab7f7eab), +W64LIT(0x9f0fd595ee277cee), +W64LIT(0x676f102d0fb2740f), +W64LIT(0x9e9c047684d61d84), +W64LIT(0x49cefb6ecb5247cb), +W64LIT(0xd41279c8f162f9f1), +W64LIT(0x1f0c2617d82c01d8), +W64LIT(0x97a97c59547b9e54), +W64LIT(0xe76ce3af39b90939), +W64LIT(0xc3b8f61393121a93), +W64LIT(0x5ba40b309efdb49e), +W64LIT(0xea0a35e6b43afbb4), +W64LIT(0x5a37dad3f40cd5f4), +W64LIT(0x14ea090bdc9640dc), +W64LIT(0x5e6474b5a922a4a9), +W64LIT(0xfee03ced68acbb68), +W64LIT(0x071328b6e3c8d2e3), +W64LIT(0x5302a2fc24a15624), +W64LIT(0x85c38c0701d46d01), +W64LIT(0x3d58cafefbbea1fb), +W64LIT(0x84505de46b250c6b), +W64LIT(0x642f96fdb154d7b1), +W64LIT(0xbf886e4f19a21e19), +W64LIT(0x02d35733d417c2d4), +W64LIT(0x68da915756264456), +W64LIT(0x8710db34d5c3afd5), +W64LIT(0x0d66d6498d83f28d), +W64LIT(0x7b23b0ea6978d669), +W64LIT(0x1b5f887185027085), +W64LIT(0x3ccb1b1d914fc091), +W64LIT(0x0453ae665d2e715d), +W64LIT(0xcb1e5fdf294ef829), +W64LIT(0xf6469521d2f059d2), +W64LIT(0xb03def3540362e40), +W64LIT(0x633cbe4b529c0552), +W64LIT(0xf7d544c2b80138b8), +W64LIT(0x7ab061090389b703), +W64LIT(0x0000000000000000), +W64LIT(0xdba7f8b2a8f6c9a8), +W64LIT(0x35fe633241e24341), +W64LIT(0x21146a399d74039d), +W64LIT(0xd581a82b9b93989b), +W64LIT(0x0935782fd0ad83d0), +W64LIT(0x5ff7a556c3d3c5c3), +W64LIT(0xaf31c922981a2f98), +W64LIT(0x90ba54efb7b34cb7), +W64LIT(0x5291731f4e50374e), +W64LIT(0xc0f870c32df4b92d), +W64LIT(0x7ee3cf6f5ea7c65e), +W64LIT(0xe07fcb19da71dbda), +W64LIT(0x4eddd3d8289a9528), +W64LIT(0x13f921bd3f5e923f), +W64LIT(0xf50613f16c16fa6c), +W64LIT(0x981cfd230defae0d), +W64LIT(0x4c0e84ebfc8d57fc), +W64LIT(0x82d0a4b1e21cbfe2), +W64LIT(0x89368bade6a6fee6), +W64LIT(0xd292809d785b4a78), +W64LIT(0x47e8abf7f83716f8), +W64LIT(0x8e25a31b056e2c05), +W64LIT(0xd752ff184f845a4f), +W64LIT(0xcc0d7769ca862aca), +W64LIT(0x694940b43cd7253c), +W64LIT(0x2ea1eb43c4e033c4), +W64LIT(0xde6787379f29d99f), +W64LIT(0x181f0ea13be4d33b), +W64LIT(0x416852a2710ea571), +W64LIT(0x62af6fa8386d6438), +W64LIT(0xa0844858c18e1fc1), +W64LIT(0x337e9a67c8dbf0c8), +W64LIT(0x2c72bc7010f7f110), +W64LIT(0xbd5b397ccdb5dccd), +W64LIT(0xd8e77e6216106a16), +W64LIT(0x86830ad7bf32cebf), +W64LIT(0x4f4e023b426bf442), +W64LIT(0xe5bfb49cedaecbed), +W64LIT(0x8a760d7d58405d58), +W64LIT(0xe2ac9c2a0e66190e), +W64LIT(0xb5fd90b077e93e77), +W64LIT(0xdcb4d0044b3e1b4b), +W64LIT(0x453bfcc42c20d42c), +W64LIT(0xed191d5057f22957), +W64LIT(0xe1ec1afab080bab0), +W64LIT(0xee599b80e9148ae9), +W64LIT(0x2607428f7ebcd17e), +W64LIT(0x5d24f26517c40717), +W64LIT(0x6a09c66482318682), +W64LIT(0xa604b10d48b7ac48), +W64LIT(0xbe1bbfac73537f73), +W64LIT(0x282112164dd9804d), +W64LIT(0x7505e0735a1d875a), +W64LIT(0x73851926d32434d3), +W64LIT(0xd974af817ce10b7c), +W64LIT(0xeb99e405decb9ade), +W64LIT(0x9b5c7bf3b3090db3), +W64LIT(0xfab3928b3582ca35), +W64LIT(0x8003f382360b7d36), +W64LIT(0x94e9fa89ea9d3dea), +W64LIT(0xb1ae3ed62ac74f2a), +W64LIT(0x9acfaa10d9f86cd9), +W64LIT(0x390b6498a690d0a6), +W64LIT(0xf2153b478fde288f), +W64LIT(0x71564e150733f607), +W64LIT(0xa3c4ce887f68bc7f), +W64LIT(0xaaf1b6a7afc53faf), +W64LIT(0x1ddf71240c3bc30c), +W64LIT(0x77d6b7408e0a458e), +W64LIT(0x2b6194c6f33f23f3), +W64LIT(0xc9cd08ecfd593afd), +W64LIT(0xc85ed90f97a85b97), +W64LIT(0x8cf6f428d179eed1), +W64LIT(0x957a2b6a806c5c80), +W64LIT(0xbbdbc029448c6f44), +W64LIT(0x7863363ad79e75d7), +W64LIT(0x6e5a6802df1ff7df), +W64LIT(0xfb2043685f73ab5f), +}; + +NAMESPACE_END + +#endif // WORD64_AVAILABLE diff --git a/CryptoPP/crypto/sharkval.dat b/CryptoPP/crypto/sharkval.dat new file mode 100644 index 0000000..59106c4 --- /dev/null +++ b/CryptoPP/crypto/sharkval.dat @@ -0,0 +1,7 @@ +00000000000000000000000000000000 0000000000000000 214BCF4E7716420A +000102030405060708090A0B0C0D0E0F 0000000000000000 C76C696289898137 +000102030405060708090A0B0C0D0E0F C76C696289898137 077A4A59FAEEEA4D +915F4619BE41B2516355A50110A9CE91 21A5DBEE154B8F6D 6FF33B98F448E95A +783348E75AEB0F2FD7B169BB8DC16787 F7C013AC5B2B8952 E5E554ABE9CED2D2 +DC49DB1375A5584F6485B413B5F12BAF 2F42B3B70369FC92 9AE068313F343A7A +5269F149D41BA0152497574D7F153125 65C178B284D197CC D3F111A282F17F29 diff --git a/CryptoPP/crypto/simple.cpp b/CryptoPP/crypto/simple.cpp new file mode 100644 index 0000000..d0a120d --- /dev/null +++ b/CryptoPP/crypto/simple.cpp @@ -0,0 +1,14 @@ +// simple.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "simple.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/simple.h b/CryptoPP/crypto/simple.h new file mode 100644 index 0000000..2686907 --- /dev/null +++ b/CryptoPP/crypto/simple.h @@ -0,0 +1,209 @@ +// simple.h - written and placed in the public domain by Wei Dai +/*! \file + Simple non-interface classes derived from classes in cryptlib.h. +*/ + +#ifndef CRYPTOPP_SIMPLE_H +#define CRYPTOPP_SIMPLE_H + +#include "cryptlib.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! _ +template +class CRYPTOPP_NO_VTABLE ClonableImpl : public BASE +{ +public: + Clonable * Clone() const {return new DERIVED(*static_cast(this));} +}; + +//! _ +template +class CRYPTOPP_NO_VTABLE AlgorithmImpl : public BASE +{ +public: + static std::string CRYPTOPP_API StaticAlgorithmName() {return ALGORITHM_INFO::StaticAlgorithmName();} + std::string AlgorithmName() const {return ALGORITHM_INFO::StaticAlgorithmName();} +}; + +//! _ +class CRYPTOPP_DLL InvalidKeyLength : public InvalidArgument +{ +public: + explicit InvalidKeyLength(const std::string &algorithm, size_t length) : InvalidArgument(algorithm + ": " + IntToString(length) + " is not a valid key length") {} +}; + +//! _ +class CRYPTOPP_DLL InvalidRounds : public InvalidArgument +{ +public: + explicit InvalidRounds(const std::string &algorithm, unsigned int rounds) : InvalidArgument(algorithm + ": " + IntToString(rounds) + " is not a valid number of rounds") {} +}; + +// ***************************** + +//! _ +template +class CRYPTOPP_NO_VTABLE Bufferless : public T +{ +public: + bool IsolatedFlush(bool hardFlush, bool blocking) {return false;} +}; + +//! _ +template +class CRYPTOPP_NO_VTABLE Unflushable : public T +{ +public: + bool Flush(bool completeFlush, int propagation=-1, bool blocking=true) + {return ChannelFlush(this->NULL_CHANNEL, completeFlush, propagation, blocking);} + bool IsolatedFlush(bool hardFlush, bool blocking) + {assert(false); return false;} + bool ChannelFlush(const std::string &channel, bool hardFlush, int propagation=-1, bool blocking=true) + { + if (hardFlush && !InputBufferIsEmpty()) + throw CannotFlush("Unflushable: this object has buffered input that cannot be flushed"); + else + { + BufferedTransformation *attached = this->AttachedTransformation(); + return attached && propagation ? attached->ChannelFlush(channel, hardFlush, propagation-1, blocking) : false; + } + } + +protected: + virtual bool InputBufferIsEmpty() const {return false;} +}; + +//! _ +template +class CRYPTOPP_NO_VTABLE InputRejecting : public T +{ +public: + struct InputRejected : public NotImplemented + {InputRejected() : NotImplemented("BufferedTransformation: this object doesn't allow input") {}}; + + // shouldn't be calling these functions on this class + size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking) + {throw InputRejected();} + bool IsolatedFlush(bool, bool) {return false;} + bool IsolatedMessageSeriesEnd(bool) {throw InputRejected();} + + size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking) + {throw InputRejected();} + bool ChannelMessageSeriesEnd(const std::string &, int, bool) {throw InputRejected();} +}; + +//! _ +template +class CRYPTOPP_NO_VTABLE CustomFlushPropagation : public T +{ +public: + virtual bool Flush(bool hardFlush, int propagation=-1, bool blocking=true) =0; + +private: + bool IsolatedFlush(bool hardFlush, bool blocking) {assert(false); return false;} +}; + +//! _ +template +class CRYPTOPP_NO_VTABLE CustomSignalPropagation : public CustomFlushPropagation +{ +public: + virtual void Initialize(const NameValuePairs ¶meters=g_nullNameValuePairs, int propagation=-1) =0; + +private: + void IsolatedInitialize(const NameValuePairs ¶meters) {assert(false);} +}; + +//! _ +template +class CRYPTOPP_NO_VTABLE Multichannel : public CustomFlushPropagation +{ +public: + bool Flush(bool hardFlush, int propagation=-1, bool blocking=true) + {return ChannelFlush(this->NULL_CHANNEL, hardFlush, propagation, blocking);} + bool MessageSeriesEnd(int propagation=-1, bool blocking=true) + {return ChannelMessageSeriesEnd(this->NULL_CHANNEL, propagation, blocking);} + byte * CreatePutSpace(size_t &size) + {return ChannelCreatePutSpace(this->NULL_CHANNEL, size);} + size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking) + {return ChannelPut2(this->NULL_CHANNEL, begin, length, messageEnd, blocking);} + size_t PutModifiable2(byte *inString, size_t length, int messageEnd, bool blocking) + {return ChannelPutModifiable2(this->NULL_CHANNEL, inString, length, messageEnd, blocking);} + +// void ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1) +// {PropagateMessageSeriesEnd(propagation, channel);} + byte * ChannelCreatePutSpace(const std::string &channel, size_t &size) + {size = 0; return NULL;} + bool ChannelPutModifiable(const std::string &channel, byte *inString, size_t length) + {this->ChannelPut(channel, inString, length); return false;} + + virtual size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking) =0; + size_t ChannelPutModifiable2(const std::string &channel, byte *begin, size_t length, int messageEnd, bool blocking) + {return ChannelPut2(channel, begin, length, messageEnd, blocking);} + + virtual bool ChannelFlush(const std::string &channel, bool hardFlush, int propagation=-1, bool blocking=true) =0; +}; + +//! _ +template +class CRYPTOPP_NO_VTABLE AutoSignaling : public T +{ +public: + AutoSignaling(int propagation=-1) : m_autoSignalPropagation(propagation) {} + + void SetAutoSignalPropagation(int propagation) + {m_autoSignalPropagation = propagation;} + int GetAutoSignalPropagation() const + {return m_autoSignalPropagation;} + +private: + int m_autoSignalPropagation; +}; + +//! A BufferedTransformation that only contains pre-existing data as "output" +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Store : public AutoSignaling > +{ +public: + Store() : m_messageEnd(false) {} + + void IsolatedInitialize(const NameValuePairs ¶meters) + { + m_messageEnd = false; + StoreInitialize(parameters); + } + + unsigned int NumberOfMessages() const {return m_messageEnd ? 0 : 1;} + bool GetNextMessage(); + unsigned int CopyMessagesTo(BufferedTransformation &target, unsigned int count=UINT_MAX, const std::string &channel=NULL_CHANNEL) const; + +protected: + virtual void StoreInitialize(const NameValuePairs ¶meters) =0; + + bool m_messageEnd; +}; + +//! A BufferedTransformation that doesn't produce any retrievable output +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Sink : public BufferedTransformation +{ +public: + size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=NULL_CHANNEL, bool blocking=true) + {transferBytes = 0; return 0;} + size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=NULL_CHANNEL, bool blocking=true) const + {return 0;} +}; + +class CRYPTOPP_DLL BitBucket : public Bufferless +{ +public: + std::string AlgorithmName() const {return "BitBucket";} + void IsolatedInitialize(const NameValuePairs ¶meters) {} + size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking) + {return 0;} +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/skipjack.cpp b/CryptoPP/crypto/skipjack.cpp new file mode 100644 index 0000000..e0a0e01 --- /dev/null +++ b/CryptoPP/crypto/skipjack.cpp @@ -0,0 +1,202 @@ +// skipjack.cpp - modified by Wei Dai from Paulo Barreto's skipjack32.c, +// which is public domain according to his web site. + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "skipjack.h" + +/* + * Optimized implementation of SKIPJACK algorithm + * + * originally written by Panu Rissanen 1998.06.24 + * optimized by Mark Tillotson 1998.06.25 + * optimized by Paulo Barreto 1998.06.30 + */ + +NAMESPACE_BEGIN(CryptoPP) + +/** + * The F-table byte permutation (see description of the G-box permutation) + */ +const byte SKIPJACK::Base::fTable[256] = { + 0xa3,0xd7,0x09,0x83,0xf8,0x48,0xf6,0xf4,0xb3,0x21,0x15,0x78,0x99,0xb1,0xaf,0xf9, + 0xe7,0x2d,0x4d,0x8a,0xce,0x4c,0xca,0x2e,0x52,0x95,0xd9,0x1e,0x4e,0x38,0x44,0x28, + 0x0a,0xdf,0x02,0xa0,0x17,0xf1,0x60,0x68,0x12,0xb7,0x7a,0xc3,0xe9,0xfa,0x3d,0x53, + 0x96,0x84,0x6b,0xba,0xf2,0x63,0x9a,0x19,0x7c,0xae,0xe5,0xf5,0xf7,0x16,0x6a,0xa2, + 0x39,0xb6,0x7b,0x0f,0xc1,0x93,0x81,0x1b,0xee,0xb4,0x1a,0xea,0xd0,0x91,0x2f,0xb8, + 0x55,0xb9,0xda,0x85,0x3f,0x41,0xbf,0xe0,0x5a,0x58,0x80,0x5f,0x66,0x0b,0xd8,0x90, + 0x35,0xd5,0xc0,0xa7,0x33,0x06,0x65,0x69,0x45,0x00,0x94,0x56,0x6d,0x98,0x9b,0x76, + 0x97,0xfc,0xb2,0xc2,0xb0,0xfe,0xdb,0x20,0xe1,0xeb,0xd6,0xe4,0xdd,0x47,0x4a,0x1d, + 0x42,0xed,0x9e,0x6e,0x49,0x3c,0xcd,0x43,0x27,0xd2,0x07,0xd4,0xde,0xc7,0x67,0x18, + 0x89,0xcb,0x30,0x1f,0x8d,0xc6,0x8f,0xaa,0xc8,0x74,0xdc,0xc9,0x5d,0x5c,0x31,0xa4, + 0x70,0x88,0x61,0x2c,0x9f,0x0d,0x2b,0x87,0x50,0x82,0x54,0x64,0x26,0x7d,0x03,0x40, + 0x34,0x4b,0x1c,0x73,0xd1,0xc4,0xfd,0x3b,0xcc,0xfb,0x7f,0xab,0xe6,0x3e,0x5b,0xa5, + 0xad,0x04,0x23,0x9c,0x14,0x51,0x22,0xf0,0x29,0x79,0x71,0x7e,0xff,0x8c,0x0e,0xe2, + 0x0c,0xef,0xbc,0x72,0x75,0x6f,0x37,0xa1,0xec,0xd3,0x8e,0x62,0x8b,0x86,0x10,0xe8, + 0x08,0x77,0x11,0xbe,0x92,0x4f,0x24,0xc5,0x32,0x36,0x9d,0xcf,0xf3,0xa6,0xbb,0xac, + 0x5e,0x6c,0xa9,0x13,0x57,0x25,0xb5,0xe3,0xbd,0xa8,0x3a,0x01,0x05,0x59,0x2a,0x46 +}; + +/** + * The key-dependent permutation G on V^16 is a four-round Feistel network. + * The round function is a fixed byte-substitution table (permutation on V^8), + * the F-table. Each round of G incorporates a single byte from the key. + */ +#define g(tab, w, i, j, k, l) \ +{ \ + w ^= (word)tab[i][w & 0xff] << 8; \ + w ^= (word)tab[j][w >> 8]; \ + w ^= (word)tab[k][w & 0xff] << 8; \ + w ^= (word)tab[l][w >> 8]; \ +} + +#define g0(tab, w) g(tab, w, 0, 1, 2, 3) +#define g1(tab, w) g(tab, w, 4, 5, 6, 7) +#define g2(tab, w) g(tab, w, 8, 9, 0, 1) +#define g3(tab, w) g(tab, w, 2, 3, 4, 5) +#define g4(tab, w) g(tab, w, 6, 7, 8, 9) + +/** + * The inverse of the G permutation. + */ +#define h(tab, w, i, j, k, l) \ +{ \ + w ^= (word)tab[l][w >> 8]; \ + w ^= (word)tab[k][w & 0xff] << 8; \ + w ^= (word)tab[j][w >> 8]; \ + w ^= (word)tab[i][w & 0xff] << 8; \ +} + +#define h0(tab, w) h(tab, w, 0, 1, 2, 3) +#define h1(tab, w) h(tab, w, 4, 5, 6, 7) +#define h2(tab, w) h(tab, w, 8, 9, 0, 1) +#define h3(tab, w) h(tab, w, 2, 3, 4, 5) +#define h4(tab, w) h(tab, w, 6, 7, 8, 9) + +/** + * Preprocess a user key into a table to save an XOR at each F-table access. + */ +void SKIPJACK::Base::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &) +{ + AssertValidKeyLength(length); + + /* tab[i][c] = fTable[c ^ key[i]] */ + int i; + for (i = 0; i < 10; i++) { + byte *t = tab[i], k = key[9-i]; + int c; + for (c = 0; c < 256; c++) { + t[c] = fTable[c ^ k]; + } + } +} + +typedef BlockGetAndPut Block; + +/** + * Encrypt a single block of data. + */ +void SKIPJACK::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word16 w1, w2, w3, w4; + Block::Get(inBlock)(w4)(w3)(w2)(w1); + + /* stepping rule A: */ + g0(tab, w1); w4 ^= w1 ^ 1; + g1(tab, w4); w3 ^= w4 ^ 2; + g2(tab, w3); w2 ^= w3 ^ 3; + g3(tab, w2); w1 ^= w2 ^ 4; + g4(tab, w1); w4 ^= w1 ^ 5; + g0(tab, w4); w3 ^= w4 ^ 6; + g1(tab, w3); w2 ^= w3 ^ 7; + g2(tab, w2); w1 ^= w2 ^ 8; + + /* stepping rule B: */ + w2 ^= w1 ^ 9; g3(tab, w1); + w1 ^= w4 ^ 10; g4(tab, w4); + w4 ^= w3 ^ 11; g0(tab, w3); + w3 ^= w2 ^ 12; g1(tab, w2); + w2 ^= w1 ^ 13; g2(tab, w1); + w1 ^= w4 ^ 14; g3(tab, w4); + w4 ^= w3 ^ 15; g4(tab, w3); + w3 ^= w2 ^ 16; g0(tab, w2); + + /* stepping rule A: */ + g1(tab, w1); w4 ^= w1 ^ 17; + g2(tab, w4); w3 ^= w4 ^ 18; + g3(tab, w3); w2 ^= w3 ^ 19; + g4(tab, w2); w1 ^= w2 ^ 20; + g0(tab, w1); w4 ^= w1 ^ 21; + g1(tab, w4); w3 ^= w4 ^ 22; + g2(tab, w3); w2 ^= w3 ^ 23; + g3(tab, w2); w1 ^= w2 ^ 24; + + /* stepping rule B: */ + w2 ^= w1 ^ 25; g4(tab, w1); + w1 ^= w4 ^ 26; g0(tab, w4); + w4 ^= w3 ^ 27; g1(tab, w3); + w3 ^= w2 ^ 28; g2(tab, w2); + w2 ^= w1 ^ 29; g3(tab, w1); + w1 ^= w4 ^ 30; g4(tab, w4); + w4 ^= w3 ^ 31; g0(tab, w3); + w3 ^= w2 ^ 32; g1(tab, w2); + + Block::Put(xorBlock, outBlock)(w4)(w3)(w2)(w1); +} + +/** + * Decrypt a single block of data. + */ +void SKIPJACK::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word16 w1, w2, w3, w4; + Block::Get(inBlock)(w4)(w3)(w2)(w1); + + /* stepping rule A: */ + h1(tab, w2); w3 ^= w2 ^ 32; + h0(tab, w3); w4 ^= w3 ^ 31; + h4(tab, w4); w1 ^= w4 ^ 30; + h3(tab, w1); w2 ^= w1 ^ 29; + h2(tab, w2); w3 ^= w2 ^ 28; + h1(tab, w3); w4 ^= w3 ^ 27; + h0(tab, w4); w1 ^= w4 ^ 26; + h4(tab, w1); w2 ^= w1 ^ 25; + + /* stepping rule B: */ + w1 ^= w2 ^ 24; h3(tab, w2); + w2 ^= w3 ^ 23; h2(tab, w3); + w3 ^= w4 ^ 22; h1(tab, w4); + w4 ^= w1 ^ 21; h0(tab, w1); + w1 ^= w2 ^ 20; h4(tab, w2); + w2 ^= w3 ^ 19; h3(tab, w3); + w3 ^= w4 ^ 18; h2(tab, w4); + w4 ^= w1 ^ 17; h1(tab, w1); + + /* stepping rule A: */ + h0(tab, w2); w3 ^= w2 ^ 16; + h4(tab, w3); w4 ^= w3 ^ 15; + h3(tab, w4); w1 ^= w4 ^ 14; + h2(tab, w1); w2 ^= w1 ^ 13; + h1(tab, w2); w3 ^= w2 ^ 12; + h0(tab, w3); w4 ^= w3 ^ 11; + h4(tab, w4); w1 ^= w4 ^ 10; + h3(tab, w1); w2 ^= w1 ^ 9; + + /* stepping rule B: */ + w1 ^= w2 ^ 8; h2(tab, w2); + w2 ^= w3 ^ 7; h1(tab, w3); + w3 ^= w4 ^ 6; h0(tab, w4); + w4 ^= w1 ^ 5; h4(tab, w1); + w1 ^= w2 ^ 4; h3(tab, w2); + w2 ^= w3 ^ 3; h2(tab, w3); + w3 ^= w4 ^ 2; h1(tab, w4); + w4 ^= w1 ^ 1; h0(tab, w1); + + Block::Put(xorBlock, outBlock)(w4)(w3)(w2)(w1); +} + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/skipjack.dat b/CryptoPP/crypto/skipjack.dat new file mode 100644 index 0000000..3f2f67a --- /dev/null +++ b/CryptoPP/crypto/skipjack.dat @@ -0,0 +1 @@ +11223344556677889900 aabbccdd00112233 00d3127ae2ca8725 diff --git a/CryptoPP/crypto/skipjack.h b/CryptoPP/crypto/skipjack.h new file mode 100644 index 0000000..9e8a33b --- /dev/null +++ b/CryptoPP/crypto/skipjack.h @@ -0,0 +1,60 @@ +#ifndef CRYPTOPP_SKIPJACK_H +#define CRYPTOPP_SKIPJACK_H + +/** \file +*/ + +#include "seckey.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! _ +struct SKIPJACK_Info : public FixedBlockSize<8>, public FixedKeyLength<10> +{ + CRYPTOPP_DLL static const char * CRYPTOPP_API StaticAlgorithmName() {return "SKIPJACK";} +}; + +/// SKIPJACK +class SKIPJACK : public SKIPJACK_Info, public BlockCipherDocumentation +{ + class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + public: + void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); + + protected: + static const byte fTable[256]; + + FixedSizeSecBlock tab; + }; + + class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + private: + static const byte Se[256]; + static const word32 Te[4][256]; + }; + + class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + private: + static const byte Sd[256]; + static const word32 Td[4][256]; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef SKIPJACK::Encryption SKIPJACKEncryption; +typedef SKIPJACK::Decryption SKIPJACKDecryption; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/smartptr.h b/CryptoPP/crypto/smartptr.h new file mode 100644 index 0000000..5259aa8 --- /dev/null +++ b/CryptoPP/crypto/smartptr.h @@ -0,0 +1,223 @@ +#ifndef CRYPTOPP_SMARTPTR_H +#define CRYPTOPP_SMARTPTR_H + +#include "config.h" +#include + +NAMESPACE_BEGIN(CryptoPP) + +template class simple_ptr +{ +public: + simple_ptr() : m_p(NULL) {} + ~simple_ptr() {delete m_p;} + T *m_p; +}; + +template class member_ptr +{ +public: + explicit member_ptr(T *p = NULL) : m_p(p) {} + + ~member_ptr(); + + const T& operator*() const { return *m_p; } + T& operator*() { return *m_p; } + + const T* operator->() const { return m_p; } + T* operator->() { return m_p; } + + const T* get() const { return m_p; } + T* get() { return m_p; } + + T* release() + { + T *old_p = m_p; + m_p = 0; + return old_p; + } + + void reset(T *p = 0); + +protected: + member_ptr(const member_ptr& rhs); // copy not allowed + void operator=(const member_ptr& rhs); // assignment not allowed + + T *m_p; +}; + +template member_ptr::~member_ptr() {delete m_p;} +template void member_ptr::reset(T *p) {delete m_p; m_p = p;} + +// ******************************************************** + +template class value_ptr : public member_ptr +{ +public: + value_ptr(const T &obj) : member_ptr(new T(obj)) {} + value_ptr(T *p = NULL) : member_ptr(p) {} + value_ptr(const value_ptr& rhs) + : member_ptr(rhs.m_p ? new T(*rhs.m_p) : NULL) {} + + value_ptr& operator=(const value_ptr& rhs); + bool operator==(const value_ptr& rhs) + { + return (!this->m_p && !rhs.m_p) || (this->m_p && rhs.m_p && *this->m_p == *rhs.m_p); + } +}; + +template value_ptr& value_ptr::operator=(const value_ptr& rhs) +{ + T *old_p = this->m_p; + this->m_p = rhs.m_p ? new T(*rhs.m_p) : NULL; + delete old_p; + return *this; +} + +// ******************************************************** + +template class clonable_ptr : public member_ptr +{ +public: + clonable_ptr(const T &obj) : member_ptr(obj.Clone()) {} + clonable_ptr(T *p = NULL) : member_ptr(p) {} + clonable_ptr(const clonable_ptr& rhs) + : member_ptr(rhs.m_p ? rhs.m_p->Clone() : NULL) {} + + clonable_ptr& operator=(const clonable_ptr& rhs); +}; + +template clonable_ptr& clonable_ptr::operator=(const clonable_ptr& rhs) +{ + T *old_p = this->m_p; + this->m_p = rhs.m_p ? rhs.m_p->Clone() : NULL; + delete old_p; + return *this; +} + +// ******************************************************** + +template class counted_ptr +{ +public: + explicit counted_ptr(T *p = 0); + counted_ptr(const T &r) : m_p(0) {attach(r);} + counted_ptr(const counted_ptr& rhs); + + ~counted_ptr(); + + const T& operator*() const { return *m_p; } + T& operator*() { return *m_p; } + + const T* operator->() const { return m_p; } + T* operator->() { return get(); } + + const T* get() const { return m_p; } + T* get(); + + void attach(const T &p); + + counted_ptr & operator=(const counted_ptr& rhs); + +private: + T *m_p; +}; + +template counted_ptr::counted_ptr(T *p) + : m_p(p) +{ + if (m_p) + m_p->m_referenceCount = 1; +} + +template counted_ptr::counted_ptr(const counted_ptr& rhs) + : m_p(rhs.m_p) +{ + if (m_p) + m_p->m_referenceCount++; +} + +template counted_ptr::~counted_ptr() +{ + if (m_p && --m_p->m_referenceCount == 0) + delete m_p; +} + +template void counted_ptr::attach(const T &r) +{ + if (m_p && --m_p->m_referenceCount == 0) + delete m_p; + if (r.m_referenceCount == 0) + { + m_p = r.clone(); + m_p->m_referenceCount = 1; + } + else + { + m_p = const_cast(&r); + m_p->m_referenceCount++; + } +} + +template T* counted_ptr::get() +{ + if (m_p && m_p->m_referenceCount > 1) + { + T *temp = m_p->clone(); + m_p->m_referenceCount--; + m_p = temp; + m_p->m_referenceCount = 1; + } + return m_p; +} + +template counted_ptr & counted_ptr::operator=(const counted_ptr& rhs) +{ + if (m_p != rhs.m_p) + { + if (m_p && --m_p->m_referenceCount == 0) + delete m_p; + m_p = rhs.m_p; + if (m_p) + m_p->m_referenceCount++; + } + return *this; +} + +// ******************************************************** + +template class vector_member_ptrs +{ +public: + vector_member_ptrs(size_t size=0) + : m_size(size), m_ptr(new member_ptr[size]) {} + ~vector_member_ptrs() + {delete [] this->m_ptr;} + + member_ptr& operator[](size_t index) + {assert(indexm_size); return this->m_ptr[index];} + const member_ptr& operator[](size_t index) const + {assert(indexm_size); return this->m_ptr[index];} + + size_t size() const {return this->m_size;} + void resize(size_t newSize) + { + member_ptr *newPtr = new member_ptr[newSize]; + for (size_t i=0; im_size && im_ptr[i].release()); + delete [] this->m_ptr; + this->m_size = newSize; + this->m_ptr = newPtr; + } + +private: + vector_member_ptrs(const vector_member_ptrs &c); // copy not allowed + void operator=(const vector_member_ptrs &x); // assignment not allowed + + size_t m_size; + member_ptr *m_ptr; +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/socketft.cpp b/CryptoPP/crypto/socketft.cpp new file mode 100644 index 0000000..bcb6e0a --- /dev/null +++ b/CryptoPP/crypto/socketft.cpp @@ -0,0 +1,531 @@ +// socketft.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "socketft.h" + +#ifdef SOCKETS_AVAILABLE + +#include "wait.h" + +#ifdef USE_BERKELEY_STYLE_SOCKETS +#include +#include +#include +#include +#include +#include +#endif + +NAMESPACE_BEGIN(CryptoPP) + +#ifdef USE_WINDOWS_STYLE_SOCKETS +const int SOCKET_EINVAL = WSAEINVAL; +const int SOCKET_EWOULDBLOCK = WSAEWOULDBLOCK; +typedef int socklen_t; +#else +const int SOCKET_EINVAL = EINVAL; +const int SOCKET_EWOULDBLOCK = EWOULDBLOCK; +#endif + +Socket::Err::Err(socket_t s, const std::string& operation, int error) + : OS_Error(IO_ERROR, "Socket: " + operation + " operation failed with error " + IntToString(error), operation, error) + , m_s(s) +{ +} + +Socket::~Socket() +{ + if (m_own) + { + try + { + CloseSocket(); + } + catch (...) + { + } + } +} + +void Socket::AttachSocket(socket_t s, bool own) +{ + if (m_own) + CloseSocket(); + + m_s = s; + m_own = own; + SocketChanged(); +} + +socket_t Socket::DetachSocket() +{ + socket_t s = m_s; + m_s = INVALID_SOCKET; + SocketChanged(); + return s; +} + +void Socket::Create(int nType) +{ + assert(m_s == INVALID_SOCKET); + m_s = socket(AF_INET, nType, 0); + CheckAndHandleError("socket", m_s); + m_own = true; + SocketChanged(); +} + +void Socket::CloseSocket() +{ + if (m_s != INVALID_SOCKET) + { +#ifdef USE_WINDOWS_STYLE_SOCKETS + CancelIo((HANDLE) m_s); + CheckAndHandleError_int("closesocket", closesocket(m_s)); +#else + CheckAndHandleError_int("close", close(m_s)); +#endif + m_s = INVALID_SOCKET; + SocketChanged(); + } +} + +void Socket::Bind(unsigned int port, const char *addr) +{ + sockaddr_in sa; + memset(&sa, 0, sizeof(sa)); + sa.sin_family = AF_INET; + + if (addr == NULL) + sa.sin_addr.s_addr = htonl(INADDR_ANY); + else + { + unsigned long result = inet_addr(addr); + if (result == -1) // Solaris doesn't have INADDR_NONE + { + SetLastError(SOCKET_EINVAL); + CheckAndHandleError_int("inet_addr", SOCKET_ERROR); + } + sa.sin_addr.s_addr = result; + } + + sa.sin_port = htons((u_short)port); + + Bind((sockaddr *)&sa, sizeof(sa)); +} + +void Socket::Bind(const sockaddr *psa, socklen_t saLen) +{ + assert(m_s != INVALID_SOCKET); + // cygwin workaround: needs const_cast + CheckAndHandleError_int("bind", bind(m_s, const_cast(psa), saLen)); +} + +void Socket::Listen(int backlog) +{ + assert(m_s != INVALID_SOCKET); + CheckAndHandleError_int("listen", listen(m_s, backlog)); +} + +bool Socket::Connect(const char *addr, unsigned int port) +{ + assert(addr != NULL); + + sockaddr_in sa; + memset(&sa, 0, sizeof(sa)); + sa.sin_family = AF_INET; + sa.sin_addr.s_addr = inet_addr(addr); + + if (sa.sin_addr.s_addr == -1) // Solaris doesn't have INADDR_NONE + { + hostent *lphost = gethostbyname(addr); + if (lphost == NULL) + { + SetLastError(SOCKET_EINVAL); + CheckAndHandleError_int("gethostbyname", SOCKET_ERROR); + } + + sa.sin_addr.s_addr = ((in_addr *)lphost->h_addr)->s_addr; + } + + sa.sin_port = htons((u_short)port); + + return Connect((const sockaddr *)&sa, sizeof(sa)); +} + +bool Socket::Connect(const sockaddr* psa, socklen_t saLen) +{ + assert(m_s != INVALID_SOCKET); + int result = connect(m_s, const_cast(psa), saLen); + if (result == SOCKET_ERROR && GetLastError() == SOCKET_EWOULDBLOCK) + return false; + CheckAndHandleError_int("connect", result); + return true; +} + +bool Socket::Accept(Socket& target, sockaddr *psa, socklen_t *psaLen) +{ + assert(m_s != INVALID_SOCKET); + socket_t s = accept(m_s, psa, psaLen); + if (s == INVALID_SOCKET && GetLastError() == SOCKET_EWOULDBLOCK) + return false; + CheckAndHandleError("accept", s); + target.AttachSocket(s, true); + return true; +} + +void Socket::GetSockName(sockaddr *psa, socklen_t *psaLen) +{ + assert(m_s != INVALID_SOCKET); + CheckAndHandleError_int("getsockname", getsockname(m_s, psa, psaLen)); +} + +void Socket::GetPeerName(sockaddr *psa, socklen_t *psaLen) +{ + assert(m_s != INVALID_SOCKET); + CheckAndHandleError_int("getpeername", getpeername(m_s, psa, psaLen)); +} + +unsigned int Socket::Send(const byte* buf, size_t bufLen, int flags) +{ + assert(m_s != INVALID_SOCKET); + int result = send(m_s, (const char *)buf, UnsignedMin(INT_MAX, bufLen), flags); + CheckAndHandleError_int("send", result); + return result; +} + +unsigned int Socket::Receive(byte* buf, size_t bufLen, int flags) +{ + assert(m_s != INVALID_SOCKET); + int result = recv(m_s, (char *)buf, UnsignedMin(INT_MAX, bufLen), flags); + CheckAndHandleError_int("recv", result); + return result; +} + +void Socket::ShutDown(int how) +{ + assert(m_s != INVALID_SOCKET); + int result = shutdown(m_s, how); + CheckAndHandleError_int("shutdown", result); +} + +void Socket::IOCtl(long cmd, unsigned long *argp) +{ + assert(m_s != INVALID_SOCKET); +#ifdef USE_WINDOWS_STYLE_SOCKETS + CheckAndHandleError_int("ioctlsocket", ioctlsocket(m_s, cmd, argp)); +#else + CheckAndHandleError_int("ioctl", ioctl(m_s, cmd, argp)); +#endif +} + +bool Socket::SendReady(const timeval *timeout) +{ + fd_set fds; + FD_ZERO(&fds); + FD_SET(m_s, &fds); + int ready; + if (timeout == NULL) + ready = select((int)m_s+1, NULL, &fds, NULL, NULL); + else + { + timeval timeoutCopy = *timeout; // select() modified timeout on Linux + ready = select((int)m_s+1, NULL, &fds, NULL, &timeoutCopy); + } + CheckAndHandleError_int("select", ready); + return ready > 0; +} + +bool Socket::ReceiveReady(const timeval *timeout) +{ + fd_set fds; + FD_ZERO(&fds); + FD_SET(m_s, &fds); + int ready; + if (timeout == NULL) + ready = select((int)m_s+1, &fds, NULL, NULL, NULL); + else + { + timeval timeoutCopy = *timeout; // select() modified timeout on Linux + ready = select((int)m_s+1, &fds, NULL, NULL, &timeoutCopy); + } + CheckAndHandleError_int("select", ready); + return ready > 0; +} + +unsigned int Socket::PortNameToNumber(const char *name, const char *protocol) +{ + int port = atoi(name); + if (IntToString(port) == name) + return port; + + servent *se = getservbyname(name, protocol); + if (!se) + throw Err(INVALID_SOCKET, "getservbyname", SOCKET_EINVAL); + return ntohs(se->s_port); +} + +void Socket::StartSockets() +{ +#ifdef USE_WINDOWS_STYLE_SOCKETS + WSADATA wsd; + int result = WSAStartup(0x0202, &wsd); + if (result != 0) + throw Err(INVALID_SOCKET, "WSAStartup", result); +#endif +} + +void Socket::ShutdownSockets() +{ +#ifdef USE_WINDOWS_STYLE_SOCKETS + int result = WSACleanup(); + if (result != 0) + throw Err(INVALID_SOCKET, "WSACleanup", result); +#endif +} + +int Socket::GetLastError() +{ +#ifdef USE_WINDOWS_STYLE_SOCKETS + return WSAGetLastError(); +#else + return errno; +#endif +} + +void Socket::SetLastError(int errorCode) +{ +#ifdef USE_WINDOWS_STYLE_SOCKETS + WSASetLastError(errorCode); +#else + errno = errorCode; +#endif +} + +void Socket::HandleError(const char *operation) const +{ + int err = GetLastError(); + throw Err(m_s, operation, err); +} + +#ifdef USE_WINDOWS_STYLE_SOCKETS + +SocketReceiver::SocketReceiver(Socket &s) + : m_s(s), m_resultPending(false), m_eofReceived(false) +{ + m_event.AttachHandle(CreateEvent(NULL, true, false, NULL), true); + m_s.CheckAndHandleError("CreateEvent", m_event.HandleValid()); + memset(&m_overlapped, 0, sizeof(m_overlapped)); + m_overlapped.hEvent = m_event; +} + +SocketReceiver::~SocketReceiver() +{ +#ifdef USE_WINDOWS_STYLE_SOCKETS + CancelIo((HANDLE) m_s.GetSocket()); +#endif +} + +bool SocketReceiver::Receive(byte* buf, size_t bufLen) +{ + assert(!m_resultPending && !m_eofReceived); + + DWORD flags = 0; + // don't queue too much at once, or we might use up non-paged memory + WSABUF wsabuf = {UnsignedMin((u_long)128*1024, bufLen), (char *)buf}; + if (WSARecv(m_s, &wsabuf, 1, &m_lastResult, &flags, &m_overlapped, NULL) == 0) + { + if (m_lastResult == 0) + m_eofReceived = true; + } + else + { + switch (WSAGetLastError()) + { + default: + m_s.CheckAndHandleError_int("WSARecv", SOCKET_ERROR); + case WSAEDISCON: + m_lastResult = 0; + m_eofReceived = true; + break; + case WSA_IO_PENDING: + m_resultPending = true; + } + } + return !m_resultPending; +} + +void SocketReceiver::GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack) +{ + if (m_resultPending) + container.AddHandle(m_event, CallStack("SocketReceiver::GetWaitObjects() - result pending", &callStack)); + else if (!m_eofReceived) + container.SetNoWait(CallStack("SocketReceiver::GetWaitObjects() - result ready", &callStack)); +} + +unsigned int SocketReceiver::GetReceiveResult() +{ + if (m_resultPending) + { + DWORD flags = 0; + if (WSAGetOverlappedResult(m_s, &m_overlapped, &m_lastResult, false, &flags)) + { + if (m_lastResult == 0) + m_eofReceived = true; + } + else + { + switch (WSAGetLastError()) + { + default: + m_s.CheckAndHandleError("WSAGetOverlappedResult", FALSE); + case WSAEDISCON: + m_lastResult = 0; + m_eofReceived = true; + } + } + m_resultPending = false; + } + return m_lastResult; +} + +// ************************************************************* + +SocketSender::SocketSender(Socket &s) + : m_s(s), m_resultPending(false), m_lastResult(0) +{ + m_event.AttachHandle(CreateEvent(NULL, true, false, NULL), true); + m_s.CheckAndHandleError("CreateEvent", m_event.HandleValid()); + memset(&m_overlapped, 0, sizeof(m_overlapped)); + m_overlapped.hEvent = m_event; +} + + +SocketSender::~SocketSender() +{ +#ifdef USE_WINDOWS_STYLE_SOCKETS + CancelIo((HANDLE) m_s.GetSocket()); +#endif +} + +void SocketSender::Send(const byte* buf, size_t bufLen) +{ + assert(!m_resultPending); + DWORD written = 0; + // don't queue too much at once, or we might use up non-paged memory + WSABUF wsabuf = {UnsignedMin((u_long)128*1024, bufLen), (char *)buf}; + if (WSASend(m_s, &wsabuf, 1, &written, 0, &m_overlapped, NULL) == 0) + { + m_resultPending = false; + m_lastResult = written; + } + else + { + if (WSAGetLastError() != WSA_IO_PENDING) + m_s.CheckAndHandleError_int("WSASend", SOCKET_ERROR); + + m_resultPending = true; + } +} + +void SocketSender::SendEof() +{ + assert(!m_resultPending); + m_s.ShutDown(SD_SEND); + m_s.CheckAndHandleError("ResetEvent", ResetEvent(m_event)); + m_s.CheckAndHandleError_int("WSAEventSelect", WSAEventSelect(m_s, m_event, FD_CLOSE)); + m_resultPending = true; +} + +bool SocketSender::EofSent() +{ + if (m_resultPending) + { + WSANETWORKEVENTS events; + m_s.CheckAndHandleError_int("WSAEnumNetworkEvents", WSAEnumNetworkEvents(m_s, m_event, &events)); + if ((events.lNetworkEvents & FD_CLOSE) != FD_CLOSE) + throw Socket::Err(m_s, "WSAEnumNetworkEvents (FD_CLOSE not present)", E_FAIL); + if (events.iErrorCode[FD_CLOSE_BIT] != 0) + throw Socket::Err(m_s, "FD_CLOSE (via WSAEnumNetworkEvents)", events.iErrorCode[FD_CLOSE_BIT]); + m_resultPending = false; + } + return m_lastResult != 0; +} + +void SocketSender::GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack) +{ + if (m_resultPending) + container.AddHandle(m_event, CallStack("SocketSender::GetWaitObjects() - result pending", &callStack)); + else + container.SetNoWait(CallStack("SocketSender::GetWaitObjects() - result ready", &callStack)); +} + +unsigned int SocketSender::GetSendResult() +{ + if (m_resultPending) + { + DWORD flags = 0; + BOOL result = WSAGetOverlappedResult(m_s, &m_overlapped, &m_lastResult, false, &flags); + m_s.CheckAndHandleError("WSAGetOverlappedResult", result); + m_resultPending = false; + } + return m_lastResult; +} + +#endif + +#ifdef USE_BERKELEY_STYLE_SOCKETS + +SocketReceiver::SocketReceiver(Socket &s) + : m_s(s), m_lastResult(0), m_eofReceived(false) +{ +} + +void SocketReceiver::GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack) +{ + if (!m_eofReceived) + container.AddReadFd(m_s, CallStack("SocketReceiver::GetWaitObjects()", &callStack)); +} + +bool SocketReceiver::Receive(byte* buf, size_t bufLen) +{ + m_lastResult = m_s.Receive(buf, bufLen); + if (bufLen > 0 && m_lastResult == 0) + m_eofReceived = true; + return true; +} + +unsigned int SocketReceiver::GetReceiveResult() +{ + return m_lastResult; +} + +SocketSender::SocketSender(Socket &s) + : m_s(s), m_lastResult(0) +{ +} + +void SocketSender::Send(const byte* buf, size_t bufLen) +{ + m_lastResult = m_s.Send(buf, bufLen); +} + +void SocketSender::SendEof() +{ + m_s.ShutDown(SD_SEND); +} + +unsigned int SocketSender::GetSendResult() +{ + return m_lastResult; +} + +void SocketSender::GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack) +{ + container.AddWriteFd(m_s, CallStack("SocketSender::GetWaitObjects()", &callStack)); +} + +#endif + +NAMESPACE_END + +#endif // #ifdef SOCKETS_AVAILABLE diff --git a/CryptoPP/crypto/socketft.h b/CryptoPP/crypto/socketft.h new file mode 100644 index 0000000..211c8db --- /dev/null +++ b/CryptoPP/crypto/socketft.h @@ -0,0 +1,224 @@ +#ifndef CRYPTOPP_SOCKETFT_H +#define CRYPTOPP_SOCKETFT_H + +#include "config.h" + +#ifdef SOCKETS_AVAILABLE + +#include "network.h" +#include "queue.h" + +#ifdef USE_WINDOWS_STYLE_SOCKETS +# if defined(_WINSOCKAPI_) && !defined(_WINSOCK2API_) +# error Winsock 1 is not supported by this library. Please include this file or winsock2.h before windows.h. +# endif +#include +#include "winpipes.h" +#else +#include +#include +#include +#include +#endif + +NAMESPACE_BEGIN(CryptoPP) + +#ifdef USE_WINDOWS_STYLE_SOCKETS +typedef ::SOCKET socket_t; +#else +typedef int socket_t; +const socket_t INVALID_SOCKET = -1; +// cygwin 1.1.4 doesn't have SHUT_RD +const int SD_RECEIVE = 0; +const int SD_SEND = 1; +const int SD_BOTH = 2; +const int SOCKET_ERROR = -1; +#endif + +#ifndef socklen_t +typedef TYPE_OF_SOCKLEN_T socklen_t; // see config.h +#endif + +//! wrapper for Windows or Berkeley Sockets +class Socket +{ +public: + //! exception thrown by Socket class + class Err : public OS_Error + { + public: + Err(socket_t s, const std::string& operation, int error); + socket_t GetSocket() const {return m_s;} + + private: + socket_t m_s; + }; + + Socket(socket_t s = INVALID_SOCKET, bool own=false) : m_s(s), m_own(own) {} + Socket(const Socket &s) : m_s(s.m_s), m_own(false) {} + virtual ~Socket(); + + bool GetOwnership() const {return m_own;} + void SetOwnership(bool own) {m_own = own;} + + operator socket_t() {return m_s;} + socket_t GetSocket() const {return m_s;} + void AttachSocket(socket_t s, bool own=false); + socket_t DetachSocket(); + void CloseSocket(); + + void Create(int nType = SOCK_STREAM); + void Bind(unsigned int port, const char *addr=NULL); + void Bind(const sockaddr* psa, socklen_t saLen); + void Listen(int backlog=5); + // the next three functions return false if the socket is in nonblocking mode + // and the operation cannot be completed immediately + bool Connect(const char *addr, unsigned int port); + bool Connect(const sockaddr* psa, socklen_t saLen); + bool Accept(Socket& s, sockaddr *psa=NULL, socklen_t *psaLen=NULL); + void GetSockName(sockaddr *psa, socklen_t *psaLen); + void GetPeerName(sockaddr *psa, socklen_t *psaLen); + unsigned int Send(const byte* buf, size_t bufLen, int flags=0); + unsigned int Receive(byte* buf, size_t bufLen, int flags=0); + void ShutDown(int how = SD_SEND); + + void IOCtl(long cmd, unsigned long *argp); + bool SendReady(const timeval *timeout); + bool ReceiveReady(const timeval *timeout); + + virtual void HandleError(const char *operation) const; + void CheckAndHandleError_int(const char *operation, int result) const + {if (result == SOCKET_ERROR) HandleError(operation);} + void CheckAndHandleError(const char *operation, socket_t result) const + {if (result == SOCKET_ERROR) HandleError(operation);} +#ifdef USE_WINDOWS_STYLE_SOCKETS + void CheckAndHandleError(const char *operation, BOOL result) const + {assert(result==TRUE || result==FALSE); if (!result) HandleError(operation);} + void CheckAndHandleError(const char *operation, bool result) const + {if (!result) HandleError(operation);} +#endif + + //! look up the port number given its name, returns 0 if not found + static unsigned int PortNameToNumber(const char *name, const char *protocol="tcp"); + //! start Windows Sockets 2 + static void StartSockets(); + //! calls WSACleanup for Windows Sockets + static void ShutdownSockets(); + //! returns errno or WSAGetLastError + static int GetLastError(); + //! sets errno or calls WSASetLastError + static void SetLastError(int errorCode); + +protected: + virtual void SocketChanged() {} + + socket_t m_s; + bool m_own; +}; + +class SocketsInitializer +{ +public: + SocketsInitializer() {Socket::StartSockets();} + ~SocketsInitializer() {try {Socket::ShutdownSockets();} catch (...) {}} +}; + +class SocketReceiver : public NetworkReceiver +{ +public: + SocketReceiver(Socket &s); + +#ifdef USE_BERKELEY_STYLE_SOCKETS + bool MustWaitToReceive() {return true;} +#else + ~SocketReceiver(); + bool MustWaitForResult() {return true;} +#endif + bool Receive(byte* buf, size_t bufLen); + unsigned int GetReceiveResult(); + bool EofReceived() const {return m_eofReceived;} + + unsigned int GetMaxWaitObjectCount() const {return 1;} + void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack); + +private: + Socket &m_s; + bool m_eofReceived; + +#ifdef USE_WINDOWS_STYLE_SOCKETS + WindowsHandle m_event; + OVERLAPPED m_overlapped; + bool m_resultPending; + DWORD m_lastResult; +#else + unsigned int m_lastResult; +#endif +}; + +class SocketSender : public NetworkSender +{ +public: + SocketSender(Socket &s); + +#ifdef USE_BERKELEY_STYLE_SOCKETS + bool MustWaitToSend() {return true;} +#else + ~SocketSender(); + bool MustWaitForResult() {return true;} + bool MustWaitForEof() { return true; } + bool EofSent(); +#endif + void Send(const byte* buf, size_t bufLen); + unsigned int GetSendResult(); + void SendEof(); + + unsigned int GetMaxWaitObjectCount() const {return 1;} + void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack); + +private: + Socket &m_s; +#ifdef USE_WINDOWS_STYLE_SOCKETS + WindowsHandle m_event; + OVERLAPPED m_overlapped; + bool m_resultPending; + DWORD m_lastResult; +#else + unsigned int m_lastResult; +#endif +}; + +//! socket-based implementation of NetworkSource +class SocketSource : public NetworkSource, public Socket +{ +public: + SocketSource(socket_t s = INVALID_SOCKET, bool pumpAll = false, BufferedTransformation *attachment = NULL) + : NetworkSource(attachment), Socket(s), m_receiver(*this) + { + if (pumpAll) + PumpAll(); + } + +private: + NetworkReceiver & AccessReceiver() {return m_receiver;} + SocketReceiver m_receiver; +}; + +//! socket-based implementation of NetworkSink +class SocketSink : public NetworkSink, public Socket +{ +public: + SocketSink(socket_t s=INVALID_SOCKET, unsigned int maxBufferSize=0, unsigned int autoFlushBound=16*1024) + : NetworkSink(maxBufferSize, autoFlushBound), Socket(s), m_sender(*this) {} + + void SendEof() {ShutDown(SD_SEND);} + +private: + NetworkSender & AccessSender() {return m_sender;} + SocketSender m_sender; +}; + +NAMESPACE_END + +#endif // #ifdef SOCKETS_AVAILABLE + +#endif diff --git a/CryptoPP/crypto/sosemanuk.cpp b/CryptoPP/crypto/sosemanuk.cpp new file mode 100644 index 0000000..d33c8db --- /dev/null +++ b/CryptoPP/crypto/sosemanuk.cpp @@ -0,0 +1,710 @@ +// sosemanuk.cpp - written and placed in the public domain by Wei Dai + +// use "cl /EP /P /DCRYPTOPP_GENERATE_X64_MASM sosemanuk.cpp" to generate MASM code + +#include "pch.h" + +#ifndef CRYPTOPP_GENERATE_X64_MASM + +#include "sosemanuk.h" +#include "misc.h" +#include "cpu.h" + +#include "serpentp.h" + +#if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE +#include +#endif + +NAMESPACE_BEGIN(CryptoPP) + +void SosemanukPolicy::CipherSetKey(const NameValuePairs ¶ms, const byte *userKey, size_t keylen) +{ + Serpent_KeySchedule(m_key, 24, userKey, keylen); +} + +void SosemanukPolicy::CipherResynchronize(byte *keystreamBuffer, const byte *iv) +{ + word32 a, b, c, d, e; + + typedef BlockGetAndPut Block; + Block::Get(iv)(a)(b)(c)(d); + + const word32 *k = m_key; + unsigned int i=1; + + do + { + beforeS0(KX); beforeS0(S0); afterS0(LT); + afterS0(KX); afterS0(S1); afterS1(LT); + if (i == 3) // after 18th round + { + m_state[4] = b; + m_state[5] = e; + m_state[10] = c; + m_state[11] = a; + } + afterS1(KX); afterS1(S2); afterS2(LT); + afterS2(KX); afterS2(S3); afterS3(LT); + if (i == 2) // after 12th round + { + m_state[6] = c; + m_state[7] = d; + m_state[8] = b; + m_state[9] = e; + } + afterS3(KX); afterS3(S4); afterS4(LT); + afterS4(KX); afterS4(S5); afterS5(LT); + afterS5(KX); afterS5(S6); afterS6(LT); + afterS6(KX); afterS6(S7); afterS7(LT); + + if (i == 3) + break; + + ++i; + c = b; + b = e; + e = d; + d = a; + a = e; + k += 32; + } + while (true); + + afterS7(KX); + + m_state[0] = a; + m_state[1] = b; + m_state[2] = e; + m_state[3] = d; + +#define XMUX(c, x, y) (x ^ (y & (0 - (c & 1)))) + m_state[11] += XMUX(m_state[10], m_state[1], m_state[8]); + m_state[10] = rotlFixed(m_state[10] * 0x54655307, 7); +} + +extern "C" { +word32 s_sosemanukMulTables[512] = { +#if CRYPTOPP_BOOL_X86 | CRYPTOPP_BOOL_X64 + 0x00000000, 0xE19FCF12, 0x6B973724, 0x8A08F836, + 0xD6876E48, 0x3718A15A, 0xBD10596C, 0x5C8F967E, + 0x05A7DC90, 0xE4381382, 0x6E30EBB4, 0x8FAF24A6, + 0xD320B2D8, 0x32BF7DCA, 0xB8B785FC, 0x59284AEE, + 0x0AE71189, 0xEB78DE9B, 0x617026AD, 0x80EFE9BF, + 0xDC607FC1, 0x3DFFB0D3, 0xB7F748E5, 0x566887F7, + 0x0F40CD19, 0xEEDF020B, 0x64D7FA3D, 0x8548352F, + 0xD9C7A351, 0x38586C43, 0xB2509475, 0x53CF5B67, + 0x146722BB, 0xF5F8EDA9, 0x7FF0159F, 0x9E6FDA8D, + 0xC2E04CF3, 0x237F83E1, 0xA9777BD7, 0x48E8B4C5, + 0x11C0FE2B, 0xF05F3139, 0x7A57C90F, 0x9BC8061D, + 0xC7479063, 0x26D85F71, 0xACD0A747, 0x4D4F6855, + 0x1E803332, 0xFF1FFC20, 0x75170416, 0x9488CB04, + 0xC8075D7A, 0x29989268, 0xA3906A5E, 0x420FA54C, + 0x1B27EFA2, 0xFAB820B0, 0x70B0D886, 0x912F1794, + 0xCDA081EA, 0x2C3F4EF8, 0xA637B6CE, 0x47A879DC, + 0x28CE44DF, 0xC9518BCD, 0x435973FB, 0xA2C6BCE9, + 0xFE492A97, 0x1FD6E585, 0x95DE1DB3, 0x7441D2A1, + 0x2D69984F, 0xCCF6575D, 0x46FEAF6B, 0xA7616079, + 0xFBEEF607, 0x1A713915, 0x9079C123, 0x71E60E31, + 0x22295556, 0xC3B69A44, 0x49BE6272, 0xA821AD60, + 0xF4AE3B1E, 0x1531F40C, 0x9F390C3A, 0x7EA6C328, + 0x278E89C6, 0xC61146D4, 0x4C19BEE2, 0xAD8671F0, + 0xF109E78E, 0x1096289C, 0x9A9ED0AA, 0x7B011FB8, + 0x3CA96664, 0xDD36A976, 0x573E5140, 0xB6A19E52, + 0xEA2E082C, 0x0BB1C73E, 0x81B93F08, 0x6026F01A, + 0x390EBAF4, 0xD89175E6, 0x52998DD0, 0xB30642C2, + 0xEF89D4BC, 0x0E161BAE, 0x841EE398, 0x65812C8A, + 0x364E77ED, 0xD7D1B8FF, 0x5DD940C9, 0xBC468FDB, + 0xE0C919A5, 0x0156D6B7, 0x8B5E2E81, 0x6AC1E193, + 0x33E9AB7D, 0xD276646F, 0x587E9C59, 0xB9E1534B, + 0xE56EC535, 0x04F10A27, 0x8EF9F211, 0x6F663D03, + 0x50358817, 0xB1AA4705, 0x3BA2BF33, 0xDA3D7021, + 0x86B2E65F, 0x672D294D, 0xED25D17B, 0x0CBA1E69, + 0x55925487, 0xB40D9B95, 0x3E0563A3, 0xDF9AACB1, + 0x83153ACF, 0x628AF5DD, 0xE8820DEB, 0x091DC2F9, + 0x5AD2999E, 0xBB4D568C, 0x3145AEBA, 0xD0DA61A8, + 0x8C55F7D6, 0x6DCA38C4, 0xE7C2C0F2, 0x065D0FE0, + 0x5F75450E, 0xBEEA8A1C, 0x34E2722A, 0xD57DBD38, + 0x89F22B46, 0x686DE454, 0xE2651C62, 0x03FAD370, + 0x4452AAAC, 0xA5CD65BE, 0x2FC59D88, 0xCE5A529A, + 0x92D5C4E4, 0x734A0BF6, 0xF942F3C0, 0x18DD3CD2, + 0x41F5763C, 0xA06AB92E, 0x2A624118, 0xCBFD8E0A, + 0x97721874, 0x76EDD766, 0xFCE52F50, 0x1D7AE042, + 0x4EB5BB25, 0xAF2A7437, 0x25228C01, 0xC4BD4313, + 0x9832D56D, 0x79AD1A7F, 0xF3A5E249, 0x123A2D5B, + 0x4B1267B5, 0xAA8DA8A7, 0x20855091, 0xC11A9F83, + 0x9D9509FD, 0x7C0AC6EF, 0xF6023ED9, 0x179DF1CB, + 0x78FBCCC8, 0x996403DA, 0x136CFBEC, 0xF2F334FE, + 0xAE7CA280, 0x4FE36D92, 0xC5EB95A4, 0x24745AB6, + 0x7D5C1058, 0x9CC3DF4A, 0x16CB277C, 0xF754E86E, + 0xABDB7E10, 0x4A44B102, 0xC04C4934, 0x21D38626, + 0x721CDD41, 0x93831253, 0x198BEA65, 0xF8142577, + 0xA49BB309, 0x45047C1B, 0xCF0C842D, 0x2E934B3F, + 0x77BB01D1, 0x9624CEC3, 0x1C2C36F5, 0xFDB3F9E7, + 0xA13C6F99, 0x40A3A08B, 0xCAAB58BD, 0x2B3497AF, + 0x6C9CEE73, 0x8D032161, 0x070BD957, 0xE6941645, + 0xBA1B803B, 0x5B844F29, 0xD18CB71F, 0x3013780D, + 0x693B32E3, 0x88A4FDF1, 0x02AC05C7, 0xE333CAD5, + 0xBFBC5CAB, 0x5E2393B9, 0xD42B6B8F, 0x35B4A49D, + 0x667BFFFA, 0x87E430E8, 0x0DECC8DE, 0xEC7307CC, + 0xB0FC91B2, 0x51635EA0, 0xDB6BA696, 0x3AF46984, + 0x63DC236A, 0x8243EC78, 0x084B144E, 0xE9D4DB5C, + 0xB55B4D22, 0x54C48230, 0xDECC7A06, 0x3F53B514, +#else + 0x00000000, 0xE19FCF13, 0x6B973726, 0x8A08F835, + 0xD6876E4C, 0x3718A15F, 0xBD10596A, 0x5C8F9679, + 0x05A7DC98, 0xE438138B, 0x6E30EBBE, 0x8FAF24AD, + 0xD320B2D4, 0x32BF7DC7, 0xB8B785F2, 0x59284AE1, + 0x0AE71199, 0xEB78DE8A, 0x617026BF, 0x80EFE9AC, + 0xDC607FD5, 0x3DFFB0C6, 0xB7F748F3, 0x566887E0, + 0x0F40CD01, 0xEEDF0212, 0x64D7FA27, 0x85483534, + 0xD9C7A34D, 0x38586C5E, 0xB250946B, 0x53CF5B78, + 0x1467229B, 0xF5F8ED88, 0x7FF015BD, 0x9E6FDAAE, + 0xC2E04CD7, 0x237F83C4, 0xA9777BF1, 0x48E8B4E2, + 0x11C0FE03, 0xF05F3110, 0x7A57C925, 0x9BC80636, + 0xC747904F, 0x26D85F5C, 0xACD0A769, 0x4D4F687A, + 0x1E803302, 0xFF1FFC11, 0x75170424, 0x9488CB37, + 0xC8075D4E, 0x2998925D, 0xA3906A68, 0x420FA57B, + 0x1B27EF9A, 0xFAB82089, 0x70B0D8BC, 0x912F17AF, + 0xCDA081D6, 0x2C3F4EC5, 0xA637B6F0, 0x47A879E3, + 0x28CE449F, 0xC9518B8C, 0x435973B9, 0xA2C6BCAA, + 0xFE492AD3, 0x1FD6E5C0, 0x95DE1DF5, 0x7441D2E6, + 0x2D699807, 0xCCF65714, 0x46FEAF21, 0xA7616032, + 0xFBEEF64B, 0x1A713958, 0x9079C16D, 0x71E60E7E, + 0x22295506, 0xC3B69A15, 0x49BE6220, 0xA821AD33, + 0xF4AE3B4A, 0x1531F459, 0x9F390C6C, 0x7EA6C37F, + 0x278E899E, 0xC611468D, 0x4C19BEB8, 0xAD8671AB, + 0xF109E7D2, 0x109628C1, 0x9A9ED0F4, 0x7B011FE7, + 0x3CA96604, 0xDD36A917, 0x573E5122, 0xB6A19E31, + 0xEA2E0848, 0x0BB1C75B, 0x81B93F6E, 0x6026F07D, + 0x390EBA9C, 0xD891758F, 0x52998DBA, 0xB30642A9, + 0xEF89D4D0, 0x0E161BC3, 0x841EE3F6, 0x65812CE5, + 0x364E779D, 0xD7D1B88E, 0x5DD940BB, 0xBC468FA8, + 0xE0C919D1, 0x0156D6C2, 0x8B5E2EF7, 0x6AC1E1E4, + 0x33E9AB05, 0xD2766416, 0x587E9C23, 0xB9E15330, + 0xE56EC549, 0x04F10A5A, 0x8EF9F26F, 0x6F663D7C, + 0x50358897, 0xB1AA4784, 0x3BA2BFB1, 0xDA3D70A2, + 0x86B2E6DB, 0x672D29C8, 0xED25D1FD, 0x0CBA1EEE, + 0x5592540F, 0xB40D9B1C, 0x3E056329, 0xDF9AAC3A, + 0x83153A43, 0x628AF550, 0xE8820D65, 0x091DC276, + 0x5AD2990E, 0xBB4D561D, 0x3145AE28, 0xD0DA613B, + 0x8C55F742, 0x6DCA3851, 0xE7C2C064, 0x065D0F77, + 0x5F754596, 0xBEEA8A85, 0x34E272B0, 0xD57DBDA3, + 0x89F22BDA, 0x686DE4C9, 0xE2651CFC, 0x03FAD3EF, + 0x4452AA0C, 0xA5CD651F, 0x2FC59D2A, 0xCE5A5239, + 0x92D5C440, 0x734A0B53, 0xF942F366, 0x18DD3C75, + 0x41F57694, 0xA06AB987, 0x2A6241B2, 0xCBFD8EA1, + 0x977218D8, 0x76EDD7CB, 0xFCE52FFE, 0x1D7AE0ED, + 0x4EB5BB95, 0xAF2A7486, 0x25228CB3, 0xC4BD43A0, + 0x9832D5D9, 0x79AD1ACA, 0xF3A5E2FF, 0x123A2DEC, + 0x4B12670D, 0xAA8DA81E, 0x2085502B, 0xC11A9F38, + 0x9D950941, 0x7C0AC652, 0xF6023E67, 0x179DF174, + 0x78FBCC08, 0x9964031B, 0x136CFB2E, 0xF2F3343D, + 0xAE7CA244, 0x4FE36D57, 0xC5EB9562, 0x24745A71, + 0x7D5C1090, 0x9CC3DF83, 0x16CB27B6, 0xF754E8A5, + 0xABDB7EDC, 0x4A44B1CF, 0xC04C49FA, 0x21D386E9, + 0x721CDD91, 0x93831282, 0x198BEAB7, 0xF81425A4, + 0xA49BB3DD, 0x45047CCE, 0xCF0C84FB, 0x2E934BE8, + 0x77BB0109, 0x9624CE1A, 0x1C2C362F, 0xFDB3F93C, + 0xA13C6F45, 0x40A3A056, 0xCAAB5863, 0x2B349770, + 0x6C9CEE93, 0x8D032180, 0x070BD9B5, 0xE69416A6, + 0xBA1B80DF, 0x5B844FCC, 0xD18CB7F9, 0x301378EA, + 0x693B320B, 0x88A4FD18, 0x02AC052D, 0xE333CA3E, + 0xBFBC5C47, 0x5E239354, 0xD42B6B61, 0x35B4A472, + 0x667BFF0A, 0x87E43019, 0x0DECC82C, 0xEC73073F, + 0xB0FC9146, 0x51635E55, 0xDB6BA660, 0x3AF46973, + 0x63DC2392, 0x8243EC81, 0x084B14B4, 0xE9D4DBA7, + 0xB55B4DDE, 0x54C482CD, 0xDECC7AF8, 0x3F53B5EB, +#endif + 0x00000000, 0x180F40CD, 0x301E8033, 0x2811C0FE, + 0x603CA966, 0x7833E9AB, 0x50222955, 0x482D6998, + 0xC078FBCC, 0xD877BB01, 0xF0667BFF, 0xE8693B32, + 0xA04452AA, 0xB84B1267, 0x905AD299, 0x88559254, + 0x29F05F31, 0x31FF1FFC, 0x19EEDF02, 0x01E19FCF, + 0x49CCF657, 0x51C3B69A, 0x79D27664, 0x61DD36A9, + 0xE988A4FD, 0xF187E430, 0xD99624CE, 0xC1996403, + 0x89B40D9B, 0x91BB4D56, 0xB9AA8DA8, 0xA1A5CD65, + 0x5249BE62, 0x4A46FEAF, 0x62573E51, 0x7A587E9C, + 0x32751704, 0x2A7A57C9, 0x026B9737, 0x1A64D7FA, + 0x923145AE, 0x8A3E0563, 0xA22FC59D, 0xBA208550, + 0xF20DECC8, 0xEA02AC05, 0xC2136CFB, 0xDA1C2C36, + 0x7BB9E153, 0x63B6A19E, 0x4BA76160, 0x53A821AD, + 0x1B854835, 0x038A08F8, 0x2B9BC806, 0x339488CB, + 0xBBC11A9F, 0xA3CE5A52, 0x8BDF9AAC, 0x93D0DA61, + 0xDBFDB3F9, 0xC3F2F334, 0xEBE333CA, 0xF3EC7307, + 0xA492D5C4, 0xBC9D9509, 0x948C55F7, 0x8C83153A, + 0xC4AE7CA2, 0xDCA13C6F, 0xF4B0FC91, 0xECBFBC5C, + 0x64EA2E08, 0x7CE56EC5, 0x54F4AE3B, 0x4CFBEEF6, + 0x04D6876E, 0x1CD9C7A3, 0x34C8075D, 0x2CC74790, + 0x8D628AF5, 0x956DCA38, 0xBD7C0AC6, 0xA5734A0B, + 0xED5E2393, 0xF551635E, 0xDD40A3A0, 0xC54FE36D, + 0x4D1A7139, 0x551531F4, 0x7D04F10A, 0x650BB1C7, + 0x2D26D85F, 0x35299892, 0x1D38586C, 0x053718A1, + 0xF6DB6BA6, 0xEED42B6B, 0xC6C5EB95, 0xDECAAB58, + 0x96E7C2C0, 0x8EE8820D, 0xA6F942F3, 0xBEF6023E, + 0x36A3906A, 0x2EACD0A7, 0x06BD1059, 0x1EB25094, + 0x569F390C, 0x4E9079C1, 0x6681B93F, 0x7E8EF9F2, + 0xDF2B3497, 0xC724745A, 0xEF35B4A4, 0xF73AF469, + 0xBF179DF1, 0xA718DD3C, 0x8F091DC2, 0x97065D0F, + 0x1F53CF5B, 0x075C8F96, 0x2F4D4F68, 0x37420FA5, + 0x7F6F663D, 0x676026F0, 0x4F71E60E, 0x577EA6C3, + 0xE18D0321, 0xF98243EC, 0xD1938312, 0xC99CC3DF, + 0x81B1AA47, 0x99BEEA8A, 0xB1AF2A74, 0xA9A06AB9, + 0x21F5F8ED, 0x39FAB820, 0x11EB78DE, 0x09E43813, + 0x41C9518B, 0x59C61146, 0x71D7D1B8, 0x69D89175, + 0xC87D5C10, 0xD0721CDD, 0xF863DC23, 0xE06C9CEE, + 0xA841F576, 0xB04EB5BB, 0x985F7545, 0x80503588, + 0x0805A7DC, 0x100AE711, 0x381B27EF, 0x20146722, + 0x68390EBA, 0x70364E77, 0x58278E89, 0x4028CE44, + 0xB3C4BD43, 0xABCBFD8E, 0x83DA3D70, 0x9BD57DBD, + 0xD3F81425, 0xCBF754E8, 0xE3E69416, 0xFBE9D4DB, + 0x73BC468F, 0x6BB30642, 0x43A2C6BC, 0x5BAD8671, + 0x1380EFE9, 0x0B8FAF24, 0x239E6FDA, 0x3B912F17, + 0x9A34E272, 0x823BA2BF, 0xAA2A6241, 0xB225228C, + 0xFA084B14, 0xE2070BD9, 0xCA16CB27, 0xD2198BEA, + 0x5A4C19BE, 0x42435973, 0x6A52998D, 0x725DD940, + 0x3A70B0D8, 0x227FF015, 0x0A6E30EB, 0x12617026, + 0x451FD6E5, 0x5D109628, 0x750156D6, 0x6D0E161B, + 0x25237F83, 0x3D2C3F4E, 0x153DFFB0, 0x0D32BF7D, + 0x85672D29, 0x9D686DE4, 0xB579AD1A, 0xAD76EDD7, + 0xE55B844F, 0xFD54C482, 0xD545047C, 0xCD4A44B1, + 0x6CEF89D4, 0x74E0C919, 0x5CF109E7, 0x44FE492A, + 0x0CD320B2, 0x14DC607F, 0x3CCDA081, 0x24C2E04C, + 0xAC977218, 0xB49832D5, 0x9C89F22B, 0x8486B2E6, + 0xCCABDB7E, 0xD4A49BB3, 0xFCB55B4D, 0xE4BA1B80, + 0x17566887, 0x0F59284A, 0x2748E8B4, 0x3F47A879, + 0x776AC1E1, 0x6F65812C, 0x477441D2, 0x5F7B011F, + 0xD72E934B, 0xCF21D386, 0xE7301378, 0xFF3F53B5, + 0xB7123A2D, 0xAF1D7AE0, 0x870CBA1E, 0x9F03FAD3, + 0x3EA637B6, 0x26A9777B, 0x0EB8B785, 0x16B7F748, + 0x5E9A9ED0, 0x4695DE1D, 0x6E841EE3, 0x768B5E2E, + 0xFEDECC7A, 0xE6D18CB7, 0xCEC04C49, 0xD6CF0C84, + 0x9EE2651C, 0x86ED25D1, 0xAEFCE52F, 0xB6F3A5E2 +}; +} + +#if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X64 +unsigned int SosemanukPolicy::GetAlignment() const +{ +#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE +#ifdef __INTEL_COMPILER + if (HasSSE2() && !IsP4()) // Intel compiler produces faster code for this algorithm on the P4 +#else + if (HasSSE2()) +#endif + return 16; + else +#endif + return 1; +} + +unsigned int SosemanukPolicy::GetOptimalBlockSize() const +{ +#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE +#ifdef __INTEL_COMPILER + if (HasSSE2() && !IsP4()) // Intel compiler produces faster code for this algorithm on the P4 +#else + if (HasSSE2()) +#endif + return 4*BYTES_PER_ITERATION; + else +#endif + return BYTES_PER_ITERATION; +} +#endif + +#ifdef CRYPTOPP_X64_MASM_AVAILABLE +extern "C" { +void Sosemanuk_OperateKeystream(size_t iterationCount, const byte *input, byte *output, word32 *state); +} +#endif + +#pragma warning(disable: 4731) // frame pointer register 'ebp' modified by inline assembly code + +void SosemanukPolicy::OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount) +{ +#endif // #ifdef CRYPTOPP_GENERATE_X64_MASM + +#ifdef CRYPTOPP_X64_MASM_AVAILABLE + Sosemanuk_OperateKeystream(iterationCount, input, output, m_state.data()); + return; +#endif + +#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE +#ifdef CRYPTOPP_GENERATE_X64_MASM + ALIGN 8 + Sosemanuk_OperateKeystream PROC FRAME + rex_push_reg rsi + push_reg rdi + alloc_stack(80*4*2+12*4+8*WORD_SZ + 2*16+8) + save_xmm128 xmm6, 02f0h + save_xmm128 xmm7, 0300h + .endprolog + mov rdi, r8 + mov rax, r9 +#else +#ifdef __INTEL_COMPILER + if (HasSSE2() && !IsP4()) // Intel compiler produces faster code for this algorithm on the P4 +#else + if (HasSSE2()) +#endif + { +#ifdef __GNUC__ + #if CRYPTOPP_BOOL_X64 + __m128i workspace[(80*4*2+12*4+8*WORD_SZ)/16]; + #endif + __asm__ __volatile__ + ( + ".intel_syntax noprefix;" + AS_PUSH_IF86( bx) +#else + word32 *state = m_state; + AS2( mov WORD_REG(ax), state) + AS2( mov WORD_REG(di), output) + AS2( mov WORD_REG(dx), input) + AS2( mov WORD_REG(cx), iterationCount) +#endif +#endif // #ifdef CRYPTOPP_GENERATE_X64_MASM + +#if defined(__GNUC__) && CRYPTOPP_BOOL_X64 + #define SSE2_workspace %5 +#else + #define SSE2_workspace WORD_REG(sp) +#endif + +#define SSE2_output WORD_PTR [SSE2_workspace+1*WORD_SZ] +#define SSE2_input WORD_PTR [SSE2_workspace+2*WORD_SZ] +#define SSE2_wordsLeft WORD_PTR [SSE2_workspace+3*WORD_SZ] +#define SSE2_diEnd WORD_PTR [SSE2_workspace+4*WORD_SZ] +#define SSE2_pMulTables WORD_PTR [SSE2_workspace+5*WORD_SZ] +#define SSE2_state WORD_PTR [SSE2_workspace+6*WORD_SZ] +#define SSE2_wordsLeft2 WORD_PTR [SSE2_workspace+7*WORD_SZ] +#define SSE2_stateCopy SSE2_workspace + 8*WORD_SZ +#define SSE2_uvStart SSE2_stateCopy + 12*4 + +#if CRYPTOPP_BOOL_X86 + AS_PUSH_IF86( bp) + AS2( mov AS_REG_6, esp) + AS2( and esp, -16) + AS2( sub esp, 80*4*2+12*4+8*WORD_SZ) // 80 v's, 80 u's, 12 state, 8 locals + AS2( mov [esp], AS_REG_6) +#endif + AS2( mov SSE2_output, WORD_REG(di)) + AS2( mov SSE2_input, WORD_REG(dx)) + AS2( mov SSE2_state, WORD_REG(ax)) +#ifndef _MSC_VER + AS2( mov SSE2_pMulTables, WORD_REG(si)) +#endif + AS2( lea WORD_REG(cx), [4*WORD_REG(cx)+WORD_REG(cx)]) + AS2( lea WORD_REG(si), [4*WORD_REG(cx)]) + AS2( mov SSE2_wordsLeft, WORD_REG(si)) + AS2( movdqa xmm0, [WORD_REG(ax)+0*16]) // copy state to stack to save a register + AS2( movdqa [SSE2_stateCopy+0*16], xmm0) + AS2( movdqa xmm0, [WORD_REG(ax)+1*16]) + AS2( movdqa [SSE2_stateCopy+1*16], xmm0) + AS2( movq xmm0, QWORD PTR [WORD_REG(ax)+2*16]) + AS2( movq QWORD PTR [SSE2_stateCopy+2*16], xmm0) + AS2( psrlq xmm0, 32) + AS2( movd AS_REG_6d, xmm0) // s(9) + AS2( mov ecx, [WORD_REG(ax)+10*4]) + AS2( mov edx, [WORD_REG(ax)+11*4]) + AS2( pcmpeqb xmm7, xmm7) // all ones + +#define s(i) SSE2_stateCopy + ASM_MOD(i,10)*4 +#define u(j) WORD_REG(di) + (ASM_MOD(j,4)*20 + (j/4)) * 4 +#define v(j) WORD_REG(di) + (ASM_MOD(j,4)*20 + (j/4)) * 4 + 80*4 + +#define R10 ecx +#define R11 edx +#define R20 edx +#define R21 ecx + +#define SSE2_STEP(i, j) \ + AS2( mov eax, [s(i+0)])\ + AS2( mov [v(i)], eax)\ + AS2( rol eax, 8)\ + AS2( lea AS_REG_7d, [AS_REG_6d + R2##j])\ + AS2( xor AS_REG_7d, R1##j)\ + AS2( mov [u(i)], AS_REG_7d)\ + AS2( mov AS_REG_7d, 1)\ + AS2( and AS_REG_7d, R2##j)\ + AS1( neg AS_REG_7d)\ + AS2( and AS_REG_7d, AS_REG_6d)\ + AS2( xor AS_REG_6d, eax)\ + AS2( movzx eax, al)\ + AS2( xor AS_REG_6d, [WORD_REG(si)+WORD_REG(ax)*4])\ + AS2( mov eax, [s(i+3)])\ + AS2( xor AS_REG_7d, [s(i+2)])\ + AS2( add R1##j, AS_REG_7d)\ + AS2( movzx AS_REG_7d, al)\ + AS2( shr eax, 8)\ + AS2( xor AS_REG_6d, [WORD_REG(si)+1024+AS_REG_7*4])\ + AS2( xor AS_REG_6d, eax)\ + AS2( imul R2##j, AS_HEX(54655307))\ + AS2( rol R2##j, 7)\ + AS2( mov [s(i+0)], AS_REG_6d)\ + + ASL(2) // outer loop, each iteration of this processes 80 words + AS2( lea WORD_REG(di), [SSE2_uvStart]) // start of v and u + AS2( mov WORD_REG(ax), 80) + AS2( cmp WORD_REG(si), 80) + AS2( cmovg WORD_REG(si), WORD_REG(ax)) + AS2( mov SSE2_wordsLeft2, WORD_REG(si)) + AS2( lea WORD_REG(si), [WORD_REG(di)+WORD_REG(si)]) // use to end first inner loop + AS2( mov SSE2_diEnd, WORD_REG(si)) +#ifdef _MSC_VER + AS2( lea WORD_REG(si), s_sosemanukMulTables) +#else + AS2( mov WORD_REG(si), SSE2_pMulTables) +#endif + + ASL(0) // first inner loop, 20 words each, 4 iterations + SSE2_STEP(0, 0) + SSE2_STEP(1, 1) + SSE2_STEP(2, 0) + SSE2_STEP(3, 1) + SSE2_STEP(4, 0) + SSE2_STEP(5, 1) + SSE2_STEP(6, 0) + SSE2_STEP(7, 1) + SSE2_STEP(8, 0) + SSE2_STEP(9, 1) + SSE2_STEP(10, 0) + SSE2_STEP(11, 1) + SSE2_STEP(12, 0) + SSE2_STEP(13, 1) + SSE2_STEP(14, 0) + SSE2_STEP(15, 1) + SSE2_STEP(16, 0) + SSE2_STEP(17, 1) + SSE2_STEP(18, 0) + SSE2_STEP(19, 1) + // loop + AS2( add WORD_REG(di), 5*4) + AS2( cmp WORD_REG(di), SSE2_diEnd) + ASJ( jne, 0, b) + + AS2( mov WORD_REG(ax), SSE2_input) + AS2( mov AS_REG_7, SSE2_output) + AS2( lea WORD_REG(di), [SSE2_uvStart]) // start of v and u + AS2( mov WORD_REG(si), SSE2_wordsLeft2) + + ASL(1) // second inner loop, 16 words each, 5 iterations + AS2( movdqa xmm0, [WORD_REG(di)+0*20*4]) + AS2( movdqa xmm2, [WORD_REG(di)+2*20*4]) + AS2( movdqa xmm3, [WORD_REG(di)+3*20*4]) + AS2( movdqa xmm1, [WORD_REG(di)+1*20*4]) + // S2 + AS2( movdqa xmm4, xmm0) + AS2( pand xmm0, xmm2) + AS2( pxor xmm0, xmm3) + AS2( pxor xmm2, xmm1) + AS2( pxor xmm2, xmm0) + AS2( por xmm3, xmm4) + AS2( pxor xmm3, xmm1) + AS2( pxor xmm4, xmm2) + AS2( movdqa xmm1, xmm3) + AS2( por xmm3, xmm4) + AS2( pxor xmm3, xmm0) + AS2( pand xmm0, xmm1) + AS2( pxor xmm4, xmm0) + AS2( pxor xmm1, xmm3) + AS2( pxor xmm1, xmm4) + AS2( pxor xmm4, xmm7) + // xor with v + AS2( pxor xmm2, [WORD_REG(di)+80*4]) + AS2( pxor xmm3, [WORD_REG(di)+80*5]) + AS2( pxor xmm1, [WORD_REG(di)+80*6]) + AS2( pxor xmm4, [WORD_REG(di)+80*7]) + // exit loop early if less than 16 words left to output + // this is necessary because block size is 20 words, and we output 16 words in each iteration of this loop + AS2( cmp WORD_REG(si), 16) + ASJ( jl, 4, f) + // unpack + AS2( movdqa xmm6, xmm2) + AS2( punpckldq xmm2, xmm3) + AS2( movdqa xmm5, xmm1) + AS2( punpckldq xmm1, xmm4) + AS2( movdqa xmm0, xmm2) + AS2( punpcklqdq xmm2, xmm1) + AS2( punpckhqdq xmm0, xmm1) + AS2( punpckhdq xmm6, xmm3) + AS2( punpckhdq xmm5, xmm4) + AS2( movdqa xmm3, xmm6) + AS2( punpcklqdq xmm6, xmm5) + AS2( punpckhqdq xmm3, xmm5) + // output keystream + AS_XMM_OUTPUT4(SSE2_Sosemanuk_Output, WORD_REG(ax), AS_REG_7, 2,0,6,3, 1, 0,1,2,3, 4) + + // loop + AS2( add WORD_REG(di), 4*4) + AS2( sub WORD_REG(si), 16) + ASJ( jnz, 1, b) + + // outer loop + AS2( mov WORD_REG(si), SSE2_wordsLeft) + AS2( sub WORD_REG(si), 80) + ASJ( jz, 6, f) + AS2( mov SSE2_wordsLeft, WORD_REG(si)) + AS2( mov SSE2_input, WORD_REG(ax)) + AS2( mov SSE2_output, AS_REG_7) + ASJ( jmp, 2, b) + + ASL(4) // final output of less than 16 words + AS2( test WORD_REG(ax), WORD_REG(ax)) + ASJ( jz, 5, f) + AS2( movd xmm0, dword ptr [WORD_REG(ax)+0*4]) + AS2( pxor xmm2, xmm0) + AS2( movd xmm0, dword ptr [WORD_REG(ax)+1*4]) + AS2( pxor xmm3, xmm0) + AS2( movd xmm0, dword ptr [WORD_REG(ax)+2*4]) + AS2( pxor xmm1, xmm0) + AS2( movd xmm0, dword ptr [WORD_REG(ax)+3*4]) + AS2( pxor xmm4, xmm0) + AS2( add WORD_REG(ax), 16) + ASL(5) + AS2( movd dword ptr [AS_REG_7+0*4], xmm2) + AS2( movd dword ptr [AS_REG_7+1*4], xmm3) + AS2( movd dword ptr [AS_REG_7+2*4], xmm1) + AS2( movd dword ptr [AS_REG_7+3*4], xmm4) + AS2( sub WORD_REG(si), 4) + ASJ( jz, 6, f) + AS2( add AS_REG_7, 16) + AS2( psrldq xmm2, 4) + AS2( psrldq xmm3, 4) + AS2( psrldq xmm1, 4) + AS2( psrldq xmm4, 4) + ASJ( jmp, 4, b) + + ASL(6) // save state + AS2( mov AS_REG_6, SSE2_state) + AS2( movdqa xmm0, [SSE2_stateCopy+0*16]) + AS2( movdqa [AS_REG_6+0*16], xmm0) + AS2( movdqa xmm0, [SSE2_stateCopy+1*16]) + AS2( movdqa [AS_REG_6+1*16], xmm0) + AS2( movq xmm0, QWORD PTR [SSE2_stateCopy+2*16]) + AS2( movq QWORD PTR [AS_REG_6+2*16], xmm0) + AS2( mov [AS_REG_6+10*4], ecx) + AS2( mov [AS_REG_6+11*4], edx) + + AS_POP_IF86( sp) + AS_POP_IF86( bp) + +#ifdef __GNUC__ + AS_POP_IF86( bx) + ".att_syntax prefix;" + : + : "a" (m_state.m_ptr), "c" (iterationCount), "S" (s_sosemanukMulTables), "D" (output), "d" (input) + #if CRYPTOPP_BOOL_X64 + , "r" (workspace) + : "memory", "cc", "%xmm0", "%xmm1", "%xmm2", "%xmm3", "%xmm4", "%xmm5", "%xmm6", "%xmm7" + #else + : "memory", "cc" + #endif + ); +#endif +#ifdef CRYPTOPP_GENERATE_X64_MASM + movdqa xmm6, [rsp + 02f0h] + movdqa xmm7, [rsp + 0300h] + add rsp, 80*4*2+12*4+8*WORD_SZ + 2*16+8 + pop rdi + pop rsi + ret + Sosemanuk_OperateKeystream ENDP +#else + } + else +#endif +#endif +#ifndef CRYPTOPP_GENERATE_X64_MASM + { +#if CRYPTOPP_BOOL_X86 | CRYPTOPP_BOOL_X64 +#define MUL_A(x) (x = rotlFixed(x, 8), x ^ s_sosemanukMulTables[byte(x)]) +#else +#define MUL_A(x) (((x) << 8) ^ s_sosemanukMulTables[(x) >> 24]) +#endif + +#define DIV_A(x) (((x) >> 8) ^ s_sosemanukMulTables[256 + byte(x)]) + +#define r1(i) ((i%2) ? reg2 : reg1) +#define r2(i) ((i%2) ? reg1 : reg2) + +#define STEP(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, v, u) \ + u = (s##x9 + r2(x0)) ^ r1(x0);\ + v = s##x0;\ + s##x0 = MUL_A(s##x0) ^ DIV_A(s##x3) ^ s##x9;\ + r1(x0) += XMUX(r2(x0), s##x2, s##x9);\ + r2(x0) = rotlFixed(r2(x0) * 0x54655307, 7);\ + +#define SOSEMANUK_OUTPUT(x) \ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 0, u2 ^ v0);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 1, u3 ^ v1);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 2, u1 ^ v2);\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 3, u4 ^ v3); + +#define OUTPUT4 \ + S2(0, u0, u1, u2, u3, u4);\ + CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(SOSEMANUK_OUTPUT, 4*4); + + word32 s0 = m_state[0]; + word32 s1 = m_state[1]; + word32 s2 = m_state[2]; + word32 s3 = m_state[3]; + word32 s4 = m_state[4]; + word32 s5 = m_state[5]; + word32 s6 = m_state[6]; + word32 s7 = m_state[7]; + word32 s8 = m_state[8]; + word32 s9 = m_state[9]; + word32 reg1 = m_state[10]; + word32 reg2 = m_state[11]; + word32 u0, u1, u2, u3, u4, v0, v1, v2, v3; + + do + { + STEP(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, v0, u0) + STEP(1, 2, 3, 4, 5, 6, 7, 8, 9, 0, v1, u1) + STEP(2, 3, 4, 5, 6, 7, 8, 9, 0, 1, v2, u2) + STEP(3, 4, 5, 6, 7, 8, 9, 0, 1, 2, v3, u3) + OUTPUT4 + STEP(4, 5, 6, 7, 8, 9, 0, 1, 2, 3, v0, u0) + STEP(5, 6, 7, 8, 9, 0, 1, 2, 3, 4, v1, u1) + STEP(6, 7, 8, 9, 0, 1, 2, 3, 4, 5, v2, u2) + STEP(7, 8, 9, 0, 1, 2, 3, 4, 5, 6, v3, u3) + OUTPUT4 + STEP(8, 9, 0, 1, 2, 3, 4, 5, 6, 7, v0, u0) + STEP(9, 0, 1, 2, 3, 4, 5, 6, 7, 8, v1, u1) + STEP(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, v2, u2) + STEP(1, 2, 3, 4, 5, 6, 7, 8, 9, 0, v3, u3) + OUTPUT4 + STEP(2, 3, 4, 5, 6, 7, 8, 9, 0, 1, v0, u0) + STEP(3, 4, 5, 6, 7, 8, 9, 0, 1, 2, v1, u1) + STEP(4, 5, 6, 7, 8, 9, 0, 1, 2, 3, v2, u2) + STEP(5, 6, 7, 8, 9, 0, 1, 2, 3, 4, v3, u3) + OUTPUT4 + STEP(6, 7, 8, 9, 0, 1, 2, 3, 4, 5, v0, u0) + STEP(7, 8, 9, 0, 1, 2, 3, 4, 5, 6, v1, u1) + STEP(8, 9, 0, 1, 2, 3, 4, 5, 6, 7, v2, u2) + STEP(9, 0, 1, 2, 3, 4, 5, 6, 7, 8, v3, u3) + OUTPUT4 + } + while (--iterationCount); + + m_state[0] = s0; + m_state[1] = s1; + m_state[2] = s2; + m_state[3] = s3; + m_state[4] = s4; + m_state[5] = s5; + m_state[6] = s6; + m_state[7] = s7; + m_state[8] = s8; + m_state[9] = s9; + m_state[10] = reg1; + m_state[11] = reg2; + } +} + +NAMESPACE_END + +#endif // #ifndef CRYPTOPP_GENERATE_X64_MASM diff --git a/CryptoPP/crypto/sosemanuk.h b/CryptoPP/crypto/sosemanuk.h new file mode 100644 index 0000000..f101e2c --- /dev/null +++ b/CryptoPP/crypto/sosemanuk.h @@ -0,0 +1,40 @@ +#ifndef CRYPTOPP_SOSEMANUK_H +#define CRYPTOPP_SOSEMANUK_H + +#include "strciphr.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! algorithm info +struct SosemanukInfo : public VariableKeyLength<16, 1, 32, 1, SimpleKeyingInterface::UNIQUE_IV, 16> +{ + static const char * StaticAlgorithmName() {return "Sosemanuk";} +}; + +//! _ +class SosemanukPolicy : public AdditiveCipherConcretePolicy, public SosemanukInfo +{ +protected: + void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length); + void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount); + void CipherResynchronize(byte *keystreamBuffer, const byte *iv); + bool IsRandomAccess() const {return false;} +#if CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X64 + unsigned int GetAlignment() const; + unsigned int GetOptimalBlockSize() const; +#endif + + FixedSizeSecBlock m_key; + FixedSizeAlignedSecBlock m_state; +}; + +//! Sosemanuk +struct Sosemanuk : public SosemanukInfo, public SymmetricCipherDocumentation +{ + typedef SymmetricCipherFinal >, SosemanukInfo> Encryption; + typedef Encryption Decryption; +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/square.cpp b/CryptoPP/crypto/square.cpp new file mode 100644 index 0000000..4bd7b9a --- /dev/null +++ b/CryptoPP/crypto/square.cpp @@ -0,0 +1,174 @@ +// square.cpp - written and placed in the public domain by Wei Dai +// Based on Paulo S.L.M. Barreto's public domain implementation + +#include "pch.h" +#include "square.h" +#include "misc.h" +#include "gf256.h" + +NAMESPACE_BEGIN(CryptoPP) + +// apply theta to a roundkey +static void SquareTransform (word32 in[4], word32 out[4]) +{ + static const byte G[4][4] = + { + 0x02U, 0x01U, 0x01U, 0x03U, + 0x03U, 0x02U, 0x01U, 0x01U, + 0x01U, 0x03U, 0x02U, 0x01U, + 0x01U, 0x01U, 0x03U, 0x02U + }; + + GF256 gf256(0xf5); + + for (int i = 0; i < 4; i++) + { + word32 temp = 0; + for (int j = 0; j < 4; j++) + for (int k = 0; k < 4; k++) + temp ^= (word32)gf256.Multiply(GETBYTE(in[i], 3-k), G[k][j]) << ((3-j)*8); + out[i] = temp; + } +} + +void Square::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs &) +{ + AssertValidKeyLength(length); + + static const word32 offset[ROUNDS] = { + 0x01000000UL, 0x02000000UL, 0x04000000UL, 0x08000000UL, + 0x10000000UL, 0x20000000UL, 0x40000000UL, 0x80000000UL, + }; + + GetUserKey(BIG_ENDIAN_ORDER, roundkeys[0], KEYLENGTH/4, userKey, KEYLENGTH); + + /* apply the key evolution function */ + for (int i = 1; i < ROUNDS+1; i++) + { + roundkeys[i][0] = roundkeys[i-1][0] ^ rotlFixed(roundkeys[i-1][3], 8U) ^ offset[i-1]; + roundkeys[i][1] = roundkeys[i-1][1] ^ roundkeys[i][0]; + roundkeys[i][2] = roundkeys[i-1][2] ^ roundkeys[i][1]; + roundkeys[i][3] = roundkeys[i-1][3] ^ roundkeys[i][2]; + } + + /* produce the round keys */ + if (IsForwardTransformation()) + { + for (int i = 0; i < ROUNDS; i++) + SquareTransform (roundkeys[i], roundkeys[i]); + } + else + { + for (int i = 0; i < ROUNDS/2; i++) + for (int j = 0; j < 4; j++) + std::swap(roundkeys[i][j], roundkeys[ROUNDS-i][j]); + SquareTransform (roundkeys[ROUNDS], roundkeys[ROUNDS]); + } +} + +#define MSB(x) (((x) >> 24) & 0xffU) /* most significant byte */ +#define SSB(x) (((x) >> 16) & 0xffU) /* second in significance */ +#define TSB(x) (((x) >> 8) & 0xffU) /* third in significance */ +#define LSB(x) (((x) ) & 0xffU) /* least significant byte */ + +#define squareRound(text, temp, T0, T1, T2, T3, roundkey) \ +{ \ + temp[0] = T0[MSB (text[0])] \ + ^ T1[MSB (text[1])] \ + ^ T2[MSB (text[2])] \ + ^ T3[MSB (text[3])] \ + ^ roundkey[0]; \ + temp[1] = T0[SSB (text[0])] \ + ^ T1[SSB (text[1])] \ + ^ T2[SSB (text[2])] \ + ^ T3[SSB (text[3])] \ + ^ roundkey[1]; \ + temp[2] = T0[TSB (text[0])] \ + ^ T1[TSB (text[1])] \ + ^ T2[TSB (text[2])] \ + ^ T3[TSB (text[3])] \ + ^ roundkey[2]; \ + temp[3] = T0[LSB (text[0])] \ + ^ T1[LSB (text[1])] \ + ^ T2[LSB (text[2])] \ + ^ T3[LSB (text[3])] \ + ^ roundkey[3]; \ +} /* squareRound */ + +#define squareFinal(text, temp, S, roundkey) \ +{ \ + text[0] = ((word32) (S[MSB (temp[0])]) << 24) \ + ^ ((word32) (S[MSB (temp[1])]) << 16) \ + ^ ((word32) (S[MSB (temp[2])]) << 8) \ + ^ (word32) (S[MSB (temp[3])]) \ + ^ roundkey[0]; \ + text[1] = ((word32) (S[SSB (temp[0])]) << 24) \ + ^ ((word32) (S[SSB (temp[1])]) << 16) \ + ^ ((word32) (S[SSB (temp[2])]) << 8) \ + ^ (word32) (S[SSB (temp[3])]) \ + ^ roundkey[1]; \ + text[2] = ((word32) (S[TSB (temp[0])]) << 24) \ + ^ ((word32) (S[TSB (temp[1])]) << 16) \ + ^ ((word32) (S[TSB (temp[2])]) << 8) \ + ^ (word32) (S[TSB (temp[3])]) \ + ^ roundkey[2]; \ + text[3] = ((word32) (S[LSB (temp[0])]) << 24) \ + ^ ((word32) (S[LSB (temp[1])]) << 16) \ + ^ ((word32) (S[LSB (temp[2])]) << 8) \ + ^ (word32) (S[LSB (temp[3])]) \ + ^ roundkey[3]; \ +} /* squareFinal */ + +typedef BlockGetAndPut Block; + +void Square::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word32 text[4], temp[4]; + Block::Get(inBlock)(text[0])(text[1])(text[2])(text[3]); + + /* initial key addition */ + text[0] ^= roundkeys[0][0]; + text[1] ^= roundkeys[0][1]; + text[2] ^= roundkeys[0][2]; + text[3] ^= roundkeys[0][3]; + + /* ROUNDS - 1 full rounds */ + for (int i=1; i+1, public FixedKeyLength<16>, FixedRounds<8> +{ + static const char *StaticAlgorithmName() {return "Square";} +}; + +/// Square +class Square : public Square_Info, public BlockCipherDocumentation +{ + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + public: + void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); + + protected: + FixedSizeSecBlock roundkeys; + }; + + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + private: + static const byte Se[256]; + static const word32 Te[4][256]; + }; + + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + private: + static const byte Sd[256]; + static const word32 Td[4][256]; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef Square::Encryption SquareEncryption; +typedef Square::Decryption SquareDecryption; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/squaretb.cpp b/CryptoPP/crypto/squaretb.cpp new file mode 100644 index 0000000..a54465a --- /dev/null +++ b/CryptoPP/crypto/squaretb.cpp @@ -0,0 +1,582 @@ +#include "pch.h" +#include "square.h" + +NAMESPACE_BEGIN(CryptoPP) + +const byte Square::Enc::Se[256] = { +177, 206, 195, 149, 90, 173, 231, 2, 77, 68, 251, 145, 12, 135, 161, 80, +203, 103, 84, 221, 70, 143, 225, 78, 240, 253, 252, 235, 249, 196, 26, 110, + 94, 245, 204, 141, 28, 86, 67, 254, 7, 97, 248, 117, 89, 255, 3, 34, +138, 209, 19, 238, 136, 0, 14, 52, 21, 128, 148, 227, 237, 181, 83, 35, + 75, 71, 23, 167, 144, 53, 171, 216, 184, 223, 79, 87, 154, 146, 219, 27, + 60, 200, 153, 4, 142, 224, 215, 125, 133, 187, 64, 44, 58, 69, 241, 66, +101, 32, 65, 24, 114, 37, 147, 112, 54, 5, 242, 11, 163, 121, 236, 8, + 39, 49, 50, 182, 124, 176, 10, 115, 91, 123, 183, 129, 210, 13, 106, 38, +158, 88, 156, 131, 116, 179, 172, 48, 122, 105, 119, 15, 174, 33, 222, 208, + 46, 151, 16, 164, 152, 168, 212, 104, 45, 98, 41, 109, 22, 73, 118, 199, +232, 193, 150, 55, 229, 202, 244, 233, 99, 18, 194, 166, 20, 188, 211, 40, +175, 47, 230, 36, 82, 198, 160, 9, 189, 140, 207, 93, 17, 95, 1, 197, +159, 61, 162, 155, 201, 59, 190, 81, 25, 31, 63, 92, 178, 239, 74, 205, +191, 186, 111, 100, 217, 243, 62, 180, 170, 220, 213, 6, 192, 126, 246, 102, +108, 132, 113, 56, 185, 29, 127, 157, 72, 139, 42, 218, 165, 51, 130, 57, +214, 120, 134, 250, 228, 43, 169, 30, 137, 96, 107, 234, 85, 76, 247, 226, +}; + +const byte Square::Dec::Sd[256] = { + 53, 190, 7, 46, 83, 105, 219, 40, 111, 183, 118, 107, 12, 125, 54, 139, +146, 188, 169, 50, 172, 56, 156, 66, 99, 200, 30, 79, 36, 229, 247, 201, + 97, 141, 47, 63, 179, 101, 127, 112, 175, 154, 234, 245, 91, 152, 144, 177, +135, 113, 114, 237, 55, 69, 104, 163, 227, 239, 92, 197, 80, 193, 214, 202, + 90, 98, 95, 38, 9, 93, 20, 65, 232, 157, 206, 64, 253, 8, 23, 74, + 15, 199, 180, 62, 18, 252, 37, 75, 129, 44, 4, 120, 203, 187, 32, 189, +249, 41, 153, 168, 211, 96, 223, 17, 151, 137, 126, 250, 224, 155, 31, 210, +103, 226, 100, 119, 132, 43, 158, 138, 241, 109, 136, 121, 116, 87, 221, 230, + 57, 123, 238, 131, 225, 88, 242, 13, 52, 248, 48, 233, 185, 35, 84, 21, + 68, 11, 77, 102, 58, 3, 162, 145, 148, 82, 76, 195, 130, 231, 128, 192, +182, 14, 194, 108, 147, 236, 171, 67, 149, 246, 216, 70, 134, 5, 140, 176, +117, 0, 204, 133, 215, 61, 115, 122, 72, 228, 209, 89, 173, 184, 198, 208, +220, 161, 170, 2, 29, 191, 181, 159, 81, 196, 165, 16, 34, 207, 1, 186, +143, 49, 124, 174, 150, 218, 240, 86, 71, 212, 235, 78, 217, 19, 142, 73, + 85, 22, 255, 59, 244, 164, 178, 6, 160, 167, 251, 27, 110, 60, 51, 205, + 24, 94, 106, 213, 166, 33, 222, 254, 42, 28, 243, 10, 26, 25, 39, 45, +}; + +const word32 Square::Enc::Te[4][256] = { +{ +0x97b1b126UL, 0x69cecea7UL, 0x73c3c3b0UL, 0xdf95954aUL, +0xb45a5aeeUL, 0xafadad02UL, 0x3be7e7dcUL, 0x04020206UL, +0x9a4d4dd7UL, 0x884444ccUL, 0x03fbfbf8UL, 0xd7919146UL, +0x180c0c14UL, 0xfb87877cUL, 0xb7a1a116UL, 0xa05050f0UL, +0x63cbcba8UL, 0xce6767a9UL, 0xa85454fcUL, 0x4fdddd92UL, +0x8c4646caUL, 0xeb8f8f64UL, 0x37e1e1d6UL, 0x9c4e4ed2UL, +0x15f0f0e5UL, 0x0ffdfdf2UL, 0x0dfcfcf1UL, 0x23ebebc8UL, +0x07f9f9feUL, 0x7dc4c4b9UL, 0x341a1a2eUL, 0xdc6e6eb2UL, +0xbc5e5ee2UL, 0x1ff5f5eaUL, 0x6dcccca1UL, 0xef8d8d62UL, +0x381c1c24UL, 0xac5656faUL, 0x864343c5UL, 0x09fefef7UL, +0x0e070709UL, 0xc26161a3UL, 0x05f8f8fdUL, 0xea75759fUL, +0xb25959ebUL, 0x0bfffff4UL, 0x06030305UL, 0x44222266UL, +0xe18a8a6bUL, 0x57d1d186UL, 0x26131335UL, 0x29eeeec7UL, +0xe588886dUL, 0x00000000UL, 0x1c0e0e12UL, 0x6834345cUL, +0x2a15153fUL, 0xf5808075UL, 0xdd949449UL, 0x33e3e3d0UL, +0x2fededc2UL, 0x9fb5b52aUL, 0xa65353f5UL, 0x46232365UL, +0x964b4bddUL, 0x8e4747c9UL, 0x2e171739UL, 0xbba7a71cUL, +0xd5909045UL, 0x6a35355fUL, 0xa3abab08UL, 0x45d8d89dUL, +0x85b8b83dUL, 0x4bdfdf94UL, 0x9e4f4fd1UL, 0xae5757f9UL, +0xc19a9a5bUL, 0xd1929243UL, 0x43dbdb98UL, 0x361b1b2dUL, +0x783c3c44UL, 0x65c8c8adUL, 0xc799995eUL, 0x0804040cUL, +0xe98e8e67UL, 0x35e0e0d5UL, 0x5bd7d78cUL, 0xfa7d7d87UL, +0xff85857aUL, 0x83bbbb38UL, 0x804040c0UL, 0x582c2c74UL, +0x743a3a4eUL, 0x8a4545cfUL, 0x17f1f1e6UL, 0x844242c6UL, +0xca6565afUL, 0x40202060UL, 0x824141c3UL, 0x30181828UL, +0xe4727296UL, 0x4a25256fUL, 0xd3939340UL, 0xe0707090UL, +0x6c36365aUL, 0x0a05050fUL, 0x11f2f2e3UL, 0x160b0b1dUL, +0xb3a3a310UL, 0xf279798bUL, 0x2dececc1UL, 0x10080818UL, +0x4e272769UL, 0x62313153UL, 0x64323256UL, 0x99b6b62fUL, +0xf87c7c84UL, 0x95b0b025UL, 0x140a0a1eUL, 0xe6737395UL, +0xb65b5bedUL, 0xf67b7b8dUL, 0x9bb7b72cUL, 0xf7818176UL, +0x51d2d283UL, 0x1a0d0d17UL, 0xd46a6abeUL, 0x4c26266aUL, +0xc99e9e57UL, 0xb05858e8UL, 0xcd9c9c51UL, 0xf3838370UL, +0xe874749cUL, 0x93b3b320UL, 0xadacac01UL, 0x60303050UL, +0xf47a7a8eUL, 0xd26969bbUL, 0xee777799UL, 0x1e0f0f11UL, +0xa9aeae07UL, 0x42212163UL, 0x49dede97UL, 0x55d0d085UL, +0x5c2e2e72UL, 0xdb97974cUL, 0x20101030UL, 0xbda4a419UL, +0xc598985dUL, 0xa5a8a80dUL, 0x5dd4d489UL, 0xd06868b8UL, +0x5a2d2d77UL, 0xc46262a6UL, 0x5229297bUL, 0xda6d6db7UL, +0x2c16163aUL, 0x924949dbUL, 0xec76769aUL, 0x7bc7c7bcUL, +0x25e8e8cdUL, 0x77c1c1b6UL, 0xd996964fUL, 0x6e373759UL, +0x3fe5e5daUL, 0x61cacaabUL, 0x1df4f4e9UL, 0x27e9e9ceUL, +0xc66363a5UL, 0x24121236UL, 0x71c2c2b3UL, 0xb9a6a61fUL, +0x2814143cUL, 0x8dbcbc31UL, 0x53d3d380UL, 0x50282878UL, +0xabafaf04UL, 0x5e2f2f71UL, 0x39e6e6dfUL, 0x4824246cUL, +0xa45252f6UL, 0x79c6c6bfUL, 0xb5a0a015UL, 0x1209091bUL, +0x8fbdbd32UL, 0xed8c8c61UL, 0x6bcfcfa4UL, 0xba5d5de7UL, +0x22111133UL, 0xbe5f5fe1UL, 0x02010103UL, 0x7fc5c5baUL, +0xcb9f9f54UL, 0x7a3d3d47UL, 0xb1a2a213UL, 0xc39b9b58UL, +0x67c9c9aeUL, 0x763b3b4dUL, 0x89bebe37UL, 0xa25151f3UL, +0x3219192bUL, 0x3e1f1f21UL, 0x7e3f3f41UL, 0xb85c5ce4UL, +0x91b2b223UL, 0x2befefc4UL, 0x944a4adeUL, 0x6fcdcda2UL, +0x8bbfbf34UL, 0x81baba3bUL, 0xde6f6fb1UL, 0xc86464acUL, +0x47d9d99eUL, 0x13f3f3e0UL, 0x7c3e3e42UL, 0x9db4b429UL, +0xa1aaaa0bUL, 0x4ddcdc91UL, 0x5fd5d58aUL, 0x0c06060aUL, +0x75c0c0b5UL, 0xfc7e7e82UL, 0x19f6f6efUL, 0xcc6666aaUL, +0xd86c6cb4UL, 0xfd848479UL, 0xe2717193UL, 0x70383848UL, +0x87b9b93eUL, 0x3a1d1d27UL, 0xfe7f7f81UL, 0xcf9d9d52UL, +0x904848d8UL, 0xe38b8b68UL, 0x542a2a7eUL, 0x41dada9bUL, +0xbfa5a51aUL, 0x66333355UL, 0xf1828273UL, 0x7239394bUL, +0x59d6d68fUL, 0xf0787888UL, 0xf986867fUL, 0x01fafafbUL, +0x3de4e4d9UL, 0x562b2b7dUL, 0xa7a9a90eUL, 0x3c1e1e22UL, +0xe789896eUL, 0xc06060a0UL, 0xd66b6bbdUL, 0x21eaeacbUL, +0xaa5555ffUL, 0x984c4cd4UL, 0x1bf7f7ecUL, 0x31e2e2d3UL, +}, + +{ +0x2697b1b1UL, 0xa769ceceUL, 0xb073c3c3UL, 0x4adf9595UL, +0xeeb45a5aUL, 0x02afadadUL, 0xdc3be7e7UL, 0x06040202UL, +0xd79a4d4dUL, 0xcc884444UL, 0xf803fbfbUL, 0x46d79191UL, +0x14180c0cUL, 0x7cfb8787UL, 0x16b7a1a1UL, 0xf0a05050UL, +0xa863cbcbUL, 0xa9ce6767UL, 0xfca85454UL, 0x924fddddUL, +0xca8c4646UL, 0x64eb8f8fUL, 0xd637e1e1UL, 0xd29c4e4eUL, +0xe515f0f0UL, 0xf20ffdfdUL, 0xf10dfcfcUL, 0xc823ebebUL, +0xfe07f9f9UL, 0xb97dc4c4UL, 0x2e341a1aUL, 0xb2dc6e6eUL, +0xe2bc5e5eUL, 0xea1ff5f5UL, 0xa16dccccUL, 0x62ef8d8dUL, +0x24381c1cUL, 0xfaac5656UL, 0xc5864343UL, 0xf709fefeUL, +0x090e0707UL, 0xa3c26161UL, 0xfd05f8f8UL, 0x9fea7575UL, +0xebb25959UL, 0xf40bffffUL, 0x05060303UL, 0x66442222UL, +0x6be18a8aUL, 0x8657d1d1UL, 0x35261313UL, 0xc729eeeeUL, +0x6de58888UL, 0x00000000UL, 0x121c0e0eUL, 0x5c683434UL, +0x3f2a1515UL, 0x75f58080UL, 0x49dd9494UL, 0xd033e3e3UL, +0xc22fededUL, 0x2a9fb5b5UL, 0xf5a65353UL, 0x65462323UL, +0xdd964b4bUL, 0xc98e4747UL, 0x392e1717UL, 0x1cbba7a7UL, +0x45d59090UL, 0x5f6a3535UL, 0x08a3ababUL, 0x9d45d8d8UL, +0x3d85b8b8UL, 0x944bdfdfUL, 0xd19e4f4fUL, 0xf9ae5757UL, +0x5bc19a9aUL, 0x43d19292UL, 0x9843dbdbUL, 0x2d361b1bUL, +0x44783c3cUL, 0xad65c8c8UL, 0x5ec79999UL, 0x0c080404UL, +0x67e98e8eUL, 0xd535e0e0UL, 0x8c5bd7d7UL, 0x87fa7d7dUL, +0x7aff8585UL, 0x3883bbbbUL, 0xc0804040UL, 0x74582c2cUL, +0x4e743a3aUL, 0xcf8a4545UL, 0xe617f1f1UL, 0xc6844242UL, +0xafca6565UL, 0x60402020UL, 0xc3824141UL, 0x28301818UL, +0x96e47272UL, 0x6f4a2525UL, 0x40d39393UL, 0x90e07070UL, +0x5a6c3636UL, 0x0f0a0505UL, 0xe311f2f2UL, 0x1d160b0bUL, +0x10b3a3a3UL, 0x8bf27979UL, 0xc12dececUL, 0x18100808UL, +0x694e2727UL, 0x53623131UL, 0x56643232UL, 0x2f99b6b6UL, +0x84f87c7cUL, 0x2595b0b0UL, 0x1e140a0aUL, 0x95e67373UL, +0xedb65b5bUL, 0x8df67b7bUL, 0x2c9bb7b7UL, 0x76f78181UL, +0x8351d2d2UL, 0x171a0d0dUL, 0xbed46a6aUL, 0x6a4c2626UL, +0x57c99e9eUL, 0xe8b05858UL, 0x51cd9c9cUL, 0x70f38383UL, +0x9ce87474UL, 0x2093b3b3UL, 0x01adacacUL, 0x50603030UL, +0x8ef47a7aUL, 0xbbd26969UL, 0x99ee7777UL, 0x111e0f0fUL, +0x07a9aeaeUL, 0x63422121UL, 0x9749dedeUL, 0x8555d0d0UL, +0x725c2e2eUL, 0x4cdb9797UL, 0x30201010UL, 0x19bda4a4UL, +0x5dc59898UL, 0x0da5a8a8UL, 0x895dd4d4UL, 0xb8d06868UL, +0x775a2d2dUL, 0xa6c46262UL, 0x7b522929UL, 0xb7da6d6dUL, +0x3a2c1616UL, 0xdb924949UL, 0x9aec7676UL, 0xbc7bc7c7UL, +0xcd25e8e8UL, 0xb677c1c1UL, 0x4fd99696UL, 0x596e3737UL, +0xda3fe5e5UL, 0xab61cacaUL, 0xe91df4f4UL, 0xce27e9e9UL, +0xa5c66363UL, 0x36241212UL, 0xb371c2c2UL, 0x1fb9a6a6UL, +0x3c281414UL, 0x318dbcbcUL, 0x8053d3d3UL, 0x78502828UL, +0x04abafafUL, 0x715e2f2fUL, 0xdf39e6e6UL, 0x6c482424UL, +0xf6a45252UL, 0xbf79c6c6UL, 0x15b5a0a0UL, 0x1b120909UL, +0x328fbdbdUL, 0x61ed8c8cUL, 0xa46bcfcfUL, 0xe7ba5d5dUL, +0x33221111UL, 0xe1be5f5fUL, 0x03020101UL, 0xba7fc5c5UL, +0x54cb9f9fUL, 0x477a3d3dUL, 0x13b1a2a2UL, 0x58c39b9bUL, +0xae67c9c9UL, 0x4d763b3bUL, 0x3789bebeUL, 0xf3a25151UL, +0x2b321919UL, 0x213e1f1fUL, 0x417e3f3fUL, 0xe4b85c5cUL, +0x2391b2b2UL, 0xc42befefUL, 0xde944a4aUL, 0xa26fcdcdUL, +0x348bbfbfUL, 0x3b81babaUL, 0xb1de6f6fUL, 0xacc86464UL, +0x9e47d9d9UL, 0xe013f3f3UL, 0x427c3e3eUL, 0x299db4b4UL, +0x0ba1aaaaUL, 0x914ddcdcUL, 0x8a5fd5d5UL, 0x0a0c0606UL, +0xb575c0c0UL, 0x82fc7e7eUL, 0xef19f6f6UL, 0xaacc6666UL, +0xb4d86c6cUL, 0x79fd8484UL, 0x93e27171UL, 0x48703838UL, +0x3e87b9b9UL, 0x273a1d1dUL, 0x81fe7f7fUL, 0x52cf9d9dUL, +0xd8904848UL, 0x68e38b8bUL, 0x7e542a2aUL, 0x9b41dadaUL, +0x1abfa5a5UL, 0x55663333UL, 0x73f18282UL, 0x4b723939UL, +0x8f59d6d6UL, 0x88f07878UL, 0x7ff98686UL, 0xfb01fafaUL, +0xd93de4e4UL, 0x7d562b2bUL, 0x0ea7a9a9UL, 0x223c1e1eUL, +0x6ee78989UL, 0xa0c06060UL, 0xbdd66b6bUL, 0xcb21eaeaUL, +0xffaa5555UL, 0xd4984c4cUL, 0xec1bf7f7UL, 0xd331e2e2UL, +}, + +{ +0xb12697b1UL, 0xcea769ceUL, 0xc3b073c3UL, 0x954adf95UL, +0x5aeeb45aUL, 0xad02afadUL, 0xe7dc3be7UL, 0x02060402UL, +0x4dd79a4dUL, 0x44cc8844UL, 0xfbf803fbUL, 0x9146d791UL, +0x0c14180cUL, 0x877cfb87UL, 0xa116b7a1UL, 0x50f0a050UL, +0xcba863cbUL, 0x67a9ce67UL, 0x54fca854UL, 0xdd924fddUL, +0x46ca8c46UL, 0x8f64eb8fUL, 0xe1d637e1UL, 0x4ed29c4eUL, +0xf0e515f0UL, 0xfdf20ffdUL, 0xfcf10dfcUL, 0xebc823ebUL, +0xf9fe07f9UL, 0xc4b97dc4UL, 0x1a2e341aUL, 0x6eb2dc6eUL, +0x5ee2bc5eUL, 0xf5ea1ff5UL, 0xcca16dccUL, 0x8d62ef8dUL, +0x1c24381cUL, 0x56faac56UL, 0x43c58643UL, 0xfef709feUL, +0x07090e07UL, 0x61a3c261UL, 0xf8fd05f8UL, 0x759fea75UL, +0x59ebb259UL, 0xfff40bffUL, 0x03050603UL, 0x22664422UL, +0x8a6be18aUL, 0xd18657d1UL, 0x13352613UL, 0xeec729eeUL, +0x886de588UL, 0x00000000UL, 0x0e121c0eUL, 0x345c6834UL, +0x153f2a15UL, 0x8075f580UL, 0x9449dd94UL, 0xe3d033e3UL, +0xedc22fedUL, 0xb52a9fb5UL, 0x53f5a653UL, 0x23654623UL, +0x4bdd964bUL, 0x47c98e47UL, 0x17392e17UL, 0xa71cbba7UL, +0x9045d590UL, 0x355f6a35UL, 0xab08a3abUL, 0xd89d45d8UL, +0xb83d85b8UL, 0xdf944bdfUL, 0x4fd19e4fUL, 0x57f9ae57UL, +0x9a5bc19aUL, 0x9243d192UL, 0xdb9843dbUL, 0x1b2d361bUL, +0x3c44783cUL, 0xc8ad65c8UL, 0x995ec799UL, 0x040c0804UL, +0x8e67e98eUL, 0xe0d535e0UL, 0xd78c5bd7UL, 0x7d87fa7dUL, +0x857aff85UL, 0xbb3883bbUL, 0x40c08040UL, 0x2c74582cUL, +0x3a4e743aUL, 0x45cf8a45UL, 0xf1e617f1UL, 0x42c68442UL, +0x65afca65UL, 0x20604020UL, 0x41c38241UL, 0x18283018UL, +0x7296e472UL, 0x256f4a25UL, 0x9340d393UL, 0x7090e070UL, +0x365a6c36UL, 0x050f0a05UL, 0xf2e311f2UL, 0x0b1d160bUL, +0xa310b3a3UL, 0x798bf279UL, 0xecc12decUL, 0x08181008UL, +0x27694e27UL, 0x31536231UL, 0x32566432UL, 0xb62f99b6UL, +0x7c84f87cUL, 0xb02595b0UL, 0x0a1e140aUL, 0x7395e673UL, +0x5bedb65bUL, 0x7b8df67bUL, 0xb72c9bb7UL, 0x8176f781UL, +0xd28351d2UL, 0x0d171a0dUL, 0x6abed46aUL, 0x266a4c26UL, +0x9e57c99eUL, 0x58e8b058UL, 0x9c51cd9cUL, 0x8370f383UL, +0x749ce874UL, 0xb32093b3UL, 0xac01adacUL, 0x30506030UL, +0x7a8ef47aUL, 0x69bbd269UL, 0x7799ee77UL, 0x0f111e0fUL, +0xae07a9aeUL, 0x21634221UL, 0xde9749deUL, 0xd08555d0UL, +0x2e725c2eUL, 0x974cdb97UL, 0x10302010UL, 0xa419bda4UL, +0x985dc598UL, 0xa80da5a8UL, 0xd4895dd4UL, 0x68b8d068UL, +0x2d775a2dUL, 0x62a6c462UL, 0x297b5229UL, 0x6db7da6dUL, +0x163a2c16UL, 0x49db9249UL, 0x769aec76UL, 0xc7bc7bc7UL, +0xe8cd25e8UL, 0xc1b677c1UL, 0x964fd996UL, 0x37596e37UL, +0xe5da3fe5UL, 0xcaab61caUL, 0xf4e91df4UL, 0xe9ce27e9UL, +0x63a5c663UL, 0x12362412UL, 0xc2b371c2UL, 0xa61fb9a6UL, +0x143c2814UL, 0xbc318dbcUL, 0xd38053d3UL, 0x28785028UL, +0xaf04abafUL, 0x2f715e2fUL, 0xe6df39e6UL, 0x246c4824UL, +0x52f6a452UL, 0xc6bf79c6UL, 0xa015b5a0UL, 0x091b1209UL, +0xbd328fbdUL, 0x8c61ed8cUL, 0xcfa46bcfUL, 0x5de7ba5dUL, +0x11332211UL, 0x5fe1be5fUL, 0x01030201UL, 0xc5ba7fc5UL, +0x9f54cb9fUL, 0x3d477a3dUL, 0xa213b1a2UL, 0x9b58c39bUL, +0xc9ae67c9UL, 0x3b4d763bUL, 0xbe3789beUL, 0x51f3a251UL, +0x192b3219UL, 0x1f213e1fUL, 0x3f417e3fUL, 0x5ce4b85cUL, +0xb22391b2UL, 0xefc42befUL, 0x4ade944aUL, 0xcda26fcdUL, +0xbf348bbfUL, 0xba3b81baUL, 0x6fb1de6fUL, 0x64acc864UL, +0xd99e47d9UL, 0xf3e013f3UL, 0x3e427c3eUL, 0xb4299db4UL, +0xaa0ba1aaUL, 0xdc914ddcUL, 0xd58a5fd5UL, 0x060a0c06UL, +0xc0b575c0UL, 0x7e82fc7eUL, 0xf6ef19f6UL, 0x66aacc66UL, +0x6cb4d86cUL, 0x8479fd84UL, 0x7193e271UL, 0x38487038UL, +0xb93e87b9UL, 0x1d273a1dUL, 0x7f81fe7fUL, 0x9d52cf9dUL, +0x48d89048UL, 0x8b68e38bUL, 0x2a7e542aUL, 0xda9b41daUL, +0xa51abfa5UL, 0x33556633UL, 0x8273f182UL, 0x394b7239UL, +0xd68f59d6UL, 0x7888f078UL, 0x867ff986UL, 0xfafb01faUL, +0xe4d93de4UL, 0x2b7d562bUL, 0xa90ea7a9UL, 0x1e223c1eUL, +0x896ee789UL, 0x60a0c060UL, 0x6bbdd66bUL, 0xeacb21eaUL, +0x55ffaa55UL, 0x4cd4984cUL, 0xf7ec1bf7UL, 0xe2d331e2UL, +}, + +{ +0xb1b12697UL, 0xcecea769UL, 0xc3c3b073UL, 0x95954adfUL, +0x5a5aeeb4UL, 0xadad02afUL, 0xe7e7dc3bUL, 0x02020604UL, +0x4d4dd79aUL, 0x4444cc88UL, 0xfbfbf803UL, 0x919146d7UL, +0x0c0c1418UL, 0x87877cfbUL, 0xa1a116b7UL, 0x5050f0a0UL, +0xcbcba863UL, 0x6767a9ceUL, 0x5454fca8UL, 0xdddd924fUL, +0x4646ca8cUL, 0x8f8f64ebUL, 0xe1e1d637UL, 0x4e4ed29cUL, +0xf0f0e515UL, 0xfdfdf20fUL, 0xfcfcf10dUL, 0xebebc823UL, +0xf9f9fe07UL, 0xc4c4b97dUL, 0x1a1a2e34UL, 0x6e6eb2dcUL, +0x5e5ee2bcUL, 0xf5f5ea1fUL, 0xcccca16dUL, 0x8d8d62efUL, +0x1c1c2438UL, 0x5656faacUL, 0x4343c586UL, 0xfefef709UL, +0x0707090eUL, 0x6161a3c2UL, 0xf8f8fd05UL, 0x75759feaUL, +0x5959ebb2UL, 0xfffff40bUL, 0x03030506UL, 0x22226644UL, +0x8a8a6be1UL, 0xd1d18657UL, 0x13133526UL, 0xeeeec729UL, +0x88886de5UL, 0x00000000UL, 0x0e0e121cUL, 0x34345c68UL, +0x15153f2aUL, 0x808075f5UL, 0x949449ddUL, 0xe3e3d033UL, +0xededc22fUL, 0xb5b52a9fUL, 0x5353f5a6UL, 0x23236546UL, +0x4b4bdd96UL, 0x4747c98eUL, 0x1717392eUL, 0xa7a71cbbUL, +0x909045d5UL, 0x35355f6aUL, 0xabab08a3UL, 0xd8d89d45UL, +0xb8b83d85UL, 0xdfdf944bUL, 0x4f4fd19eUL, 0x5757f9aeUL, +0x9a9a5bc1UL, 0x929243d1UL, 0xdbdb9843UL, 0x1b1b2d36UL, +0x3c3c4478UL, 0xc8c8ad65UL, 0x99995ec7UL, 0x04040c08UL, +0x8e8e67e9UL, 0xe0e0d535UL, 0xd7d78c5bUL, 0x7d7d87faUL, +0x85857affUL, 0xbbbb3883UL, 0x4040c080UL, 0x2c2c7458UL, +0x3a3a4e74UL, 0x4545cf8aUL, 0xf1f1e617UL, 0x4242c684UL, +0x6565afcaUL, 0x20206040UL, 0x4141c382UL, 0x18182830UL, +0x727296e4UL, 0x25256f4aUL, 0x939340d3UL, 0x707090e0UL, +0x36365a6cUL, 0x05050f0aUL, 0xf2f2e311UL, 0x0b0b1d16UL, +0xa3a310b3UL, 0x79798bf2UL, 0xececc12dUL, 0x08081810UL, +0x2727694eUL, 0x31315362UL, 0x32325664UL, 0xb6b62f99UL, +0x7c7c84f8UL, 0xb0b02595UL, 0x0a0a1e14UL, 0x737395e6UL, +0x5b5bedb6UL, 0x7b7b8df6UL, 0xb7b72c9bUL, 0x818176f7UL, +0xd2d28351UL, 0x0d0d171aUL, 0x6a6abed4UL, 0x26266a4cUL, +0x9e9e57c9UL, 0x5858e8b0UL, 0x9c9c51cdUL, 0x838370f3UL, +0x74749ce8UL, 0xb3b32093UL, 0xacac01adUL, 0x30305060UL, +0x7a7a8ef4UL, 0x6969bbd2UL, 0x777799eeUL, 0x0f0f111eUL, +0xaeae07a9UL, 0x21216342UL, 0xdede9749UL, 0xd0d08555UL, +0x2e2e725cUL, 0x97974cdbUL, 0x10103020UL, 0xa4a419bdUL, +0x98985dc5UL, 0xa8a80da5UL, 0xd4d4895dUL, 0x6868b8d0UL, +0x2d2d775aUL, 0x6262a6c4UL, 0x29297b52UL, 0x6d6db7daUL, +0x16163a2cUL, 0x4949db92UL, 0x76769aecUL, 0xc7c7bc7bUL, +0xe8e8cd25UL, 0xc1c1b677UL, 0x96964fd9UL, 0x3737596eUL, +0xe5e5da3fUL, 0xcacaab61UL, 0xf4f4e91dUL, 0xe9e9ce27UL, +0x6363a5c6UL, 0x12123624UL, 0xc2c2b371UL, 0xa6a61fb9UL, +0x14143c28UL, 0xbcbc318dUL, 0xd3d38053UL, 0x28287850UL, +0xafaf04abUL, 0x2f2f715eUL, 0xe6e6df39UL, 0x24246c48UL, +0x5252f6a4UL, 0xc6c6bf79UL, 0xa0a015b5UL, 0x09091b12UL, +0xbdbd328fUL, 0x8c8c61edUL, 0xcfcfa46bUL, 0x5d5de7baUL, +0x11113322UL, 0x5f5fe1beUL, 0x01010302UL, 0xc5c5ba7fUL, +0x9f9f54cbUL, 0x3d3d477aUL, 0xa2a213b1UL, 0x9b9b58c3UL, +0xc9c9ae67UL, 0x3b3b4d76UL, 0xbebe3789UL, 0x5151f3a2UL, +0x19192b32UL, 0x1f1f213eUL, 0x3f3f417eUL, 0x5c5ce4b8UL, +0xb2b22391UL, 0xefefc42bUL, 0x4a4ade94UL, 0xcdcda26fUL, +0xbfbf348bUL, 0xbaba3b81UL, 0x6f6fb1deUL, 0x6464acc8UL, +0xd9d99e47UL, 0xf3f3e013UL, 0x3e3e427cUL, 0xb4b4299dUL, +0xaaaa0ba1UL, 0xdcdc914dUL, 0xd5d58a5fUL, 0x06060a0cUL, +0xc0c0b575UL, 0x7e7e82fcUL, 0xf6f6ef19UL, 0x6666aaccUL, +0x6c6cb4d8UL, 0x848479fdUL, 0x717193e2UL, 0x38384870UL, +0xb9b93e87UL, 0x1d1d273aUL, 0x7f7f81feUL, 0x9d9d52cfUL, +0x4848d890UL, 0x8b8b68e3UL, 0x2a2a7e54UL, 0xdada9b41UL, +0xa5a51abfUL, 0x33335566UL, 0x828273f1UL, 0x39394b72UL, +0xd6d68f59UL, 0x787888f0UL, 0x86867ff9UL, 0xfafafb01UL, +0xe4e4d93dUL, 0x2b2b7d56UL, 0xa9a90ea7UL, 0x1e1e223cUL, +0x89896ee7UL, 0x6060a0c0UL, 0x6b6bbdd6UL, 0xeaeacb21UL, +0x5555ffaaUL, 0x4c4cd498UL, 0xf7f7ec1bUL, 0xe2e2d331UL, +}}; + +const word32 Square::Dec::Td[4][256] = { +{ +0xe368bc02UL, 0x5585620cUL, 0x2a3f2331UL, 0x61ab13f7UL, +0x98d46d72UL, 0x21cb9a19UL, 0x3c22a461UL, 0x459d3dcdUL, +0x05fdb423UL, 0x2bc4075fUL, 0x9b2c01c0UL, 0x3dd9800fUL, +0x486c5c74UL, 0xf97f7e85UL, 0xf173ab1fUL, 0xb6edde0eUL, +0x283c6bedUL, 0x4997781aUL, 0x9f2a918dUL, 0xc9579f33UL, +0xa907a8aaUL, 0xa50ded7dUL, 0x7c422d8fUL, 0x764db0c9UL, +0x4d91e857UL, 0xcea963ccUL, 0xb4ee96d2UL, 0x3028e1b6UL, +0x0df161b9UL, 0xbd196726UL, 0x419bad80UL, 0xc0a06ec7UL, +0x5183f241UL, 0x92dbf034UL, 0x6fa21efcUL, 0x8f32ce4cUL, +0x13e03373UL, 0x69a7c66dUL, 0xe56d6493UL, 0xbf1a2ffaUL, +0xbb1cbfb7UL, 0x587403b5UL, 0xe76e2c4fUL, 0x5d89b796UL, +0xe89c052aUL, 0x446619a3UL, 0x342e71fbUL, 0x0ff22965UL, +0xfe81827aUL, 0xb11322f1UL, 0xa30835ecUL, 0xcd510f7eUL, +0xff7aa614UL, 0x5c7293f8UL, 0x2fc29712UL, 0xf370e3c3UL, +0x992f491cUL, 0xd1431568UL, 0xc2a3261bUL, 0x88cc32b3UL, +0x8acf7a6fUL, 0xb0e8069fUL, 0x7a47f51eUL, 0xd2bb79daUL, +0xe6950821UL, 0x4398e55cUL, 0xd0b83106UL, 0x11e37bafUL, +0x7e416553UL, 0xccaa2b10UL, 0xd8b4e49cUL, 0x6456a7d4UL, +0xfb7c3659UL, 0x724b2084UL, 0xea9f4df6UL, 0x6a5faadfUL, +0x2dc1dfceUL, 0x70486858UL, 0xcaaff381UL, 0x0605d891UL, +0x5a774b69UL, 0x94de28a5UL, 0x39df1042UL, 0x813bc347UL, +0xfc82caa6UL, 0x23c8d2c5UL, 0x03f86cb2UL, 0x080cd59aUL, +0xdab7ac40UL, 0x7db909e1UL, 0x3824342cUL, 0xcf5247a2UL, +0xdcb274d1UL, 0x63a85b2bUL, 0x35d55595UL, 0x479e7511UL, +0x15e5ebe2UL, 0x4b9430c6UL, 0x4a6f14a8UL, 0x91239c86UL, +0x4c6acc39UL, 0x5f8aff4aUL, 0x0406904dUL, 0xee99ddbbUL, +0x1e1152caUL, 0xaaffc418UL, 0xeb646998UL, 0x07fefcffUL, +0x8b345e01UL, 0x567d0ebeUL, 0xbae79bd9UL, 0x4263c132UL, +0x75b5dc7bUL, 0x97264417UL, 0x67aecb66UL, 0x95250ccbUL, +0xec9a9567UL, 0x57862ad0UL, 0x60503799UL, 0xb8e4d305UL, +0x65ad83baUL, 0x19efae35UL, 0xa4f6c913UL, 0xc15b4aa9UL, +0x873e1bd6UL, 0xa0f0595eUL, 0x18148a5bUL, 0xaf02703bUL, +0xab04e076UL, 0xdd4950bfUL, 0xdf4a1863UL, 0xc6a5b656UL, +0x853d530aUL, 0xfa871237UL, 0x77b694a7UL, 0x4665517fUL, +0xed61b109UL, 0x1bece6e9UL, 0xd5458525UL, 0xf5753b52UL, +0x7fba413dUL, 0x27ce4288UL, 0xb2eb4e43UL, 0xd6bde997UL, +0x527b9ef3UL, 0x62537f45UL, 0x2c3afba0UL, 0x7bbcd170UL, +0xb91ff76bUL, 0x121b171dUL, 0xfd79eec8UL, 0x3a277cf0UL, +0x0c0a45d7UL, 0x96dd6079UL, 0x2233f6abUL, 0xacfa1c89UL, +0xc8acbb5dUL, 0xa10b7d30UL, 0xd4bea14bUL, 0xbee10b94UL, +0x25cd0a54UL, 0x547e4662UL, 0xa2f31182UL, 0x17e6a33eUL, +0x263566e6UL, 0xc3580275UL, 0x83388b9bUL, 0x7844bdc2UL, +0x020348dcUL, 0x4f92a08bUL, 0x2e39b37cUL, 0x4e6984e5UL, +0xf0888f71UL, 0x362d3927UL, 0x9cd2fd3fUL, 0x01fb246eUL, +0x893716ddUL, 0x00000000UL, 0xf68d57e0UL, 0xe293986cUL, +0x744ef815UL, 0x9320d45aUL, 0xad0138e7UL, 0xd3405db4UL, +0x1a17c287UL, 0xb3106a2dUL, 0x5078d62fUL, 0xf48e1f3cUL, +0xa70ea5a1UL, 0x71b34c36UL, 0x9ad725aeUL, 0x5e71db24UL, +0x161d8750UL, 0xef62f9d5UL, 0x8d318690UL, 0x1c121a16UL, +0xa6f581cfUL, 0x5b8c6f07UL, 0x37d61d49UL, 0x6e593a92UL, +0x84c67764UL, 0x86c53fb8UL, 0xd746cdf9UL, 0xe090d0b0UL, +0x29c74f83UL, 0xe49640fdUL, 0x0e090d0bUL, 0x6da15620UL, +0x8ec9ea22UL, 0xdb4c882eUL, 0xf776738eUL, 0xb515b2bcUL, +0x10185fc1UL, 0x322ba96aUL, 0x6ba48eb1UL, 0xaef95455UL, +0x406089eeUL, 0x6655ef08UL, 0xe9672144UL, 0x3e21ecbdUL, +0x2030be77UL, 0xf28bc7adUL, 0x80c0e729UL, 0x141ecf8cUL, +0xbce24348UL, 0xc4a6fe8aUL, 0x31d3c5d8UL, 0xb716fa60UL, +0x5380ba9dUL, 0xd94fc0f2UL, 0x1de93e78UL, 0x24362e3aUL, +0xe16bf4deUL, 0xcb54d7efUL, 0x09f7f1f4UL, 0x82c3aff5UL, +0x0bf4b928UL, 0x9d29d951UL, 0xc75e9238UL, 0xf8845aebUL, +0x90d8b8e8UL, 0xdeb13c0dUL, 0x33d08d04UL, 0x685ce203UL, +0xc55ddae4UL, 0x3bdc589eUL, 0x0a0f9d46UL, 0x3fdac8d3UL, +0x598f27dbUL, 0xa8fc8cc4UL, 0x79bf99acUL, 0x6c5a724eUL, +0x8ccaa2feUL, 0x9ed1b5e3UL, 0x1fea76a4UL, 0x73b004eaUL, +}, + +{ +0x02e368bcUL, 0x0c558562UL, 0x312a3f23UL, 0xf761ab13UL, +0x7298d46dUL, 0x1921cb9aUL, 0x613c22a4UL, 0xcd459d3dUL, +0x2305fdb4UL, 0x5f2bc407UL, 0xc09b2c01UL, 0x0f3dd980UL, +0x74486c5cUL, 0x85f97f7eUL, 0x1ff173abUL, 0x0eb6eddeUL, +0xed283c6bUL, 0x1a499778UL, 0x8d9f2a91UL, 0x33c9579fUL, +0xaaa907a8UL, 0x7da50dedUL, 0x8f7c422dUL, 0xc9764db0UL, +0x574d91e8UL, 0xcccea963UL, 0xd2b4ee96UL, 0xb63028e1UL, +0xb90df161UL, 0x26bd1967UL, 0x80419badUL, 0xc7c0a06eUL, +0x415183f2UL, 0x3492dbf0UL, 0xfc6fa21eUL, 0x4c8f32ceUL, +0x7313e033UL, 0x6d69a7c6UL, 0x93e56d64UL, 0xfabf1a2fUL, +0xb7bb1cbfUL, 0xb5587403UL, 0x4fe76e2cUL, 0x965d89b7UL, +0x2ae89c05UL, 0xa3446619UL, 0xfb342e71UL, 0x650ff229UL, +0x7afe8182UL, 0xf1b11322UL, 0xeca30835UL, 0x7ecd510fUL, +0x14ff7aa6UL, 0xf85c7293UL, 0x122fc297UL, 0xc3f370e3UL, +0x1c992f49UL, 0x68d14315UL, 0x1bc2a326UL, 0xb388cc32UL, +0x6f8acf7aUL, 0x9fb0e806UL, 0x1e7a47f5UL, 0xdad2bb79UL, +0x21e69508UL, 0x5c4398e5UL, 0x06d0b831UL, 0xaf11e37bUL, +0x537e4165UL, 0x10ccaa2bUL, 0x9cd8b4e4UL, 0xd46456a7UL, +0x59fb7c36UL, 0x84724b20UL, 0xf6ea9f4dUL, 0xdf6a5faaUL, +0xce2dc1dfUL, 0x58704868UL, 0x81caaff3UL, 0x910605d8UL, +0x695a774bUL, 0xa594de28UL, 0x4239df10UL, 0x47813bc3UL, +0xa6fc82caUL, 0xc523c8d2UL, 0xb203f86cUL, 0x9a080cd5UL, +0x40dab7acUL, 0xe17db909UL, 0x2c382434UL, 0xa2cf5247UL, +0xd1dcb274UL, 0x2b63a85bUL, 0x9535d555UL, 0x11479e75UL, +0xe215e5ebUL, 0xc64b9430UL, 0xa84a6f14UL, 0x8691239cUL, +0x394c6accUL, 0x4a5f8affUL, 0x4d040690UL, 0xbbee99ddUL, +0xca1e1152UL, 0x18aaffc4UL, 0x98eb6469UL, 0xff07fefcUL, +0x018b345eUL, 0xbe567d0eUL, 0xd9bae79bUL, 0x324263c1UL, +0x7b75b5dcUL, 0x17972644UL, 0x6667aecbUL, 0xcb95250cUL, +0x67ec9a95UL, 0xd057862aUL, 0x99605037UL, 0x05b8e4d3UL, +0xba65ad83UL, 0x3519efaeUL, 0x13a4f6c9UL, 0xa9c15b4aUL, +0xd6873e1bUL, 0x5ea0f059UL, 0x5b18148aUL, 0x3baf0270UL, +0x76ab04e0UL, 0xbfdd4950UL, 0x63df4a18UL, 0x56c6a5b6UL, +0x0a853d53UL, 0x37fa8712UL, 0xa777b694UL, 0x7f466551UL, +0x09ed61b1UL, 0xe91bece6UL, 0x25d54585UL, 0x52f5753bUL, +0x3d7fba41UL, 0x8827ce42UL, 0x43b2eb4eUL, 0x97d6bde9UL, +0xf3527b9eUL, 0x4562537fUL, 0xa02c3afbUL, 0x707bbcd1UL, +0x6bb91ff7UL, 0x1d121b17UL, 0xc8fd79eeUL, 0xf03a277cUL, +0xd70c0a45UL, 0x7996dd60UL, 0xab2233f6UL, 0x89acfa1cUL, +0x5dc8acbbUL, 0x30a10b7dUL, 0x4bd4bea1UL, 0x94bee10bUL, +0x5425cd0aUL, 0x62547e46UL, 0x82a2f311UL, 0x3e17e6a3UL, +0xe6263566UL, 0x75c35802UL, 0x9b83388bUL, 0xc27844bdUL, +0xdc020348UL, 0x8b4f92a0UL, 0x7c2e39b3UL, 0xe54e6984UL, +0x71f0888fUL, 0x27362d39UL, 0x3f9cd2fdUL, 0x6e01fb24UL, +0xdd893716UL, 0x00000000UL, 0xe0f68d57UL, 0x6ce29398UL, +0x15744ef8UL, 0x5a9320d4UL, 0xe7ad0138UL, 0xb4d3405dUL, +0x871a17c2UL, 0x2db3106aUL, 0x2f5078d6UL, 0x3cf48e1fUL, +0xa1a70ea5UL, 0x3671b34cUL, 0xae9ad725UL, 0x245e71dbUL, +0x50161d87UL, 0xd5ef62f9UL, 0x908d3186UL, 0x161c121aUL, +0xcfa6f581UL, 0x075b8c6fUL, 0x4937d61dUL, 0x926e593aUL, +0x6484c677UL, 0xb886c53fUL, 0xf9d746cdUL, 0xb0e090d0UL, +0x8329c74fUL, 0xfde49640UL, 0x0b0e090dUL, 0x206da156UL, +0x228ec9eaUL, 0x2edb4c88UL, 0x8ef77673UL, 0xbcb515b2UL, +0xc110185fUL, 0x6a322ba9UL, 0xb16ba48eUL, 0x55aef954UL, +0xee406089UL, 0x086655efUL, 0x44e96721UL, 0xbd3e21ecUL, +0x772030beUL, 0xadf28bc7UL, 0x2980c0e7UL, 0x8c141ecfUL, +0x48bce243UL, 0x8ac4a6feUL, 0xd831d3c5UL, 0x60b716faUL, +0x9d5380baUL, 0xf2d94fc0UL, 0x781de93eUL, 0x3a24362eUL, +0xdee16bf4UL, 0xefcb54d7UL, 0xf409f7f1UL, 0xf582c3afUL, +0x280bf4b9UL, 0x519d29d9UL, 0x38c75e92UL, 0xebf8845aUL, +0xe890d8b8UL, 0x0ddeb13cUL, 0x0433d08dUL, 0x03685ce2UL, +0xe4c55ddaUL, 0x9e3bdc58UL, 0x460a0f9dUL, 0xd33fdac8UL, +0xdb598f27UL, 0xc4a8fc8cUL, 0xac79bf99UL, 0x4e6c5a72UL, +0xfe8ccaa2UL, 0xe39ed1b5UL, 0xa41fea76UL, 0xea73b004UL, +}, + +{ +0xbc02e368UL, 0x620c5585UL, 0x23312a3fUL, 0x13f761abUL, +0x6d7298d4UL, 0x9a1921cbUL, 0xa4613c22UL, 0x3dcd459dUL, +0xb42305fdUL, 0x075f2bc4UL, 0x01c09b2cUL, 0x800f3dd9UL, +0x5c74486cUL, 0x7e85f97fUL, 0xab1ff173UL, 0xde0eb6edUL, +0x6bed283cUL, 0x781a4997UL, 0x918d9f2aUL, 0x9f33c957UL, +0xa8aaa907UL, 0xed7da50dUL, 0x2d8f7c42UL, 0xb0c9764dUL, +0xe8574d91UL, 0x63cccea9UL, 0x96d2b4eeUL, 0xe1b63028UL, +0x61b90df1UL, 0x6726bd19UL, 0xad80419bUL, 0x6ec7c0a0UL, +0xf2415183UL, 0xf03492dbUL, 0x1efc6fa2UL, 0xce4c8f32UL, +0x337313e0UL, 0xc66d69a7UL, 0x6493e56dUL, 0x2ffabf1aUL, +0xbfb7bb1cUL, 0x03b55874UL, 0x2c4fe76eUL, 0xb7965d89UL, +0x052ae89cUL, 0x19a34466UL, 0x71fb342eUL, 0x29650ff2UL, +0x827afe81UL, 0x22f1b113UL, 0x35eca308UL, 0x0f7ecd51UL, +0xa614ff7aUL, 0x93f85c72UL, 0x97122fc2UL, 0xe3c3f370UL, +0x491c992fUL, 0x1568d143UL, 0x261bc2a3UL, 0x32b388ccUL, +0x7a6f8acfUL, 0x069fb0e8UL, 0xf51e7a47UL, 0x79dad2bbUL, +0x0821e695UL, 0xe55c4398UL, 0x3106d0b8UL, 0x7baf11e3UL, +0x65537e41UL, 0x2b10ccaaUL, 0xe49cd8b4UL, 0xa7d46456UL, +0x3659fb7cUL, 0x2084724bUL, 0x4df6ea9fUL, 0xaadf6a5fUL, +0xdfce2dc1UL, 0x68587048UL, 0xf381caafUL, 0xd8910605UL, +0x4b695a77UL, 0x28a594deUL, 0x104239dfUL, 0xc347813bUL, +0xcaa6fc82UL, 0xd2c523c8UL, 0x6cb203f8UL, 0xd59a080cUL, +0xac40dab7UL, 0x09e17db9UL, 0x342c3824UL, 0x47a2cf52UL, +0x74d1dcb2UL, 0x5b2b63a8UL, 0x559535d5UL, 0x7511479eUL, +0xebe215e5UL, 0x30c64b94UL, 0x14a84a6fUL, 0x9c869123UL, +0xcc394c6aUL, 0xff4a5f8aUL, 0x904d0406UL, 0xddbbee99UL, +0x52ca1e11UL, 0xc418aaffUL, 0x6998eb64UL, 0xfcff07feUL, +0x5e018b34UL, 0x0ebe567dUL, 0x9bd9bae7UL, 0xc1324263UL, +0xdc7b75b5UL, 0x44179726UL, 0xcb6667aeUL, 0x0ccb9525UL, +0x9567ec9aUL, 0x2ad05786UL, 0x37996050UL, 0xd305b8e4UL, +0x83ba65adUL, 0xae3519efUL, 0xc913a4f6UL, 0x4aa9c15bUL, +0x1bd6873eUL, 0x595ea0f0UL, 0x8a5b1814UL, 0x703baf02UL, +0xe076ab04UL, 0x50bfdd49UL, 0x1863df4aUL, 0xb656c6a5UL, +0x530a853dUL, 0x1237fa87UL, 0x94a777b6UL, 0x517f4665UL, +0xb109ed61UL, 0xe6e91becUL, 0x8525d545UL, 0x3b52f575UL, +0x413d7fbaUL, 0x428827ceUL, 0x4e43b2ebUL, 0xe997d6bdUL, +0x9ef3527bUL, 0x7f456253UL, 0xfba02c3aUL, 0xd1707bbcUL, +0xf76bb91fUL, 0x171d121bUL, 0xeec8fd79UL, 0x7cf03a27UL, +0x45d70c0aUL, 0x607996ddUL, 0xf6ab2233UL, 0x1c89acfaUL, +0xbb5dc8acUL, 0x7d30a10bUL, 0xa14bd4beUL, 0x0b94bee1UL, +0x0a5425cdUL, 0x4662547eUL, 0x1182a2f3UL, 0xa33e17e6UL, +0x66e62635UL, 0x0275c358UL, 0x8b9b8338UL, 0xbdc27844UL, +0x48dc0203UL, 0xa08b4f92UL, 0xb37c2e39UL, 0x84e54e69UL, +0x8f71f088UL, 0x3927362dUL, 0xfd3f9cd2UL, 0x246e01fbUL, +0x16dd8937UL, 0x00000000UL, 0x57e0f68dUL, 0x986ce293UL, +0xf815744eUL, 0xd45a9320UL, 0x38e7ad01UL, 0x5db4d340UL, +0xc2871a17UL, 0x6a2db310UL, 0xd62f5078UL, 0x1f3cf48eUL, +0xa5a1a70eUL, 0x4c3671b3UL, 0x25ae9ad7UL, 0xdb245e71UL, +0x8750161dUL, 0xf9d5ef62UL, 0x86908d31UL, 0x1a161c12UL, +0x81cfa6f5UL, 0x6f075b8cUL, 0x1d4937d6UL, 0x3a926e59UL, +0x776484c6UL, 0x3fb886c5UL, 0xcdf9d746UL, 0xd0b0e090UL, +0x4f8329c7UL, 0x40fde496UL, 0x0d0b0e09UL, 0x56206da1UL, +0xea228ec9UL, 0x882edb4cUL, 0x738ef776UL, 0xb2bcb515UL, +0x5fc11018UL, 0xa96a322bUL, 0x8eb16ba4UL, 0x5455aef9UL, +0x89ee4060UL, 0xef086655UL, 0x2144e967UL, 0xecbd3e21UL, +0xbe772030UL, 0xc7adf28bUL, 0xe72980c0UL, 0xcf8c141eUL, +0x4348bce2UL, 0xfe8ac4a6UL, 0xc5d831d3UL, 0xfa60b716UL, +0xba9d5380UL, 0xc0f2d94fUL, 0x3e781de9UL, 0x2e3a2436UL, +0xf4dee16bUL, 0xd7efcb54UL, 0xf1f409f7UL, 0xaff582c3UL, +0xb9280bf4UL, 0xd9519d29UL, 0x9238c75eUL, 0x5aebf884UL, +0xb8e890d8UL, 0x3c0ddeb1UL, 0x8d0433d0UL, 0xe203685cUL, +0xdae4c55dUL, 0x589e3bdcUL, 0x9d460a0fUL, 0xc8d33fdaUL, +0x27db598fUL, 0x8cc4a8fcUL, 0x99ac79bfUL, 0x724e6c5aUL, +0xa2fe8ccaUL, 0xb5e39ed1UL, 0x76a41feaUL, 0x04ea73b0UL, +}, + +{ +0x68bc02e3UL, 0x85620c55UL, 0x3f23312aUL, 0xab13f761UL, +0xd46d7298UL, 0xcb9a1921UL, 0x22a4613cUL, 0x9d3dcd45UL, +0xfdb42305UL, 0xc4075f2bUL, 0x2c01c09bUL, 0xd9800f3dUL, +0x6c5c7448UL, 0x7f7e85f9UL, 0x73ab1ff1UL, 0xedde0eb6UL, +0x3c6bed28UL, 0x97781a49UL, 0x2a918d9fUL, 0x579f33c9UL, +0x07a8aaa9UL, 0x0ded7da5UL, 0x422d8f7cUL, 0x4db0c976UL, +0x91e8574dUL, 0xa963ccceUL, 0xee96d2b4UL, 0x28e1b630UL, +0xf161b90dUL, 0x196726bdUL, 0x9bad8041UL, 0xa06ec7c0UL, +0x83f24151UL, 0xdbf03492UL, 0xa21efc6fUL, 0x32ce4c8fUL, +0xe0337313UL, 0xa7c66d69UL, 0x6d6493e5UL, 0x1a2ffabfUL, +0x1cbfb7bbUL, 0x7403b558UL, 0x6e2c4fe7UL, 0x89b7965dUL, +0x9c052ae8UL, 0x6619a344UL, 0x2e71fb34UL, 0xf229650fUL, +0x81827afeUL, 0x1322f1b1UL, 0x0835eca3UL, 0x510f7ecdUL, +0x7aa614ffUL, 0x7293f85cUL, 0xc297122fUL, 0x70e3c3f3UL, +0x2f491c99UL, 0x431568d1UL, 0xa3261bc2UL, 0xcc32b388UL, +0xcf7a6f8aUL, 0xe8069fb0UL, 0x47f51e7aUL, 0xbb79dad2UL, +0x950821e6UL, 0x98e55c43UL, 0xb83106d0UL, 0xe37baf11UL, +0x4165537eUL, 0xaa2b10ccUL, 0xb4e49cd8UL, 0x56a7d464UL, +0x7c3659fbUL, 0x4b208472UL, 0x9f4df6eaUL, 0x5faadf6aUL, +0xc1dfce2dUL, 0x48685870UL, 0xaff381caUL, 0x05d89106UL, +0x774b695aUL, 0xde28a594UL, 0xdf104239UL, 0x3bc34781UL, +0x82caa6fcUL, 0xc8d2c523UL, 0xf86cb203UL, 0x0cd59a08UL, +0xb7ac40daUL, 0xb909e17dUL, 0x24342c38UL, 0x5247a2cfUL, +0xb274d1dcUL, 0xa85b2b63UL, 0xd5559535UL, 0x9e751147UL, +0xe5ebe215UL, 0x9430c64bUL, 0x6f14a84aUL, 0x239c8691UL, +0x6acc394cUL, 0x8aff4a5fUL, 0x06904d04UL, 0x99ddbbeeUL, +0x1152ca1eUL, 0xffc418aaUL, 0x646998ebUL, 0xfefcff07UL, +0x345e018bUL, 0x7d0ebe56UL, 0xe79bd9baUL, 0x63c13242UL, +0xb5dc7b75UL, 0x26441797UL, 0xaecb6667UL, 0x250ccb95UL, +0x9a9567ecUL, 0x862ad057UL, 0x50379960UL, 0xe4d305b8UL, +0xad83ba65UL, 0xefae3519UL, 0xf6c913a4UL, 0x5b4aa9c1UL, +0x3e1bd687UL, 0xf0595ea0UL, 0x148a5b18UL, 0x02703bafUL, +0x04e076abUL, 0x4950bfddUL, 0x4a1863dfUL, 0xa5b656c6UL, +0x3d530a85UL, 0x871237faUL, 0xb694a777UL, 0x65517f46UL, +0x61b109edUL, 0xece6e91bUL, 0x458525d5UL, 0x753b52f5UL, +0xba413d7fUL, 0xce428827UL, 0xeb4e43b2UL, 0xbde997d6UL, +0x7b9ef352UL, 0x537f4562UL, 0x3afba02cUL, 0xbcd1707bUL, +0x1ff76bb9UL, 0x1b171d12UL, 0x79eec8fdUL, 0x277cf03aUL, +0x0a45d70cUL, 0xdd607996UL, 0x33f6ab22UL, 0xfa1c89acUL, +0xacbb5dc8UL, 0x0b7d30a1UL, 0xbea14bd4UL, 0xe10b94beUL, +0xcd0a5425UL, 0x7e466254UL, 0xf31182a2UL, 0xe6a33e17UL, +0x3566e626UL, 0x580275c3UL, 0x388b9b83UL, 0x44bdc278UL, +0x0348dc02UL, 0x92a08b4fUL, 0x39b37c2eUL, 0x6984e54eUL, +0x888f71f0UL, 0x2d392736UL, 0xd2fd3f9cUL, 0xfb246e01UL, +0x3716dd89UL, 0x00000000UL, 0x8d57e0f6UL, 0x93986ce2UL, +0x4ef81574UL, 0x20d45a93UL, 0x0138e7adUL, 0x405db4d3UL, +0x17c2871aUL, 0x106a2db3UL, 0x78d62f50UL, 0x8e1f3cf4UL, +0x0ea5a1a7UL, 0xb34c3671UL, 0xd725ae9aUL, 0x71db245eUL, +0x1d875016UL, 0x62f9d5efUL, 0x3186908dUL, 0x121a161cUL, +0xf581cfa6UL, 0x8c6f075bUL, 0xd61d4937UL, 0x593a926eUL, +0xc6776484UL, 0xc53fb886UL, 0x46cdf9d7UL, 0x90d0b0e0UL, +0xc74f8329UL, 0x9640fde4UL, 0x090d0b0eUL, 0xa156206dUL, +0xc9ea228eUL, 0x4c882edbUL, 0x76738ef7UL, 0x15b2bcb5UL, +0x185fc110UL, 0x2ba96a32UL, 0xa48eb16bUL, 0xf95455aeUL, +0x6089ee40UL, 0x55ef0866UL, 0x672144e9UL, 0x21ecbd3eUL, +0x30be7720UL, 0x8bc7adf2UL, 0xc0e72980UL, 0x1ecf8c14UL, +0xe24348bcUL, 0xa6fe8ac4UL, 0xd3c5d831UL, 0x16fa60b7UL, +0x80ba9d53UL, 0x4fc0f2d9UL, 0xe93e781dUL, 0x362e3a24UL, +0x6bf4dee1UL, 0x54d7efcbUL, 0xf7f1f409UL, 0xc3aff582UL, +0xf4b9280bUL, 0x29d9519dUL, 0x5e9238c7UL, 0x845aebf8UL, +0xd8b8e890UL, 0xb13c0ddeUL, 0xd08d0433UL, 0x5ce20368UL, +0x5ddae4c5UL, 0xdc589e3bUL, 0x0f9d460aUL, 0xdac8d33fUL, +0x8f27db59UL, 0xfc8cc4a8UL, 0xbf99ac79UL, 0x5a724e6cUL, +0xcaa2fe8cUL, 0xd1b5e39eUL, 0xea76a41fUL, 0xb004ea73UL, +}}; + +NAMESPACE_END diff --git a/CryptoPP/crypto/squareva.dat b/CryptoPP/crypto/squareva.dat new file mode 100644 index 0000000..c09013a --- /dev/null +++ b/CryptoPP/crypto/squareva.dat @@ -0,0 +1,8 @@ +00000000000000000000000000000000 00000000000000000000000000000000 3C00428F8ABBC0B84F057CC19C26F8CF +000102030405060708090A0B0C0D0E0F 00000000000000000000000000000000 FF596FA668BFC3014200AE01E2BBA0A0 +000102030405060708090A0B0C0D0E0F 000102030405060708090A0B0C0D0E0F 7C3491D94994E70F0EC2E7A5CCB5A14F +000102030405060708090A0B0C0D0E0F C76C696289898137077A4A59FAEEEA4D 88C6FF4B92604C6E66656B02DDAF9F40 +915F4619BE41B2516355A50110A9CE91 21A5DBEE154B8F6D6FF33B98F448E95A 3388801F66E7FCC0BCE522A23A4F0C7F +783348E75AEB0F2FD7B169BB8DC16787 F7C013AC5B2B8952E5E554ABE9CED2D2 A1C0E9215141343DEC2B556942C92BDE +DC49DB1375A5584F6485B413B5F12BAF 2F42B3B70369FC929AE068313F343A7A 3FBE6811B998CDF3E50ABDE2F3C075E3 +5269F149D41BA0152497574D7F153125 65C178B284D197CCD3F111A282F17F29 D7B7209E0879744C782809B6D2E0B1B0 diff --git a/CryptoPP/crypto/stdcpp.h b/CryptoPP/crypto/stdcpp.h new file mode 100644 index 0000000..e535310 --- /dev/null +++ b/CryptoPP/crypto/stdcpp.h @@ -0,0 +1,27 @@ +#ifndef CRYPTOPP_STDCPP_H +#define CRYPTOPP_STDCPP_H + +#include +#include +#include +#include +#include +#include +#include + + +#ifdef _MSC_VER +#include // CodeWarrior doesn't have memory.h +#include +#include +#include + +// re-disable this +#pragma warning(disable: 4231) +#endif + +#if defined(_MSC_VER) && defined(_CRTAPI1) +#define CRYPTOPP_MSVCRT6 +#endif + +#endif diff --git a/CryptoPP/crypto/strciphr.cpp b/CryptoPP/crypto/strciphr.cpp new file mode 100644 index 0000000..fcc1e90 --- /dev/null +++ b/CryptoPP/crypto/strciphr.cpp @@ -0,0 +1,256 @@ +// strciphr.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" + +// prevent Sun's CC compiler from including this file automatically +#if !defined(__SUNPRO_CC) || defined(CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES) + +#ifndef CRYPTOPP_IMPORTS + +#include "strciphr.h" + +NAMESPACE_BEGIN(CryptoPP) + +template +void AdditiveCipherTemplate::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms) +{ + PolicyInterface &policy = this->AccessPolicy(); + policy.CipherSetKey(params, key, length); + m_leftOver = 0; + m_buffer.New(GetBufferByteSize(policy)); + + if (this->IsResynchronizable()) + policy.CipherResynchronize(m_buffer, this->GetIVAndThrowIfInvalid(params)); +} + +template +void AdditiveCipherTemplate::GenerateBlock(byte *outString, size_t length) +{ + if (m_leftOver > 0) + { + size_t len = STDMIN(m_leftOver, length); + memcpy(outString, KeystreamBufferEnd()-m_leftOver, len); + length -= len; + m_leftOver -= len; + outString += len; + + if (!length) + return; + } + assert(m_leftOver == 0); + + PolicyInterface &policy = this->AccessPolicy(); + unsigned int bytesPerIteration = policy.GetBytesPerIteration(); + + if (length >= bytesPerIteration) + { + size_t iterations = length / bytesPerIteration; + policy.WriteKeystream(outString, iterations); + outString += iterations * bytesPerIteration; + length -= iterations * bytesPerIteration; + + if (!length) + return; + } + + unsigned int bufferByteSize = GetBufferByteSize(policy); + unsigned int bufferIterations = policy.GetIterationsToBuffer(); + + while (length >= bufferByteSize) + { + policy.WriteKeystream(m_buffer, bufferIterations); + memcpy(outString, KeystreamBufferBegin(), bufferByteSize); + length -= bufferByteSize; + outString += bufferByteSize; + } + + if (length > 0) + { + policy.WriteKeystream(m_buffer, bufferIterations); + memcpy(outString, KeystreamBufferBegin(), length); + m_leftOver = bytesPerIteration - length; + } +} + +template +void AdditiveCipherTemplate::ProcessData(byte *outString, const byte *inString, size_t length) +{ + if (m_leftOver > 0) + { + size_t len = STDMIN(m_leftOver, length); + xorbuf(outString, inString, KeystreamBufferEnd()-m_leftOver, len); + length -= len; + m_leftOver -= len; + inString += len; + outString += len; + + if (!length) + return; + } + assert(m_leftOver == 0); + + PolicyInterface &policy = this->AccessPolicy(); + unsigned int bytesPerIteration = policy.GetBytesPerIteration(); + + if (policy.CanOperateKeystream() && length >= bytesPerIteration) + { + size_t iterations = length / bytesPerIteration; + unsigned int alignment = policy.GetAlignment(); + KeystreamOperation operation = KeystreamOperation((IsAlignedOn(inString, alignment) * 2) | (int)IsAlignedOn(outString, alignment)); + + policy.OperateKeystream(operation, outString, inString, iterations); + + inString += iterations * bytesPerIteration; + outString += iterations * bytesPerIteration; + length -= iterations * bytesPerIteration; + + if (!length) + return; + } + + unsigned int bufferByteSize = GetBufferByteSize(policy); + unsigned int bufferIterations = policy.GetIterationsToBuffer(); + + while (length >= bufferByteSize) + { + policy.WriteKeystream(m_buffer, bufferIterations); + xorbuf(outString, inString, KeystreamBufferBegin(), bufferByteSize); + length -= bufferByteSize; + inString += bufferByteSize; + outString += bufferByteSize; + } + + if (length > 0) + { + policy.WriteKeystream(m_buffer, bufferIterations); + xorbuf(outString, inString, KeystreamBufferBegin(), length); + m_leftOver = bytesPerIteration - length; + } +} + +template +void AdditiveCipherTemplate::Resynchronize(const byte *iv) +{ + PolicyInterface &policy = this->AccessPolicy(); + m_leftOver = 0; + m_buffer.New(GetBufferByteSize(policy)); + policy.CipherResynchronize(m_buffer, iv); +} + +template +void AdditiveCipherTemplate::Seek(lword position) +{ + PolicyInterface &policy = this->AccessPolicy(); + unsigned int bytesPerIteration = policy.GetBytesPerIteration(); + + policy.SeekToIteration(position / bytesPerIteration); + position %= bytesPerIteration; + + if (position > 0) + { + policy.WriteKeystream(m_buffer, 1); + m_leftOver = bytesPerIteration - (unsigned int)position; + } + else + m_leftOver = 0; +} + +template +void CFB_CipherTemplate::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms) +{ + PolicyInterface &policy = this->AccessPolicy(); + policy.CipherSetKey(params, key, length); + + if (this->IsResynchronizable()) + policy.CipherResynchronize(this->GetIVAndThrowIfInvalid(params)); + + m_leftOver = policy.GetBytesPerIteration(); +} + +template +void CFB_CipherTemplate::Resynchronize(const byte *iv) +{ + PolicyInterface &policy = this->AccessPolicy(); + policy.CipherResynchronize(iv); + m_leftOver = policy.GetBytesPerIteration(); +} + +template +void CFB_CipherTemplate::ProcessData(byte *outString, const byte *inString, size_t length) +{ + assert(length % this->MandatoryBlockSize() == 0); + + PolicyInterface &policy = this->AccessPolicy(); + unsigned int bytesPerIteration = policy.GetBytesPerIteration(); + unsigned int alignment = policy.GetAlignment(); + byte *reg = policy.GetRegisterBegin(); + + if (m_leftOver) + { + size_t len = STDMIN(m_leftOver, length); + CombineMessageAndShiftRegister(outString, reg + bytesPerIteration - m_leftOver, inString, len); + m_leftOver -= len; + length -= len; + inString += len; + outString += len; + } + + if (!length) + return; + + assert(m_leftOver == 0); + + if (policy.CanIterate() && length >= bytesPerIteration && IsAlignedOn(outString, alignment)) + { + if (IsAlignedOn(inString, alignment)) + policy.Iterate(outString, inString, GetCipherDir(*this), length / bytesPerIteration); + else + { + memcpy(outString, inString, length); + policy.Iterate(outString, outString, GetCipherDir(*this), length / bytesPerIteration); + } + inString += length - length % bytesPerIteration; + outString += length - length % bytesPerIteration; + length %= bytesPerIteration; + } + + while (length >= bytesPerIteration) + { + policy.TransformRegister(); + CombineMessageAndShiftRegister(outString, reg, inString, bytesPerIteration); + length -= bytesPerIteration; + inString += bytesPerIteration; + outString += bytesPerIteration; + } + + if (length > 0) + { + policy.TransformRegister(); + CombineMessageAndShiftRegister(outString, reg, inString, length); + m_leftOver = bytesPerIteration - length; + } +} + +template +void CFB_EncryptionTemplate::CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length) +{ + xorbuf(reg, message, length); + memcpy(output, reg, length); +} + +template +void CFB_DecryptionTemplate::CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length) +{ + for (unsigned int i=0; i, AdditiveCipherTemplate\<\> \> \> Encryption; + + AdditiveCipherTemplate and CFB_CipherTemplate are designed so that they don't need + to take a policy class as a template parameter (although this is allowed), so that + their code is not duplicated for each new cipher. Instead they each + get a reference to an abstract policy interface by calling AccessPolicy() on itself, so + AccessPolicy() must be overriden to return the actual policy reference. This is done + by the ConceretePolicyHolder class. Finally, SymmetricCipherFinal implements the constructors and + other functions that must be implemented by the most derived class. +*/ + +#ifndef CRYPTOPP_STRCIPHR_H +#define CRYPTOPP_STRCIPHR_H + +#include "seckey.h" +#include "secblock.h" +#include "argnames.h" + +NAMESPACE_BEGIN(CryptoPP) + +template +class CRYPTOPP_NO_VTABLE AbstractPolicyHolder : public BASE +{ +public: + typedef POLICY_INTERFACE PolicyInterface; + +protected: + virtual const POLICY_INTERFACE & GetPolicy() const =0; + virtual POLICY_INTERFACE & AccessPolicy() =0; +}; + +template +class ConcretePolicyHolder : public BASE, protected POLICY +{ +protected: + const POLICY_INTERFACE & GetPolicy() const {return *this;} + POLICY_INTERFACE & AccessPolicy() {return *this;} +}; + +enum KeystreamOperationFlags {OUTPUT_ALIGNED=1, INPUT_ALIGNED=2, INPUT_NULL = 4}; +enum KeystreamOperation { + WRITE_KEYSTREAM = INPUT_NULL, + WRITE_KEYSTREAM_ALIGNED = INPUT_NULL | OUTPUT_ALIGNED, + XOR_KEYSTREAM = 0, + XOR_KEYSTREAM_INPUT_ALIGNED = INPUT_ALIGNED, + XOR_KEYSTREAM_OUTPUT_ALIGNED= OUTPUT_ALIGNED, + XOR_KEYSTREAM_BOTH_ALIGNED = OUTPUT_ALIGNED | INPUT_ALIGNED}; + +struct CRYPTOPP_DLL CRYPTOPP_NO_VTABLE AdditiveCipherAbstractPolicy +{ + virtual ~AdditiveCipherAbstractPolicy() {} + virtual unsigned int GetAlignment() const {return 1;} + virtual unsigned int GetBytesPerIteration() const =0; + virtual unsigned int GetOptimalBlockSize() const {return GetBytesPerIteration();} + virtual unsigned int GetIterationsToBuffer() const =0; + virtual void WriteKeystream(byte *keystream, size_t iterationCount) + {OperateKeystream(KeystreamOperation(INPUT_NULL | (KeystreamOperationFlags)IsAlignedOn(keystream, GetAlignment())), keystream, NULL, iterationCount);} + virtual bool CanOperateKeystream() const {return false;} + virtual void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount) {assert(false);} + virtual void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length) =0; + virtual void CipherResynchronize(byte *keystreamBuffer, const byte *iv) {throw NotImplemented("SimpleKeyingInterface: this object doesn't support resynchronization");} + virtual bool IsRandomAccess() const =0; + virtual void SeekToIteration(lword iterationCount) {assert(!IsRandomAccess()); throw NotImplemented("StreamTransformation: this object doesn't support random access");} +}; + +template +struct CRYPTOPP_NO_VTABLE AdditiveCipherConcretePolicy : public BASE +{ + typedef WT WordType; + CRYPTOPP_CONSTANT(BYTES_PER_ITERATION = sizeof(WordType) * W) + +#if !(CRYPTOPP_BOOL_X86 || CRYPTOPP_BOOL_X64) + unsigned int GetAlignment() const {return GetAlignmentOf();} +#endif + unsigned int GetBytesPerIteration() const {return BYTES_PER_ITERATION;} + unsigned int GetIterationsToBuffer() const {return X;} + bool CanOperateKeystream() const {return true;} + virtual void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount) =0; +}; + +// use these to implement OperateKeystream +#define CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, b, i, a) \ + PutWord(bool(x & OUTPUT_ALIGNED), b, output+i*sizeof(WordType), (x & INPUT_NULL) ? a : a ^ GetWord(bool(x & INPUT_ALIGNED), b, input+i*sizeof(WordType))); +#define CRYPTOPP_KEYSTREAM_OUTPUT_XMM(x, i, a) {\ + __m128i t = (x & INPUT_NULL) ? a : _mm_xor_si128(a, (x & INPUT_ALIGNED) ? _mm_load_si128((__m128i *)input+i) : _mm_loadu_si128((__m128i *)input+i));\ + if (x & OUTPUT_ALIGNED) _mm_store_si128((__m128i *)output+i, t);\ + else _mm_storeu_si128((__m128i *)output+i, t);} +#define CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(x, y) \ + switch (operation) \ + { \ + case WRITE_KEYSTREAM: \ + x(WRITE_KEYSTREAM) \ + break; \ + case XOR_KEYSTREAM: \ + x(XOR_KEYSTREAM) \ + input += y; \ + break; \ + case XOR_KEYSTREAM_INPUT_ALIGNED: \ + x(XOR_KEYSTREAM_INPUT_ALIGNED) \ + input += y; \ + break; \ + case XOR_KEYSTREAM_OUTPUT_ALIGNED: \ + x(XOR_KEYSTREAM_OUTPUT_ALIGNED) \ + input += y; \ + break; \ + case WRITE_KEYSTREAM_ALIGNED: \ + x(WRITE_KEYSTREAM_ALIGNED) \ + break; \ + case XOR_KEYSTREAM_BOTH_ALIGNED: \ + x(XOR_KEYSTREAM_BOTH_ALIGNED) \ + input += y; \ + break; \ + } \ + output += y; + +template > > +class CRYPTOPP_NO_VTABLE AdditiveCipherTemplate : public BASE +{ +public: + void GenerateBlock(byte *output, size_t size); + void ProcessData(byte *outString, const byte *inString, size_t length); + void Resynchronize(const byte *iv); + unsigned int OptimalBlockSize() const {return this->GetPolicy().GetOptimalBlockSize();} + unsigned int GetOptimalNextBlockSize() const {return (unsigned int)this->m_leftOver;} + unsigned int OptimalDataAlignment() const {return this->GetPolicy().GetAlignment();} + bool IsSelfInverting() const {return true;} + bool IsForwardTransformation() const {return true;} + bool IsRandomAccess() const {return this->GetPolicy().IsRandomAccess();} + void Seek(lword position); + + typedef typename BASE::PolicyInterface PolicyInterface; + +protected: + void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms); + + unsigned int GetBufferByteSize(const PolicyInterface &policy) const {return policy.GetBytesPerIteration() * policy.GetIterationsToBuffer();} + + inline byte * KeystreamBufferBegin() {return this->m_buffer.data();} + inline byte * KeystreamBufferEnd() {return (this->m_buffer.data() + this->m_buffer.size());} + + SecByteBlock m_buffer; + size_t m_leftOver; +}; + +class CRYPTOPP_DLL CRYPTOPP_NO_VTABLE CFB_CipherAbstractPolicy +{ +public: + virtual ~CFB_CipherAbstractPolicy() {} + virtual unsigned int GetAlignment() const =0; + virtual unsigned int GetBytesPerIteration() const =0; + virtual byte * GetRegisterBegin() =0; + virtual void TransformRegister() =0; + virtual bool CanIterate() const {return false;} + virtual void Iterate(byte *output, const byte *input, CipherDir dir, size_t iterationCount) {assert(false);} + virtual void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length) =0; + virtual void CipherResynchronize(const byte *iv) {throw NotImplemented("SimpleKeyingInterface: this object doesn't support resynchronization");} +}; + +template +struct CRYPTOPP_NO_VTABLE CFB_CipherConcretePolicy : public BASE +{ + typedef WT WordType; + + unsigned int GetAlignment() const {return sizeof(WordType);} + unsigned int GetBytesPerIteration() const {return sizeof(WordType) * W;} + bool CanIterate() const {return true;} + void TransformRegister() {this->Iterate(NULL, NULL, ENCRYPTION, 1);} + + template + struct RegisterOutput + { + RegisterOutput(byte *output, const byte *input, CipherDir dir) + : m_output(output), m_input(input), m_dir(dir) {} + + inline RegisterOutput& operator()(WordType ®isterWord) + { + assert(IsAligned(m_output)); + assert(IsAligned(m_input)); + + if (!NativeByteOrderIs(B::ToEnum())) + registerWord = ByteReverse(registerWord); + + if (m_dir == ENCRYPTION) + { + if (m_input == NULL) + assert(m_output == NULL); + else + { + WordType ct = *(const WordType *)m_input ^ registerWord; + registerWord = ct; + *(WordType*)m_output = ct; + m_input += sizeof(WordType); + m_output += sizeof(WordType); + } + } + else + { + WordType ct = *(const WordType *)m_input; + *(WordType*)m_output = registerWord ^ ct; + registerWord = ct; + m_input += sizeof(WordType); + m_output += sizeof(WordType); + } + + // registerWord is left unreversed so it can be xor-ed with further input + + return *this; + } + + byte *m_output; + const byte *m_input; + CipherDir m_dir; + }; +}; + +template +class CRYPTOPP_NO_VTABLE CFB_CipherTemplate : public BASE +{ +public: + void ProcessData(byte *outString, const byte *inString, size_t length); + void Resynchronize(const byte *iv); + unsigned int OptimalBlockSize() const {return this->GetPolicy().GetBytesPerIteration();} + unsigned int GetOptimalNextBlockSize() const {return (unsigned int)m_leftOver;} + unsigned int OptimalDataAlignment() const {return this->GetPolicy().GetAlignment();} + bool IsRandomAccess() const {return false;} + bool IsSelfInverting() const {return false;} + + typedef typename BASE::PolicyInterface PolicyInterface; + +protected: + virtual void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length) =0; + + void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms); + + size_t m_leftOver; +}; + +template > +class CRYPTOPP_NO_VTABLE CFB_EncryptionTemplate : public CFB_CipherTemplate +{ + bool IsForwardTransformation() const {return true;} + void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length); +}; + +template > +class CRYPTOPP_NO_VTABLE CFB_DecryptionTemplate : public CFB_CipherTemplate +{ + bool IsForwardTransformation() const {return false;} + void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length); +}; + +template +class CFB_RequireFullDataBlocks : public BASE +{ +public: + unsigned int MandatoryBlockSize() const {return this->OptimalBlockSize();} +}; + +//! _ +template +class SymmetricCipherFinal : public AlgorithmImpl, INFO> +{ +public: + SymmetricCipherFinal() {} + SymmetricCipherFinal(const byte *key) + {this->SetKey(key, this->DEFAULT_KEYLENGTH);} + SymmetricCipherFinal(const byte *key, size_t length) + {this->SetKey(key, length);} + SymmetricCipherFinal(const byte *key, size_t length, const byte *iv) + {this->SetKeyWithIV(key, length, iv);} + + Clonable * Clone() const {return static_cast(new SymmetricCipherFinal(*this));} +}; + +NAMESPACE_END + +#ifdef CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES +#include "strciphr.cpp" +#endif + +NAMESPACE_BEGIN(CryptoPP) +CRYPTOPP_DLL_TEMPLATE_CLASS TwoBases; +CRYPTOPP_DLL_TEMPLATE_CLASS AbstractPolicyHolder >; +CRYPTOPP_DLL_TEMPLATE_CLASS AdditiveCipherTemplate > >; +CRYPTOPP_DLL_TEMPLATE_CLASS CFB_CipherTemplate >; +CRYPTOPP_DLL_TEMPLATE_CLASS CFB_EncryptionTemplate >; +CRYPTOPP_DLL_TEMPLATE_CLASS CFB_DecryptionTemplate >; +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/tea.cpp b/CryptoPP/crypto/tea.cpp new file mode 100644 index 0000000..1c2e2e1 --- /dev/null +++ b/CryptoPP/crypto/tea.cpp @@ -0,0 +1,147 @@ +// tea.cpp - modified by Wei Dai from code in the original paper + +#include "pch.h" +#include "tea.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +static const word32 DELTA = 0x9e3779b9; +typedef BlockGetAndPut Block; + +void TEA::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms) +{ + AssertValidKeyLength(length); + + GetUserKey(BIG_ENDIAN_ORDER, m_k.begin(), 4, userKey, KEYLENGTH); + m_limit = GetRoundsAndThrowIfInvalid(params, this) * DELTA; +} + +void TEA::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word32 y, z; + Block::Get(inBlock)(y)(z); + + word32 sum = 0; + while (sum != m_limit) + { + sum += DELTA; + y += (z << 4) + m_k[0] ^ z + sum ^ (z >> 5) + m_k[1]; + z += (y << 4) + m_k[2] ^ y + sum ^ (y >> 5) + m_k[3]; + } + + Block::Put(xorBlock, outBlock)(y)(z); +} + +void TEA::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word32 y, z; + Block::Get(inBlock)(y)(z); + + word32 sum = m_limit; + while (sum != 0) + { + z -= (y << 4) + m_k[2] ^ y + sum ^ (y >> 5) + m_k[3]; + y -= (z << 4) + m_k[0] ^ z + sum ^ (z >> 5) + m_k[1]; + sum -= DELTA; + } + + Block::Put(xorBlock, outBlock)(y)(z); +} + +void XTEA::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms) +{ + AssertValidKeyLength(length); + + GetUserKey(BIG_ENDIAN_ORDER, m_k.begin(), 4, userKey, KEYLENGTH); + m_limit = GetRoundsAndThrowIfInvalid(params, this) * DELTA; +} + +void XTEA::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word32 y, z; + Block::Get(inBlock)(y)(z); + + word32 sum = 0; + while (sum != m_limit) + { + y += (z<<4 ^ z>>5) + z ^ sum + m_k[sum&3]; + sum += DELTA; + z += (y<<4 ^ y>>5) + y ^ sum + m_k[sum>>11 & 3]; + } + + Block::Put(xorBlock, outBlock)(y)(z); +} + +void XTEA::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word32 y, z; + Block::Get(inBlock)(y)(z); + + word32 sum = m_limit; + while (sum != 0) + { + z -= (y<<4 ^ y>>5) + y ^ sum + m_k[sum>>11 & 3]; + sum -= DELTA; + y -= (z<<4 ^ z>>5) + z ^ sum + m_k[sum&3]; + } + + Block::Put(xorBlock, outBlock)(y)(z); +} + +#define MX (z>>5^y<<2)+(y>>3^z<<4)^(sum^y)+(m_k[p&3^e]^z) + +void BTEA::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + unsigned int n = m_blockSize / 4; + word32 *v = (word32*)outBlock; + ConditionalByteReverse(BIG_ENDIAN_ORDER, v, (const word32*)inBlock, m_blockSize); + + word32 y = v[0], z = v[n-1], e; + word32 p, q = 6+52/n; + word32 sum = 0; + + while (q-- > 0) + { + sum += DELTA; + e = sum>>2 & 3; + for (p = 0; p < n-1; p++) + { + y = v[p+1]; + z = v[p] += MX; + } + y = v[0]; + z = v[n-1] += MX; + } + + ConditionalByteReverse(BIG_ENDIAN_ORDER, v, v, m_blockSize); +} + +void BTEA::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + unsigned int n = m_blockSize / 4; + word32 *v = (word32*)outBlock; + ConditionalByteReverse(BIG_ENDIAN_ORDER, v, (const word32*)inBlock, m_blockSize); + + word32 y = v[0], z = v[n-1], e; + word32 p, q = 6+52/n; + word32 sum = q * DELTA; + + while (sum != 0) + { + e = sum>>2 & 3; + for (p = n-1; p > 0; p--) + { + z = v[p-1]; + y = v[p] -= MX; + } + + z = v[n-1]; + y = v[0] -= MX; + sum -= DELTA; + } + + ConditionalByteReverse(BIG_ENDIAN_ORDER, v, v, m_blockSize); +} + +NAMESPACE_END diff --git a/CryptoPP/crypto/tea.h b/CryptoPP/crypto/tea.h new file mode 100644 index 0000000..4cc1e92 --- /dev/null +++ b/CryptoPP/crypto/tea.h @@ -0,0 +1,132 @@ +#ifndef CRYPTOPP_TEA_H +#define CRYPTOPP_TEA_H + +/** \file +*/ + +#include "seckey.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! _ +struct TEA_Info : public FixedBlockSize<8>, public FixedKeyLength<16>, public VariableRounds<32> +{ + static const char *StaticAlgorithmName() {return "TEA";} +}; + +/// TEA +class TEA : public TEA_Info, public BlockCipherDocumentation +{ + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + public: + void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); + + protected: + FixedSizeSecBlock m_k; + word32 m_limit; + }; + + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef TEA::Encryption TEAEncryption; +typedef TEA::Decryption TEADecryption; + +//! _ +struct XTEA_Info : public FixedBlockSize<8>, public FixedKeyLength<16>, public VariableRounds<32> +{ + static const char *StaticAlgorithmName() {return "XTEA";} +}; + +/// XTEA +class XTEA : public XTEA_Info, public BlockCipherDocumentation +{ + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + public: + void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); + + protected: + FixedSizeSecBlock m_k; + word32 m_limit; + }; + + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +//! _ +struct BTEA_Info : public FixedKeyLength<16> +{ + static const char *StaticAlgorithmName() {return "BTEA";} +}; + +//! corrected Block TEA (as described in "xxtea"). +/*! This class hasn't been tested yet. */ +class BTEA : public BTEA_Info, public BlockCipherDocumentation +{ + class CRYPTOPP_NO_VTABLE Base : public AlgorithmImpl, BTEA_Info>, public BTEA_Info + { + public: + void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms) + { + m_blockSize = params.GetIntValueWithDefault("BlockSize", 60*4); + GetUserKey(BIG_ENDIAN_ORDER, m_k.begin(), 4, key, KEYLENGTH); + } + + unsigned int BlockSize() const {return m_blockSize;} + + protected: + FixedSizeSecBlock m_k; + unsigned int m_blockSize; + }; + + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/test.cpp b/CryptoPP/crypto/test.cpp new file mode 100644 index 0000000..c49a222 --- /dev/null +++ b/CryptoPP/crypto/test.cpp @@ -0,0 +1,855 @@ +// test.cpp - written and placed in the public domain by Wei Dai + +#define _CRT_SECURE_NO_DEPRECATE +#define CRYPTOPP_DEFAULT_NO_DLL +#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 + +#include "dll.h" +#include "md5.h" +#include "ripemd.h" +#include "rng.h" +#include "gzip.h" +#include "default.h" +#include "randpool.h" +#include "ida.h" +#include "base64.h" +#include "socketft.h" +#include "wait.h" +#include "factory.h" +#include "whrlpool.h" +#include "tiger.h" + +#include "validate.h" +#include "bench.h" + +#include +#include + +#ifdef CRYPTOPP_WIN32_AVAILABLE +#include +#endif + +#if defined(USE_BERKELEY_STYLE_SOCKETS) && !defined(macintosh) +#include +#include +#endif + +#if (_MSC_VER >= 1000) +#include // for the debug heap +#endif + +#if defined(__MWERKS__) && defined(macintosh) +#include +#endif + +#ifdef __BORLANDC__ +#pragma comment(lib, "cryptlib_bds.lib") +#pragma comment(lib, "ws2_32.lib") +#endif + +USING_NAMESPACE(CryptoPP) +USING_NAMESPACE(std) + +const int MAX_PHRASE_LENGTH=250; + +void RegisterFactories(); + +void GenerateRSAKey(unsigned int keyLength, const char *privFilename, const char *pubFilename, const char *seed); +string RSAEncryptString(const char *pubFilename, const char *seed, const char *message); +string RSADecryptString(const char *privFilename, const char *ciphertext); +void RSASignFile(const char *privFilename, const char *messageFilename, const char *signatureFilename); +bool RSAVerifyFile(const char *pubFilename, const char *messageFilename, const char *signatureFilename); + +void DigestFile(const char *file); +void HmacFile(const char *hexKey, const char *file); + +void AES_CTR_Encrypt(const char *hexKey, const char *hexIV, const char *infile, const char *outfile); + +string EncryptString(const char *plaintext, const char *passPhrase); +string DecryptString(const char *ciphertext, const char *passPhrase); + +void EncryptFile(const char *in, const char *out, const char *passPhrase); +void DecryptFile(const char *in, const char *out, const char *passPhrase); + +void SecretShareFile(int threshold, int nShares, const char *filename, const char *seed); +void SecretRecoverFile(int threshold, const char *outFilename, char *const *inFilenames); + +void InformationDisperseFile(int threshold, int nShares, const char *filename); +void InformationRecoverFile(int threshold, const char *outFilename, char *const *inFilenames); + +void GzipFile(const char *in, const char *out, int deflate_level); +void GunzipFile(const char *in, const char *out); + +void Base64Encode(const char *infile, const char *outfile); +void Base64Decode(const char *infile, const char *outfile); +void HexEncode(const char *infile, const char *outfile); +void HexDecode(const char *infile, const char *outfile); + +void ForwardTcpPort(const char *sourcePort, const char *destinationHost, const char *destinationPort); + +void FIPS140_SampleApplication(); +void FIPS140_GenerateRandomFiles(); + +bool Validate(int, bool, const char *); + +int (*AdhocTest)(int argc, char *argv[]) = NULL; + +int CRYPTOPP_API main(int argc, char *argv[]) +{ +#ifdef _CRTDBG_LEAK_CHECK_DF + // Turn on leak-checking + int tempflag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG ); + tempflag |= _CRTDBG_LEAK_CHECK_DF; + _CrtSetDbgFlag( tempflag ); +#endif + +#if defined(__MWERKS__) && defined(macintosh) + argc = ccommand(&argv); +#endif + + try + { + RegisterFactories(); + + std::string command, executableName, macFilename; + + if (argc < 2) + command = 'h'; + else + command = argv[1]; + + if (command == "g") + { + char seed[1024], privFilename[128], pubFilename[128]; + unsigned int keyLength; + + cout << "Key length in bits: "; + cin >> keyLength; + + cout << "\nSave private key to file: "; + cin >> privFilename; + + cout << "\nSave public key to file: "; + cin >> pubFilename; + + cout << "\nRandom Seed: "; + ws(cin); + cin.getline(seed, 1024); + + GenerateRSAKey(keyLength, privFilename, pubFilename, seed); + } + else if (command == "rs") + RSASignFile(argv[2], argv[3], argv[4]); + else if (command == "rv") + { + bool verified = RSAVerifyFile(argv[2], argv[3], argv[4]); + cout << (verified ? "valid signature" : "invalid signature") << endl; + } + else if (command == "r") + { + char privFilename[128], pubFilename[128]; + char seed[1024], message[1024]; + + cout << "Private key file: "; + cin >> privFilename; + + cout << "\nPublic key file: "; + cin >> pubFilename; + + cout << "\nRandom Seed: "; + ws(cin); + cin.getline(seed, 1024); + + cout << "\nMessage: "; + cin.getline(message, 1024); + + string ciphertext = RSAEncryptString(pubFilename, seed, message); + cout << "\nCiphertext: " << ciphertext << endl; + + string decrypted = RSADecryptString(privFilename, ciphertext.c_str()); + cout << "\nDecrypted: " << decrypted << endl; + } + else if (command == "mt") + { + MaurerRandomnessTest mt; + FileStore fs(argv[2]); + fs.TransferAllTo(mt); + cout << "Maurer Test Value: " << mt.GetTestValue() << endl; + } + else if (command == "mac_dll") + { + // sanity check on file size + std::fstream dllFile(argv[2], ios::in | ios::out | ios::binary); + std::ifstream::pos_type fileEnd = dllFile.seekg(0, std::ios_base::end).tellg(); + if (fileEnd > 20*1000*1000) + { + cerr << "Input file too large (more than 20 MB).\n"; + return 1; + } + + // read file into memory + unsigned int fileSize = (unsigned int)fileEnd; + SecByteBlock buf(fileSize); + dllFile.seekg(0, std::ios_base::beg); + dllFile.read((char *)buf.begin(), fileSize); + + // find positions of relevant sections in the file, based on version 8 of documentation from http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx + word32 coffPos = *(word16 *)(buf+0x3c); + word32 optionalHeaderPos = coffPos + 24; + word16 optionalHeaderMagic = *(word16 *)(buf+optionalHeaderPos); + if (optionalHeaderMagic != 0x10b && optionalHeaderMagic != 0x20b) + { + cerr << "Target file is not a PE32 or PE32+ image.\n"; + return 3; + } + word32 checksumPos = optionalHeaderPos + 64; + word32 certificateTableDirectoryPos = optionalHeaderPos + (optionalHeaderMagic == 0x10b ? 128 : 144); + word32 certificateTablePos = *(word32 *)(buf+certificateTableDirectoryPos); + word32 certificateTableSize = *(word32 *)(buf+certificateTableDirectoryPos+4); + if (certificateTableSize != 0) + cerr << "Warning: certificate table (IMAGE_DIRECTORY_ENTRY_SECURITY) of target image is not empty.\n"; + + // find where to place computed MAC + byte mac[] = CRYPTOPP_DUMMY_DLL_MAC; + byte *found = std::search(buf.begin(), buf.end(), mac+0, mac+sizeof(mac)); + if (found == buf.end()) + { + cerr << "MAC placeholder not found. Possibly the actual MAC was already placed.\n"; + return 2; + } + word32 macPos = (unsigned int)(found-buf.begin()); + + // compute MAC + member_ptr pMac(NewIntegrityCheckingMAC()); + assert(pMac->DigestSize() == sizeof(mac)); + MeterFilter f(new HashFilter(*pMac, new ArraySink(mac, sizeof(mac)))); + f.AddRangeToSkip(0, checksumPos, 4); + f.AddRangeToSkip(0, certificateTableDirectoryPos, 8); + f.AddRangeToSkip(0, macPos, sizeof(mac)); + f.AddRangeToSkip(0, certificateTablePos, certificateTableSize); + f.PutMessageEnd(buf.begin(), buf.size()); + + // place MAC + cout << "Placing MAC in file " << argv[2] << ", location " << macPos << ".\n"; + dllFile.seekg(macPos, std::ios_base::beg); + dllFile.write((char *)mac, sizeof(mac)); + } + else if (command == "m") + DigestFile(argv[2]); + else if (command == "tv") + { + std::string fname = argv[2]; + if (fname.find(".txt") == std::string::npos) + fname = "TestVectors/" + fname + ".txt"; + return !RunTestDataFile(fname.c_str()); + } + else if (command == "t") + { + // VC60 workaround: use char array instead of std::string to workaround MSVC's getline bug + char passPhrase[MAX_PHRASE_LENGTH], plaintext[1024]; + + cout << "Passphrase: "; + cin.getline(passPhrase, MAX_PHRASE_LENGTH); + + cout << "\nPlaintext: "; + cin.getline(plaintext, 1024); + + string ciphertext = EncryptString(plaintext, passPhrase); + cout << "\nCiphertext: " << ciphertext << endl; + + string decrypted = DecryptString(ciphertext.c_str(), passPhrase); + cout << "\nDecrypted: " << decrypted << endl; + + return 0; + } + else if (command == "e64") + Base64Encode(argv[2], argv[3]); + else if (command == "d64") + Base64Decode(argv[2], argv[3]); + else if (command == "e16") + HexEncode(argv[2], argv[3]); + else if (command == "d16") + HexDecode(argv[2], argv[3]); + else if (command == "e" || command == "d") + { + char passPhrase[MAX_PHRASE_LENGTH]; + cout << "Passphrase: "; + cin.getline(passPhrase, MAX_PHRASE_LENGTH); + if (command == "e") + EncryptFile(argv[2], argv[3], passPhrase); + else + DecryptFile(argv[2], argv[3], passPhrase); + } + else if (command == "ss") + { + char seed[1024]; + cout << "\nRandom Seed: "; + ws(cin); + cin.getline(seed, 1024); + SecretShareFile(atoi(argv[2]), atoi(argv[3]), argv[4], seed); + } + else if (command == "sr") + SecretRecoverFile(argc-3, argv[2], argv+3); + else if (command == "id") + InformationDisperseFile(atoi(argv[2]), atoi(argv[3]), argv[4]); + else if (command == "ir") + InformationRecoverFile(argc-3, argv[2], argv+3); + else if (command == "v") + return !Validate(argc>2 ? atoi(argv[2]) : 0, argv[1][1] == 'v', argc>3 ? argv[3] : NULL); + else if (command == "b") + BenchmarkAll(argc<3 ? 1 : atof(argv[2]), argc<4 ? 0 : atof(argv[3])*1e9); + else if (command == "b2") + BenchmarkAll2(argc<3 ? 1 : atof(argv[2]), argc<4 ? 0 : atof(argv[3])*1e9); + else if (command == "z") + GzipFile(argv[3], argv[4], argv[2][0]-'0'); + else if (command == "u") + GunzipFile(argv[2], argv[3]); + else if (command == "fips") + FIPS140_SampleApplication(); + else if (command == "fips-rand") + FIPS140_GenerateRandomFiles(); + else if (command == "ft") + ForwardTcpPort(argv[2], argv[3], argv[4]); + else if (command == "a") + { + if (AdhocTest) + return (*AdhocTest)(argc, argv); + else + { + cerr << "AdhocTest not defined.\n"; + return 1; + } + } + else if (command == "hmac") + HmacFile(argv[2], argv[3]); + else if (command == "ae") + AES_CTR_Encrypt(argv[2], argv[3], argv[4], argv[5]); + else if (command == "h") + { + FileSource usage("usage.dat", true, new FileSink(cout)); + return 1; + } + else if (command == "V") + { + cout << CRYPTOPP_VERSION / 100 << '.' << (CRYPTOPP_VERSION % 100) / 10 << '.' << CRYPTOPP_VERSION % 10 << endl; + } + else + { + cerr << "Unrecognized command. Run \"cryptest h\" to obtain usage information.\n"; + return 1; + } + return 0; + } + catch(CryptoPP::Exception &e) + { + cout << "\nCryptoPP::Exception caught: " << e.what() << endl; + return -1; + } + catch(std::exception &e) + { + cout << "\nstd::exception caught: " << e.what() << endl; + return -2; + } +} + +void FIPS140_GenerateRandomFiles() +{ +#ifdef OS_RNG_AVAILABLE + DefaultAutoSeededRNG rng; + RandomNumberStore store(rng, ULONG_MAX); + + for (unsigned int i=0; i<100000; i++) + store.TransferTo(FileSink((IntToString(i) + ".rnd").c_str()).Ref(), 20000); +#else + cout << "OS provided RNG not available.\n"; + exit(-1); +#endif +} + +SecByteBlock HexDecodeString(const char *hex) +{ + StringSource ss(hex, true, new HexDecoder); + SecByteBlock result((size_t)ss.MaxRetrievable()); + ss.Get(result, result.size()); + return result; +} + +RandomNumberGenerator & GlobalRNG() +{ + static RandomPool randomPool; + return randomPool; +} + +void GenerateRSAKey(unsigned int keyLength, const char *privFilename, const char *pubFilename, const char *seed) +{ + RandomPool randPool; + randPool.IncorporateEntropy((byte *)seed, strlen(seed)); + + RSAES_OAEP_SHA_Decryptor priv(randPool, keyLength); + HexEncoder privFile(new FileSink(privFilename)); + priv.DEREncode(privFile); + privFile.MessageEnd(); + + RSAES_OAEP_SHA_Encryptor pub(priv); + HexEncoder pubFile(new FileSink(pubFilename)); + pub.DEREncode(pubFile); + pubFile.MessageEnd(); +} + +string RSAEncryptString(const char *pubFilename, const char *seed, const char *message) +{ + FileSource pubFile(pubFilename, true, new HexDecoder); + RSAES_OAEP_SHA_Encryptor pub(pubFile); + + RandomPool randPool; + randPool.IncorporateEntropy((byte *)seed, strlen(seed)); + + string result; + StringSource(message, true, new PK_EncryptorFilter(randPool, pub, new HexEncoder(new StringSink(result)))); + return result; +} + +string RSADecryptString(const char *privFilename, const char *ciphertext) +{ + FileSource privFile(privFilename, true, new HexDecoder); + RSAES_OAEP_SHA_Decryptor priv(privFile); + + string result; + StringSource(ciphertext, true, new HexDecoder(new PK_DecryptorFilter(GlobalRNG(), priv, new StringSink(result)))); + return result; +} + +void RSASignFile(const char *privFilename, const char *messageFilename, const char *signatureFilename) +{ + FileSource privFile(privFilename, true, new HexDecoder); + RSASS::Signer priv(privFile); + FileSource f(messageFilename, true, new SignerFilter(GlobalRNG(), priv, new HexEncoder(new FileSink(signatureFilename)))); +} + +bool RSAVerifyFile(const char *pubFilename, const char *messageFilename, const char *signatureFilename) +{ + FileSource pubFile(pubFilename, true, new HexDecoder); + RSASS::Verifier pub(pubFile); + + FileSource signatureFile(signatureFilename, true, new HexDecoder); + if (signatureFile.MaxRetrievable() != pub.SignatureLength()) + return false; + SecByteBlock signature(pub.SignatureLength()); + signatureFile.Get(signature, signature.size()); + + VerifierFilter *verifierFilter = new VerifierFilter(pub); + verifierFilter->Put(signature, pub.SignatureLength()); + FileSource f(messageFilename, true, verifierFilter); + + return verifierFilter->GetLastResult(); +} + +void DigestFile(const char *filename) +{ + SHA1 sha; + RIPEMD160 ripemd; + SHA256 sha256; +#ifdef WORD64_AVAILABLE + Tiger tiger; + SHA512 sha512; + Whirlpool whirlpool; + vector_member_ptrs filters(6); + filters[0].reset(new HashFilter(sha)); + filters[1].reset(new HashFilter(ripemd)); + filters[2].reset(new HashFilter(tiger)); + filters[3].reset(new HashFilter(sha256)); + filters[4].reset(new HashFilter(sha512)); + filters[5].reset(new HashFilter(whirlpool)); +#else + vector_member_ptrs filters(3); + filters[0].reset(new HashFilter(sha)); + filters[1].reset(new HashFilter(ripemd)); + filters[2].reset(new HashFilter(sha256)); +#endif + + auto_ptr channelSwitch(new ChannelSwitch); + size_t i; + for (i=0; iAddDefaultRoute(*filters[i]); + FileSource(filename, true, channelSwitch.release()); + + HexEncoder encoder(new FileSink(cout), false); + for (i=0; iAlgorithmName() << ": "; + filters[i]->TransferTo(encoder); + cout << "\n"; + } +} + +void HmacFile(const char *hexKey, const char *file) +{ + member_ptr mac; + if (strcmp(hexKey, "selftest") == 0) + { + cerr << "Computing HMAC/SHA1 value for self test.\n"; + mac.reset(NewIntegrityCheckingMAC()); + } + else + { + std::string decodedKey; + StringSource(hexKey, true, new HexDecoder(new StringSink(decodedKey))); + mac.reset(new HMAC((const byte *)decodedKey.data(), decodedKey.size())); + } + FileSource(file, true, new HashFilter(*mac, new HexEncoder(new FileSink(cout)))); +} + +void AES_CTR_Encrypt(const char *hexKey, const char *hexIV, const char *infile, const char *outfile) +{ + SecByteBlock key = HexDecodeString(hexKey); + SecByteBlock iv = HexDecodeString(hexIV); + CTR_Mode::Encryption aes(key, key.size(), iv); + FileSource(infile, true, new StreamTransformationFilter(aes, new FileSink(outfile))); +} + +string EncryptString(const char *instr, const char *passPhrase) +{ + string outstr; + + DefaultEncryptorWithMAC encryptor(passPhrase, new HexEncoder(new StringSink(outstr))); + encryptor.Put((byte *)instr, strlen(instr)); + encryptor.MessageEnd(); + + return outstr; +} + +string DecryptString(const char *instr, const char *passPhrase) +{ + string outstr; + + HexDecoder decryptor(new DefaultDecryptorWithMAC(passPhrase, new StringSink(outstr))); + decryptor.Put((byte *)instr, strlen(instr)); + decryptor.MessageEnd(); + + return outstr; +} + +void EncryptFile(const char *in, const char *out, const char *passPhrase) +{ + FileSource f(in, true, new DefaultEncryptorWithMAC(passPhrase, new FileSink(out))); +} + +void DecryptFile(const char *in, const char *out, const char *passPhrase) +{ + FileSource f(in, true, new DefaultDecryptorWithMAC(passPhrase, new FileSink(out))); +} + +void SecretShareFile(int threshold, int nShares, const char *filename, const char *seed) +{ + assert(nShares<=1000); + + RandomPool rng; + rng.IncorporateEntropy((byte *)seed, strlen(seed)); + + ChannelSwitch *channelSwitch; + FileSource source(filename, false, new SecretSharing(rng, threshold, nShares, channelSwitch = new ChannelSwitch)); + + vector_member_ptrs fileSinks(nShares); + string channel; + for (int i=0; i(i); + fileSinks[i]->Put((byte *)channel.data(), 4); + channelSwitch->AddRoute(channel, *fileSinks[i], BufferedTransformation::NULL_CHANNEL); + } + + source.PumpAll(); +} + +void SecretRecoverFile(int threshold, const char *outFilename, char *const *inFilenames) +{ + assert(threshold<=1000); + + SecretRecovery recovery(threshold, new FileSink(outFilename)); + + vector_member_ptrs fileSources(threshold); + SecByteBlock channel(4); + int i; + for (i=0; iPump(4); + fileSources[i]->Get(channel, 4); + fileSources[i]->Attach(new ChannelSwitch(recovery, string((char *)channel.begin(), 4))); + } + + while (fileSources[0]->Pump(256)) + for (i=1; iPump(256); + + for (i=0; iPumpAll(); +} + +void InformationDisperseFile(int threshold, int nShares, const char *filename) +{ + assert(nShares<=1000); + + ChannelSwitch *channelSwitch; + FileSource source(filename, false, new InformationDispersal(threshold, nShares, channelSwitch = new ChannelSwitch)); + + vector_member_ptrs fileSinks(nShares); + string channel; + for (int i=0; i(i); + fileSinks[i]->Put((byte *)channel.data(), 4); + channelSwitch->AddRoute(channel, *fileSinks[i], BufferedTransformation::NULL_CHANNEL); + } + + source.PumpAll(); +} + +void InformationRecoverFile(int threshold, const char *outFilename, char *const *inFilenames) +{ + assert(threshold<=1000); + + InformationRecovery recovery(threshold, new FileSink(outFilename)); + + vector_member_ptrs fileSources(threshold); + SecByteBlock channel(4); + int i; + for (i=0; iPump(4); + fileSources[i]->Get(channel, 4); + fileSources[i]->Attach(new ChannelSwitch(recovery, string((char *)channel.begin(), 4))); + } + + while (fileSources[0]->Pump(256)) + for (i=1; iPump(256); + + for (i=0; iPumpAll(); +} + +void GzipFile(const char *in, const char *out, int deflate_level) +{ +// FileSource(in, true, new Gzip(new FileSink(out), deflate_level)); + + // use a filter graph to compare decompressed data with original + // + // Source ----> Gzip ------> Sink + // \ | + // \ Gunzip + // \ | + // \ v + // > ComparisonFilter + + EqualityComparisonFilter comparison; + + Gunzip gunzip(new ChannelSwitch(comparison, "0")); + gunzip.SetAutoSignalPropagation(0); + + FileSink sink(out); + + ChannelSwitch *cs; + Gzip gzip(cs = new ChannelSwitch(sink), deflate_level); + cs->AddDefaultRoute(gunzip); + + cs = new ChannelSwitch(gzip); + cs->AddDefaultRoute(comparison, "1"); + FileSource source(in, true, cs); + + comparison.ChannelMessageSeriesEnd("0"); + comparison.ChannelMessageSeriesEnd("1"); +} + +void GunzipFile(const char *in, const char *out) +{ + FileSource(in, true, new Gunzip(new FileSink(out))); +} + +void Base64Encode(const char *in, const char *out) +{ + FileSource(in, true, new Base64Encoder(new FileSink(out))); +} + +void Base64Decode(const char *in, const char *out) +{ + FileSource(in, true, new Base64Decoder(new FileSink(out))); +} + +void HexEncode(const char *in, const char *out) +{ + FileSource(in, true, new HexEncoder(new FileSink(out))); +} + +void HexDecode(const char *in, const char *out) +{ + FileSource(in, true, new HexDecoder(new FileSink(out))); +} + +void ForwardTcpPort(const char *sourcePortName, const char *destinationHost, const char *destinationPortName) +{ +#ifdef SOCKETS_AVAILABLE + SocketsInitializer sockInit; + + Socket sockListen, sockSource, sockDestination; + + int sourcePort = Socket::PortNameToNumber(sourcePortName); + int destinationPort = Socket::PortNameToNumber(destinationPortName); + + sockListen.Create(); + sockListen.Bind(sourcePort); + setsockopt(sockListen, IPPROTO_TCP, TCP_NODELAY, "\x01", 1); + + cout << "Listing on port " << sourcePort << ".\n"; + sockListen.Listen(); + + sockListen.Accept(sockSource); + cout << "Connection accepted on port " << sourcePort << ".\n"; + sockListen.CloseSocket(); + + cout << "Making connection to " << destinationHost << ", port " << destinationPort << ".\n"; + sockDestination.Create(); + sockDestination.Connect(destinationHost, destinationPort); + + cout << "Connection made to " << destinationHost << ", starting to forward.\n"; + + SocketSource out(sockSource, false, new SocketSink(sockDestination)); + SocketSource in(sockDestination, false, new SocketSink(sockSource)); + + WaitObjectContainer waitObjects; + + while (!(in.SourceExhausted() && out.SourceExhausted())) + { + waitObjects.Clear(); + + out.GetWaitObjects(waitObjects, CallStack("ForwardTcpPort - out", NULL)); + in.GetWaitObjects(waitObjects, CallStack("ForwardTcpPort - in", NULL)); + + waitObjects.Wait(INFINITE_TIME); + + if (!out.SourceExhausted()) + { + cout << "o" << flush; + out.PumpAll2(false); + if (out.SourceExhausted()) + cout << "EOF received on source socket.\n"; + } + + if (!in.SourceExhausted()) + { + cout << "i" << flush; + in.PumpAll2(false); + if (in.SourceExhausted()) + cout << "EOF received on destination socket.\n"; + } + } +#else + cout << "Socket support was not enabled at compile time.\n"; + exit(-1); +#endif +} + +bool Validate(int alg, bool thorough, const char *seed) +{ + bool result; + + std::string timeSeed; + if (!seed) + { + timeSeed = IntToString(time(NULL)); + seed = timeSeed.c_str(); + } + + cout << "Using seed: " << seed << endl << endl; + GlobalRNG().IncorporateEntropy((const byte *)seed, strlen(seed)); + + switch (alg) + { + case 0: result = ValidateAll(thorough); break; + case 1: result = TestSettings(); break; + case 2: result = TestOS_RNG(); break; + case 3: result = ValidateMD5(); break; + case 4: result = ValidateSHA(); break; + case 5: result = ValidateDES(); break; + case 6: result = ValidateIDEA(); break; + case 7: result = ValidateARC4(); break; + case 8: result = ValidateRC5(); break; + case 9: result = ValidateBlowfish(); break; +// case 10: result = ValidateDiamond2(); break; + case 11: result = ValidateThreeWay(); break; + case 12: result = ValidateBBS(); break; + case 13: result = ValidateDH(); break; + case 14: result = ValidateRSA(); break; + case 15: result = ValidateElGamal(); break; + case 16: result = ValidateDSA(thorough); break; +// case 17: result = ValidateHAVAL(); break; + case 18: result = ValidateSAFER(); break; + case 19: result = ValidateLUC(); break; + case 20: result = ValidateRabin(); break; +// case 21: result = ValidateBlumGoldwasser(); break; + case 22: result = ValidateECP(); break; + case 23: result = ValidateEC2N(); break; +// case 24: result = ValidateMD5MAC(); break; + case 25: result = ValidateGOST(); break; + case 26: result = ValidateTiger(); break; + case 27: result = ValidateRIPEMD(); break; + case 28: result = ValidateHMAC(); break; +// case 29: result = ValidateXMACC(); break; + case 30: result = ValidateSHARK(); break; + case 32: result = ValidateLUC_DH(); break; + case 33: result = ValidateLUC_DL(); break; + case 34: result = ValidateSEAL(); break; + case 35: result = ValidateCAST(); break; + case 36: result = ValidateSquare(); break; + case 37: result = ValidateRC2(); break; + case 38: result = ValidateRC6(); break; + case 39: result = ValidateMARS(); break; + case 40: result = ValidateRW(); break; + case 41: result = ValidateMD2(); break; + case 42: result = ValidateNR(); break; + case 43: result = ValidateMQV(); break; + case 44: result = ValidateRijndael(); break; + case 45: result = ValidateTwofish(); break; + case 46: result = ValidateSerpent(); break; + case 47: result = ValidateCipherModes(); break; + case 48: result = ValidateCRC32(); break; + case 49: result = ValidateECDSA(); break; + case 50: result = ValidateXTR_DH(); break; + case 51: result = ValidateSKIPJACK(); break; + case 52: result = ValidateSHA2(); break; + case 53: result = ValidatePanama(); break; + case 54: result = ValidateAdler32(); break; + case 55: result = ValidateMD4(); break; + case 56: result = ValidatePBKDF(); break; + case 57: result = ValidateESIGN(); break; + case 58: result = ValidateDLIES(); break; + case 59: result = ValidateBaseCode(); break; + case 60: result = ValidateSHACAL2(); break; + case 61: result = ValidateCamellia(); break; + case 62: result = ValidateWhirlpool(); break; + case 63: result = ValidateTTMAC(); break; + case 64: result = ValidateSalsa(); break; + case 65: result = ValidateSosemanuk(); break; + case 66: result = ValidateVMAC(); break; + default: return false; + } + + time_t endTime = time(NULL); + cout << "\nTest ended at " << asctime(localtime(&endTime)); + cout << "Seed used was: " << seed << endl; + + return result; +} diff --git a/CryptoPP/crypto/tftables.cpp b/CryptoPP/crypto/tftables.cpp new file mode 100644 index 0000000..ad55aa7 --- /dev/null +++ b/CryptoPP/crypto/tftables.cpp @@ -0,0 +1,317 @@ +// Twofish tables + +#include "pch.h" +#include "twofish.h" + +NAMESPACE_BEGIN(CryptoPP) + +const byte Twofish::Base::q[2][256] = { + 0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76, 0x9A, 0x92, 0x80, 0x78, + 0xE4, 0xDD, 0xD1, 0x38, 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C, + 0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48, 0xF2, 0xD0, 0x8B, 0x30, + 0x84, 0x54, 0xDF, 0x23, 0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82, + 0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C, 0xA6, 0xEB, 0xA5, 0xBE, + 0x16, 0x0C, 0xE3, 0x61, 0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B, + 0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1, 0xE1, 0xE6, 0xBD, 0x45, + 0xE2, 0xF4, 0xB6, 0x66, 0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7, + 0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA, 0xEA, 0x77, 0x39, 0xAF, + 0x33, 0xC9, 0x62, 0x71, 0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8, + 0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7, 0xA1, 0x1D, 0xAA, 0xED, + 0x06, 0x70, 0xB2, 0xD2, 0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90, + 0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB, 0x9E, 0x9C, 0x52, 0x1B, + 0x5F, 0x93, 0x0A, 0xEF, 0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B, + 0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64, 0x2A, 0xCE, 0xCB, 0x2F, + 0xFC, 0x97, 0x05, 0x7A, 0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A, + 0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02, 0xB8, 0xDA, 0xB0, 0x17, + 0x55, 0x1F, 0x8A, 0x7D, 0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72, + 0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34, 0x6E, 0x50, 0xDE, 0x68, + 0x65, 0xBC, 0xDB, 0xF8, 0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4, + 0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00, 0x6F, 0x9D, 0x36, 0x42, + 0x4A, 0x5E, 0xC1, 0xE0, + + 0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8, 0x4A, 0xD3, 0xE6, 0x6B, + 0x45, 0x7D, 0xE8, 0x4B, 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1, + 0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F, 0x5E, 0xBA, 0xAE, 0x5B, + 0x8A, 0x00, 0xBC, 0x9D, 0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5, + 0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3, 0xB2, 0x73, 0x4C, 0x54, + 0x92, 0x74, 0x36, 0x51, 0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96, + 0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C, 0x13, 0x95, 0x9C, 0xC7, + 0x24, 0x46, 0x3B, 0x70, 0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8, + 0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC, 0x03, 0x6F, 0x08, 0xBF, + 0x40, 0xE7, 0x2B, 0xE2, 0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9, + 0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17, 0x66, 0x94, 0xA1, 0x1D, + 0x3D, 0xF0, 0xDE, 0xB3, 0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E, + 0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49, 0x81, 0x88, 0xEE, 0x21, + 0xC4, 0x1A, 0xEB, 0xD9, 0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01, + 0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48, 0x4F, 0xF2, 0x65, 0x8E, + 0x78, 0x5C, 0x58, 0x19, 0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64, + 0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5, 0xCE, 0xE9, 0x68, 0x44, + 0xE0, 0x4D, 0x43, 0x69, 0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E, + 0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC, 0x22, 0xC9, 0xC0, 0x9B, + 0x89, 0xD4, 0xED, 0xAB, 0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9, + 0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2, 0x16, 0x25, 0x86, 0x56, + 0x55, 0x09, 0xBE, 0x91 +}; + +const word32 Twofish::Base::mds[4][256] = { + 0xbcbc3275, 0xecec21f3, 0x202043c6, 0xb3b3c9f4, + 0xdada03db, 0x02028b7b, 0xe2e22bfb, 0x9e9efac8, + 0xc9c9ec4a, 0xd4d409d3, 0x18186be6, 0x1e1e9f6b, + 0x98980e45, 0xb2b2387d, 0xa6a6d2e8, 0x2626b74b, + 0x3c3c57d6, 0x93938a32, 0x8282eed8, 0x525298fd, + 0x7b7bd437, 0xbbbb3771, 0x5b5b97f1, 0x474783e1, + 0x24243c30, 0x5151e20f, 0xbabac6f8, 0x4a4af31b, + 0xbfbf4887, 0x0d0d70fa, 0xb0b0b306, 0x7575de3f, + 0xd2d2fd5e, 0x7d7d20ba, 0x666631ae, 0x3a3aa35b, + 0x59591c8a, 0x00000000, 0xcdcd93bc, 0x1a1ae09d, + 0xaeae2c6d, 0x7f7fabc1, 0x2b2bc7b1, 0xbebeb90e, + 0xe0e0a080, 0x8a8a105d, 0x3b3b52d2, 0x6464bad5, + 0xd8d888a0, 0xe7e7a584, 0x5f5fe807, 0x1b1b1114, + 0x2c2cc2b5, 0xfcfcb490, 0x3131272c, 0x808065a3, + 0x73732ab2, 0x0c0c8173, 0x79795f4c, 0x6b6b4154, + 0x4b4b0292, 0x53536974, 0x94948f36, 0x83831f51, + 0x2a2a3638, 0xc4c49cb0, 0x2222c8bd, 0xd5d5f85a, + 0xbdbdc3fc, 0x48487860, 0xffffce62, 0x4c4c0796, + 0x4141776c, 0xc7c7e642, 0xebeb24f7, 0x1c1c1410, + 0x5d5d637c, 0x36362228, 0x6767c027, 0xe9e9af8c, + 0x4444f913, 0x1414ea95, 0xf5f5bb9c, 0xcfcf18c7, + 0x3f3f2d24, 0xc0c0e346, 0x7272db3b, 0x54546c70, + 0x29294cca, 0xf0f035e3, 0x0808fe85, 0xc6c617cb, + 0xf3f34f11, 0x8c8ce4d0, 0xa4a45993, 0xcaca96b8, + 0x68683ba6, 0xb8b84d83, 0x38382820, 0xe5e52eff, + 0xadad569f, 0x0b0b8477, 0xc8c81dc3, 0x9999ffcc, + 0x5858ed03, 0x19199a6f, 0x0e0e0a08, 0x95957ebf, + 0x70705040, 0xf7f730e7, 0x6e6ecf2b, 0x1f1f6ee2, + 0xb5b53d79, 0x09090f0c, 0x616134aa, 0x57571682, + 0x9f9f0b41, 0x9d9d803a, 0x111164ea, 0x2525cdb9, + 0xafafdde4, 0x4545089a, 0xdfdf8da4, 0xa3a35c97, + 0xeaead57e, 0x353558da, 0xededd07a, 0x4343fc17, + 0xf8f8cb66, 0xfbfbb194, 0x3737d3a1, 0xfafa401d, + 0xc2c2683d, 0xb4b4ccf0, 0x32325dde, 0x9c9c71b3, + 0x5656e70b, 0xe3e3da72, 0x878760a7, 0x15151b1c, + 0xf9f93aef, 0x6363bfd1, 0x3434a953, 0x9a9a853e, + 0xb1b1428f, 0x7c7cd133, 0x88889b26, 0x3d3da65f, + 0xa1a1d7ec, 0xe4e4df76, 0x8181942a, 0x91910149, + 0x0f0ffb81, 0xeeeeaa88, 0x161661ee, 0xd7d77321, + 0x9797f5c4, 0xa5a5a81a, 0xfefe3feb, 0x6d6db5d9, + 0x7878aec5, 0xc5c56d39, 0x1d1de599, 0x7676a4cd, + 0x3e3edcad, 0xcbcb6731, 0xb6b6478b, 0xefef5b01, + 0x12121e18, 0x6060c523, 0x6a6ab0dd, 0x4d4df61f, + 0xcecee94e, 0xdede7c2d, 0x55559df9, 0x7e7e5a48, + 0x2121b24f, 0x03037af2, 0xa0a02665, 0x5e5e198e, + 0x5a5a6678, 0x65654b5c, 0x62624e58, 0xfdfd4519, + 0x0606f48d, 0x404086e5, 0xf2f2be98, 0x3333ac57, + 0x17179067, 0x05058e7f, 0xe8e85e05, 0x4f4f7d64, + 0x89896aaf, 0x10109563, 0x74742fb6, 0x0a0a75fe, + 0x5c5c92f5, 0x9b9b74b7, 0x2d2d333c, 0x3030d6a5, + 0x2e2e49ce, 0x494989e9, 0x46467268, 0x77775544, + 0xa8a8d8e0, 0x9696044d, 0x2828bd43, 0xa9a92969, + 0xd9d97929, 0x8686912e, 0xd1d187ac, 0xf4f44a15, + 0x8d8d1559, 0xd6d682a8, 0xb9b9bc0a, 0x42420d9e, + 0xf6f6c16e, 0x2f2fb847, 0xdddd06df, 0x23233934, + 0xcccc6235, 0xf1f1c46a, 0xc1c112cf, 0x8585ebdc, + 0x8f8f9e22, 0x7171a1c9, 0x9090f0c0, 0xaaaa539b, + 0x0101f189, 0x8b8be1d4, 0x4e4e8ced, 0x8e8e6fab, + 0xababa212, 0x6f6f3ea2, 0xe6e6540d, 0xdbdbf252, + 0x92927bbb, 0xb7b7b602, 0x6969ca2f, 0x3939d9a9, + 0xd3d30cd7, 0xa7a72361, 0xa2a2ad1e, 0xc3c399b4, + 0x6c6c4450, 0x07070504, 0x04047ff6, 0x272746c2, + 0xacaca716, 0xd0d07625, 0x50501386, 0xdcdcf756, + 0x84841a55, 0xe1e15109, 0x7a7a25be, 0x1313ef91, + + 0xa9d93939, 0x67901717, 0xb3719c9c, 0xe8d2a6a6, + 0x04050707, 0xfd985252, 0xa3658080, 0x76dfe4e4, + 0x9a084545, 0x92024b4b, 0x80a0e0e0, 0x78665a5a, + 0xe4ddafaf, 0xddb06a6a, 0xd1bf6363, 0x38362a2a, + 0x0d54e6e6, 0xc6432020, 0x3562cccc, 0x98bef2f2, + 0x181e1212, 0xf724ebeb, 0xecd7a1a1, 0x6c774141, + 0x43bd2828, 0x7532bcbc, 0x37d47b7b, 0x269b8888, + 0xfa700d0d, 0x13f94444, 0x94b1fbfb, 0x485a7e7e, + 0xf27a0303, 0xd0e48c8c, 0x8b47b6b6, 0x303c2424, + 0x84a5e7e7, 0x54416b6b, 0xdf06dddd, 0x23c56060, + 0x1945fdfd, 0x5ba33a3a, 0x3d68c2c2, 0x59158d8d, + 0xf321ecec, 0xae316666, 0xa23e6f6f, 0x82165757, + 0x63951010, 0x015befef, 0x834db8b8, 0x2e918686, + 0xd9b56d6d, 0x511f8383, 0x9b53aaaa, 0x7c635d5d, + 0xa63b6868, 0xeb3ffefe, 0xa5d63030, 0xbe257a7a, + 0x16a7acac, 0x0c0f0909, 0xe335f0f0, 0x6123a7a7, + 0xc0f09090, 0x8cafe9e9, 0x3a809d9d, 0xf5925c5c, + 0x73810c0c, 0x2c273131, 0x2576d0d0, 0x0be75656, + 0xbb7b9292, 0x4ee9cece, 0x89f10101, 0x6b9f1e1e, + 0x53a93434, 0x6ac4f1f1, 0xb499c3c3, 0xf1975b5b, + 0xe1834747, 0xe66b1818, 0xbdc82222, 0x450e9898, + 0xe26e1f1f, 0xf4c9b3b3, 0xb62f7474, 0x66cbf8f8, + 0xccff9999, 0x95ea1414, 0x03ed5858, 0x56f7dcdc, + 0xd4e18b8b, 0x1c1b1515, 0x1eada2a2, 0xd70cd3d3, + 0xfb2be2e2, 0xc31dc8c8, 0x8e195e5e, 0xb5c22c2c, + 0xe9894949, 0xcf12c1c1, 0xbf7e9595, 0xba207d7d, + 0xea641111, 0x77840b0b, 0x396dc5c5, 0xaf6a8989, + 0x33d17c7c, 0xc9a17171, 0x62ceffff, 0x7137bbbb, + 0x81fb0f0f, 0x793db5b5, 0x0951e1e1, 0xaddc3e3e, + 0x242d3f3f, 0xcda47676, 0xf99d5555, 0xd8ee8282, + 0xe5864040, 0xc5ae7878, 0xb9cd2525, 0x4d049696, + 0x44557777, 0x080a0e0e, 0x86135050, 0xe730f7f7, + 0xa1d33737, 0x1d40fafa, 0xaa346161, 0xed8c4e4e, + 0x06b3b0b0, 0x706c5454, 0xb22a7373, 0xd2523b3b, + 0x410b9f9f, 0x7b8b0202, 0xa088d8d8, 0x114ff3f3, + 0x3167cbcb, 0xc2462727, 0x27c06767, 0x90b4fcfc, + 0x20283838, 0xf67f0404, 0x60784848, 0xff2ee5e5, + 0x96074c4c, 0x5c4b6565, 0xb1c72b2b, 0xab6f8e8e, + 0x9e0d4242, 0x9cbbf5f5, 0x52f2dbdb, 0x1bf34a4a, + 0x5fa63d3d, 0x9359a4a4, 0x0abcb9b9, 0xef3af9f9, + 0x91ef1313, 0x85fe0808, 0x49019191, 0xee611616, + 0x2d7cdede, 0x4fb22121, 0x8f42b1b1, 0x3bdb7272, + 0x47b82f2f, 0x8748bfbf, 0x6d2caeae, 0x46e3c0c0, + 0xd6573c3c, 0x3e859a9a, 0x6929a9a9, 0x647d4f4f, + 0x2a948181, 0xce492e2e, 0xcb17c6c6, 0x2fca6969, + 0xfcc3bdbd, 0x975ca3a3, 0x055ee8e8, 0x7ad0eded, + 0xac87d1d1, 0x7f8e0505, 0xd5ba6464, 0x1aa8a5a5, + 0x4bb72626, 0x0eb9bebe, 0xa7608787, 0x5af8d5d5, + 0x28223636, 0x14111b1b, 0x3fde7575, 0x2979d9d9, + 0x88aaeeee, 0x3c332d2d, 0x4c5f7979, 0x02b6b7b7, + 0xb896caca, 0xda583535, 0xb09cc4c4, 0x17fc4343, + 0x551a8484, 0x1ff64d4d, 0x8a1c5959, 0x7d38b2b2, + 0x57ac3333, 0xc718cfcf, 0x8df40606, 0x74695353, + 0xb7749b9b, 0xc4f59797, 0x9f56adad, 0x72dae3e3, + 0x7ed5eaea, 0x154af4f4, 0x229e8f8f, 0x12a2abab, + 0x584e6262, 0x07e85f5f, 0x99e51d1d, 0x34392323, + 0x6ec1f6f6, 0x50446c6c, 0xde5d3232, 0x68724646, + 0x6526a0a0, 0xbc93cdcd, 0xdb03dada, 0xf8c6baba, + 0xc8fa9e9e, 0xa882d6d6, 0x2bcf6e6e, 0x40507070, + 0xdceb8585, 0xfe750a0a, 0x328a9393, 0xa48ddfdf, + 0xca4c2929, 0x10141c1c, 0x2173d7d7, 0xf0ccb4b4, + 0xd309d4d4, 0x5d108a8a, 0x0fe25151, 0x00000000, + 0x6f9a1919, 0x9de01a1a, 0x368f9494, 0x42e6c7c7, + 0x4aecc9c9, 0x5efdd2d2, 0xc1ab7f7f, 0xe0d8a8a8, + + 0xbc75bc32, 0xecf3ec21, 0x20c62043, 0xb3f4b3c9, + 0xdadbda03, 0x027b028b, 0xe2fbe22b, 0x9ec89efa, + 0xc94ac9ec, 0xd4d3d409, 0x18e6186b, 0x1e6b1e9f, + 0x9845980e, 0xb27db238, 0xa6e8a6d2, 0x264b26b7, + 0x3cd63c57, 0x9332938a, 0x82d882ee, 0x52fd5298, + 0x7b377bd4, 0xbb71bb37, 0x5bf15b97, 0x47e14783, + 0x2430243c, 0x510f51e2, 0xbaf8bac6, 0x4a1b4af3, + 0xbf87bf48, 0x0dfa0d70, 0xb006b0b3, 0x753f75de, + 0xd25ed2fd, 0x7dba7d20, 0x66ae6631, 0x3a5b3aa3, + 0x598a591c, 0x00000000, 0xcdbccd93, 0x1a9d1ae0, + 0xae6dae2c, 0x7fc17fab, 0x2bb12bc7, 0xbe0ebeb9, + 0xe080e0a0, 0x8a5d8a10, 0x3bd23b52, 0x64d564ba, + 0xd8a0d888, 0xe784e7a5, 0x5f075fe8, 0x1b141b11, + 0x2cb52cc2, 0xfc90fcb4, 0x312c3127, 0x80a38065, + 0x73b2732a, 0x0c730c81, 0x794c795f, 0x6b546b41, + 0x4b924b02, 0x53745369, 0x9436948f, 0x8351831f, + 0x2a382a36, 0xc4b0c49c, 0x22bd22c8, 0xd55ad5f8, + 0xbdfcbdc3, 0x48604878, 0xff62ffce, 0x4c964c07, + 0x416c4177, 0xc742c7e6, 0xebf7eb24, 0x1c101c14, + 0x5d7c5d63, 0x36283622, 0x672767c0, 0xe98ce9af, + 0x441344f9, 0x149514ea, 0xf59cf5bb, 0xcfc7cf18, + 0x3f243f2d, 0xc046c0e3, 0x723b72db, 0x5470546c, + 0x29ca294c, 0xf0e3f035, 0x088508fe, 0xc6cbc617, + 0xf311f34f, 0x8cd08ce4, 0xa493a459, 0xcab8ca96, + 0x68a6683b, 0xb883b84d, 0x38203828, 0xe5ffe52e, + 0xad9fad56, 0x0b770b84, 0xc8c3c81d, 0x99cc99ff, + 0x580358ed, 0x196f199a, 0x0e080e0a, 0x95bf957e, + 0x70407050, 0xf7e7f730, 0x6e2b6ecf, 0x1fe21f6e, + 0xb579b53d, 0x090c090f, 0x61aa6134, 0x57825716, + 0x9f419f0b, 0x9d3a9d80, 0x11ea1164, 0x25b925cd, + 0xafe4afdd, 0x459a4508, 0xdfa4df8d, 0xa397a35c, + 0xea7eead5, 0x35da3558, 0xed7aedd0, 0x431743fc, + 0xf866f8cb, 0xfb94fbb1, 0x37a137d3, 0xfa1dfa40, + 0xc23dc268, 0xb4f0b4cc, 0x32de325d, 0x9cb39c71, + 0x560b56e7, 0xe372e3da, 0x87a78760, 0x151c151b, + 0xf9eff93a, 0x63d163bf, 0x345334a9, 0x9a3e9a85, + 0xb18fb142, 0x7c337cd1, 0x8826889b, 0x3d5f3da6, + 0xa1eca1d7, 0xe476e4df, 0x812a8194, 0x91499101, + 0x0f810ffb, 0xee88eeaa, 0x16ee1661, 0xd721d773, + 0x97c497f5, 0xa51aa5a8, 0xfeebfe3f, 0x6dd96db5, + 0x78c578ae, 0xc539c56d, 0x1d991de5, 0x76cd76a4, + 0x3ead3edc, 0xcb31cb67, 0xb68bb647, 0xef01ef5b, + 0x1218121e, 0x602360c5, 0x6add6ab0, 0x4d1f4df6, + 0xce4ecee9, 0xde2dde7c, 0x55f9559d, 0x7e487e5a, + 0x214f21b2, 0x03f2037a, 0xa065a026, 0x5e8e5e19, + 0x5a785a66, 0x655c654b, 0x6258624e, 0xfd19fd45, + 0x068d06f4, 0x40e54086, 0xf298f2be, 0x335733ac, + 0x17671790, 0x057f058e, 0xe805e85e, 0x4f644f7d, + 0x89af896a, 0x10631095, 0x74b6742f, 0x0afe0a75, + 0x5cf55c92, 0x9bb79b74, 0x2d3c2d33, 0x30a530d6, + 0x2ece2e49, 0x49e94989, 0x46684672, 0x77447755, + 0xa8e0a8d8, 0x964d9604, 0x284328bd, 0xa969a929, + 0xd929d979, 0x862e8691, 0xd1acd187, 0xf415f44a, + 0x8d598d15, 0xd6a8d682, 0xb90ab9bc, 0x429e420d, + 0xf66ef6c1, 0x2f472fb8, 0xdddfdd06, 0x23342339, + 0xcc35cc62, 0xf16af1c4, 0xc1cfc112, 0x85dc85eb, + 0x8f228f9e, 0x71c971a1, 0x90c090f0, 0xaa9baa53, + 0x018901f1, 0x8bd48be1, 0x4eed4e8c, 0x8eab8e6f, + 0xab12aba2, 0x6fa26f3e, 0xe60de654, 0xdb52dbf2, + 0x92bb927b, 0xb702b7b6, 0x692f69ca, 0x39a939d9, + 0xd3d7d30c, 0xa761a723, 0xa21ea2ad, 0xc3b4c399, + 0x6c506c44, 0x07040705, 0x04f6047f, 0x27c22746, + 0xac16aca7, 0xd025d076, 0x50865013, 0xdc56dcf7, + 0x8455841a, 0xe109e151, 0x7abe7a25, 0x139113ef, + + 0xd939a9d9, 0x90176790, 0x719cb371, 0xd2a6e8d2, + 0x05070405, 0x9852fd98, 0x6580a365, 0xdfe476df, + 0x08459a08, 0x024b9202, 0xa0e080a0, 0x665a7866, + 0xddafe4dd, 0xb06addb0, 0xbf63d1bf, 0x362a3836, + 0x54e60d54, 0x4320c643, 0x62cc3562, 0xbef298be, + 0x1e12181e, 0x24ebf724, 0xd7a1ecd7, 0x77416c77, + 0xbd2843bd, 0x32bc7532, 0xd47b37d4, 0x9b88269b, + 0x700dfa70, 0xf94413f9, 0xb1fb94b1, 0x5a7e485a, + 0x7a03f27a, 0xe48cd0e4, 0x47b68b47, 0x3c24303c, + 0xa5e784a5, 0x416b5441, 0x06dddf06, 0xc56023c5, + 0x45fd1945, 0xa33a5ba3, 0x68c23d68, 0x158d5915, + 0x21ecf321, 0x3166ae31, 0x3e6fa23e, 0x16578216, + 0x95106395, 0x5bef015b, 0x4db8834d, 0x91862e91, + 0xb56dd9b5, 0x1f83511f, 0x53aa9b53, 0x635d7c63, + 0x3b68a63b, 0x3ffeeb3f, 0xd630a5d6, 0x257abe25, + 0xa7ac16a7, 0x0f090c0f, 0x35f0e335, 0x23a76123, + 0xf090c0f0, 0xafe98caf, 0x809d3a80, 0x925cf592, + 0x810c7381, 0x27312c27, 0x76d02576, 0xe7560be7, + 0x7b92bb7b, 0xe9ce4ee9, 0xf10189f1, 0x9f1e6b9f, + 0xa93453a9, 0xc4f16ac4, 0x99c3b499, 0x975bf197, + 0x8347e183, 0x6b18e66b, 0xc822bdc8, 0x0e98450e, + 0x6e1fe26e, 0xc9b3f4c9, 0x2f74b62f, 0xcbf866cb, + 0xff99ccff, 0xea1495ea, 0xed5803ed, 0xf7dc56f7, + 0xe18bd4e1, 0x1b151c1b, 0xada21ead, 0x0cd3d70c, + 0x2be2fb2b, 0x1dc8c31d, 0x195e8e19, 0xc22cb5c2, + 0x8949e989, 0x12c1cf12, 0x7e95bf7e, 0x207dba20, + 0x6411ea64, 0x840b7784, 0x6dc5396d, 0x6a89af6a, + 0xd17c33d1, 0xa171c9a1, 0xceff62ce, 0x37bb7137, + 0xfb0f81fb, 0x3db5793d, 0x51e10951, 0xdc3eaddc, + 0x2d3f242d, 0xa476cda4, 0x9d55f99d, 0xee82d8ee, + 0x8640e586, 0xae78c5ae, 0xcd25b9cd, 0x04964d04, + 0x55774455, 0x0a0e080a, 0x13508613, 0x30f7e730, + 0xd337a1d3, 0x40fa1d40, 0x3461aa34, 0x8c4eed8c, + 0xb3b006b3, 0x6c54706c, 0x2a73b22a, 0x523bd252, + 0x0b9f410b, 0x8b027b8b, 0x88d8a088, 0x4ff3114f, + 0x67cb3167, 0x4627c246, 0xc06727c0, 0xb4fc90b4, + 0x28382028, 0x7f04f67f, 0x78486078, 0x2ee5ff2e, + 0x074c9607, 0x4b655c4b, 0xc72bb1c7, 0x6f8eab6f, + 0x0d429e0d, 0xbbf59cbb, 0xf2db52f2, 0xf34a1bf3, + 0xa63d5fa6, 0x59a49359, 0xbcb90abc, 0x3af9ef3a, + 0xef1391ef, 0xfe0885fe, 0x01914901, 0x6116ee61, + 0x7cde2d7c, 0xb2214fb2, 0x42b18f42, 0xdb723bdb, + 0xb82f47b8, 0x48bf8748, 0x2cae6d2c, 0xe3c046e3, + 0x573cd657, 0x859a3e85, 0x29a96929, 0x7d4f647d, + 0x94812a94, 0x492ece49, 0x17c6cb17, 0xca692fca, + 0xc3bdfcc3, 0x5ca3975c, 0x5ee8055e, 0xd0ed7ad0, + 0x87d1ac87, 0x8e057f8e, 0xba64d5ba, 0xa8a51aa8, + 0xb7264bb7, 0xb9be0eb9, 0x6087a760, 0xf8d55af8, + 0x22362822, 0x111b1411, 0xde753fde, 0x79d92979, + 0xaaee88aa, 0x332d3c33, 0x5f794c5f, 0xb6b702b6, + 0x96cab896, 0x5835da58, 0x9cc4b09c, 0xfc4317fc, + 0x1a84551a, 0xf64d1ff6, 0x1c598a1c, 0x38b27d38, + 0xac3357ac, 0x18cfc718, 0xf4068df4, 0x69537469, + 0x749bb774, 0xf597c4f5, 0x56ad9f56, 0xdae372da, + 0xd5ea7ed5, 0x4af4154a, 0x9e8f229e, 0xa2ab12a2, + 0x4e62584e, 0xe85f07e8, 0xe51d99e5, 0x39233439, + 0xc1f66ec1, 0x446c5044, 0x5d32de5d, 0x72466872, + 0x26a06526, 0x93cdbc93, 0x03dadb03, 0xc6baf8c6, + 0xfa9ec8fa, 0x82d6a882, 0xcf6e2bcf, 0x50704050, + 0xeb85dceb, 0x750afe75, 0x8a93328a, 0x8ddfa48d, + 0x4c29ca4c, 0x141c1014, 0x73d72173, 0xccb4f0cc, + 0x09d4d309, 0x108a5d10, 0xe2510fe2, 0x00000000, + 0x9a196f9a, 0xe01a9de0, 0x8f94368f, 0xe6c742e6, + 0xecc94aec, 0xfdd25efd, 0xab7fc1ab, 0xd8a8e0d8}; + +NAMESPACE_END diff --git a/CryptoPP/crypto/tiger.cpp b/CryptoPP/crypto/tiger.cpp new file mode 100644 index 0000000..a4ecfd1 --- /dev/null +++ b/CryptoPP/crypto/tiger.cpp @@ -0,0 +1,269 @@ +// tiger.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "tiger.h" +#include "misc.h" +#include "cpu.h" + +#ifdef WORD64_AVAILABLE + +NAMESPACE_BEGIN(CryptoPP) + +void Tiger::InitState(HashWordType *state) +{ + state[0] = W64LIT(0x0123456789ABCDEF); + state[1] = W64LIT(0xFEDCBA9876543210); + state[2] = W64LIT(0xF096A5B4C3B2E187); +} + +void Tiger::TruncatedFinal(byte *hash, size_t size) +{ + ThrowIfInvalidTruncatedSize(size); + + PadLastBlock(56, 0x01); + CorrectEndianess(m_data, m_data, 56); + + m_data[7] = GetBitCountLo(); + + Transform(m_state, m_data); + CorrectEndianess(m_state, m_state, DigestSize()); + memcpy(hash, m_state, size); + + Restart(); // reinit for next use +} + +void Tiger::Transform (word64 *digest, const word64 *X) +{ +#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86 + if (HasSSE2()) + { +#ifdef __GNUC__ + __asm__ __volatile__ + ( + ".intel_syntax noprefix;" + AS1( push ebx) +#else + #if _MSC_VER < 1300 + const word64 *t = table; + AS2( mov edx, t) + #else + AS2( lea edx, [table]) + #endif + AS2( mov eax, digest) + AS2( mov esi, X) +#endif + AS2( movq mm0, [eax]) + AS2( movq mm1, [eax+1*8]) + AS2( movq mm5, mm1) + AS2( movq mm2, [eax+2*8]) + AS2( movq mm7, [edx+4*2048+0*8]) + AS2( movq mm6, [edx+4*2048+1*8]) + AS2( mov ecx, esp) + AS2( and esp, 0xfffffff0) + AS2( sub esp, 8*8) + AS1( push ecx) + +#define SSE2_round(a,b,c,x,mul) \ + AS2( pxor c, [x])\ + AS2( movd ecx, c)\ + AS2( movzx edi, cl)\ + AS2( movq mm3, [edx+0*2048+edi*8])\ + AS2( movzx edi, ch)\ + AS2( movq mm4, [edx+3*2048+edi*8])\ + AS2( shr ecx, 16)\ + AS2( movzx edi, cl)\ + AS2( pxor mm3, [edx+1*2048+edi*8])\ + AS2( movzx edi, ch)\ + AS2( pxor mm4, [edx+2*2048+edi*8])\ + AS3( pextrw ecx, c, 2)\ + AS2( movzx edi, cl)\ + AS2( pxor mm3, [edx+2*2048+edi*8])\ + AS2( movzx edi, ch)\ + AS2( pxor mm4, [edx+1*2048+edi*8])\ + AS3( pextrw ecx, c, 3)\ + AS2( movzx edi, cl)\ + AS2( pxor mm3, [edx+3*2048+edi*8])\ + AS2( psubq a, mm3)\ + AS2( movzx edi, ch)\ + AS2( pxor mm4, [edx+0*2048+edi*8])\ + AS2( paddq b, mm4)\ + SSE2_mul_##mul(b) + +#define SSE2_mul_5(b) \ + AS2( movq mm3, b)\ + AS2( psllq b, 2)\ + AS2( paddq b, mm3) + +#define SSE2_mul_7(b) \ + AS2( movq mm3, b)\ + AS2( psllq b, 3)\ + AS2( psubq b, mm3) + +#define SSE2_mul_9(b) \ + AS2( movq mm3, b)\ + AS2( psllq b, 3)\ + AS2( paddq b, mm3) + +#define label2_5 1 +#define label2_7 2 +#define label2_9 3 + +#define SSE2_pass(A,B,C,mul,X) \ + AS2( xor ebx, ebx)\ + ASL(mul)\ + SSE2_round(A,B,C,X+0*8+ebx,mul)\ + SSE2_round(B,C,A,X+1*8+ebx,mul)\ + AS2( cmp ebx, 6*8)\ + ASJ( je, label2_##mul, f)\ + SSE2_round(C,A,B,X+2*8+ebx,mul)\ + AS2( add ebx, 3*8)\ + ASJ( jmp, mul, b)\ + ASL(label2_##mul) + +#define SSE2_key_schedule(Y,X) \ + AS2( movq mm3, [X+7*8])\ + AS2( pxor mm3, mm6)\ + AS2( movq mm4, [X+0*8])\ + AS2( psubq mm4, mm3)\ + AS2( movq [Y+0*8], mm4)\ + AS2( pxor mm4, [X+1*8])\ + AS2( movq mm3, mm4)\ + AS2( movq [Y+1*8], mm4)\ + AS2( paddq mm4, [X+2*8])\ + AS2( pxor mm3, mm7)\ + AS2( psllq mm3, 19)\ + AS2( movq [Y+2*8], mm4)\ + AS2( pxor mm3, mm4)\ + AS2( movq mm4, [X+3*8])\ + AS2( psubq mm4, mm3)\ + AS2( movq [Y+3*8], mm4)\ + AS2( pxor mm4, [X+4*8])\ + AS2( movq mm3, mm4)\ + AS2( movq [Y+4*8], mm4)\ + AS2( paddq mm4, [X+5*8])\ + AS2( pxor mm3, mm7)\ + AS2( psrlq mm3, 23)\ + AS2( movq [Y+5*8], mm4)\ + AS2( pxor mm3, mm4)\ + AS2( movq mm4, [X+6*8])\ + AS2( psubq mm4, mm3)\ + AS2( movq [Y+6*8], mm4)\ + AS2( pxor mm4, [X+7*8])\ + AS2( movq mm3, mm4)\ + AS2( movq [Y+7*8], mm4)\ + AS2( paddq mm4, [Y+0*8])\ + AS2( pxor mm3, mm7)\ + AS2( psllq mm3, 19)\ + AS2( movq [Y+0*8], mm4)\ + AS2( pxor mm3, mm4)\ + AS2( movq mm4, [Y+1*8])\ + AS2( psubq mm4, mm3)\ + AS2( movq [Y+1*8], mm4)\ + AS2( pxor mm4, [Y+2*8])\ + AS2( movq mm3, mm4)\ + AS2( movq [Y+2*8], mm4)\ + AS2( paddq mm4, [Y+3*8])\ + AS2( pxor mm3, mm7)\ + AS2( psrlq mm3, 23)\ + AS2( movq [Y+3*8], mm4)\ + AS2( pxor mm3, mm4)\ + AS2( movq mm4, [Y+4*8])\ + AS2( psubq mm4, mm3)\ + AS2( movq [Y+4*8], mm4)\ + AS2( pxor mm4, [Y+5*8])\ + AS2( movq [Y+5*8], mm4)\ + AS2( paddq mm4, [Y+6*8])\ + AS2( movq [Y+6*8], mm4)\ + AS2( pxor mm4, [edx+4*2048+2*8])\ + AS2( movq mm3, [Y+7*8])\ + AS2( psubq mm3, mm4)\ + AS2( movq [Y+7*8], mm3) + + SSE2_pass(mm0, mm1, mm2, 5, esi) + SSE2_key_schedule(esp+4, esi) + SSE2_pass(mm2, mm0, mm1, 7, esp+4) + SSE2_key_schedule(esp+4, esp+4) + SSE2_pass(mm1, mm2, mm0, 9, esp+4) + + AS2( pxor mm0, [eax+0*8]) + AS2( movq [eax+0*8], mm0) + AS2( psubq mm1, mm5) + AS2( movq [eax+1*8], mm1) + AS2( paddq mm2, [eax+2*8]) + AS2( movq [eax+2*8], mm2) + + AS1( pop esp) + AS1( emms) +#ifdef __GNUC__ + AS1( pop ebx) + ".att_syntax prefix;" + : + : "a" (digest), "S" (X), "d" (table) + : "%ecx", "%edi", "memory", "cc" + ); +#endif + } + else +#endif + { + word64 a = digest[0]; + word64 b = digest[1]; + word64 c = digest[2]; + word64 Y[8]; + +#define t1 (table) +#define t2 (table+256) +#define t3 (table+256*2) +#define t4 (table+256*3) + +#define round(a,b,c,x,mul) \ + c ^= x; \ + a -= t1[GETBYTE(c,0)] ^ t2[GETBYTE(c,2)] ^ t3[GETBYTE(c,4)] ^ t4[GETBYTE(c,6)]; \ + b += t4[GETBYTE(c,1)] ^ t3[GETBYTE(c,3)] ^ t2[GETBYTE(c,5)] ^ t1[GETBYTE(c,7)]; \ + b *= mul + +#define pass(a,b,c,mul,X) {\ + int i=0;\ + while (true)\ + {\ + round(a,b,c,X[i+0],mul); \ + round(b,c,a,X[i+1],mul); \ + if (i==6)\ + break;\ + round(c,a,b,X[i+2],mul); \ + i+=3;\ + }} + +#define key_schedule(Y,X) \ + Y[0] = X[0] - (X[7]^W64LIT(0xA5A5A5A5A5A5A5A5)); \ + Y[1] = X[1] ^ Y[0]; \ + Y[2] = X[2] + Y[1]; \ + Y[3] = X[3] - (Y[2] ^ ((~Y[1])<<19)); \ + Y[4] = X[4] ^ Y[3]; \ + Y[5] = X[5] + Y[4]; \ + Y[6] = X[6] - (Y[5] ^ ((~Y[4])>>23)); \ + Y[7] = X[7] ^ Y[6]; \ + Y[0] += Y[7]; \ + Y[1] -= Y[0] ^ ((~Y[7])<<19); \ + Y[2] ^= Y[1]; \ + Y[3] += Y[2]; \ + Y[4] -= Y[3] ^ ((~Y[2])>>23); \ + Y[5] ^= Y[4]; \ + Y[6] += Y[5]; \ + Y[7] -= Y[6] ^ W64LIT(0x0123456789ABCDEF) + + pass(a,b,c,5,X); + key_schedule(Y,X); + pass(c,a,b,7,Y); + key_schedule(Y,Y); + pass(b,c,a,9,Y); + + digest[0] = a ^ digest[0]; + digest[1] = b - digest[1]; + digest[2] = c + digest[2]; + } +} + +NAMESPACE_END + +#endif // WORD64_AVAILABLE diff --git a/CryptoPP/crypto/tiger.h b/CryptoPP/crypto/tiger.h new file mode 100644 index 0000000..05b49d4 --- /dev/null +++ b/CryptoPP/crypto/tiger.h @@ -0,0 +1,29 @@ +#ifndef CRYPTOPP_TIGER_H +#define CRYPTOPP_TIGER_H + +#include "config.h" + +#ifdef WORD64_AVAILABLE + +#include "iterhash.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// Tiger +class Tiger : public IteratedHashWithStaticTransform +{ +public: + static void InitState(HashWordType *state); + static void Transform(word64 *digest, const word64 *data); + void TruncatedFinal(byte *hash, size_t size); + static const char * StaticAlgorithmName() {return "Tiger";} + +protected: + static const word64 table[4*256+3]; +}; + +NAMESPACE_END + +#endif + +#endif diff --git a/CryptoPP/crypto/tigertab.cpp b/CryptoPP/crypto/tigertab.cpp new file mode 100644 index 0000000..0a72432 --- /dev/null +++ b/CryptoPP/crypto/tigertab.cpp @@ -0,0 +1,529 @@ +#include "pch.h" +#include "tiger.h" + +#ifdef WORD64_AVAILABLE + +NAMESPACE_BEGIN(CryptoPP) + +const word64 Tiger::table[4*256+3] = +{ + W64LIT(0x02AAB17CF7E90C5E) /* 0 */, W64LIT(0xAC424B03E243A8EC) /* 1 */, + W64LIT(0x72CD5BE30DD5FCD3) /* 2 */, W64LIT(0x6D019B93F6F97F3A) /* 3 */, + W64LIT(0xCD9978FFD21F9193) /* 4 */, W64LIT(0x7573A1C9708029E2) /* 5 */, + W64LIT(0xB164326B922A83C3) /* 6 */, W64LIT(0x46883EEE04915870) /* 7 */, + W64LIT(0xEAACE3057103ECE6) /* 8 */, W64LIT(0xC54169B808A3535C) /* 9 */, + W64LIT(0x4CE754918DDEC47C) /* 10 */, W64LIT(0x0AA2F4DFDC0DF40C) /* 11 */, + W64LIT(0x10B76F18A74DBEFA) /* 12 */, W64LIT(0xC6CCB6235AD1AB6A) /* 13 */, + W64LIT(0x13726121572FE2FF) /* 14 */, W64LIT(0x1A488C6F199D921E) /* 15 */, + W64LIT(0x4BC9F9F4DA0007CA) /* 16 */, W64LIT(0x26F5E6F6E85241C7) /* 17 */, + W64LIT(0x859079DBEA5947B6) /* 18 */, W64LIT(0x4F1885C5C99E8C92) /* 19 */, + W64LIT(0xD78E761EA96F864B) /* 20 */, W64LIT(0x8E36428C52B5C17D) /* 21 */, + W64LIT(0x69CF6827373063C1) /* 22 */, W64LIT(0xB607C93D9BB4C56E) /* 23 */, + W64LIT(0x7D820E760E76B5EA) /* 24 */, W64LIT(0x645C9CC6F07FDC42) /* 25 */, + W64LIT(0xBF38A078243342E0) /* 26 */, W64LIT(0x5F6B343C9D2E7D04) /* 27 */, + W64LIT(0xF2C28AEB600B0EC6) /* 28 */, W64LIT(0x6C0ED85F7254BCAC) /* 29 */, + W64LIT(0x71592281A4DB4FE5) /* 30 */, W64LIT(0x1967FA69CE0FED9F) /* 31 */, + W64LIT(0xFD5293F8B96545DB) /* 32 */, W64LIT(0xC879E9D7F2A7600B) /* 33 */, + W64LIT(0x860248920193194E) /* 34 */, W64LIT(0xA4F9533B2D9CC0B3) /* 35 */, + W64LIT(0x9053836C15957613) /* 36 */, W64LIT(0xDB6DCF8AFC357BF1) /* 37 */, + W64LIT(0x18BEEA7A7A370F57) /* 38 */, W64LIT(0x037117CA50B99066) /* 39 */, + W64LIT(0x6AB30A9774424A35) /* 40 */, W64LIT(0xF4E92F02E325249B) /* 41 */, + W64LIT(0x7739DB07061CCAE1) /* 42 */, W64LIT(0xD8F3B49CECA42A05) /* 43 */, + W64LIT(0xBD56BE3F51382F73) /* 44 */, W64LIT(0x45FAED5843B0BB28) /* 45 */, + W64LIT(0x1C813D5C11BF1F83) /* 46 */, W64LIT(0x8AF0E4B6D75FA169) /* 47 */, + W64LIT(0x33EE18A487AD9999) /* 48 */, W64LIT(0x3C26E8EAB1C94410) /* 49 */, + W64LIT(0xB510102BC0A822F9) /* 50 */, W64LIT(0x141EEF310CE6123B) /* 51 */, + W64LIT(0xFC65B90059DDB154) /* 52 */, W64LIT(0xE0158640C5E0E607) /* 53 */, + W64LIT(0x884E079826C3A3CF) /* 54 */, W64LIT(0x930D0D9523C535FD) /* 55 */, + W64LIT(0x35638D754E9A2B00) /* 56 */, W64LIT(0x4085FCCF40469DD5) /* 57 */, + W64LIT(0xC4B17AD28BE23A4C) /* 58 */, W64LIT(0xCAB2F0FC6A3E6A2E) /* 59 */, + W64LIT(0x2860971A6B943FCD) /* 60 */, W64LIT(0x3DDE6EE212E30446) /* 61 */, + W64LIT(0x6222F32AE01765AE) /* 62 */, W64LIT(0x5D550BB5478308FE) /* 63 */, + W64LIT(0xA9EFA98DA0EDA22A) /* 64 */, W64LIT(0xC351A71686C40DA7) /* 65 */, + W64LIT(0x1105586D9C867C84) /* 66 */, W64LIT(0xDCFFEE85FDA22853) /* 67 */, + W64LIT(0xCCFBD0262C5EEF76) /* 68 */, W64LIT(0xBAF294CB8990D201) /* 69 */, + W64LIT(0xE69464F52AFAD975) /* 70 */, W64LIT(0x94B013AFDF133E14) /* 71 */, + W64LIT(0x06A7D1A32823C958) /* 72 */, W64LIT(0x6F95FE5130F61119) /* 73 */, + W64LIT(0xD92AB34E462C06C0) /* 74 */, W64LIT(0xED7BDE33887C71D2) /* 75 */, + W64LIT(0x79746D6E6518393E) /* 76 */, W64LIT(0x5BA419385D713329) /* 77 */, + W64LIT(0x7C1BA6B948A97564) /* 78 */, W64LIT(0x31987C197BFDAC67) /* 79 */, + W64LIT(0xDE6C23C44B053D02) /* 80 */, W64LIT(0x581C49FED002D64D) /* 81 */, + W64LIT(0xDD474D6338261571) /* 82 */, W64LIT(0xAA4546C3E473D062) /* 83 */, + W64LIT(0x928FCE349455F860) /* 84 */, W64LIT(0x48161BBACAAB94D9) /* 85 */, + W64LIT(0x63912430770E6F68) /* 86 */, W64LIT(0x6EC8A5E602C6641C) /* 87 */, + W64LIT(0x87282515337DDD2B) /* 88 */, W64LIT(0x2CDA6B42034B701B) /* 89 */, + W64LIT(0xB03D37C181CB096D) /* 90 */, W64LIT(0xE108438266C71C6F) /* 91 */, + W64LIT(0x2B3180C7EB51B255) /* 92 */, W64LIT(0xDF92B82F96C08BBC) /* 93 */, + W64LIT(0x5C68C8C0A632F3BA) /* 94 */, W64LIT(0x5504CC861C3D0556) /* 95 */, + W64LIT(0xABBFA4E55FB26B8F) /* 96 */, W64LIT(0x41848B0AB3BACEB4) /* 97 */, + W64LIT(0xB334A273AA445D32) /* 98 */, W64LIT(0xBCA696F0A85AD881) /* 99 */, + W64LIT(0x24F6EC65B528D56C) /* 100 */, W64LIT(0x0CE1512E90F4524A) /* 101 */, + W64LIT(0x4E9DD79D5506D35A) /* 102 */, W64LIT(0x258905FAC6CE9779) /* 103 */, + W64LIT(0x2019295B3E109B33) /* 104 */, W64LIT(0xF8A9478B73A054CC) /* 105 */, + W64LIT(0x2924F2F934417EB0) /* 106 */, W64LIT(0x3993357D536D1BC4) /* 107 */, + W64LIT(0x38A81AC21DB6FF8B) /* 108 */, W64LIT(0x47C4FBF17D6016BF) /* 109 */, + W64LIT(0x1E0FAADD7667E3F5) /* 110 */, W64LIT(0x7ABCFF62938BEB96) /* 111 */, + W64LIT(0xA78DAD948FC179C9) /* 112 */, W64LIT(0x8F1F98B72911E50D) /* 113 */, + W64LIT(0x61E48EAE27121A91) /* 114 */, W64LIT(0x4D62F7AD31859808) /* 115 */, + W64LIT(0xECEBA345EF5CEAEB) /* 116 */, W64LIT(0xF5CEB25EBC9684CE) /* 117 */, + W64LIT(0xF633E20CB7F76221) /* 118 */, W64LIT(0xA32CDF06AB8293E4) /* 119 */, + W64LIT(0x985A202CA5EE2CA4) /* 120 */, W64LIT(0xCF0B8447CC8A8FB1) /* 121 */, + W64LIT(0x9F765244979859A3) /* 122 */, W64LIT(0xA8D516B1A1240017) /* 123 */, + W64LIT(0x0BD7BA3EBB5DC726) /* 124 */, W64LIT(0xE54BCA55B86ADB39) /* 125 */, + W64LIT(0x1D7A3AFD6C478063) /* 126 */, W64LIT(0x519EC608E7669EDD) /* 127 */, + W64LIT(0x0E5715A2D149AA23) /* 128 */, W64LIT(0x177D4571848FF194) /* 129 */, + W64LIT(0xEEB55F3241014C22) /* 130 */, W64LIT(0x0F5E5CA13A6E2EC2) /* 131 */, + W64LIT(0x8029927B75F5C361) /* 132 */, W64LIT(0xAD139FABC3D6E436) /* 133 */, + W64LIT(0x0D5DF1A94CCF402F) /* 134 */, W64LIT(0x3E8BD948BEA5DFC8) /* 135 */, + W64LIT(0xA5A0D357BD3FF77E) /* 136 */, W64LIT(0xA2D12E251F74F645) /* 137 */, + W64LIT(0x66FD9E525E81A082) /* 138 */, W64LIT(0x2E0C90CE7F687A49) /* 139 */, + W64LIT(0xC2E8BCBEBA973BC5) /* 140 */, W64LIT(0x000001BCE509745F) /* 141 */, + W64LIT(0x423777BBE6DAB3D6) /* 142 */, W64LIT(0xD1661C7EAEF06EB5) /* 143 */, + W64LIT(0xA1781F354DAACFD8) /* 144 */, W64LIT(0x2D11284A2B16AFFC) /* 145 */, + W64LIT(0xF1FC4F67FA891D1F) /* 146 */, W64LIT(0x73ECC25DCB920ADA) /* 147 */, + W64LIT(0xAE610C22C2A12651) /* 148 */, W64LIT(0x96E0A810D356B78A) /* 149 */, + W64LIT(0x5A9A381F2FE7870F) /* 150 */, W64LIT(0xD5AD62EDE94E5530) /* 151 */, + W64LIT(0xD225E5E8368D1427) /* 152 */, W64LIT(0x65977B70C7AF4631) /* 153 */, + W64LIT(0x99F889B2DE39D74F) /* 154 */, W64LIT(0x233F30BF54E1D143) /* 155 */, + W64LIT(0x9A9675D3D9A63C97) /* 156 */, W64LIT(0x5470554FF334F9A8) /* 157 */, + W64LIT(0x166ACB744A4F5688) /* 158 */, W64LIT(0x70C74CAAB2E4AEAD) /* 159 */, + W64LIT(0xF0D091646F294D12) /* 160 */, W64LIT(0x57B82A89684031D1) /* 161 */, + W64LIT(0xEFD95A5A61BE0B6B) /* 162 */, W64LIT(0x2FBD12E969F2F29A) /* 163 */, + W64LIT(0x9BD37013FEFF9FE8) /* 164 */, W64LIT(0x3F9B0404D6085A06) /* 165 */, + W64LIT(0x4940C1F3166CFE15) /* 166 */, W64LIT(0x09542C4DCDF3DEFB) /* 167 */, + W64LIT(0xB4C5218385CD5CE3) /* 168 */, W64LIT(0xC935B7DC4462A641) /* 169 */, + W64LIT(0x3417F8A68ED3B63F) /* 170 */, W64LIT(0xB80959295B215B40) /* 171 */, + W64LIT(0xF99CDAEF3B8C8572) /* 172 */, W64LIT(0x018C0614F8FCB95D) /* 173 */, + W64LIT(0x1B14ACCD1A3ACDF3) /* 174 */, W64LIT(0x84D471F200BB732D) /* 175 */, + W64LIT(0xC1A3110E95E8DA16) /* 176 */, W64LIT(0x430A7220BF1A82B8) /* 177 */, + W64LIT(0xB77E090D39DF210E) /* 178 */, W64LIT(0x5EF4BD9F3CD05E9D) /* 179 */, + W64LIT(0x9D4FF6DA7E57A444) /* 180 */, W64LIT(0xDA1D60E183D4A5F8) /* 181 */, + W64LIT(0xB287C38417998E47) /* 182 */, W64LIT(0xFE3EDC121BB31886) /* 183 */, + W64LIT(0xC7FE3CCC980CCBEF) /* 184 */, W64LIT(0xE46FB590189BFD03) /* 185 */, + W64LIT(0x3732FD469A4C57DC) /* 186 */, W64LIT(0x7EF700A07CF1AD65) /* 187 */, + W64LIT(0x59C64468A31D8859) /* 188 */, W64LIT(0x762FB0B4D45B61F6) /* 189 */, + W64LIT(0x155BAED099047718) /* 190 */, W64LIT(0x68755E4C3D50BAA6) /* 191 */, + W64LIT(0xE9214E7F22D8B4DF) /* 192 */, W64LIT(0x2ADDBF532EAC95F4) /* 193 */, + W64LIT(0x32AE3909B4BD0109) /* 194 */, W64LIT(0x834DF537B08E3450) /* 195 */, + W64LIT(0xFA209DA84220728D) /* 196 */, W64LIT(0x9E691D9B9EFE23F7) /* 197 */, + W64LIT(0x0446D288C4AE8D7F) /* 198 */, W64LIT(0x7B4CC524E169785B) /* 199 */, + W64LIT(0x21D87F0135CA1385) /* 200 */, W64LIT(0xCEBB400F137B8AA5) /* 201 */, + W64LIT(0x272E2B66580796BE) /* 202 */, W64LIT(0x3612264125C2B0DE) /* 203 */, + W64LIT(0x057702BDAD1EFBB2) /* 204 */, W64LIT(0xD4BABB8EACF84BE9) /* 205 */, + W64LIT(0x91583139641BC67B) /* 206 */, W64LIT(0x8BDC2DE08036E024) /* 207 */, + W64LIT(0x603C8156F49F68ED) /* 208 */, W64LIT(0xF7D236F7DBEF5111) /* 209 */, + W64LIT(0x9727C4598AD21E80) /* 210 */, W64LIT(0xA08A0896670A5FD7) /* 211 */, + W64LIT(0xCB4A8F4309EBA9CB) /* 212 */, W64LIT(0x81AF564B0F7036A1) /* 213 */, + W64LIT(0xC0B99AA778199ABD) /* 214 */, W64LIT(0x959F1EC83FC8E952) /* 215 */, + W64LIT(0x8C505077794A81B9) /* 216 */, W64LIT(0x3ACAAF8F056338F0) /* 217 */, + W64LIT(0x07B43F50627A6778) /* 218 */, W64LIT(0x4A44AB49F5ECCC77) /* 219 */, + W64LIT(0x3BC3D6E4B679EE98) /* 220 */, W64LIT(0x9CC0D4D1CF14108C) /* 221 */, + W64LIT(0x4406C00B206BC8A0) /* 222 */, W64LIT(0x82A18854C8D72D89) /* 223 */, + W64LIT(0x67E366B35C3C432C) /* 224 */, W64LIT(0xB923DD61102B37F2) /* 225 */, + W64LIT(0x56AB2779D884271D) /* 226 */, W64LIT(0xBE83E1B0FF1525AF) /* 227 */, + W64LIT(0xFB7C65D4217E49A9) /* 228 */, W64LIT(0x6BDBE0E76D48E7D4) /* 229 */, + W64LIT(0x08DF828745D9179E) /* 230 */, W64LIT(0x22EA6A9ADD53BD34) /* 231 */, + W64LIT(0xE36E141C5622200A) /* 232 */, W64LIT(0x7F805D1B8CB750EE) /* 233 */, + W64LIT(0xAFE5C7A59F58E837) /* 234 */, W64LIT(0xE27F996A4FB1C23C) /* 235 */, + W64LIT(0xD3867DFB0775F0D0) /* 236 */, W64LIT(0xD0E673DE6E88891A) /* 237 */, + W64LIT(0x123AEB9EAFB86C25) /* 238 */, W64LIT(0x30F1D5D5C145B895) /* 239 */, + W64LIT(0xBB434A2DEE7269E7) /* 240 */, W64LIT(0x78CB67ECF931FA38) /* 241 */, + W64LIT(0xF33B0372323BBF9C) /* 242 */, W64LIT(0x52D66336FB279C74) /* 243 */, + W64LIT(0x505F33AC0AFB4EAA) /* 244 */, W64LIT(0xE8A5CD99A2CCE187) /* 245 */, + W64LIT(0x534974801E2D30BB) /* 246 */, W64LIT(0x8D2D5711D5876D90) /* 247 */, + W64LIT(0x1F1A412891BC038E) /* 248 */, W64LIT(0xD6E2E71D82E56648) /* 249 */, + W64LIT(0x74036C3A497732B7) /* 250 */, W64LIT(0x89B67ED96361F5AB) /* 251 */, + W64LIT(0xFFED95D8F1EA02A2) /* 252 */, W64LIT(0xE72B3BD61464D43D) /* 253 */, + W64LIT(0xA6300F170BDC4820) /* 254 */, W64LIT(0xEBC18760ED78A77A) /* 255 */, + W64LIT(0xE6A6BE5A05A12138) /* 256 */, W64LIT(0xB5A122A5B4F87C98) /* 257 */, + W64LIT(0x563C6089140B6990) /* 258 */, W64LIT(0x4C46CB2E391F5DD5) /* 259 */, + W64LIT(0xD932ADDBC9B79434) /* 260 */, W64LIT(0x08EA70E42015AFF5) /* 261 */, + W64LIT(0xD765A6673E478CF1) /* 262 */, W64LIT(0xC4FB757EAB278D99) /* 263 */, + W64LIT(0xDF11C6862D6E0692) /* 264 */, W64LIT(0xDDEB84F10D7F3B16) /* 265 */, + W64LIT(0x6F2EF604A665EA04) /* 266 */, W64LIT(0x4A8E0F0FF0E0DFB3) /* 267 */, + W64LIT(0xA5EDEEF83DBCBA51) /* 268 */, W64LIT(0xFC4F0A2A0EA4371E) /* 269 */, + W64LIT(0xE83E1DA85CB38429) /* 270 */, W64LIT(0xDC8FF882BA1B1CE2) /* 271 */, + W64LIT(0xCD45505E8353E80D) /* 272 */, W64LIT(0x18D19A00D4DB0717) /* 273 */, + W64LIT(0x34A0CFEDA5F38101) /* 274 */, W64LIT(0x0BE77E518887CAF2) /* 275 */, + W64LIT(0x1E341438B3C45136) /* 276 */, W64LIT(0xE05797F49089CCF9) /* 277 */, + W64LIT(0xFFD23F9DF2591D14) /* 278 */, W64LIT(0x543DDA228595C5CD) /* 279 */, + W64LIT(0x661F81FD99052A33) /* 280 */, W64LIT(0x8736E641DB0F7B76) /* 281 */, + W64LIT(0x15227725418E5307) /* 282 */, W64LIT(0xE25F7F46162EB2FA) /* 283 */, + W64LIT(0x48A8B2126C13D9FE) /* 284 */, W64LIT(0xAFDC541792E76EEA) /* 285 */, + W64LIT(0x03D912BFC6D1898F) /* 286 */, W64LIT(0x31B1AAFA1B83F51B) /* 287 */, + W64LIT(0xF1AC2796E42AB7D9) /* 288 */, W64LIT(0x40A3A7D7FCD2EBAC) /* 289 */, + W64LIT(0x1056136D0AFBBCC5) /* 290 */, W64LIT(0x7889E1DD9A6D0C85) /* 291 */, + W64LIT(0xD33525782A7974AA) /* 292 */, W64LIT(0xA7E25D09078AC09B) /* 293 */, + W64LIT(0xBD4138B3EAC6EDD0) /* 294 */, W64LIT(0x920ABFBE71EB9E70) /* 295 */, + W64LIT(0xA2A5D0F54FC2625C) /* 296 */, W64LIT(0xC054E36B0B1290A3) /* 297 */, + W64LIT(0xF6DD59FF62FE932B) /* 298 */, W64LIT(0x3537354511A8AC7D) /* 299 */, + W64LIT(0xCA845E9172FADCD4) /* 300 */, W64LIT(0x84F82B60329D20DC) /* 301 */, + W64LIT(0x79C62CE1CD672F18) /* 302 */, W64LIT(0x8B09A2ADD124642C) /* 303 */, + W64LIT(0xD0C1E96A19D9E726) /* 304 */, W64LIT(0x5A786A9B4BA9500C) /* 305 */, + W64LIT(0x0E020336634C43F3) /* 306 */, W64LIT(0xC17B474AEB66D822) /* 307 */, + W64LIT(0x6A731AE3EC9BAAC2) /* 308 */, W64LIT(0x8226667AE0840258) /* 309 */, + W64LIT(0x67D4567691CAECA5) /* 310 */, W64LIT(0x1D94155C4875ADB5) /* 311 */, + W64LIT(0x6D00FD985B813FDF) /* 312 */, W64LIT(0x51286EFCB774CD06) /* 313 */, + W64LIT(0x5E8834471FA744AF) /* 314 */, W64LIT(0xF72CA0AEE761AE2E) /* 315 */, + W64LIT(0xBE40E4CDAEE8E09A) /* 316 */, W64LIT(0xE9970BBB5118F665) /* 317 */, + W64LIT(0x726E4BEB33DF1964) /* 318 */, W64LIT(0x703B000729199762) /* 319 */, + W64LIT(0x4631D816F5EF30A7) /* 320 */, W64LIT(0xB880B5B51504A6BE) /* 321 */, + W64LIT(0x641793C37ED84B6C) /* 322 */, W64LIT(0x7B21ED77F6E97D96) /* 323 */, + W64LIT(0x776306312EF96B73) /* 324 */, W64LIT(0xAE528948E86FF3F4) /* 325 */, + W64LIT(0x53DBD7F286A3F8F8) /* 326 */, W64LIT(0x16CADCE74CFC1063) /* 327 */, + W64LIT(0x005C19BDFA52C6DD) /* 328 */, W64LIT(0x68868F5D64D46AD3) /* 329 */, + W64LIT(0x3A9D512CCF1E186A) /* 330 */, W64LIT(0x367E62C2385660AE) /* 331 */, + W64LIT(0xE359E7EA77DCB1D7) /* 332 */, W64LIT(0x526C0773749ABE6E) /* 333 */, + W64LIT(0x735AE5F9D09F734B) /* 334 */, W64LIT(0x493FC7CC8A558BA8) /* 335 */, + W64LIT(0xB0B9C1533041AB45) /* 336 */, W64LIT(0x321958BA470A59BD) /* 337 */, + W64LIT(0x852DB00B5F46C393) /* 338 */, W64LIT(0x91209B2BD336B0E5) /* 339 */, + W64LIT(0x6E604F7D659EF19F) /* 340 */, W64LIT(0xB99A8AE2782CCB24) /* 341 */, + W64LIT(0xCCF52AB6C814C4C7) /* 342 */, W64LIT(0x4727D9AFBE11727B) /* 343 */, + W64LIT(0x7E950D0C0121B34D) /* 344 */, W64LIT(0x756F435670AD471F) /* 345 */, + W64LIT(0xF5ADD442615A6849) /* 346 */, W64LIT(0x4E87E09980B9957A) /* 347 */, + W64LIT(0x2ACFA1DF50AEE355) /* 348 */, W64LIT(0xD898263AFD2FD556) /* 349 */, + W64LIT(0xC8F4924DD80C8FD6) /* 350 */, W64LIT(0xCF99CA3D754A173A) /* 351 */, + W64LIT(0xFE477BACAF91BF3C) /* 352 */, W64LIT(0xED5371F6D690C12D) /* 353 */, + W64LIT(0x831A5C285E687094) /* 354 */, W64LIT(0xC5D3C90A3708A0A4) /* 355 */, + W64LIT(0x0F7F903717D06580) /* 356 */, W64LIT(0x19F9BB13B8FDF27F) /* 357 */, + W64LIT(0xB1BD6F1B4D502843) /* 358 */, W64LIT(0x1C761BA38FFF4012) /* 359 */, + W64LIT(0x0D1530C4E2E21F3B) /* 360 */, W64LIT(0x8943CE69A7372C8A) /* 361 */, + W64LIT(0xE5184E11FEB5CE66) /* 362 */, W64LIT(0x618BDB80BD736621) /* 363 */, + W64LIT(0x7D29BAD68B574D0B) /* 364 */, W64LIT(0x81BB613E25E6FE5B) /* 365 */, + W64LIT(0x071C9C10BC07913F) /* 366 */, W64LIT(0xC7BEEB7909AC2D97) /* 367 */, + W64LIT(0xC3E58D353BC5D757) /* 368 */, W64LIT(0xEB017892F38F61E8) /* 369 */, + W64LIT(0xD4EFFB9C9B1CC21A) /* 370 */, W64LIT(0x99727D26F494F7AB) /* 371 */, + W64LIT(0xA3E063A2956B3E03) /* 372 */, W64LIT(0x9D4A8B9A4AA09C30) /* 373 */, + W64LIT(0x3F6AB7D500090FB4) /* 374 */, W64LIT(0x9CC0F2A057268AC0) /* 375 */, + W64LIT(0x3DEE9D2DEDBF42D1) /* 376 */, W64LIT(0x330F49C87960A972) /* 377 */, + W64LIT(0xC6B2720287421B41) /* 378 */, W64LIT(0x0AC59EC07C00369C) /* 379 */, + W64LIT(0xEF4EAC49CB353425) /* 380 */, W64LIT(0xF450244EEF0129D8) /* 381 */, + W64LIT(0x8ACC46E5CAF4DEB6) /* 382 */, W64LIT(0x2FFEAB63989263F7) /* 383 */, + W64LIT(0x8F7CB9FE5D7A4578) /* 384 */, W64LIT(0x5BD8F7644E634635) /* 385 */, + W64LIT(0x427A7315BF2DC900) /* 386 */, W64LIT(0x17D0C4AA2125261C) /* 387 */, + W64LIT(0x3992486C93518E50) /* 388 */, W64LIT(0xB4CBFEE0A2D7D4C3) /* 389 */, + W64LIT(0x7C75D6202C5DDD8D) /* 390 */, W64LIT(0xDBC295D8E35B6C61) /* 391 */, + W64LIT(0x60B369D302032B19) /* 392 */, W64LIT(0xCE42685FDCE44132) /* 393 */, + W64LIT(0x06F3DDB9DDF65610) /* 394 */, W64LIT(0x8EA4D21DB5E148F0) /* 395 */, + W64LIT(0x20B0FCE62FCD496F) /* 396 */, W64LIT(0x2C1B912358B0EE31) /* 397 */, + W64LIT(0xB28317B818F5A308) /* 398 */, W64LIT(0xA89C1E189CA6D2CF) /* 399 */, + W64LIT(0x0C6B18576AAADBC8) /* 400 */, W64LIT(0xB65DEAA91299FAE3) /* 401 */, + W64LIT(0xFB2B794B7F1027E7) /* 402 */, W64LIT(0x04E4317F443B5BEB) /* 403 */, + W64LIT(0x4B852D325939D0A6) /* 404 */, W64LIT(0xD5AE6BEEFB207FFC) /* 405 */, + W64LIT(0x309682B281C7D374) /* 406 */, W64LIT(0xBAE309A194C3B475) /* 407 */, + W64LIT(0x8CC3F97B13B49F05) /* 408 */, W64LIT(0x98A9422FF8293967) /* 409 */, + W64LIT(0x244B16B01076FF7C) /* 410 */, W64LIT(0xF8BF571C663D67EE) /* 411 */, + W64LIT(0x1F0D6758EEE30DA1) /* 412 */, W64LIT(0xC9B611D97ADEB9B7) /* 413 */, + W64LIT(0xB7AFD5887B6C57A2) /* 414 */, W64LIT(0x6290AE846B984FE1) /* 415 */, + W64LIT(0x94DF4CDEACC1A5FD) /* 416 */, W64LIT(0x058A5BD1C5483AFF) /* 417 */, + W64LIT(0x63166CC142BA3C37) /* 418 */, W64LIT(0x8DB8526EB2F76F40) /* 419 */, + W64LIT(0xE10880036F0D6D4E) /* 420 */, W64LIT(0x9E0523C9971D311D) /* 421 */, + W64LIT(0x45EC2824CC7CD691) /* 422 */, W64LIT(0x575B8359E62382C9) /* 423 */, + W64LIT(0xFA9E400DC4889995) /* 424 */, W64LIT(0xD1823ECB45721568) /* 425 */, + W64LIT(0xDAFD983B8206082F) /* 426 */, W64LIT(0xAA7D29082386A8CB) /* 427 */, + W64LIT(0x269FCD4403B87588) /* 428 */, W64LIT(0x1B91F5F728BDD1E0) /* 429 */, + W64LIT(0xE4669F39040201F6) /* 430 */, W64LIT(0x7A1D7C218CF04ADE) /* 431 */, + W64LIT(0x65623C29D79CE5CE) /* 432 */, W64LIT(0x2368449096C00BB1) /* 433 */, + W64LIT(0xAB9BF1879DA503BA) /* 434 */, W64LIT(0xBC23ECB1A458058E) /* 435 */, + W64LIT(0x9A58DF01BB401ECC) /* 436 */, W64LIT(0xA070E868A85F143D) /* 437 */, + W64LIT(0x4FF188307DF2239E) /* 438 */, W64LIT(0x14D565B41A641183) /* 439 */, + W64LIT(0xEE13337452701602) /* 440 */, W64LIT(0x950E3DCF3F285E09) /* 441 */, + W64LIT(0x59930254B9C80953) /* 442 */, W64LIT(0x3BF299408930DA6D) /* 443 */, + W64LIT(0xA955943F53691387) /* 444 */, W64LIT(0xA15EDECAA9CB8784) /* 445 */, + W64LIT(0x29142127352BE9A0) /* 446 */, W64LIT(0x76F0371FFF4E7AFB) /* 447 */, + W64LIT(0x0239F450274F2228) /* 448 */, W64LIT(0xBB073AF01D5E868B) /* 449 */, + W64LIT(0xBFC80571C10E96C1) /* 450 */, W64LIT(0xD267088568222E23) /* 451 */, + W64LIT(0x9671A3D48E80B5B0) /* 452 */, W64LIT(0x55B5D38AE193BB81) /* 453 */, + W64LIT(0x693AE2D0A18B04B8) /* 454 */, W64LIT(0x5C48B4ECADD5335F) /* 455 */, + W64LIT(0xFD743B194916A1CA) /* 456 */, W64LIT(0x2577018134BE98C4) /* 457 */, + W64LIT(0xE77987E83C54A4AD) /* 458 */, W64LIT(0x28E11014DA33E1B9) /* 459 */, + W64LIT(0x270CC59E226AA213) /* 460 */, W64LIT(0x71495F756D1A5F60) /* 461 */, + W64LIT(0x9BE853FB60AFEF77) /* 462 */, W64LIT(0xADC786A7F7443DBF) /* 463 */, + W64LIT(0x0904456173B29A82) /* 464 */, W64LIT(0x58BC7A66C232BD5E) /* 465 */, + W64LIT(0xF306558C673AC8B2) /* 466 */, W64LIT(0x41F639C6B6C9772A) /* 467 */, + W64LIT(0x216DEFE99FDA35DA) /* 468 */, W64LIT(0x11640CC71C7BE615) /* 469 */, + W64LIT(0x93C43694565C5527) /* 470 */, W64LIT(0xEA038E6246777839) /* 471 */, + W64LIT(0xF9ABF3CE5A3E2469) /* 472 */, W64LIT(0x741E768D0FD312D2) /* 473 */, + W64LIT(0x0144B883CED652C6) /* 474 */, W64LIT(0xC20B5A5BA33F8552) /* 475 */, + W64LIT(0x1AE69633C3435A9D) /* 476 */, W64LIT(0x97A28CA4088CFDEC) /* 477 */, + W64LIT(0x8824A43C1E96F420) /* 478 */, W64LIT(0x37612FA66EEEA746) /* 479 */, + W64LIT(0x6B4CB165F9CF0E5A) /* 480 */, W64LIT(0x43AA1C06A0ABFB4A) /* 481 */, + W64LIT(0x7F4DC26FF162796B) /* 482 */, W64LIT(0x6CBACC8E54ED9B0F) /* 483 */, + W64LIT(0xA6B7FFEFD2BB253E) /* 484 */, W64LIT(0x2E25BC95B0A29D4F) /* 485 */, + W64LIT(0x86D6A58BDEF1388C) /* 486 */, W64LIT(0xDED74AC576B6F054) /* 487 */, + W64LIT(0x8030BDBC2B45805D) /* 488 */, W64LIT(0x3C81AF70E94D9289) /* 489 */, + W64LIT(0x3EFF6DDA9E3100DB) /* 490 */, W64LIT(0xB38DC39FDFCC8847) /* 491 */, + W64LIT(0x123885528D17B87E) /* 492 */, W64LIT(0xF2DA0ED240B1B642) /* 493 */, + W64LIT(0x44CEFADCD54BF9A9) /* 494 */, W64LIT(0x1312200E433C7EE6) /* 495 */, + W64LIT(0x9FFCC84F3A78C748) /* 496 */, W64LIT(0xF0CD1F72248576BB) /* 497 */, + W64LIT(0xEC6974053638CFE4) /* 498 */, W64LIT(0x2BA7B67C0CEC4E4C) /* 499 */, + W64LIT(0xAC2F4DF3E5CE32ED) /* 500 */, W64LIT(0xCB33D14326EA4C11) /* 501 */, + W64LIT(0xA4E9044CC77E58BC) /* 502 */, W64LIT(0x5F513293D934FCEF) /* 503 */, + W64LIT(0x5DC9645506E55444) /* 504 */, W64LIT(0x50DE418F317DE40A) /* 505 */, + W64LIT(0x388CB31A69DDE259) /* 506 */, W64LIT(0x2DB4A83455820A86) /* 507 */, + W64LIT(0x9010A91E84711AE9) /* 508 */, W64LIT(0x4DF7F0B7B1498371) /* 509 */, + W64LIT(0xD62A2EABC0977179) /* 510 */, W64LIT(0x22FAC097AA8D5C0E) /* 511 */, + W64LIT(0xF49FCC2FF1DAF39B) /* 512 */, W64LIT(0x487FD5C66FF29281) /* 513 */, + W64LIT(0xE8A30667FCDCA83F) /* 514 */, W64LIT(0x2C9B4BE3D2FCCE63) /* 515 */, + W64LIT(0xDA3FF74B93FBBBC2) /* 516 */, W64LIT(0x2FA165D2FE70BA66) /* 517 */, + W64LIT(0xA103E279970E93D4) /* 518 */, W64LIT(0xBECDEC77B0E45E71) /* 519 */, + W64LIT(0xCFB41E723985E497) /* 520 */, W64LIT(0xB70AAA025EF75017) /* 521 */, + W64LIT(0xD42309F03840B8E0) /* 522 */, W64LIT(0x8EFC1AD035898579) /* 523 */, + W64LIT(0x96C6920BE2B2ABC5) /* 524 */, W64LIT(0x66AF4163375A9172) /* 525 */, + W64LIT(0x2174ABDCCA7127FB) /* 526 */, W64LIT(0xB33CCEA64A72FF41) /* 527 */, + W64LIT(0xF04A4933083066A5) /* 528 */, W64LIT(0x8D970ACDD7289AF5) /* 529 */, + W64LIT(0x8F96E8E031C8C25E) /* 530 */, W64LIT(0xF3FEC02276875D47) /* 531 */, + W64LIT(0xEC7BF310056190DD) /* 532 */, W64LIT(0xF5ADB0AEBB0F1491) /* 533 */, + W64LIT(0x9B50F8850FD58892) /* 534 */, W64LIT(0x4975488358B74DE8) /* 535 */, + W64LIT(0xA3354FF691531C61) /* 536 */, W64LIT(0x0702BBE481D2C6EE) /* 537 */, + W64LIT(0x89FB24057DEDED98) /* 538 */, W64LIT(0xAC3075138596E902) /* 539 */, + W64LIT(0x1D2D3580172772ED) /* 540 */, W64LIT(0xEB738FC28E6BC30D) /* 541 */, + W64LIT(0x5854EF8F63044326) /* 542 */, W64LIT(0x9E5C52325ADD3BBE) /* 543 */, + W64LIT(0x90AA53CF325C4623) /* 544 */, W64LIT(0xC1D24D51349DD067) /* 545 */, + W64LIT(0x2051CFEEA69EA624) /* 546 */, W64LIT(0x13220F0A862E7E4F) /* 547 */, + W64LIT(0xCE39399404E04864) /* 548 */, W64LIT(0xD9C42CA47086FCB7) /* 549 */, + W64LIT(0x685AD2238A03E7CC) /* 550 */, W64LIT(0x066484B2AB2FF1DB) /* 551 */, + W64LIT(0xFE9D5D70EFBF79EC) /* 552 */, W64LIT(0x5B13B9DD9C481854) /* 553 */, + W64LIT(0x15F0D475ED1509AD) /* 554 */, W64LIT(0x0BEBCD060EC79851) /* 555 */, + W64LIT(0xD58C6791183AB7F8) /* 556 */, W64LIT(0xD1187C5052F3EEE4) /* 557 */, + W64LIT(0xC95D1192E54E82FF) /* 558 */, W64LIT(0x86EEA14CB9AC6CA2) /* 559 */, + W64LIT(0x3485BEB153677D5D) /* 560 */, W64LIT(0xDD191D781F8C492A) /* 561 */, + W64LIT(0xF60866BAA784EBF9) /* 562 */, W64LIT(0x518F643BA2D08C74) /* 563 */, + W64LIT(0x8852E956E1087C22) /* 564 */, W64LIT(0xA768CB8DC410AE8D) /* 565 */, + W64LIT(0x38047726BFEC8E1A) /* 566 */, W64LIT(0xA67738B4CD3B45AA) /* 567 */, + W64LIT(0xAD16691CEC0DDE19) /* 568 */, W64LIT(0xC6D4319380462E07) /* 569 */, + W64LIT(0xC5A5876D0BA61938) /* 570 */, W64LIT(0x16B9FA1FA58FD840) /* 571 */, + W64LIT(0x188AB1173CA74F18) /* 572 */, W64LIT(0xABDA2F98C99C021F) /* 573 */, + W64LIT(0x3E0580AB134AE816) /* 574 */, W64LIT(0x5F3B05B773645ABB) /* 575 */, + W64LIT(0x2501A2BE5575F2F6) /* 576 */, W64LIT(0x1B2F74004E7E8BA9) /* 577 */, + W64LIT(0x1CD7580371E8D953) /* 578 */, W64LIT(0x7F6ED89562764E30) /* 579 */, + W64LIT(0xB15926FF596F003D) /* 580 */, W64LIT(0x9F65293DA8C5D6B9) /* 581 */, + W64LIT(0x6ECEF04DD690F84C) /* 582 */, W64LIT(0x4782275FFF33AF88) /* 583 */, + W64LIT(0xE41433083F820801) /* 584 */, W64LIT(0xFD0DFE409A1AF9B5) /* 585 */, + W64LIT(0x4325A3342CDB396B) /* 586 */, W64LIT(0x8AE77E62B301B252) /* 587 */, + W64LIT(0xC36F9E9F6655615A) /* 588 */, W64LIT(0x85455A2D92D32C09) /* 589 */, + W64LIT(0xF2C7DEA949477485) /* 590 */, W64LIT(0x63CFB4C133A39EBA) /* 591 */, + W64LIT(0x83B040CC6EBC5462) /* 592 */, W64LIT(0x3B9454C8FDB326B0) /* 593 */, + W64LIT(0x56F56A9E87FFD78C) /* 594 */, W64LIT(0x2DC2940D99F42BC6) /* 595 */, + W64LIT(0x98F7DF096B096E2D) /* 596 */, W64LIT(0x19A6E01E3AD852BF) /* 597 */, + W64LIT(0x42A99CCBDBD4B40B) /* 598 */, W64LIT(0xA59998AF45E9C559) /* 599 */, + W64LIT(0x366295E807D93186) /* 600 */, W64LIT(0x6B48181BFAA1F773) /* 601 */, + W64LIT(0x1FEC57E2157A0A1D) /* 602 */, W64LIT(0x4667446AF6201AD5) /* 603 */, + W64LIT(0xE615EBCACFB0F075) /* 604 */, W64LIT(0xB8F31F4F68290778) /* 605 */, + W64LIT(0x22713ED6CE22D11E) /* 606 */, W64LIT(0x3057C1A72EC3C93B) /* 607 */, + W64LIT(0xCB46ACC37C3F1F2F) /* 608 */, W64LIT(0xDBB893FD02AAF50E) /* 609 */, + W64LIT(0x331FD92E600B9FCF) /* 610 */, W64LIT(0xA498F96148EA3AD6) /* 611 */, + W64LIT(0xA8D8426E8B6A83EA) /* 612 */, W64LIT(0xA089B274B7735CDC) /* 613 */, + W64LIT(0x87F6B3731E524A11) /* 614 */, W64LIT(0x118808E5CBC96749) /* 615 */, + W64LIT(0x9906E4C7B19BD394) /* 616 */, W64LIT(0xAFED7F7E9B24A20C) /* 617 */, + W64LIT(0x6509EADEEB3644A7) /* 618 */, W64LIT(0x6C1EF1D3E8EF0EDE) /* 619 */, + W64LIT(0xB9C97D43E9798FB4) /* 620 */, W64LIT(0xA2F2D784740C28A3) /* 621 */, + W64LIT(0x7B8496476197566F) /* 622 */, W64LIT(0x7A5BE3E6B65F069D) /* 623 */, + W64LIT(0xF96330ED78BE6F10) /* 624 */, W64LIT(0xEEE60DE77A076A15) /* 625 */, + W64LIT(0x2B4BEE4AA08B9BD0) /* 626 */, W64LIT(0x6A56A63EC7B8894E) /* 627 */, + W64LIT(0x02121359BA34FEF4) /* 628 */, W64LIT(0x4CBF99F8283703FC) /* 629 */, + W64LIT(0x398071350CAF30C8) /* 630 */, W64LIT(0xD0A77A89F017687A) /* 631 */, + W64LIT(0xF1C1A9EB9E423569) /* 632 */, W64LIT(0x8C7976282DEE8199) /* 633 */, + W64LIT(0x5D1737A5DD1F7ABD) /* 634 */, W64LIT(0x4F53433C09A9FA80) /* 635 */, + W64LIT(0xFA8B0C53DF7CA1D9) /* 636 */, W64LIT(0x3FD9DCBC886CCB77) /* 637 */, + W64LIT(0xC040917CA91B4720) /* 638 */, W64LIT(0x7DD00142F9D1DCDF) /* 639 */, + W64LIT(0x8476FC1D4F387B58) /* 640 */, W64LIT(0x23F8E7C5F3316503) /* 641 */, + W64LIT(0x032A2244E7E37339) /* 642 */, W64LIT(0x5C87A5D750F5A74B) /* 643 */, + W64LIT(0x082B4CC43698992E) /* 644 */, W64LIT(0xDF917BECB858F63C) /* 645 */, + W64LIT(0x3270B8FC5BF86DDA) /* 646 */, W64LIT(0x10AE72BB29B5DD76) /* 647 */, + W64LIT(0x576AC94E7700362B) /* 648 */, W64LIT(0x1AD112DAC61EFB8F) /* 649 */, + W64LIT(0x691BC30EC5FAA427) /* 650 */, W64LIT(0xFF246311CC327143) /* 651 */, + W64LIT(0x3142368E30E53206) /* 652 */, W64LIT(0x71380E31E02CA396) /* 653 */, + W64LIT(0x958D5C960AAD76F1) /* 654 */, W64LIT(0xF8D6F430C16DA536) /* 655 */, + W64LIT(0xC8FFD13F1BE7E1D2) /* 656 */, W64LIT(0x7578AE66004DDBE1) /* 657 */, + W64LIT(0x05833F01067BE646) /* 658 */, W64LIT(0xBB34B5AD3BFE586D) /* 659 */, + W64LIT(0x095F34C9A12B97F0) /* 660 */, W64LIT(0x247AB64525D60CA8) /* 661 */, + W64LIT(0xDCDBC6F3017477D1) /* 662 */, W64LIT(0x4A2E14D4DECAD24D) /* 663 */, + W64LIT(0xBDB5E6D9BE0A1EEB) /* 664 */, W64LIT(0x2A7E70F7794301AB) /* 665 */, + W64LIT(0xDEF42D8A270540FD) /* 666 */, W64LIT(0x01078EC0A34C22C1) /* 667 */, + W64LIT(0xE5DE511AF4C16387) /* 668 */, W64LIT(0x7EBB3A52BD9A330A) /* 669 */, + W64LIT(0x77697857AA7D6435) /* 670 */, W64LIT(0x004E831603AE4C32) /* 671 */, + W64LIT(0xE7A21020AD78E312) /* 672 */, W64LIT(0x9D41A70C6AB420F2) /* 673 */, + W64LIT(0x28E06C18EA1141E6) /* 674 */, W64LIT(0xD2B28CBD984F6B28) /* 675 */, + W64LIT(0x26B75F6C446E9D83) /* 676 */, W64LIT(0xBA47568C4D418D7F) /* 677 */, + W64LIT(0xD80BADBFE6183D8E) /* 678 */, W64LIT(0x0E206D7F5F166044) /* 679 */, + W64LIT(0xE258A43911CBCA3E) /* 680 */, W64LIT(0x723A1746B21DC0BC) /* 681 */, + W64LIT(0xC7CAA854F5D7CDD3) /* 682 */, W64LIT(0x7CAC32883D261D9C) /* 683 */, + W64LIT(0x7690C26423BA942C) /* 684 */, W64LIT(0x17E55524478042B8) /* 685 */, + W64LIT(0xE0BE477656A2389F) /* 686 */, W64LIT(0x4D289B5E67AB2DA0) /* 687 */, + W64LIT(0x44862B9C8FBBFD31) /* 688 */, W64LIT(0xB47CC8049D141365) /* 689 */, + W64LIT(0x822C1B362B91C793) /* 690 */, W64LIT(0x4EB14655FB13DFD8) /* 691 */, + W64LIT(0x1ECBBA0714E2A97B) /* 692 */, W64LIT(0x6143459D5CDE5F14) /* 693 */, + W64LIT(0x53A8FBF1D5F0AC89) /* 694 */, W64LIT(0x97EA04D81C5E5B00) /* 695 */, + W64LIT(0x622181A8D4FDB3F3) /* 696 */, W64LIT(0xE9BCD341572A1208) /* 697 */, + W64LIT(0x1411258643CCE58A) /* 698 */, W64LIT(0x9144C5FEA4C6E0A4) /* 699 */, + W64LIT(0x0D33D06565CF620F) /* 700 */, W64LIT(0x54A48D489F219CA1) /* 701 */, + W64LIT(0xC43E5EAC6D63C821) /* 702 */, W64LIT(0xA9728B3A72770DAF) /* 703 */, + W64LIT(0xD7934E7B20DF87EF) /* 704 */, W64LIT(0xE35503B61A3E86E5) /* 705 */, + W64LIT(0xCAE321FBC819D504) /* 706 */, W64LIT(0x129A50B3AC60BFA6) /* 707 */, + W64LIT(0xCD5E68EA7E9FB6C3) /* 708 */, W64LIT(0xB01C90199483B1C7) /* 709 */, + W64LIT(0x3DE93CD5C295376C) /* 710 */, W64LIT(0xAED52EDF2AB9AD13) /* 711 */, + W64LIT(0x2E60F512C0A07884) /* 712 */, W64LIT(0xBC3D86A3E36210C9) /* 713 */, + W64LIT(0x35269D9B163951CE) /* 714 */, W64LIT(0x0C7D6E2AD0CDB5FA) /* 715 */, + W64LIT(0x59E86297D87F5733) /* 716 */, W64LIT(0x298EF221898DB0E7) /* 717 */, + W64LIT(0x55000029D1A5AA7E) /* 718 */, W64LIT(0x8BC08AE1B5061B45) /* 719 */, + W64LIT(0xC2C31C2B6C92703A) /* 720 */, W64LIT(0x94CC596BAF25EF42) /* 721 */, + W64LIT(0x0A1D73DB22540456) /* 722 */, W64LIT(0x04B6A0F9D9C4179A) /* 723 */, + W64LIT(0xEFFDAFA2AE3D3C60) /* 724 */, W64LIT(0xF7C8075BB49496C4) /* 725 */, + W64LIT(0x9CC5C7141D1CD4E3) /* 726 */, W64LIT(0x78BD1638218E5534) /* 727 */, + W64LIT(0xB2F11568F850246A) /* 728 */, W64LIT(0xEDFABCFA9502BC29) /* 729 */, + W64LIT(0x796CE5F2DA23051B) /* 730 */, W64LIT(0xAAE128B0DC93537C) /* 731 */, + W64LIT(0x3A493DA0EE4B29AE) /* 732 */, W64LIT(0xB5DF6B2C416895D7) /* 733 */, + W64LIT(0xFCABBD25122D7F37) /* 734 */, W64LIT(0x70810B58105DC4B1) /* 735 */, + W64LIT(0xE10FDD37F7882A90) /* 736 */, W64LIT(0x524DCAB5518A3F5C) /* 737 */, + W64LIT(0x3C9E85878451255B) /* 738 */, W64LIT(0x4029828119BD34E2) /* 739 */, + W64LIT(0x74A05B6F5D3CECCB) /* 740 */, W64LIT(0xB610021542E13ECA) /* 741 */, + W64LIT(0x0FF979D12F59E2AC) /* 742 */, W64LIT(0x6037DA27E4F9CC50) /* 743 */, + W64LIT(0x5E92975A0DF1847D) /* 744 */, W64LIT(0xD66DE190D3E623FE) /* 745 */, + W64LIT(0x5032D6B87B568048) /* 746 */, W64LIT(0x9A36B7CE8235216E) /* 747 */, + W64LIT(0x80272A7A24F64B4A) /* 748 */, W64LIT(0x93EFED8B8C6916F7) /* 749 */, + W64LIT(0x37DDBFF44CCE1555) /* 750 */, W64LIT(0x4B95DB5D4B99BD25) /* 751 */, + W64LIT(0x92D3FDA169812FC0) /* 752 */, W64LIT(0xFB1A4A9A90660BB6) /* 753 */, + W64LIT(0x730C196946A4B9B2) /* 754 */, W64LIT(0x81E289AA7F49DA68) /* 755 */, + W64LIT(0x64669A0F83B1A05F) /* 756 */, W64LIT(0x27B3FF7D9644F48B) /* 757 */, + W64LIT(0xCC6B615C8DB675B3) /* 758 */, W64LIT(0x674F20B9BCEBBE95) /* 759 */, + W64LIT(0x6F31238275655982) /* 760 */, W64LIT(0x5AE488713E45CF05) /* 761 */, + W64LIT(0xBF619F9954C21157) /* 762 */, W64LIT(0xEABAC46040A8EAE9) /* 763 */, + W64LIT(0x454C6FE9F2C0C1CD) /* 764 */, W64LIT(0x419CF6496412691C) /* 765 */, + W64LIT(0xD3DC3BEF265B0F70) /* 766 */, W64LIT(0x6D0E60F5C3578A9E) /* 767 */, + W64LIT(0x5B0E608526323C55) /* 768 */, W64LIT(0x1A46C1A9FA1B59F5) /* 769 */, + W64LIT(0xA9E245A17C4C8FFA) /* 770 */, W64LIT(0x65CA5159DB2955D7) /* 771 */, + W64LIT(0x05DB0A76CE35AFC2) /* 772 */, W64LIT(0x81EAC77EA9113D45) /* 773 */, + W64LIT(0x528EF88AB6AC0A0D) /* 774 */, W64LIT(0xA09EA253597BE3FF) /* 775 */, + W64LIT(0x430DDFB3AC48CD56) /* 776 */, W64LIT(0xC4B3A67AF45CE46F) /* 777 */, + W64LIT(0x4ECECFD8FBE2D05E) /* 778 */, W64LIT(0x3EF56F10B39935F0) /* 779 */, + W64LIT(0x0B22D6829CD619C6) /* 780 */, W64LIT(0x17FD460A74DF2069) /* 781 */, + W64LIT(0x6CF8CC8E8510ED40) /* 782 */, W64LIT(0xD6C824BF3A6ECAA7) /* 783 */, + W64LIT(0x61243D581A817049) /* 784 */, W64LIT(0x048BACB6BBC163A2) /* 785 */, + W64LIT(0xD9A38AC27D44CC32) /* 786 */, W64LIT(0x7FDDFF5BAAF410AB) /* 787 */, + W64LIT(0xAD6D495AA804824B) /* 788 */, W64LIT(0xE1A6A74F2D8C9F94) /* 789 */, + W64LIT(0xD4F7851235DEE8E3) /* 790 */, W64LIT(0xFD4B7F886540D893) /* 791 */, + W64LIT(0x247C20042AA4BFDA) /* 792 */, W64LIT(0x096EA1C517D1327C) /* 793 */, + W64LIT(0xD56966B4361A6685) /* 794 */, W64LIT(0x277DA5C31221057D) /* 795 */, + W64LIT(0x94D59893A43ACFF7) /* 796 */, W64LIT(0x64F0C51CCDC02281) /* 797 */, + W64LIT(0x3D33BCC4FF6189DB) /* 798 */, W64LIT(0xE005CB184CE66AF1) /* 799 */, + W64LIT(0xFF5CCD1D1DB99BEA) /* 800 */, W64LIT(0xB0B854A7FE42980F) /* 801 */, + W64LIT(0x7BD46A6A718D4B9F) /* 802 */, W64LIT(0xD10FA8CC22A5FD8C) /* 803 */, + W64LIT(0xD31484952BE4BD31) /* 804 */, W64LIT(0xC7FA975FCB243847) /* 805 */, + W64LIT(0x4886ED1E5846C407) /* 806 */, W64LIT(0x28CDDB791EB70B04) /* 807 */, + W64LIT(0xC2B00BE2F573417F) /* 808 */, W64LIT(0x5C9590452180F877) /* 809 */, + W64LIT(0x7A6BDDFFF370EB00) /* 810 */, W64LIT(0xCE509E38D6D9D6A4) /* 811 */, + W64LIT(0xEBEB0F00647FA702) /* 812 */, W64LIT(0x1DCC06CF76606F06) /* 813 */, + W64LIT(0xE4D9F28BA286FF0A) /* 814 */, W64LIT(0xD85A305DC918C262) /* 815 */, + W64LIT(0x475B1D8732225F54) /* 816 */, W64LIT(0x2D4FB51668CCB5FE) /* 817 */, + W64LIT(0xA679B9D9D72BBA20) /* 818 */, W64LIT(0x53841C0D912D43A5) /* 819 */, + W64LIT(0x3B7EAA48BF12A4E8) /* 820 */, W64LIT(0x781E0E47F22F1DDF) /* 821 */, + W64LIT(0xEFF20CE60AB50973) /* 822 */, W64LIT(0x20D261D19DFFB742) /* 823 */, + W64LIT(0x16A12B03062A2E39) /* 824 */, W64LIT(0x1960EB2239650495) /* 825 */, + W64LIT(0x251C16FED50EB8B8) /* 826 */, W64LIT(0x9AC0C330F826016E) /* 827 */, + W64LIT(0xED152665953E7671) /* 828 */, W64LIT(0x02D63194A6369570) /* 829 */, + W64LIT(0x5074F08394B1C987) /* 830 */, W64LIT(0x70BA598C90B25CE1) /* 831 */, + W64LIT(0x794A15810B9742F6) /* 832 */, W64LIT(0x0D5925E9FCAF8C6C) /* 833 */, + W64LIT(0x3067716CD868744E) /* 834 */, W64LIT(0x910AB077E8D7731B) /* 835 */, + W64LIT(0x6A61BBDB5AC42F61) /* 836 */, W64LIT(0x93513EFBF0851567) /* 837 */, + W64LIT(0xF494724B9E83E9D5) /* 838 */, W64LIT(0xE887E1985C09648D) /* 839 */, + W64LIT(0x34B1D3C675370CFD) /* 840 */, W64LIT(0xDC35E433BC0D255D) /* 841 */, + W64LIT(0xD0AAB84234131BE0) /* 842 */, W64LIT(0x08042A50B48B7EAF) /* 843 */, + W64LIT(0x9997C4EE44A3AB35) /* 844 */, W64LIT(0x829A7B49201799D0) /* 845 */, + W64LIT(0x263B8307B7C54441) /* 846 */, W64LIT(0x752F95F4FD6A6CA6) /* 847 */, + W64LIT(0x927217402C08C6E5) /* 848 */, W64LIT(0x2A8AB754A795D9EE) /* 849 */, + W64LIT(0xA442F7552F72943D) /* 850 */, W64LIT(0x2C31334E19781208) /* 851 */, + W64LIT(0x4FA98D7CEAEE6291) /* 852 */, W64LIT(0x55C3862F665DB309) /* 853 */, + W64LIT(0xBD0610175D53B1F3) /* 854 */, W64LIT(0x46FE6CB840413F27) /* 855 */, + W64LIT(0x3FE03792DF0CFA59) /* 856 */, W64LIT(0xCFE700372EB85E8F) /* 857 */, + W64LIT(0xA7BE29E7ADBCE118) /* 858 */, W64LIT(0xE544EE5CDE8431DD) /* 859 */, + W64LIT(0x8A781B1B41F1873E) /* 860 */, W64LIT(0xA5C94C78A0D2F0E7) /* 861 */, + W64LIT(0x39412E2877B60728) /* 862 */, W64LIT(0xA1265EF3AFC9A62C) /* 863 */, + W64LIT(0xBCC2770C6A2506C5) /* 864 */, W64LIT(0x3AB66DD5DCE1CE12) /* 865 */, + W64LIT(0xE65499D04A675B37) /* 866 */, W64LIT(0x7D8F523481BFD216) /* 867 */, + W64LIT(0x0F6F64FCEC15F389) /* 868 */, W64LIT(0x74EFBE618B5B13C8) /* 869 */, + W64LIT(0xACDC82B714273E1D) /* 870 */, W64LIT(0xDD40BFE003199D17) /* 871 */, + W64LIT(0x37E99257E7E061F8) /* 872 */, W64LIT(0xFA52626904775AAA) /* 873 */, + W64LIT(0x8BBBF63A463D56F9) /* 874 */, W64LIT(0xF0013F1543A26E64) /* 875 */, + W64LIT(0xA8307E9F879EC898) /* 876 */, W64LIT(0xCC4C27A4150177CC) /* 877 */, + W64LIT(0x1B432F2CCA1D3348) /* 878 */, W64LIT(0xDE1D1F8F9F6FA013) /* 879 */, + W64LIT(0x606602A047A7DDD6) /* 880 */, W64LIT(0xD237AB64CC1CB2C7) /* 881 */, + W64LIT(0x9B938E7225FCD1D3) /* 882 */, W64LIT(0xEC4E03708E0FF476) /* 883 */, + W64LIT(0xFEB2FBDA3D03C12D) /* 884 */, W64LIT(0xAE0BCED2EE43889A) /* 885 */, + W64LIT(0x22CB8923EBFB4F43) /* 886 */, W64LIT(0x69360D013CF7396D) /* 887 */, + W64LIT(0x855E3602D2D4E022) /* 888 */, W64LIT(0x073805BAD01F784C) /* 889 */, + W64LIT(0x33E17A133852F546) /* 890 */, W64LIT(0xDF4874058AC7B638) /* 891 */, + W64LIT(0xBA92B29C678AA14A) /* 892 */, W64LIT(0x0CE89FC76CFAADCD) /* 893 */, + W64LIT(0x5F9D4E0908339E34) /* 894 */, W64LIT(0xF1AFE9291F5923B9) /* 895 */, + W64LIT(0x6E3480F60F4A265F) /* 896 */, W64LIT(0xEEBF3A2AB29B841C) /* 897 */, + W64LIT(0xE21938A88F91B4AD) /* 898 */, W64LIT(0x57DFEFF845C6D3C3) /* 899 */, + W64LIT(0x2F006B0BF62CAAF2) /* 900 */, W64LIT(0x62F479EF6F75EE78) /* 901 */, + W64LIT(0x11A55AD41C8916A9) /* 902 */, W64LIT(0xF229D29084FED453) /* 903 */, + W64LIT(0x42F1C27B16B000E6) /* 904 */, W64LIT(0x2B1F76749823C074) /* 905 */, + W64LIT(0x4B76ECA3C2745360) /* 906 */, W64LIT(0x8C98F463B91691BD) /* 907 */, + W64LIT(0x14BCC93CF1ADE66A) /* 908 */, W64LIT(0x8885213E6D458397) /* 909 */, + W64LIT(0x8E177DF0274D4711) /* 910 */, W64LIT(0xB49B73B5503F2951) /* 911 */, + W64LIT(0x10168168C3F96B6B) /* 912 */, W64LIT(0x0E3D963B63CAB0AE) /* 913 */, + W64LIT(0x8DFC4B5655A1DB14) /* 914 */, W64LIT(0xF789F1356E14DE5C) /* 915 */, + W64LIT(0x683E68AF4E51DAC1) /* 916 */, W64LIT(0xC9A84F9D8D4B0FD9) /* 917 */, + W64LIT(0x3691E03F52A0F9D1) /* 918 */, W64LIT(0x5ED86E46E1878E80) /* 919 */, + W64LIT(0x3C711A0E99D07150) /* 920 */, W64LIT(0x5A0865B20C4E9310) /* 921 */, + W64LIT(0x56FBFC1FE4F0682E) /* 922 */, W64LIT(0xEA8D5DE3105EDF9B) /* 923 */, + W64LIT(0x71ABFDB12379187A) /* 924 */, W64LIT(0x2EB99DE1BEE77B9C) /* 925 */, + W64LIT(0x21ECC0EA33CF4523) /* 926 */, W64LIT(0x59A4D7521805C7A1) /* 927 */, + W64LIT(0x3896F5EB56AE7C72) /* 928 */, W64LIT(0xAA638F3DB18F75DC) /* 929 */, + W64LIT(0x9F39358DABE9808E) /* 930 */, W64LIT(0xB7DEFA91C00B72AC) /* 931 */, + W64LIT(0x6B5541FD62492D92) /* 932 */, W64LIT(0x6DC6DEE8F92E4D5B) /* 933 */, + W64LIT(0x353F57ABC4BEEA7E) /* 934 */, W64LIT(0x735769D6DA5690CE) /* 935 */, + W64LIT(0x0A234AA642391484) /* 936 */, W64LIT(0xF6F9508028F80D9D) /* 937 */, + W64LIT(0xB8E319A27AB3F215) /* 938 */, W64LIT(0x31AD9C1151341A4D) /* 939 */, + W64LIT(0x773C22A57BEF5805) /* 940 */, W64LIT(0x45C7561A07968633) /* 941 */, + W64LIT(0xF913DA9E249DBE36) /* 942 */, W64LIT(0xDA652D9B78A64C68) /* 943 */, + W64LIT(0x4C27A97F3BC334EF) /* 944 */, W64LIT(0x76621220E66B17F4) /* 945 */, + W64LIT(0x967743899ACD7D0B) /* 946 */, W64LIT(0xF3EE5BCAE0ED6782) /* 947 */, + W64LIT(0x409F753600C879FC) /* 948 */, W64LIT(0x06D09A39B5926DB6) /* 949 */, + W64LIT(0x6F83AEB0317AC588) /* 950 */, W64LIT(0x01E6CA4A86381F21) /* 951 */, + W64LIT(0x66FF3462D19F3025) /* 952 */, W64LIT(0x72207C24DDFD3BFB) /* 953 */, + W64LIT(0x4AF6B6D3E2ECE2EB) /* 954 */, W64LIT(0x9C994DBEC7EA08DE) /* 955 */, + W64LIT(0x49ACE597B09A8BC4) /* 956 */, W64LIT(0xB38C4766CF0797BA) /* 957 */, + W64LIT(0x131B9373C57C2A75) /* 958 */, W64LIT(0xB1822CCE61931E58) /* 959 */, + W64LIT(0x9D7555B909BA1C0C) /* 960 */, W64LIT(0x127FAFDD937D11D2) /* 961 */, + W64LIT(0x29DA3BADC66D92E4) /* 962 */, W64LIT(0xA2C1D57154C2ECBC) /* 963 */, + W64LIT(0x58C5134D82F6FE24) /* 964 */, W64LIT(0x1C3AE3515B62274F) /* 965 */, + W64LIT(0xE907C82E01CB8126) /* 966 */, W64LIT(0xF8ED091913E37FCB) /* 967 */, + W64LIT(0x3249D8F9C80046C9) /* 968 */, W64LIT(0x80CF9BEDE388FB63) /* 969 */, + W64LIT(0x1881539A116CF19E) /* 970 */, W64LIT(0x5103F3F76BD52457) /* 971 */, + W64LIT(0x15B7E6F5AE47F7A8) /* 972 */, W64LIT(0xDBD7C6DED47E9CCF) /* 973 */, + W64LIT(0x44E55C410228BB1A) /* 974 */, W64LIT(0xB647D4255EDB4E99) /* 975 */, + W64LIT(0x5D11882BB8AAFC30) /* 976 */, W64LIT(0xF5098BBB29D3212A) /* 977 */, + W64LIT(0x8FB5EA14E90296B3) /* 978 */, W64LIT(0x677B942157DD025A) /* 979 */, + W64LIT(0xFB58E7C0A390ACB5) /* 980 */, W64LIT(0x89D3674C83BD4A01) /* 981 */, + W64LIT(0x9E2DA4DF4BF3B93B) /* 982 */, W64LIT(0xFCC41E328CAB4829) /* 983 */, + W64LIT(0x03F38C96BA582C52) /* 984 */, W64LIT(0xCAD1BDBD7FD85DB2) /* 985 */, + W64LIT(0xBBB442C16082AE83) /* 986 */, W64LIT(0xB95FE86BA5DA9AB0) /* 987 */, + W64LIT(0xB22E04673771A93F) /* 988 */, W64LIT(0x845358C9493152D8) /* 989 */, + W64LIT(0xBE2A488697B4541E) /* 990 */, W64LIT(0x95A2DC2DD38E6966) /* 991 */, + W64LIT(0xC02C11AC923C852B) /* 992 */, W64LIT(0x2388B1990DF2A87B) /* 993 */, + W64LIT(0x7C8008FA1B4F37BE) /* 994 */, W64LIT(0x1F70D0C84D54E503) /* 995 */, + W64LIT(0x5490ADEC7ECE57D4) /* 996 */, W64LIT(0x002B3C27D9063A3A) /* 997 */, + W64LIT(0x7EAEA3848030A2BF) /* 998 */, W64LIT(0xC602326DED2003C0) /* 999 */, + W64LIT(0x83A7287D69A94086) /* 1000 */, W64LIT(0xC57A5FCB30F57A8A) /* 1001 */, + W64LIT(0xB56844E479EBE779) /* 1002 */, W64LIT(0xA373B40F05DCBCE9) /* 1003 */, + W64LIT(0xD71A786E88570EE2) /* 1004 */, W64LIT(0x879CBACDBDE8F6A0) /* 1005 */, + W64LIT(0x976AD1BCC164A32F) /* 1006 */, W64LIT(0xAB21E25E9666D78B) /* 1007 */, + W64LIT(0x901063AAE5E5C33C) /* 1008 */, W64LIT(0x9818B34448698D90) /* 1009 */, + W64LIT(0xE36487AE3E1E8ABB) /* 1010 */, W64LIT(0xAFBDF931893BDCB4) /* 1011 */, + W64LIT(0x6345A0DC5FBBD519) /* 1012 */, W64LIT(0x8628FE269B9465CA) /* 1013 */, + W64LIT(0x1E5D01603F9C51EC) /* 1014 */, W64LIT(0x4DE44006A15049B7) /* 1015 */, + W64LIT(0xBF6C70E5F776CBB1) /* 1016 */, W64LIT(0x411218F2EF552BED) /* 1017 */, + W64LIT(0xCB0C0708705A36A3) /* 1018 */, W64LIT(0xE74D14754F986044) /* 1019 */, + W64LIT(0xCD56D9430EA8280E) /* 1020 */, W64LIT(0xC12591D7535F5065) /* 1021 */, + W64LIT(0xC83223F1720AEF96) /* 1022 */, W64LIT(0xC3A0396F7363A51F) /* 1023 */, + W64LIT(0xffffffffffffffff), + W64LIT(0xA5A5A5A5A5A5A5A5), + W64LIT(0x0123456789ABCDEF), +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/trdlocal.cpp b/CryptoPP/crypto/trdlocal.cpp new file mode 100644 index 0000000..6cf1799 --- /dev/null +++ b/CryptoPP/crypto/trdlocal.cpp @@ -0,0 +1,73 @@ +// trdlocal.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS +#ifdef THREADS_AVAILABLE + +#include "trdlocal.h" + +#ifdef HAS_WINTHREADS +#include +#endif + +NAMESPACE_BEGIN(CryptoPP) + +ThreadLocalStorage::Err::Err(const std::string& operation, int error) + : OS_Error(OTHER_ERROR, "ThreadLocalStorage: " + operation + " operation failed with error 0x" + IntToString(error, 16), operation, error) +{ +} + +ThreadLocalStorage::ThreadLocalStorage() +{ +#ifdef HAS_WINTHREADS + m_index = TlsAlloc(); + if (m_index == TLS_OUT_OF_INDEXES) + throw Err("TlsAlloc", GetLastError()); +#else + int error = pthread_key_create(&m_index, NULL); + if (error) + throw Err("pthread_key_create", error); +#endif +} + +ThreadLocalStorage::~ThreadLocalStorage() +{ +#ifdef HAS_WINTHREADS + if (!TlsFree(m_index)) + throw Err("TlsFree", GetLastError()); +#else + int error = pthread_key_delete(m_index); + if (error) + throw Err("pthread_key_delete", error); +#endif +} + +void ThreadLocalStorage::SetValue(void *value) +{ +#ifdef HAS_WINTHREADS + if (!TlsSetValue(m_index, value)) + throw Err("TlsSetValue", GetLastError()); +#else + int error = pthread_setspecific(m_index, value); + if (error) + throw Err("pthread_key_getspecific", error); +#endif +} + +void *ThreadLocalStorage::GetValue() const +{ +#ifdef HAS_WINTHREADS + void *result = TlsGetValue(m_index); + if (!result && GetLastError() != NO_ERROR) + throw Err("TlsGetValue", GetLastError()); +#else + void *result = pthread_getspecific(m_index); +#endif + return result; +} + +NAMESPACE_END + +#endif // #ifdef THREADS_AVAILABLE +#endif diff --git a/CryptoPP/crypto/trdlocal.h b/CryptoPP/crypto/trdlocal.h new file mode 100644 index 0000000..10f14a4 --- /dev/null +++ b/CryptoPP/crypto/trdlocal.h @@ -0,0 +1,44 @@ +#ifndef CRYPTOPP_TRDLOCAL_H +#define CRYPTOPP_TRDLOCAL_H + +#include "config.h" + +#ifdef THREADS_AVAILABLE + +#include "misc.h" + +#ifdef HAS_WINTHREADS +typedef unsigned long ThreadLocalIndexType; +#else +#include +typedef pthread_key_t ThreadLocalIndexType; +#endif + +NAMESPACE_BEGIN(CryptoPP) + +//! thread local storage +class CRYPTOPP_DLL ThreadLocalStorage : public NotCopyable +{ +public: + //! exception thrown by ThreadLocalStorage class + class Err : public OS_Error + { + public: + Err(const std::string& operation, int error); + }; + + ThreadLocalStorage(); + ~ThreadLocalStorage(); + + void SetValue(void *value); + void *GetValue() const; + +private: + ThreadLocalIndexType m_index; +}; + +NAMESPACE_END + +#endif // #ifdef THREADS_AVAILABLE + +#endif diff --git a/CryptoPP/crypto/trunhash.h b/CryptoPP/crypto/trunhash.h new file mode 100644 index 0000000..16fd8c0 --- /dev/null +++ b/CryptoPP/crypto/trunhash.h @@ -0,0 +1,48 @@ +#ifndef CRYPTOPP_TRUNHASH_H +#define CRYPTOPP_TRUNHASH_H + +#include "cryptlib.h" + +NAMESPACE_BEGIN(CryptoPP) + +class NullHash : public HashTransformation +{ +public: + void Update(const byte *input, size_t length) {} + unsigned int DigestSize() const {return 0;} + void TruncatedFinal(byte *digest, size_t digestSize) {} + bool TruncatedVerify(const byte *digest, size_t digestLength) {return true;} +}; + +//! construct new HashModule with smaller DigestSize() from existing one +template +class TruncatedHashTemplate : public HashTransformation +{ +public: + TruncatedHashTemplate(T hm, unsigned int digestSize) + : m_hm(hm), m_digestSize(digestSize) {} + TruncatedHashTemplate(const byte *key, size_t keyLength, unsigned int digestSize) + : m_hm(key, keyLength), m_digestSize(digestSize) {} + TruncatedHashTemplate(size_t digestSize) + : m_digestSize(digestSize) {} + + void Restart() + {m_hm.Restart();} + void Update(const byte *input, size_t length) + {m_hm.Update(input, length);} + unsigned int DigestSize() const {return m_digestSize;} + void TruncatedFinal(byte *digest, size_t digestSize) + {m_hm.TruncatedFinal(digest, digestSize);} + bool TruncatedVerify(const byte *digest, size_t digestLength) + {return m_hm.TruncatedVerify(digest, digestLength);} + +private: + T m_hm; + unsigned int m_digestSize; +}; + +typedef TruncatedHashTemplate TruncatedHashModule; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/ttmac.cpp b/CryptoPP/crypto/ttmac.cpp new file mode 100644 index 0000000..6b4e8bf --- /dev/null +++ b/CryptoPP/crypto/ttmac.cpp @@ -0,0 +1,338 @@ +// ttmac.cpp - written and placed in the public domain by Kevin Springle + +#include "pch.h" +#include "ttmac.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +void TTMAC_Base::UncheckedSetKey(const byte *userKey, unsigned int keylength, const NameValuePairs &) +{ + AssertValidKeyLength(keylength); + + memcpy(m_key, userKey, KEYLENGTH); + CorrectEndianess(m_key, m_key, KEYLENGTH); + + Init(); +} + +void TTMAC_Base::Init() +{ + m_digest[0] = m_digest[5] = m_key[0]; + m_digest[1] = m_digest[6] = m_key[1]; + m_digest[2] = m_digest[7] = m_key[2]; + m_digest[3] = m_digest[8] = m_key[3]; + m_digest[4] = m_digest[9] = m_key[4]; +} + +void TTMAC_Base::TruncatedFinal(byte *hash, size_t size) +{ + PadLastBlock(BlockSize() - 2*sizeof(HashWordType)); + CorrectEndianess(m_data, m_data, BlockSize() - 2*sizeof(HashWordType)); + + m_data[m_data.size()-2] = GetBitCountLo(); + m_data[m_data.size()-1] = GetBitCountHi(); + + Transform(m_digest, m_data, true); + + word32 t2 = m_digest[2]; + word32 t3 = m_digest[3]; + if (size != DIGESTSIZE) + { + switch (size) + { + case 16: + m_digest[3] += m_digest[1] + m_digest[4]; + + case 12: + m_digest[2] += m_digest[0] + t3; + + case 8: + m_digest[0] += m_digest[1] + t3; + m_digest[1] += m_digest[4] + t2; + break; + + case 4: + m_digest[0] += + m_digest[1] + + m_digest[2] + + m_digest[3] + + m_digest[4]; + break; + + case 0: + // Used by HashTransformation::Restart() + break; + + default: + throw InvalidArgument("TTMAC_Base: can't truncate a Two-Track-MAC 20 byte digest to " + IntToString(size) + " bytes"); + break; + } + } + + CorrectEndianess(m_digest, m_digest, size); + memcpy(hash, m_digest, size); + + Restart(); // reinit for next use +} + +// RIPEMD-160 definitions used by Two-Track-MAC + +#define F(x, y, z) (x ^ y ^ z) +#define G(x, y, z) (z ^ (x & (y^z))) +#define H(x, y, z) (z ^ (x | ~y)) +#define I(x, y, z) (y ^ (z & (x^y))) +#define J(x, y, z) (x ^ (y | ~z)) + +#define k0 0 +#define k1 0x5a827999UL +#define k2 0x6ed9eba1UL +#define k3 0x8f1bbcdcUL +#define k4 0xa953fd4eUL +#define k5 0x50a28be6UL +#define k6 0x5c4dd124UL +#define k7 0x6d703ef3UL +#define k8 0x7a6d76e9UL +#define k9 0 + +void TTMAC_Base::Transform(word32 *digest, const word32 *X, bool last) +{ +#define Subround(f, a, b, c, d, e, x, s, k) \ + a += f(b, c, d) + x + k;\ + a = rotlFixed((word32)a, s) + e;\ + c = rotlFixed((word32)c, 10U) + + word32 a1, b1, c1, d1, e1, a2, b2, c2, d2, e2; + word32 *trackA, *trackB; + + if (!last) + { + trackA = digest; + trackB = digest+5; + } + else + { + trackB = digest; + trackA = digest+5; + } + a1 = trackA[0]; + b1 = trackA[1]; + c1 = trackA[2]; + d1 = trackA[3]; + e1 = trackA[4]; + a2 = trackB[0]; + b2 = trackB[1]; + c2 = trackB[2]; + d2 = trackB[3]; + e2 = trackB[4]; + + Subround(F, a1, b1, c1, d1, e1, X[ 0], 11, k0); + Subround(F, e1, a1, b1, c1, d1, X[ 1], 14, k0); + Subround(F, d1, e1, a1, b1, c1, X[ 2], 15, k0); + Subround(F, c1, d1, e1, a1, b1, X[ 3], 12, k0); + Subround(F, b1, c1, d1, e1, a1, X[ 4], 5, k0); + Subround(F, a1, b1, c1, d1, e1, X[ 5], 8, k0); + Subround(F, e1, a1, b1, c1, d1, X[ 6], 7, k0); + Subround(F, d1, e1, a1, b1, c1, X[ 7], 9, k0); + Subround(F, c1, d1, e1, a1, b1, X[ 8], 11, k0); + Subround(F, b1, c1, d1, e1, a1, X[ 9], 13, k0); + Subround(F, a1, b1, c1, d1, e1, X[10], 14, k0); + Subround(F, e1, a1, b1, c1, d1, X[11], 15, k0); + Subround(F, d1, e1, a1, b1, c1, X[12], 6, k0); + Subround(F, c1, d1, e1, a1, b1, X[13], 7, k0); + Subround(F, b1, c1, d1, e1, a1, X[14], 9, k0); + Subround(F, a1, b1, c1, d1, e1, X[15], 8, k0); + + Subround(G, e1, a1, b1, c1, d1, X[ 7], 7, k1); + Subround(G, d1, e1, a1, b1, c1, X[ 4], 6, k1); + Subround(G, c1, d1, e1, a1, b1, X[13], 8, k1); + Subround(G, b1, c1, d1, e1, a1, X[ 1], 13, k1); + Subround(G, a1, b1, c1, d1, e1, X[10], 11, k1); + Subround(G, e1, a1, b1, c1, d1, X[ 6], 9, k1); + Subround(G, d1, e1, a1, b1, c1, X[15], 7, k1); + Subround(G, c1, d1, e1, a1, b1, X[ 3], 15, k1); + Subround(G, b1, c1, d1, e1, a1, X[12], 7, k1); + Subround(G, a1, b1, c1, d1, e1, X[ 0], 12, k1); + Subround(G, e1, a1, b1, c1, d1, X[ 9], 15, k1); + Subround(G, d1, e1, a1, b1, c1, X[ 5], 9, k1); + Subround(G, c1, d1, e1, a1, b1, X[ 2], 11, k1); + Subround(G, b1, c1, d1, e1, a1, X[14], 7, k1); + Subround(G, a1, b1, c1, d1, e1, X[11], 13, k1); + Subround(G, e1, a1, b1, c1, d1, X[ 8], 12, k1); + + Subround(H, d1, e1, a1, b1, c1, X[ 3], 11, k2); + Subround(H, c1, d1, e1, a1, b1, X[10], 13, k2); + Subround(H, b1, c1, d1, e1, a1, X[14], 6, k2); + Subround(H, a1, b1, c1, d1, e1, X[ 4], 7, k2); + Subround(H, e1, a1, b1, c1, d1, X[ 9], 14, k2); + Subround(H, d1, e1, a1, b1, c1, X[15], 9, k2); + Subround(H, c1, d1, e1, a1, b1, X[ 8], 13, k2); + Subround(H, b1, c1, d1, e1, a1, X[ 1], 15, k2); + Subround(H, a1, b1, c1, d1, e1, X[ 2], 14, k2); + Subround(H, e1, a1, b1, c1, d1, X[ 7], 8, k2); + Subround(H, d1, e1, a1, b1, c1, X[ 0], 13, k2); + Subround(H, c1, d1, e1, a1, b1, X[ 6], 6, k2); + Subround(H, b1, c1, d1, e1, a1, X[13], 5, k2); + Subround(H, a1, b1, c1, d1, e1, X[11], 12, k2); + Subround(H, e1, a1, b1, c1, d1, X[ 5], 7, k2); + Subround(H, d1, e1, a1, b1, c1, X[12], 5, k2); + + Subround(I, c1, d1, e1, a1, b1, X[ 1], 11, k3); + Subround(I, b1, c1, d1, e1, a1, X[ 9], 12, k3); + Subround(I, a1, b1, c1, d1, e1, X[11], 14, k3); + Subround(I, e1, a1, b1, c1, d1, X[10], 15, k3); + Subround(I, d1, e1, a1, b1, c1, X[ 0], 14, k3); + Subround(I, c1, d1, e1, a1, b1, X[ 8], 15, k3); + Subround(I, b1, c1, d1, e1, a1, X[12], 9, k3); + Subround(I, a1, b1, c1, d1, e1, X[ 4], 8, k3); + Subround(I, e1, a1, b1, c1, d1, X[13], 9, k3); + Subround(I, d1, e1, a1, b1, c1, X[ 3], 14, k3); + Subround(I, c1, d1, e1, a1, b1, X[ 7], 5, k3); + Subround(I, b1, c1, d1, e1, a1, X[15], 6, k3); + Subround(I, a1, b1, c1, d1, e1, X[14], 8, k3); + Subround(I, e1, a1, b1, c1, d1, X[ 5], 6, k3); + Subround(I, d1, e1, a1, b1, c1, X[ 6], 5, k3); + Subround(I, c1, d1, e1, a1, b1, X[ 2], 12, k3); + + Subround(J, b1, c1, d1, e1, a1, X[ 4], 9, k4); + Subround(J, a1, b1, c1, d1, e1, X[ 0], 15, k4); + Subround(J, e1, a1, b1, c1, d1, X[ 5], 5, k4); + Subround(J, d1, e1, a1, b1, c1, X[ 9], 11, k4); + Subround(J, c1, d1, e1, a1, b1, X[ 7], 6, k4); + Subround(J, b1, c1, d1, e1, a1, X[12], 8, k4); + Subround(J, a1, b1, c1, d1, e1, X[ 2], 13, k4); + Subround(J, e1, a1, b1, c1, d1, X[10], 12, k4); + Subround(J, d1, e1, a1, b1, c1, X[14], 5, k4); + Subround(J, c1, d1, e1, a1, b1, X[ 1], 12, k4); + Subround(J, b1, c1, d1, e1, a1, X[ 3], 13, k4); + Subround(J, a1, b1, c1, d1, e1, X[ 8], 14, k4); + Subround(J, e1, a1, b1, c1, d1, X[11], 11, k4); + Subround(J, d1, e1, a1, b1, c1, X[ 6], 8, k4); + Subround(J, c1, d1, e1, a1, b1, X[15], 5, k4); + Subround(J, b1, c1, d1, e1, a1, X[13], 6, k4); + + Subround(J, a2, b2, c2, d2, e2, X[ 5], 8, k5); + Subround(J, e2, a2, b2, c2, d2, X[14], 9, k5); + Subround(J, d2, e2, a2, b2, c2, X[ 7], 9, k5); + Subround(J, c2, d2, e2, a2, b2, X[ 0], 11, k5); + Subround(J, b2, c2, d2, e2, a2, X[ 9], 13, k5); + Subround(J, a2, b2, c2, d2, e2, X[ 2], 15, k5); + Subround(J, e2, a2, b2, c2, d2, X[11], 15, k5); + Subround(J, d2, e2, a2, b2, c2, X[ 4], 5, k5); + Subround(J, c2, d2, e2, a2, b2, X[13], 7, k5); + Subround(J, b2, c2, d2, e2, a2, X[ 6], 7, k5); + Subround(J, a2, b2, c2, d2, e2, X[15], 8, k5); + Subround(J, e2, a2, b2, c2, d2, X[ 8], 11, k5); + Subround(J, d2, e2, a2, b2, c2, X[ 1], 14, k5); + Subround(J, c2, d2, e2, a2, b2, X[10], 14, k5); + Subround(J, b2, c2, d2, e2, a2, X[ 3], 12, k5); + Subround(J, a2, b2, c2, d2, e2, X[12], 6, k5); + + Subround(I, e2, a2, b2, c2, d2, X[ 6], 9, k6); + Subround(I, d2, e2, a2, b2, c2, X[11], 13, k6); + Subround(I, c2, d2, e2, a2, b2, X[ 3], 15, k6); + Subround(I, b2, c2, d2, e2, a2, X[ 7], 7, k6); + Subround(I, a2, b2, c2, d2, e2, X[ 0], 12, k6); + Subround(I, e2, a2, b2, c2, d2, X[13], 8, k6); + Subround(I, d2, e2, a2, b2, c2, X[ 5], 9, k6); + Subround(I, c2, d2, e2, a2, b2, X[10], 11, k6); + Subround(I, b2, c2, d2, e2, a2, X[14], 7, k6); + Subround(I, a2, b2, c2, d2, e2, X[15], 7, k6); + Subround(I, e2, a2, b2, c2, d2, X[ 8], 12, k6); + Subround(I, d2, e2, a2, b2, c2, X[12], 7, k6); + Subround(I, c2, d2, e2, a2, b2, X[ 4], 6, k6); + Subround(I, b2, c2, d2, e2, a2, X[ 9], 15, k6); + Subround(I, a2, b2, c2, d2, e2, X[ 1], 13, k6); + Subround(I, e2, a2, b2, c2, d2, X[ 2], 11, k6); + + Subround(H, d2, e2, a2, b2, c2, X[15], 9, k7); + Subround(H, c2, d2, e2, a2, b2, X[ 5], 7, k7); + Subround(H, b2, c2, d2, e2, a2, X[ 1], 15, k7); + Subround(H, a2, b2, c2, d2, e2, X[ 3], 11, k7); + Subround(H, e2, a2, b2, c2, d2, X[ 7], 8, k7); + Subround(H, d2, e2, a2, b2, c2, X[14], 6, k7); + Subround(H, c2, d2, e2, a2, b2, X[ 6], 6, k7); + Subround(H, b2, c2, d2, e2, a2, X[ 9], 14, k7); + Subround(H, a2, b2, c2, d2, e2, X[11], 12, k7); + Subround(H, e2, a2, b2, c2, d2, X[ 8], 13, k7); + Subround(H, d2, e2, a2, b2, c2, X[12], 5, k7); + Subround(H, c2, d2, e2, a2, b2, X[ 2], 14, k7); + Subround(H, b2, c2, d2, e2, a2, X[10], 13, k7); + Subround(H, a2, b2, c2, d2, e2, X[ 0], 13, k7); + Subround(H, e2, a2, b2, c2, d2, X[ 4], 7, k7); + Subround(H, d2, e2, a2, b2, c2, X[13], 5, k7); + + Subround(G, c2, d2, e2, a2, b2, X[ 8], 15, k8); + Subround(G, b2, c2, d2, e2, a2, X[ 6], 5, k8); + Subround(G, a2, b2, c2, d2, e2, X[ 4], 8, k8); + Subround(G, e2, a2, b2, c2, d2, X[ 1], 11, k8); + Subround(G, d2, e2, a2, b2, c2, X[ 3], 14, k8); + Subround(G, c2, d2, e2, a2, b2, X[11], 14, k8); + Subround(G, b2, c2, d2, e2, a2, X[15], 6, k8); + Subround(G, a2, b2, c2, d2, e2, X[ 0], 14, k8); + Subround(G, e2, a2, b2, c2, d2, X[ 5], 6, k8); + Subround(G, d2, e2, a2, b2, c2, X[12], 9, k8); + Subround(G, c2, d2, e2, a2, b2, X[ 2], 12, k8); + Subround(G, b2, c2, d2, e2, a2, X[13], 9, k8); + Subround(G, a2, b2, c2, d2, e2, X[ 9], 12, k8); + Subround(G, e2, a2, b2, c2, d2, X[ 7], 5, k8); + Subround(G, d2, e2, a2, b2, c2, X[10], 15, k8); + Subround(G, c2, d2, e2, a2, b2, X[14], 8, k8); + + Subround(F, b2, c2, d2, e2, a2, X[12], 8, k9); + Subround(F, a2, b2, c2, d2, e2, X[15], 5, k9); + Subround(F, e2, a2, b2, c2, d2, X[10], 12, k9); + Subround(F, d2, e2, a2, b2, c2, X[ 4], 9, k9); + Subround(F, c2, d2, e2, a2, b2, X[ 1], 12, k9); + Subround(F, b2, c2, d2, e2, a2, X[ 5], 5, k9); + Subround(F, a2, b2, c2, d2, e2, X[ 8], 14, k9); + Subround(F, e2, a2, b2, c2, d2, X[ 7], 6, k9); + Subround(F, d2, e2, a2, b2, c2, X[ 6], 8, k9); + Subround(F, c2, d2, e2, a2, b2, X[ 2], 13, k9); + Subround(F, b2, c2, d2, e2, a2, X[13], 6, k9); + Subround(F, a2, b2, c2, d2, e2, X[14], 5, k9); + Subround(F, e2, a2, b2, c2, d2, X[ 0], 15, k9); + Subround(F, d2, e2, a2, b2, c2, X[ 3], 13, k9); + Subround(F, c2, d2, e2, a2, b2, X[ 9], 11, k9); + Subround(F, b2, c2, d2, e2, a2, X[11], 11, k9); + + a1 -= trackA[0]; + b1 -= trackA[1]; + c1 -= trackA[2]; + d1 -= trackA[3]; + e1 -= trackA[4]; + a2 -= trackB[0]; + b2 -= trackB[1]; + c2 -= trackB[2]; + d2 -= trackB[3]; + e2 -= trackB[4]; + + if (!last) + { + trackA[0] = (b1 + e1) - d2; + trackA[1] = c1 - e2; + trackA[2] = d1 - a2; + trackA[3] = e1 - b2; + trackA[4] = a1 - c2; + trackB[0] = d1 - e2; + trackB[1] = (e1 + c1) - a2; + trackB[2] = a1 - b2; + trackB[3] = b1 - c2; + trackB[4] = c1 - d2; + } + else + { + trackB[0] = a2 - a1; + trackB[1] = b2 - b1; + trackB[2] = c2 - c1; + trackB[3] = d2 - d1; + trackB[4] = e2 - e1; + trackA[0] = 0; + trackA[1] = 0; + trackA[2] = 0; + trackA[3] = 0; + trackA[4] = 0; + } +} + +NAMESPACE_END diff --git a/CryptoPP/crypto/ttmac.h b/CryptoPP/crypto/ttmac.h new file mode 100644 index 0000000..ce8d968 --- /dev/null +++ b/CryptoPP/crypto/ttmac.h @@ -0,0 +1,38 @@ +// ttmac.h - written and placed in the public domain by Kevin Springle + +#ifndef CRYPTOPP_TTMAC_H +#define CRYPTOPP_TTMAC_H + +#include "seckey.h" +#include "iterhash.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! _ +class CRYPTOPP_NO_VTABLE TTMAC_Base : public FixedKeyLength<20>, public IteratedHash +{ +public: + static std::string StaticAlgorithmName() {return std::string("Two-Track-MAC");} + CRYPTOPP_CONSTANT(DIGESTSIZE=20) + + unsigned int DigestSize() const {return DIGESTSIZE;}; + void UncheckedSetKey(const byte *userKey, unsigned int keylength, const NameValuePairs ¶ms); + void TruncatedFinal(byte *mac, size_t size); + +protected: + static void Transform (word32 *digest, const word32 *X, bool last); + void HashEndianCorrectedBlock(const word32 *data) {Transform(m_digest, data, false);} + void Init(); + word32* StateBuf() {return m_digest;} + + FixedSizeSecBlock m_digest; + FixedSizeSecBlock m_key; +}; + +//! Two-Track-MAC +/*! 160 Bit MAC with 160 Bit Key */ +DOCUMENTED_TYPEDEF(MessageAuthenticationCodeFinal, TTMAC) + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/twofish.cpp b/CryptoPP/crypto/twofish.cpp new file mode 100644 index 0000000..e34bde5 --- /dev/null +++ b/CryptoPP/crypto/twofish.cpp @@ -0,0 +1,168 @@ +// twofish.cpp - modified by Wei Dai from Matthew Skala's twofish.c +// The original code and all modifications are in the public domain. + +#include "pch.h" +#include "twofish.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +// compute (c * x^4) mod (x^4 + (a + 1/a) * x^3 + a * x^2 + (a + 1/a) * x + 1) +// over GF(256) +static inline unsigned int Mod(unsigned int c) +{ + static const unsigned int modulus = 0x14d; + unsigned int c2 = (c<<1) ^ ((c & 0x80) ? modulus : 0); + unsigned int c1 = c2 ^ (c>>1) ^ ((c & 1) ? (modulus>>1) : 0); + return c | (c1 << 8) | (c2 << 16) | (c1 << 24); +} + +// compute RS(12,8) code with the above polynomial as generator +// this is equivalent to multiplying by the RS matrix +static word32 ReedSolomon(word32 high, word32 low) +{ + for (unsigned int i=0; i<8; i++) + { + high = Mod(high>>24) ^ (high<<8) ^ (low>>24); + low <<= 8; + } + return high; +} + +inline word32 Twofish::Base::h0(word32 x, const word32 *key, unsigned int kLen) +{ + x = x | (x<<8) | (x<<16) | (x<<24); + switch(kLen) + { +#define Q(a, b, c, d, t) q[a][GETBYTE(t,0)] ^ (q[b][GETBYTE(t,1)] << 8) ^ (q[c][GETBYTE(t,2)] << 16) ^ (q[d][GETBYTE(t,3)] << 24) + case 4: x = Q(1, 0, 0, 1, x) ^ key[6]; + case 3: x = Q(1, 1, 0, 0, x) ^ key[4]; + case 2: x = Q(0, 1, 0, 1, x) ^ key[2]; + x = Q(0, 0, 1, 1, x) ^ key[0]; + } + return x; +} + +inline word32 Twofish::Base::h(word32 x, const word32 *key, unsigned int kLen) +{ + x = h0(x, key, kLen); + return mds[0][GETBYTE(x,0)] ^ mds[1][GETBYTE(x,1)] ^ mds[2][GETBYTE(x,2)] ^ mds[3][GETBYTE(x,3)]; +} + +void Twofish::Base::UncheckedSetKey(const byte *userKey, unsigned int keylength, const NameValuePairs &) +{ + AssertValidKeyLength(keylength); + + unsigned int len = (keylength <= 16 ? 2 : (keylength <= 24 ? 3 : 4)); + SecBlock key(len*2); + GetUserKey(LITTLE_ENDIAN_ORDER, key.begin(), len*2, userKey, keylength); + + unsigned int i; + for (i=0; i<40; i+=2) + { + word32 a = h(i, key, len); + word32 b = rotlFixed(h(i+1, key+1, len), 8); + m_k[i] = a+b; + m_k[i+1] = rotlFixed(a+2*b, 9); + } + + SecBlock svec(2*len); + for (i=0; i Block; + +void Twofish::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word32 x, y, a, b, c, d; + + Block::Get(inBlock)(a)(b)(c)(d); + + a ^= m_k[0]; + b ^= m_k[1]; + c ^= m_k[2]; + d ^= m_k[3]; + + const word32 *k = m_k+8; + ENCCYCLE (0); + ENCCYCLE (1); + ENCCYCLE (2); + ENCCYCLE (3); + ENCCYCLE (4); + ENCCYCLE (5); + ENCCYCLE (6); + ENCCYCLE (7); + + c ^= m_k[4]; + d ^= m_k[5]; + a ^= m_k[6]; + b ^= m_k[7]; + + Block::Put(xorBlock, outBlock)(c)(d)(a)(b); +} + +void Twofish::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const +{ + word32 x, y, a, b, c, d; + + Block::Get(inBlock)(c)(d)(a)(b); + + c ^= m_k[4]; + d ^= m_k[5]; + a ^= m_k[6]; + b ^= m_k[7]; + + const word32 *k = m_k+8; + DECCYCLE (7); + DECCYCLE (6); + DECCYCLE (5); + DECCYCLE (4); + DECCYCLE (3); + DECCYCLE (2); + DECCYCLE (1); + DECCYCLE (0); + + a ^= m_k[0]; + b ^= m_k[1]; + c ^= m_k[2]; + d ^= m_k[3]; + + Block::Put(xorBlock, outBlock)(a)(b)(c)(d); +} + +NAMESPACE_END diff --git a/CryptoPP/crypto/twofish.h b/CryptoPP/crypto/twofish.h new file mode 100644 index 0000000..d3143ad --- /dev/null +++ b/CryptoPP/crypto/twofish.h @@ -0,0 +1,59 @@ +#ifndef CRYPTOPP_TWOFISH_H +#define CRYPTOPP_TWOFISH_H + +/** \file +*/ + +#include "seckey.h" +#include "secblock.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! _ +struct Twofish_Info : public FixedBlockSize<16>, public VariableKeyLength<16, 0, 32>, FixedRounds<16> +{ + static const char *StaticAlgorithmName() {return "Twofish";} +}; + +/// Twofish +class Twofish : public Twofish_Info, public BlockCipherDocumentation +{ + class CRYPTOPP_NO_VTABLE Base : public BlockCipherImpl + { + public: + void UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms); + + protected: + static word32 h0(word32 x, const word32 *key, unsigned int kLen); + static word32 h(word32 x, const word32 *key, unsigned int kLen); + + static const byte q[2][256]; + static const word32 mds[4][256]; + + FixedSizeSecBlock m_k; + FixedSizeSecBlock m_s; + }; + + class CRYPTOPP_NO_VTABLE Enc : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + + class CRYPTOPP_NO_VTABLE Dec : public Base + { + public: + void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const; + }; + +public: + typedef BlockCipherFinal Encryption; + typedef BlockCipherFinal Decryption; +}; + +typedef Twofish::Encryption TwofishEncryption; +typedef Twofish::Decryption TwofishDecryption; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/twofishv.dat b/CryptoPP/crypto/twofishv.dat new file mode 100644 index 0000000..8b23740 --- /dev/null +++ b/CryptoPP/crypto/twofishv.dat @@ -0,0 +1,9 @@ +00000000000000000000000000000000 00000000000000000000000000000000 9F589F5CF6122C32B6BFEC2F2AE8C35A +00000000000000000000000000000000 9F589F5CF6122C32B6BFEC2F2AE8C35A D491DB16E7B1C39E86CB086B789F5419 +9F589F5CF6122C32B6BFEC2F2AE8C35A D491DB16E7B1C39E86CB086B789F5419 019F9809DE1711858FAAC3A3BA20FBC3 +D491DB16E7B1C39E86CB086B789F5419 019F9809DE1711858FAAC3A3BA20FBC3 6363977DE839486297E661C6C9D668EB +000000000000000000000000000000000000000000000000 00000000000000000000000000000000 EFA71F788965BD4453F860178FC19101 +EFA71F788965BD4453F860178FC191010000000000000000 88B2B2706B105E36B446BB6D731A1E88 39DA69D6BA4997D585B6DC073CA341B2 +88B2B2706B105E36B446BB6D731A1E88EFA71F788965BD44 39DA69D6BA4997D585B6DC073CA341B2 182B02D81497EA45F9DAACDC29193A65 +0000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000 57FF739D4DC92C1BD7FC01700CC8216F +D43BB7556EA32E46F2A282B7D45B4E0D57FF739D4DC92C1BD7FC01700CC8216F 90AFE91BB288544F2C32DC239B2635E6 6CB4561C40BF0A9705931CB6D408E7FA diff --git a/CryptoPP/crypto/usage.dat b/CryptoPP/crypto/usage.dat new file mode 100644 index 0000000..103d98e --- /dev/null +++ b/CryptoPP/crypto/usage.dat @@ -0,0 +1,81 @@ +Test Driver for Crypto++(R) Library, a C++ Class Library of Cryptographic Schemes + +- To generate an RSA key + cryptest g + +- To encrypt and decrypt a string using RSA + cryptest r + +- To sign a file using RSA + cryptest rs privatekeyfile messagefile signaturefile + +- To verify a signature of a file using RSA + cryptest rv publickeyfile messagefile signaturefile + +- To digest a file using several hash functions in parallel + cryptest m file + +- To encrypt and decrypt a string using DES-EDE in CBC mode + cryptest t + +- To encrypt or decrypt a file + cryptest e|d input output + +- To secret share a file (shares will be named file.000, file.001, etc) + cryptest ss threshold number-of-shares file + +- To reconstruct a secret-shared file + cryptest sr file share1 share2 [....] + (number of shares given must be equal to threshold) + +- To information disperse a file (shares will be named file.000, file.001, etc) + cryptest id threshold number-of-shares file + +- To reconstruct an information-dispersed file + cryptest ir file share1 share2 [....] + (number of shares given must be equal to threshold) + +- To gzip a file + cryptest z compression-level input output + +- To gunzip a file + cryptest u input output + +- To encrypt a file with AES in CTR mode + cryptest ae input output + +- To base64 encode a file + cryptest e64 input output + +- To base64 decode a file + cryptest d64 input output + +- To hex encode a file + cryptest e16 input output + +- To hex decode a file + cryptest d16 input output + +- To forward a TCP connection + cryptest ft source-port destination-host destination-port + +- To run the FIPS 140-2 sample application + cryptest fips + +- To generate 100000 random files using FIPS Approved X.917 RNG + cryptest fips-rand + +- To run Maurer's randomness test on a file + cryptest mt input + +- To run a test script (available in TestVectors subdirectory) + cryptest tv filename + +- To run validation tests + cryptest v + +- To display version number + cryptest V + +- To run benchmarks + cryptest b [time allocated for each benchmark in seconds] [frequency of CPU in gigahertz] diff --git a/CryptoPP/crypto/validat1.cpp b/CryptoPP/crypto/validat1.cpp new file mode 100644 index 0000000..fceb621 --- /dev/null +++ b/CryptoPP/crypto/validat1.cpp @@ -0,0 +1,1352 @@ +// validat1.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" + +#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 +#include "files.h" +#include "hex.h" +#include "base32.h" +#include "base64.h" +#include "modes.h" +#include "cbcmac.h" +#include "dmac.h" +#include "idea.h" +#include "des.h" +#include "rc2.h" +#include "arc4.h" +#include "rc5.h" +#include "blowfish.h" +#include "wake.h" +#include "3way.h" +#include "safer.h" +#include "gost.h" +#include "shark.h" +#include "cast.h" +#include "square.h" +#include "seal.h" +#include "rc6.h" +#include "mars.h" +#include "rijndael.h" +#include "twofish.h" +#include "serpent.h" +#include "skipjack.h" +#include "shacal2.h" +#include "camellia.h" +#include "osrng.h" +#include "zdeflate.h" +#include "cpu.h" + +#include +#include +#include +#include +#include + +#include "validate.h" + +USING_NAMESPACE(CryptoPP) +USING_NAMESPACE(std) + +bool ValidateAll(bool thorough) +{ + bool pass=TestSettings(); + pass=TestOS_RNG() && pass; + + pass=ValidateCRC32() && pass; + pass=ValidateAdler32() && pass; + pass=ValidateMD2() && pass; + pass=ValidateMD5() && pass; + pass=ValidateSHA() && pass; + pass=ValidateSHA2() && pass; + pass=ValidateTiger() && pass; + pass=ValidateRIPEMD() && pass; + pass=ValidatePanama() && pass; + pass=ValidateWhirlpool() && pass; + + pass=ValidateHMAC() && pass; + pass=ValidateTTMAC() && pass; + + pass=ValidatePBKDF() && pass; + + pass=ValidateDES() && pass; + pass=ValidateCipherModes() && pass; + pass=ValidateIDEA() && pass; + pass=ValidateSAFER() && pass; + pass=ValidateRC2() && pass; + pass=ValidateARC4() && pass; + pass=ValidateRC5() && pass; + pass=ValidateBlowfish() && pass; + pass=ValidateThreeWay() && pass; + pass=ValidateGOST() && pass; + pass=ValidateSHARK() && pass; + pass=ValidateCAST() && pass; + pass=ValidateSquare() && pass; + pass=ValidateSKIPJACK() && pass; + pass=ValidateSEAL() && pass; + pass=ValidateRC6() && pass; + pass=ValidateMARS() && pass; + pass=ValidateRijndael() && pass; + pass=ValidateTwofish() && pass; + pass=ValidateSerpent() && pass; + pass=ValidateSHACAL2() && pass; + pass=ValidateCamellia() && pass; + pass=ValidateSalsa() && pass; + pass=ValidateSosemanuk() && pass; + pass=ValidateVMAC() && pass; + + pass=ValidateBBS() && pass; + pass=ValidateDH() && pass; + pass=ValidateMQV() && pass; + pass=ValidateRSA() && pass; + pass=ValidateElGamal() && pass; + pass=ValidateDLIES() && pass; + pass=ValidateNR() && pass; + pass=ValidateDSA(thorough) && pass; + pass=ValidateLUC() && pass; + pass=ValidateLUC_DH() && pass; + pass=ValidateLUC_DL() && pass; + pass=ValidateXTR_DH() && pass; + pass=ValidateRabin() && pass; + pass=ValidateRW() && pass; +// pass=ValidateBlumGoldwasser() && pass; + pass=ValidateECP() && pass; + pass=ValidateEC2N() && pass; + pass=ValidateECDSA() && pass; + pass=ValidateESIGN() && pass; + + if (pass) + cout << "\nAll tests passed!\n"; + else + cout << "\nOops! Not all tests passed.\n"; + + return pass; +} + +bool TestSettings() +{ + bool pass = true; + + cout << "\nTesting Settings...\n\n"; + + if (*(word32 *)"\x01\x02\x03\x04" == 0x04030201L) + { +#ifdef IS_LITTLE_ENDIAN + cout << "passed: "; +#else + cout << "FAILED: "; + pass = false; +#endif + cout << "Your machine is little endian.\n"; + } + else if (*(word32 *)"\x01\x02\x03\x04" == 0x01020304L) + { +#ifndef IS_LITTLE_ENDIAN + cout << "passed: "; +#else + cout << "FAILED: "; + pass = false; +#endif + cout << "Your machine is big endian.\n"; + } + else + { + cout << "FAILED: Your machine is neither big endian nor little endian.\n"; + pass = false; + } + + if (sizeof(byte) == 1) + cout << "passed: "; + else + { + cout << "FAILED: "; + pass = false; + } + cout << "sizeof(byte) == " << sizeof(byte) << endl; + + if (sizeof(word16) == 2) + cout << "passed: "; + else + { + cout << "FAILED: "; + pass = false; + } + cout << "sizeof(word16) == " << sizeof(word16) << endl; + + if (sizeof(word32) == 4) + cout << "passed: "; + else + { + cout << "FAILED: "; + pass = false; + } + cout << "sizeof(word32) == " << sizeof(word32) << endl; + +#ifdef WORD64_AVAILABLE + if (sizeof(word64) == 8) + cout << "passed: "; + else + { + cout << "FAILED: "; + pass = false; + } + cout << "sizeof(word64) == " << sizeof(word64) << endl; +#elif defined(CRYPTOPP_NATIVE_DWORD_AVAILABLE) + if (sizeof(dword) >= 8) + { + cout << "FAILED: sizeof(dword) >= 8, but WORD64_AVAILABLE not defined" << endl; + pass = false; + } + else + cout << "passed: word64 not available" << endl; +#endif + +#ifdef CRYPTOPP_WORD128_AVAILABLE + if (sizeof(word128) == 16) + cout << "passed: "; + else + { + cout << "FAILED: "; + pass = false; + } + cout << "sizeof(word128) == " << sizeof(word128) << endl; +#endif + + if (sizeof(word) == 2*sizeof(hword) +#ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE + && sizeof(dword) == 2*sizeof(word) +#endif + ) + cout << "passed: "; + else + { + cout << "FAILED: "; + pass = false; + } + cout << "sizeof(hword) == " << sizeof(hword) << ", sizeof(word) == " << sizeof(word); +#ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE + cout << ", sizeof(dword) == " << sizeof(dword); +#endif + cout << endl; + + bool hasMMX = HasMMX(); + bool hasISSE = HasISSE(); + bool hasSSE2 = HasSSE2(); + bool hasSSSE3 = HasSSSE3(); + bool isP4 = IsP4(); + int cacheLineSize = GetCacheLineSize(); + + if ((isP4 && (!hasMMX || !hasSSE2)) || (hasSSE2 && !hasMMX) || (cacheLineSize < 16 || cacheLineSize > 256 || !IsPowerOf2(cacheLineSize))) + { + cout << "FAILED: "; + pass = false; + } + else + cout << "passed: "; + + cout << "hasMMX == " << hasMMX << ", hasISSE == " << hasISSE << ", hasSSE2 == " << hasSSE2 << ", hasSSSE3 == " << hasSSSE3 << ", isP4 == " << isP4 << ", cacheLineSize == " << cacheLineSize; + + if (!pass) + { + cout << "Some critical setting in config.h is in error. Please fix it and recompile." << endl; + abort(); + } + return pass; +} + +bool TestOS_RNG() +{ + bool pass = true; + + member_ptr rng; +#ifdef BLOCKING_RNG_AVAILABLE + try {rng.reset(new BlockingRng);} + catch (OS_RNG_Err &) {} +#endif + + if (rng.get()) + { + cout << "\nTesting operating system provided blocking random number generator...\n\n"; + + ArraySink *sink; + RandomNumberSource test(*rng, UINT_MAX, false, new Deflator(sink=new ArraySink(NULL,0))); + unsigned long total=0, length=0; + time_t t = time(NULL), t1 = 0; + + // check that it doesn't take too long to generate a reasonable amount of randomness + while (total < 16 && (t1 < 10 || total*8 > (unsigned long)t1)) + { + test.Pump(1); + total += 1; + t1 = time(NULL) - t; + } + + if (total < 16) + { + cout << "FAILED:"; + pass = false; + } + else + cout << "passed:"; + cout << " it took " << long(t1) << " seconds to generate " << total << " bytes" << endl; + +#if 0 // disable this part. it's causing an unpredictable pause during the validation testing + if (t1 < 2) + { + // that was fast, are we really blocking? + // first exhaust the extropy reserve + t = time(NULL); + while (time(NULL) - t < 2) + { + test.Pump(1); + total += 1; + } + + // if it generates too many bytes in a certain amount of time, + // something's probably wrong + t = time(NULL); + while (time(NULL) - t < 2) + { + test.Pump(1); + total += 1; + length += 1; + } + if (length > 1024) + { + cout << "FAILED:"; + pass = false; + } + else + cout << "passed:"; + cout << " it generated " << length << " bytes in " << long(time(NULL) - t) << " seconds" << endl; + } +#endif + + test.AttachedTransformation()->MessageEnd(); + + if (sink->TotalPutLength() < total) + { + cout << "FAILED:"; + pass = false; + } + else + cout << "passed:"; + cout << " " << total << " generated bytes compressed to " << (size_t)sink->TotalPutLength() << " bytes by DEFLATE" << endl; + } + else + cout << "\nNo operating system provided blocking random number generator, skipping test." << endl; + + rng.reset(NULL); +#ifdef NONBLOCKING_RNG_AVAILABLE + try {rng.reset(new NonblockingRng);} + catch (OS_RNG_Err &) {} +#endif + + if (rng.get()) + { + cout << "\nTesting operating system provided nonblocking random number generator...\n\n"; + + ArraySink *sink; + RandomNumberSource test(*rng, 100000, true, new Deflator(sink=new ArraySink(NULL, 0))); + + if (sink->TotalPutLength() < 100000) + { + cout << "FAILED:"; + pass = false; + } + else + cout << "passed:"; + cout << " 100000 generated bytes compressed to " << (size_t)sink->TotalPutLength() << " bytes by DEFLATE" << endl; + } + else + cout << "\nNo operating system provided nonblocking random number generator, skipping test." << endl; + + return pass; +} + +// VC50 workaround +typedef auto_ptr apbt; + +class CipherFactory +{ +public: + virtual unsigned int BlockSize() const =0; + virtual unsigned int KeyLength() const =0; + + virtual apbt NewEncryption(const byte *key) const =0; + virtual apbt NewDecryption(const byte *key) const =0; +}; + +template class FixedRoundsCipherFactory : public CipherFactory +{ +public: + FixedRoundsCipherFactory(unsigned int keylen=0) : m_keylen(keylen?keylen:E::DEFAULT_KEYLENGTH) {} + unsigned int BlockSize() const {return E::BLOCKSIZE;} + unsigned int KeyLength() const {return m_keylen;} + + apbt NewEncryption(const byte *key) const + {return apbt(new E(key, m_keylen));} + apbt NewDecryption(const byte *key) const + {return apbt(new D(key, m_keylen));} + + unsigned int m_keylen; +}; + +template class VariableRoundsCipherFactory : public CipherFactory +{ +public: + VariableRoundsCipherFactory(unsigned int keylen=0, unsigned int rounds=0) + : m_keylen(keylen ? keylen : E::DEFAULT_KEYLENGTH), m_rounds(rounds ? rounds : E::DEFAULT_ROUNDS) {} + unsigned int BlockSize() const {return E::BLOCKSIZE;} + unsigned int KeyLength() const {return m_keylen;} + + apbt NewEncryption(const byte *key) const + {return apbt(new E(key, m_keylen, m_rounds));} + apbt NewDecryption(const byte *key) const + {return apbt(new D(key, m_keylen, m_rounds));} + + unsigned int m_keylen, m_rounds; +}; + +bool BlockTransformationTest(const CipherFactory &cg, BufferedTransformation &valdata, unsigned int tuples = 0xffff) +{ + HexEncoder output(new FileSink(cout)); + SecByteBlock plain(cg.BlockSize()), cipher(cg.BlockSize()), out(cg.BlockSize()), outplain(cg.BlockSize()); + SecByteBlock key(cg.KeyLength()); + bool pass=true, fail; + + while (valdata.MaxRetrievable() && tuples--) + { + valdata.Get(key, cg.KeyLength()); + valdata.Get(plain, cg.BlockSize()); + valdata.Get(cipher, cg.BlockSize()); + + apbt transE = cg.NewEncryption(key); + transE->ProcessBlock(plain, out); + fail = memcmp(out, cipher, cg.BlockSize()) != 0; + + apbt transD = cg.NewDecryption(key); + transD->ProcessBlock(out, outplain); + fail=fail || memcmp(outplain, plain, cg.BlockSize()); + + pass = pass && !fail; + + cout << (fail ? "FAILED " : "passed "); + output.Put(key, cg.KeyLength()); + cout << " "; + output.Put(outplain, cg.BlockSize()); + cout << " "; + output.Put(out, cg.BlockSize()); + cout << endl; + } + return pass; +} + +class FilterTester : public Unflushable +{ +public: + FilterTester(const byte *validOutput, size_t outputLen) + : validOutput(validOutput), outputLen(outputLen), counter(0), fail(false) {} + void PutByte(byte inByte) + { + if (counter >= outputLen || validOutput[counter] != inByte) + { + std::cerr << "incorrect output " << counter << ", " << (word16)validOutput[counter] << ", " << (word16)inByte << "\n"; + fail = true; + assert(false); + } + counter++; + } + size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking) + { + while (length--) + FilterTester::PutByte(*inString++); + + if (messageEnd) + if (counter != outputLen) + { + fail = true; + assert(false); + } + + return 0; + } + bool GetResult() + { + return !fail; + } + + const byte *validOutput; + size_t outputLen, counter; + bool fail; +}; + +bool TestFilter(BufferedTransformation &bt, const byte *in, size_t inLen, const byte *out, size_t outLen) +{ + FilterTester *ft; + bt.Attach(ft = new FilterTester(out, outLen)); + + while (inLen) + { + size_t randomLen = GlobalRNG().GenerateWord32(0, (word32)inLen); + bt.Put(in, randomLen); + in += randomLen; + inLen -= randomLen; + } + bt.MessageEnd(); + return ft->GetResult(); +} + +bool ValidateDES() +{ + cout << "\nDES validation suite running...\n\n"; + + FileSource valdata("descert.dat", true, new HexDecoder); + bool pass = BlockTransformationTest(FixedRoundsCipherFactory(), valdata); + + cout << "\nTesting EDE2, EDE3, and XEX3 variants...\n\n"; + + FileSource valdata1("3desval.dat", true, new HexDecoder); + pass = BlockTransformationTest(FixedRoundsCipherFactory(), valdata1, 1) && pass; + pass = BlockTransformationTest(FixedRoundsCipherFactory(), valdata1, 1) && pass; + pass = BlockTransformationTest(FixedRoundsCipherFactory(), valdata1, 1) && pass; + + return pass; +} + +bool TestModeIV(SymmetricCipher &e, SymmetricCipher &d) +{ + SecByteBlock lastIV, iv(e.IVSize()); + StreamTransformationFilter filter(e, new StreamTransformationFilter(d)); + byte plaintext[20480]; + + for (unsigned int i=1; i cbcmac(key); + HashFilter cbcmacFilter(cbcmac); + fail = !TestFilter(cbcmacFilter, plain, sizeof(plain), mac1, sizeof(mac1)); + pass = pass && !fail; + cout << (fail ? "FAILED " : "passed ") << "CBC MAC" << endl; + + DMAC dmac(key); + HashFilter dmacFilter(dmac); + fail = !TestFilter(dmacFilter, plain, sizeof(plain), mac2, sizeof(mac2)); + pass = pass && !fail; + cout << (fail ? "FAILED " : "passed ") << "DMAC" << endl; + } + + return pass; +} + +bool ValidateIDEA() +{ + cout << "\nIDEA validation suite running...\n\n"; + + FileSource valdata("ideaval.dat", true, new HexDecoder); + return BlockTransformationTest(FixedRoundsCipherFactory(), valdata); +} + +bool ValidateSAFER() +{ + cout << "\nSAFER validation suite running...\n\n"; + + FileSource valdata("saferval.dat", true, new HexDecoder); + bool pass = true; + pass = BlockTransformationTest(VariableRoundsCipherFactory(8,6), valdata, 4) && pass; + pass = BlockTransformationTest(VariableRoundsCipherFactory(16,12), valdata, 4) && pass; + pass = BlockTransformationTest(VariableRoundsCipherFactory(8,6), valdata, 4) && pass; + pass = BlockTransformationTest(VariableRoundsCipherFactory(16,10), valdata, 4) && pass; + return pass; +} + +bool ValidateRC2() +{ + cout << "\nRC2 validation suite running...\n\n"; + + FileSource valdata("rc2val.dat", true, new HexDecoder); + HexEncoder output(new FileSink(cout)); + SecByteBlock plain(RC2Encryption::BLOCKSIZE), cipher(RC2Encryption::BLOCKSIZE), out(RC2Encryption::BLOCKSIZE), outplain(RC2Encryption::BLOCKSIZE); + SecByteBlock key(128); + bool pass=true, fail; + + while (valdata.MaxRetrievable()) + { + byte keyLen, effectiveLen; + + valdata.Get(keyLen); + valdata.Get(effectiveLen); + valdata.Get(key, keyLen); + valdata.Get(plain, RC2Encryption::BLOCKSIZE); + valdata.Get(cipher, RC2Encryption::BLOCKSIZE); + + apbt transE(new RC2Encryption(key, keyLen, effectiveLen)); + transE->ProcessBlock(plain, out); + fail = memcmp(out, cipher, RC2Encryption::BLOCKSIZE) != 0; + + apbt transD(new RC2Decryption(key, keyLen, effectiveLen)); + transD->ProcessBlock(out, outplain); + fail=fail || memcmp(outplain, plain, RC2Encryption::BLOCKSIZE); + + pass = pass && !fail; + + cout << (fail ? "FAILED " : "passed "); + output.Put(key, keyLen); + cout << " "; + output.Put(outplain, RC2Encryption::BLOCKSIZE); + cout << " "; + output.Put(out, RC2Encryption::BLOCKSIZE); + cout << endl; + } + return pass; +} + +bool ValidateARC4() +{ + unsigned char Key0[] = {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef }; + unsigned char Input0[]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}; + unsigned char Output0[] = {0x75,0xb7,0x87,0x80,0x99,0xe0,0xc5,0x96}; + + unsigned char Key1[]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef}; + unsigned char Input1[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; + unsigned char Output1[]={0x74,0x94,0xc2,0xe7,0x10,0x4b,0x08,0x79}; + + unsigned char Key2[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; + unsigned char Input2[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; + unsigned char Output2[]={0xde,0x18,0x89,0x41,0xa3,0x37,0x5d,0x3a}; + + unsigned char Key3[]={0xef,0x01,0x23,0x45}; + unsigned char Input3[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; + unsigned char Output3[]={0xd6,0xa1,0x41,0xa7,0xec,0x3c,0x38,0xdf,0xbd,0x61}; + + unsigned char Key4[]={ 0x01,0x23,0x45,0x67,0x89,0xab, 0xcd,0xef }; + unsigned char Input4[] = + {0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, + 0x01}; + unsigned char Output4[]= { + 0x75,0x95,0xc3,0xe6,0x11,0x4a,0x09,0x78,0x0c,0x4a,0xd4, + 0x52,0x33,0x8e,0x1f,0xfd,0x9a,0x1b,0xe9,0x49,0x8f, + 0x81,0x3d,0x76,0x53,0x34,0x49,0xb6,0x77,0x8d,0xca, + 0xd8,0xc7,0x8a,0x8d,0x2b,0xa9,0xac,0x66,0x08,0x5d, + 0x0e,0x53,0xd5,0x9c,0x26,0xc2,0xd1,0xc4,0x90,0xc1, + 0xeb,0xbe,0x0c,0xe6,0x6d,0x1b,0x6b,0x1b,0x13,0xb6, + 0xb9,0x19,0xb8,0x47,0xc2,0x5a,0x91,0x44,0x7a,0x95, + 0xe7,0x5e,0x4e,0xf1,0x67,0x79,0xcd,0xe8,0xbf,0x0a, + 0x95,0x85,0x0e,0x32,0xaf,0x96,0x89,0x44,0x4f,0xd3, + 0x77,0x10,0x8f,0x98,0xfd,0xcb,0xd4,0xe7,0x26,0x56, + 0x75,0x00,0x99,0x0b,0xcc,0x7e,0x0c,0xa3,0xc4,0xaa, + 0xa3,0x04,0xa3,0x87,0xd2,0x0f,0x3b,0x8f,0xbb,0xcd, + 0x42,0xa1,0xbd,0x31,0x1d,0x7a,0x43,0x03,0xdd,0xa5, + 0xab,0x07,0x88,0x96,0xae,0x80,0xc1,0x8b,0x0a,0xf6, + 0x6d,0xff,0x31,0x96,0x16,0xeb,0x78,0x4e,0x49,0x5a, + 0xd2,0xce,0x90,0xd7,0xf7,0x72,0xa8,0x17,0x47,0xb6, + 0x5f,0x62,0x09,0x3b,0x1e,0x0d,0xb9,0xe5,0xba,0x53, + 0x2f,0xaf,0xec,0x47,0x50,0x83,0x23,0xe6,0x71,0x32, + 0x7d,0xf9,0x44,0x44,0x32,0xcb,0x73,0x67,0xce,0xc8, + 0x2f,0x5d,0x44,0xc0,0xd0,0x0b,0x67,0xd6,0x50,0xa0, + 0x75,0xcd,0x4b,0x70,0xde,0xdd,0x77,0xeb,0x9b,0x10, + 0x23,0x1b,0x6b,0x5b,0x74,0x13,0x47,0x39,0x6d,0x62, + 0x89,0x74,0x21,0xd4,0x3d,0xf9,0xb4,0x2e,0x44,0x6e, + 0x35,0x8e,0x9c,0x11,0xa9,0xb2,0x18,0x4e,0xcb,0xef, + 0x0c,0xd8,0xe7,0xa8,0x77,0xef,0x96,0x8f,0x13,0x90, + 0xec,0x9b,0x3d,0x35,0xa5,0x58,0x5c,0xb0,0x09,0x29, + 0x0e,0x2f,0xcd,0xe7,0xb5,0xec,0x66,0xd9,0x08,0x4b, + 0xe4,0x40,0x55,0xa6,0x19,0xd9,0xdd,0x7f,0xc3,0x16, + 0x6f,0x94,0x87,0xf7,0xcb,0x27,0x29,0x12,0x42,0x64, + 0x45,0x99,0x85,0x14,0xc1,0x5d,0x53,0xa1,0x8c,0x86, + 0x4c,0xe3,0xa2,0xb7,0x55,0x57,0x93,0x98,0x81,0x26, + 0x52,0x0e,0xac,0xf2,0xe3,0x06,0x6e,0x23,0x0c,0x91, + 0xbe,0xe4,0xdd,0x53,0x04,0xf5,0xfd,0x04,0x05,0xb3, + 0x5b,0xd9,0x9c,0x73,0x13,0x5d,0x3d,0x9b,0xc3,0x35, + 0xee,0x04,0x9e,0xf6,0x9b,0x38,0x67,0xbf,0x2d,0x7b, + 0xd1,0xea,0xa5,0x95,0xd8,0xbf,0xc0,0x06,0x6f,0xf8, + 0xd3,0x15,0x09,0xeb,0x0c,0x6c,0xaa,0x00,0x6c,0x80, + 0x7a,0x62,0x3e,0xf8,0x4c,0x3d,0x33,0xc1,0x95,0xd2, + 0x3e,0xe3,0x20,0xc4,0x0d,0xe0,0x55,0x81,0x57,0xc8, + 0x22,0xd4,0xb8,0xc5,0x69,0xd8,0x49,0xae,0xd5,0x9d, + 0x4e,0x0f,0xd7,0xf3,0x79,0x58,0x6b,0x4b,0x7f,0xf6, + 0x84,0xed,0x6a,0x18,0x9f,0x74,0x86,0xd4,0x9b,0x9c, + 0x4b,0xad,0x9b,0xa2,0x4b,0x96,0xab,0xf9,0x24,0x37, + 0x2c,0x8a,0x8f,0xff,0xb1,0x0d,0x55,0x35,0x49,0x00, + 0xa7,0x7a,0x3d,0xb5,0xf2,0x05,0xe1,0xb9,0x9f,0xcd, + 0x86,0x60,0x86,0x3a,0x15,0x9a,0xd4,0xab,0xe4,0x0f, + 0xa4,0x89,0x34,0x16,0x3d,0xdd,0xe5,0x42,0xa6,0x58, + 0x55,0x40,0xfd,0x68,0x3c,0xbf,0xd8,0xc0,0x0f,0x12, + 0x12,0x9a,0x28,0x4d,0xea,0xcc,0x4c,0xde,0xfe,0x58, + 0xbe,0x71,0x37,0x54,0x1c,0x04,0x71,0x26,0xc8,0xd4, + 0x9e,0x27,0x55,0xab,0x18,0x1a,0xb7,0xe9,0x40,0xb0, + 0xc0}; + + // VC60 workaround: auto_ptr lacks reset() + member_ptr arc4; + bool pass=true, fail; + int i; + + cout << "\nARC4 validation suite running...\n\n"; + + arc4.reset(new Weak::ARC4(Key0, sizeof(Key0))); + arc4->ProcessString(Input0, sizeof(Input0)); + fail = memcmp(Input0, Output0, sizeof(Input0)) != 0; + cout << (fail ? "FAILED" : "passed") << " Test 0" << endl; + pass = pass && !fail; + + arc4.reset(new Weak::ARC4(Key1, sizeof(Key1))); + arc4->ProcessString(Key1, Input1, sizeof(Key1)); + fail = memcmp(Output1, Key1, sizeof(Key1)) != 0; + cout << (fail ? "FAILED" : "passed") << " Test 1" << endl; + pass = pass && !fail; + + arc4.reset(new Weak::ARC4(Key2, sizeof(Key2))); + for (i=0, fail=false; iProcessByte(Input2[i]) != Output2[i]) + fail = true; + cout << (fail ? "FAILED" : "passed") << " Test 2" << endl; + pass = pass && !fail; + + arc4.reset(new Weak::ARC4(Key3, sizeof(Key3))); + for (i=0, fail=false; iProcessByte(Input3[i]) != Output3[i]) + fail = true; + cout << (fail ? "FAILED" : "passed") << " Test 3" << endl; + pass = pass && !fail; + + arc4.reset(new Weak::ARC4(Key4, sizeof(Key4))); + for (i=0, fail=false; iProcessByte(Input4[i]) != Output4[i]) + fail = true; + cout << (fail ? "FAILED" : "passed") << " Test 4" << endl; + pass = pass && !fail; + + return pass; +} + +bool ValidateRC5() +{ + cout << "\nRC5 validation suite running...\n\n"; + + FileSource valdata("rc5val.dat", true, new HexDecoder); + return BlockTransformationTest(VariableRoundsCipherFactory(16, 12), valdata); +} + +bool ValidateRC6() +{ + cout << "\nRC6 validation suite running...\n\n"; + + FileSource valdata("rc6val.dat", true, new HexDecoder); + bool pass = true; + pass = BlockTransformationTest(FixedRoundsCipherFactory(16), valdata, 2) && pass; + pass = BlockTransformationTest(FixedRoundsCipherFactory(24), valdata, 2) && pass; + pass = BlockTransformationTest(FixedRoundsCipherFactory(32), valdata, 2) && pass; + return pass; +} + +bool ValidateMARS() +{ + cout << "\nMARS validation suite running...\n\n"; + + FileSource valdata("marsval.dat", true, new HexDecoder); + bool pass = true; + pass = BlockTransformationTest(FixedRoundsCipherFactory(16), valdata, 4) && pass; + pass = BlockTransformationTest(FixedRoundsCipherFactory(24), valdata, 3) && pass; + pass = BlockTransformationTest(FixedRoundsCipherFactory(32), valdata, 2) && pass; + return pass; +} + +bool ValidateRijndael() +{ + cout << "\nRijndael validation suite running...\n\n"; + + FileSource valdata("rijndael.dat", true, new HexDecoder); + bool pass = true; + pass = BlockTransformationTest(FixedRoundsCipherFactory(16), valdata, 4) && pass; + pass = BlockTransformationTest(FixedRoundsCipherFactory(24), valdata, 3) && pass; + pass = BlockTransformationTest(FixedRoundsCipherFactory(32), valdata, 2) && pass; + return pass; +} + +bool ValidateTwofish() +{ + cout << "\nTwofish validation suite running...\n\n"; + + FileSource valdata("twofishv.dat", true, new HexDecoder); + bool pass = true; + pass = BlockTransformationTest(FixedRoundsCipherFactory(16), valdata, 4) && pass; + pass = BlockTransformationTest(FixedRoundsCipherFactory(24), valdata, 3) && pass; + pass = BlockTransformationTest(FixedRoundsCipherFactory(32), valdata, 2) && pass; + return pass; +} + +bool ValidateSerpent() +{ + cout << "\nSerpent validation suite running...\n\n"; + + FileSource valdata("serpentv.dat", true, new HexDecoder); + bool pass = true; + pass = BlockTransformationTest(FixedRoundsCipherFactory(16), valdata, 4) && pass; + pass = BlockTransformationTest(FixedRoundsCipherFactory(24), valdata, 3) && pass; + pass = BlockTransformationTest(FixedRoundsCipherFactory(32), valdata, 2) && pass; + return pass; +} + +bool ValidateBlowfish() +{ + cout << "\nBlowfish validation suite running...\n\n"; + + HexEncoder output(new FileSink(cout)); + const char *key[]={"abcdefghijklmnopqrstuvwxyz", "Who is John Galt?"}; + byte *plain[]={(byte *)"BLOWFISH", (byte *)"\xfe\xdc\xba\x98\x76\x54\x32\x10"}; + byte *cipher[]={(byte *)"\x32\x4e\xd0\xfe\xf4\x13\xa2\x03", (byte *)"\xcc\x91\x73\x2b\x80\x22\xf6\x84"}; + byte out[8], outplain[8]; + bool pass=true, fail; + + for (int i=0; i<2; i++) + { + ECB_Mode::Encryption enc((byte *)key[i], strlen(key[i])); + enc.ProcessData(out, plain[i], 8); + fail = memcmp(out, cipher[i], 8) != 0; + + ECB_Mode::Decryption dec((byte *)key[i], strlen(key[i])); + dec.ProcessData(outplain, cipher[i], 8); + fail = fail || memcmp(outplain, plain[i], 8); + pass = pass && !fail; + + cout << (fail ? "FAILED " : "passed "); + cout << '\"' << key[i] << '\"'; + for (int j=0; j<(signed int)(30-strlen(key[i])); j++) + cout << ' '; + output.Put(outplain, 8); + cout << " "; + output.Put(out, 8); + cout << endl; + } + return pass; +} + +bool ValidateThreeWay() +{ + cout << "\n3-WAY validation suite running...\n\n"; + + FileSource valdata("3wayval.dat", true, new HexDecoder); + return BlockTransformationTest(FixedRoundsCipherFactory(), valdata); +} + +bool ValidateGOST() +{ + cout << "\nGOST validation suite running...\n\n"; + + FileSource valdata("gostval.dat", true, new HexDecoder); + return BlockTransformationTest(FixedRoundsCipherFactory(), valdata); +} + +bool ValidateSHARK() +{ + cout << "\nSHARK validation suite running...\n\n"; + +#ifdef WORD64_AVAILABLE + FileSource valdata("sharkval.dat", true, new HexDecoder); + return BlockTransformationTest(FixedRoundsCipherFactory(), valdata); +#else + cout << "word64 not available, skipping SHARK validation." << endl; + return true; +#endif +} + +bool ValidateCAST() +{ + bool pass = true; + + cout << "\nCAST-128 validation suite running...\n\n"; + + FileSource val128("cast128v.dat", true, new HexDecoder); + pass = BlockTransformationTest(FixedRoundsCipherFactory(16), val128, 1) && pass; + pass = BlockTransformationTest(FixedRoundsCipherFactory(10), val128, 1) && pass; + pass = BlockTransformationTest(FixedRoundsCipherFactory(5), val128, 1) && pass; + + cout << "\nCAST-256 validation suite running...\n\n"; + + FileSource val256("cast256v.dat", true, new HexDecoder); + pass = BlockTransformationTest(FixedRoundsCipherFactory(16), val256, 1) && pass; + pass = BlockTransformationTest(FixedRoundsCipherFactory(24), val256, 1) && pass; + pass = BlockTransformationTest(FixedRoundsCipherFactory(32), val256, 1) && pass; + + return pass; +} + +bool ValidateSquare() +{ + cout << "\nSquare validation suite running...\n\n"; + + FileSource valdata("squareva.dat", true, new HexDecoder); + return BlockTransformationTest(FixedRoundsCipherFactory(), valdata); +} + +bool ValidateSKIPJACK() +{ + cout << "\nSKIPJACK validation suite running...\n\n"; + + FileSource valdata("skipjack.dat", true, new HexDecoder); + return BlockTransformationTest(FixedRoundsCipherFactory(), valdata); +} + +bool ValidateSEAL() +{ + byte input[] = {0x37,0xa0,0x05,0x95,0x9b,0x84,0xc4,0x9c,0xa4,0xbe,0x1e,0x05,0x06,0x73,0x53,0x0f,0x5f,0xb0,0x97,0xfd,0xf6,0xa1,0x3f,0xbd,0x6c,0x2c,0xde,0xcd,0x81,0xfd,0xee,0x7c}; + byte output[32]; + byte key[] = {0x67, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab, 0x89, 0x98, 0xba, 0xdc, 0xfe, 0x10, 0x32, 0x54, 0x76, 0xc3, 0xd2, 0xe1, 0xf0}; + byte iv[] = {0x01, 0x35, 0x77, 0xaf}; + + cout << "\nSEAL validation suite running...\n\n"; + + SEAL<>::Encryption seal(key, sizeof(key), iv); + unsigned int size = sizeof(input); + bool pass = true; + + memset(output, 1, size); + seal.ProcessString(output, input, size); + for (unsigned int i=0; i(16), valdata, 4) && pass; + pass = BlockTransformationTest(FixedRoundsCipherFactory(64), valdata, 10) && pass; + return pass; +} + +bool ValidateCamellia() +{ + cout << "\nCamellia validation suite running...\n\n"; + + bool pass = true; + FileSource valdata("camellia.dat", true, new HexDecoder); + pass = BlockTransformationTest(FixedRoundsCipherFactory(16), valdata, 15) && pass; + pass = BlockTransformationTest(FixedRoundsCipherFactory(24), valdata, 15) && pass; + pass = BlockTransformationTest(FixedRoundsCipherFactory(32), valdata, 15) && pass; + return pass; +} + +bool ValidateSalsa() +{ + cout << "\nSalsa validation suite running...\n"; + + return RunTestDataFile("TestVectors/salsa.txt"); +} + +bool ValidateSosemanuk() +{ + cout << "\nSosemanuk validation suite running...\n"; + return RunTestDataFile("TestVectors/sosemanuk.txt"); +} + +bool ValidateVMAC() +{ + cout << "\nVMAC validation suite running...\n"; + return RunTestDataFile("TestVectors/vmac.txt"); +} diff --git a/CryptoPP/crypto/validat2.cpp b/CryptoPP/crypto/validat2.cpp new file mode 100644 index 0000000..76b58ea --- /dev/null +++ b/CryptoPP/crypto/validat2.cpp @@ -0,0 +1,758 @@ +// validat2.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" + +#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 +#include "blumshub.h" +#include "rsa.h" +#include "md2.h" +#include "elgamal.h" +#include "nr.h" +#include "dsa.h" +#include "dh.h" +#include "mqv.h" +#include "luc.h" +#include "xtrcrypt.h" +#include "rabin.h" +#include "rw.h" +#include "eccrypto.h" +#include "ecp.h" +#include "ec2n.h" +#include "asn.h" +#include "rng.h" +#include "files.h" +#include "hex.h" +#include "oids.h" +#include "esign.h" +#include "osrng.h" + +#include +#include + +#include "validate.h" + +USING_NAMESPACE(CryptoPP) +USING_NAMESPACE(std) + +class FixedRNG : public RandomNumberGenerator +{ +public: + FixedRNG(BufferedTransformation &source) : m_source(source) {} + + void GenerateBlock(byte *output, size_t size) + { + m_source.Get(output, size); + } + +private: + BufferedTransformation &m_source; +}; + +bool ValidateBBS() +{ + cout << "\nBlumBlumShub validation suite running...\n\n"; + + Integer p("212004934506826557583707108431463840565872545889679278744389317666981496005411448865750399674653351"); + Integer q("100677295735404212434355574418077394581488455772477016953458064183204108039226017738610663984508231"); + Integer seed("63239752671357255800299643604761065219897634268887145610573595874544114193025997412441121667211431"); + BlumBlumShub bbs(p, q, seed); + bool pass = true, fail; + int j; + + const byte output1[] = { + 0x49,0xEA,0x2C,0xFD,0xB0,0x10,0x64,0xA0,0xBB,0xB9, + 0x2A,0xF1,0x01,0xDA,0xC1,0x8A,0x94,0xF7,0xB7,0xCE}; + const byte output2[] = { + 0x74,0x45,0x48,0xAE,0xAC,0xB7,0x0E,0xDF,0xAF,0xD7, + 0xD5,0x0E,0x8E,0x29,0x83,0x75,0x6B,0x27,0x46,0xA1}; + + byte buf[20]; + + bbs.GenerateBlock(buf, 20); + fail = memcmp(output1, buf, 20) != 0; + pass = pass && !fail; + + cout << (fail ? "FAILED " : "passed "); + for (j=0;j<20;j++) + cout << setw(2) << setfill('0') << hex << (int)buf[j]; + cout << endl; + + bbs.Seek(10); + bbs.GenerateBlock(buf, 10); + fail = memcmp(output1+10, buf, 10) != 0; + pass = pass && !fail; + + cout << (fail ? "FAILED " : "passed "); + for (j=0;j<10;j++) + cout << setw(2) << setfill('0') << hex << (int)buf[j]; + cout << endl; + + bbs.Seek(1234567); + bbs.GenerateBlock(buf, 20); + fail = memcmp(output2, buf, 20) != 0; + pass = pass && !fail; + + cout << (fail ? "FAILED " : "passed "); + for (j=0;j<20;j++) + cout << setw(2) << setfill('0') << hex << (int)buf[j]; + cout << endl; + + return pass; +} + +bool SignatureValidate(PK_Signer &priv, PK_Verifier &pub, bool thorough = false) +{ + bool pass = true, fail; + + fail = !pub.GetMaterial().Validate(GlobalRNG(), thorough ? 3 : 2) || !priv.GetMaterial().Validate(GlobalRNG(), thorough ? 3 : 2); + pass = pass && !fail; + + cout << (fail ? "FAILED " : "passed "); + cout << "signature key validation\n"; + + const byte *message = (byte *)"test message"; + const int messageLen = 12; + + SecByteBlock signature(priv.MaxSignatureLength()); + size_t signatureLength = priv.SignMessage(GlobalRNG(), message, messageLen, signature); + fail = !pub.VerifyMessage(message, messageLen, signature, signatureLength); + pass = pass && !fail; + + cout << (fail ? "FAILED " : "passed "); + cout << "signature and verification\n"; + + ++signature[0]; + fail = pub.VerifyMessage(message, messageLen, signature, signatureLength); + pass = pass && !fail; + + cout << (fail ? "FAILED " : "passed "); + cout << "checking invalid signature" << endl; + + if (priv.MaxRecoverableLength() > 0) + { + signatureLength = priv.SignMessageWithRecovery(GlobalRNG(), message, messageLen, NULL, 0, signature); + SecByteBlock recovered(priv.MaxRecoverableLengthFromSignatureLength(signatureLength)); + DecodingResult result = pub.RecoverMessage(recovered, NULL, 0, signature, signatureLength); + fail = !(result.isValidCoding && result.messageLength == messageLen && memcmp(recovered, message, messageLen) == 0); + pass = pass && !fail; + + cout << (fail ? "FAILED " : "passed "); + cout << "signature and verification with recovery" << endl; + + ++signature[0]; + result = pub.RecoverMessage(recovered, NULL, 0, signature, signatureLength); + fail = result.isValidCoding; + pass = pass && !fail; + + cout << (fail ? "FAILED " : "passed "); + cout << "recovery with invalid signature" << endl; + } + + return pass; +} + +bool CryptoSystemValidate(PK_Decryptor &priv, PK_Encryptor &pub, bool thorough = false) +{ + bool pass = true, fail; + + fail = !pub.GetMaterial().Validate(GlobalRNG(), thorough ? 3 : 2) || !priv.GetMaterial().Validate(GlobalRNG(), thorough ? 3 : 2); + pass = pass && !fail; + + cout << (fail ? "FAILED " : "passed "); + cout << "cryptosystem key validation\n"; + + const byte *message = (byte *)"test message"; + const int messageLen = 12; + SecByteBlock ciphertext(priv.CiphertextLength(messageLen)); + SecByteBlock plaintext(priv.MaxPlaintextLength(ciphertext.size())); + + pub.Encrypt(GlobalRNG(), message, messageLen, ciphertext); + fail = priv.Decrypt(GlobalRNG(), ciphertext, priv.CiphertextLength(messageLen), plaintext) != DecodingResult(messageLen); + fail = fail || memcmp(message, plaintext, messageLen); + pass = pass && !fail; + + cout << (fail ? "FAILED " : "passed "); + cout << "encryption and decryption\n"; + + return pass; +} + +bool SimpleKeyAgreementValidate(SimpleKeyAgreementDomain &d) +{ + if (d.GetCryptoParameters().Validate(GlobalRNG(), 3)) + cout << "passed simple key agreement domain parameters validation" << endl; + else + { + cout << "FAILED simple key agreement domain parameters invalid" << endl; + return false; + } + + SecByteBlock priv1(d.PrivateKeyLength()), priv2(d.PrivateKeyLength()); + SecByteBlock pub1(d.PublicKeyLength()), pub2(d.PublicKeyLength()); + SecByteBlock val1(d.AgreedValueLength()), val2(d.AgreedValueLength()); + + d.GenerateKeyPair(GlobalRNG(), priv1, pub1); + d.GenerateKeyPair(GlobalRNG(), priv2, pub2); + + memset(val1.begin(), 0x10, val1.size()); + memset(val2.begin(), 0x11, val2.size()); + + if (!(d.Agree(val1, priv1, pub2) && d.Agree(val2, priv2, pub1))) + { + cout << "FAILED simple key agreement failed" << endl; + return false; + } + + if (memcmp(val1.begin(), val2.begin(), d.AgreedValueLength())) + { + cout << "FAILED simple agreed values not equal" << endl; + return false; + } + + cout << "passed simple key agreement" << endl; + return true; +} + +bool AuthenticatedKeyAgreementValidate(AuthenticatedKeyAgreementDomain &d) +{ + if (d.GetCryptoParameters().Validate(GlobalRNG(), 3)) + cout << "passed authenticated key agreement domain parameters validation" << endl; + else + { + cout << "FAILED authenticated key agreement domain parameters invalid" << endl; + return false; + } + + SecByteBlock spriv1(d.StaticPrivateKeyLength()), spriv2(d.StaticPrivateKeyLength()); + SecByteBlock epriv1(d.EphemeralPrivateKeyLength()), epriv2(d.EphemeralPrivateKeyLength()); + SecByteBlock spub1(d.StaticPublicKeyLength()), spub2(d.StaticPublicKeyLength()); + SecByteBlock epub1(d.EphemeralPublicKeyLength()), epub2(d.EphemeralPublicKeyLength()); + SecByteBlock val1(d.AgreedValueLength()), val2(d.AgreedValueLength()); + + d.GenerateStaticKeyPair(GlobalRNG(), spriv1, spub1); + d.GenerateStaticKeyPair(GlobalRNG(), spriv2, spub2); + d.GenerateEphemeralKeyPair(GlobalRNG(), epriv1, epub1); + d.GenerateEphemeralKeyPair(GlobalRNG(), epriv2, epub2); + + memset(val1.begin(), 0x10, val1.size()); + memset(val2.begin(), 0x11, val2.size()); + + if (!(d.Agree(val1, spriv1, epriv1, spub2, epub2) && d.Agree(val2, spriv2, epriv2, spub1, epub1))) + { + cout << "FAILED authenticated key agreement failed" << endl; + return false; + } + + if (memcmp(val1.begin(), val2.begin(), d.AgreedValueLength())) + { + cout << "FAILED authenticated agreed values not equal" << endl; + return false; + } + + cout << "passed authenticated key agreement" << endl; + return true; +} + +bool ValidateRSA() +{ + cout << "\nRSA validation suite running...\n\n"; + + byte out[100], outPlain[100]; + bool pass = true, fail; + + { + const char *plain = "Everyone gets Friday off."; + byte *signature = (byte *) + "\x05\xfa\x6a\x81\x2f\xc7\xdf\x8b\xf4\xf2\x54\x25\x09\xe0\x3e\x84" + "\x6e\x11\xb9\xc6\x20\xbe\x20\x09\xef\xb4\x40\xef\xbc\xc6\x69\x21" + "\x69\x94\xac\x04\xf3\x41\xb5\x7d\x05\x20\x2d\x42\x8f\xb2\xa2\x7b" + "\x5c\x77\xdf\xd9\xb1\x5b\xfc\x3d\x55\x93\x53\x50\x34\x10\xc1\xe1"; + + FileSource keys("rsa512a.dat", true, new HexDecoder); + Weak::RSASSA_PKCS1v15_MD2_Signer rsaPriv(keys); + Weak::RSASSA_PKCS1v15_MD2_Verifier rsaPub(rsaPriv); + + size_t signatureLength = rsaPriv.SignMessage(GlobalRNG(), (byte *)plain, strlen(plain), out); + fail = memcmp(signature, out, 64) != 0; + pass = pass && !fail; + + cout << (fail ? "FAILED " : "passed "); + cout << "signature check against test vector\n"; + + fail = !rsaPub.VerifyMessage((byte *)plain, strlen(plain), out, signatureLength); + pass = pass && !fail; + + cout << (fail ? "FAILED " : "passed "); + cout << "verification check against test vector\n"; + + out[10]++; + fail = rsaPub.VerifyMessage((byte *)plain, strlen(plain), out, signatureLength); + pass = pass && !fail; + + cout << (fail ? "FAILED " : "passed "); + cout << "invalid signature verification\n"; + } + { + FileSource keys("rsa1024.dat", true, new HexDecoder); + RSAES_PKCS1v15_Decryptor rsaPriv(keys); + RSAES_PKCS1v15_Encryptor rsaPub(rsaPriv); + + pass = CryptoSystemValidate(rsaPriv, rsaPub) && pass; + } + { + byte *plain = (byte *) + "\x54\x85\x9b\x34\x2c\x49\xea\x2a"; + byte *encrypted = (byte *) + "\x14\xbd\xdd\x28\xc9\x83\x35\x19\x23\x80\xe8\xe5\x49\xb1\x58\x2a" + "\x8b\x40\xb4\x48\x6d\x03\xa6\xa5\x31\x1f\x1f\xd5\xf0\xa1\x80\xe4" + "\x17\x53\x03\x29\xa9\x34\x90\x74\xb1\x52\x13\x54\x29\x08\x24\x52" + "\x62\x51"; + byte *oaepSeed = (byte *) + "\xaa\xfd\x12\xf6\x59\xca\xe6\x34\x89\xb4\x79\xe5\x07\x6d\xde\xc2" + "\xf0\x6c\xb5\x8f"; + ByteQueue bq; + bq.Put(oaepSeed, 20); + FixedRNG rng(bq); + + FileSource privFile("rsa400pv.dat", true, new HexDecoder); + FileSource pubFile("rsa400pb.dat", true, new HexDecoder); + RSAES_OAEP_SHA_Decryptor rsaPriv; + rsaPriv.AccessKey().BERDecodePrivateKey(privFile, false, 0); + RSAES_OAEP_SHA_Encryptor rsaPub(pubFile); + + memset(out, 0, 50); + memset(outPlain, 0, 8); + rsaPub.Encrypt(rng, plain, 8, out); + DecodingResult result = rsaPriv.FixedLengthDecrypt(GlobalRNG(), encrypted, outPlain); + fail = !result.isValidCoding || (result.messageLength!=8) || memcmp(out, encrypted, 50) || memcmp(plain, outPlain, 8); + pass = pass && !fail; + + cout << (fail ? "FAILED " : "passed "); + cout << "PKCS 2.0 encryption and decryption\n"; + } + + return pass; +} + +bool ValidateDH() +{ + cout << "\nDH validation suite running...\n\n"; + + FileSource f("dh1024.dat", true, new HexDecoder()); + DH dh(f); + return SimpleKeyAgreementValidate(dh); +} + +bool ValidateMQV() +{ + cout << "\nMQV validation suite running...\n\n"; + + FileSource f("mqv1024.dat", true, new HexDecoder()); + MQV mqv(f); + return AuthenticatedKeyAgreementValidate(mqv); +} + +bool ValidateLUC_DH() +{ + cout << "\nLUC-DH validation suite running...\n\n"; + + FileSource f("lucd512.dat", true, new HexDecoder()); + LUC_DH dh(f); + return SimpleKeyAgreementValidate(dh); +} + +bool ValidateXTR_DH() +{ + cout << "\nXTR-DH validation suite running...\n\n"; + + FileSource f("xtrdh171.dat", true, new HexDecoder()); + XTR_DH dh(f); + return SimpleKeyAgreementValidate(dh); +} + +bool ValidateElGamal() +{ + cout << "\nElGamal validation suite running...\n\n"; + bool pass = true; + { + FileSource fc("elgc1024.dat", true, new HexDecoder); + ElGamalDecryptor privC(fc); + ElGamalEncryptor pubC(privC); + privC.AccessKey().Precompute(); + ByteQueue queue; + privC.AccessKey().SavePrecomputation(queue); + privC.AccessKey().LoadPrecomputation(queue); + + pass = CryptoSystemValidate(privC, pubC) && pass; + } + return pass; +} + +bool ValidateDLIES() +{ + cout << "\nDLIES validation suite running...\n\n"; + bool pass = true; + { + FileSource fc("dlie1024.dat", true, new HexDecoder); + DLIES<>::Decryptor privC(fc); + DLIES<>::Encryptor pubC(privC); + pass = CryptoSystemValidate(privC, pubC) && pass; + } + { + cout << "Generating new encryption key..." << endl; + DLIES<>::GroupParameters gp; + gp.GenerateRandomWithKeySize(GlobalRNG(), 128); + DLIES<>::Decryptor decryptor; + decryptor.AccessKey().GenerateRandom(GlobalRNG(), gp); + DLIES<>::Encryptor encryptor(decryptor); + + pass = CryptoSystemValidate(decryptor, encryptor) && pass; + } + return pass; +} + +bool ValidateNR() +{ + cout << "\nNR validation suite running...\n\n"; + bool pass = true; + { + FileSource f("nr2048.dat", true, new HexDecoder); + NR::Signer privS(f); + privS.AccessKey().Precompute(); + NR::Verifier pubS(privS); + + pass = SignatureValidate(privS, pubS) && pass; + } + { + cout << "Generating new signature key..." << endl; + NR::Signer privS(GlobalRNG(), 256); + NR::Verifier pubS(privS); + + pass = SignatureValidate(privS, pubS) && pass; + } + return pass; +} + +bool ValidateDSA(bool thorough) +{ + cout << "\nDSA validation suite running...\n\n"; + + bool pass = true, fail; + { + FileSource fs("dsa512.dat", true, new HexDecoder()); + GDSA::Signer priv(fs); + priv.AccessKey().Precompute(16); + GDSA::Verifier pub(priv); + + byte seed[]={0xd5, 0x01, 0x4e, 0x4b, 0x60, 0xef, 0x2b, 0xa8, 0xb6, 0x21, + 0x1b, 0x40, 0x62, 0xba, 0x32, 0x24, 0xe0, 0x42, 0x7d, 0xd3}; + Integer k("358dad57 1462710f 50e254cf 1a376b2b deaadfbfh"); + Integer h("a9993e36 4706816a ba3e2571 7850c26c 9cd0d89dh"); + byte sig[]={0x8b, 0xac, 0x1a, 0xb6, 0x64, 0x10, 0x43, 0x5c, 0xb7, 0x18, + 0x1f, 0x95, 0xb1, 0x6a, 0xb9, 0x7c, 0x92, 0xb3, 0x41, 0xc0, + 0x41, 0xe2, 0x34, 0x5f, 0x1f, 0x56, 0xdf, 0x24, 0x58, 0xf4, + 0x26, 0xd1, 0x55, 0xb4, 0xba, 0x2d, 0xb6, 0xdc, 0xd8, 0xc8}; + Integer r(sig, 20); + Integer s(sig+20, 20); + + Integer pGen, qGen, rOut, sOut; + int c; + + fail = !DSA::GeneratePrimes(seed, 160, c, pGen, 512, qGen); + fail = fail || (pGen != pub.GetKey().GetGroupParameters().GetModulus()) || (qGen != pub.GetKey().GetGroupParameters().GetSubgroupOrder()); + pass = pass && !fail; + + cout << (fail ? "FAILED " : "passed "); + cout << "prime generation test\n"; + + priv.RawSign(k, h, rOut, sOut); + fail = (rOut != r) || (sOut != s); + pass = pass && !fail; + + cout << (fail ? "FAILED " : "passed "); + cout << "signature check against test vector\n"; + + fail = !pub.VerifyMessage((byte *)"abc", 3, sig, sizeof(sig)); + pass = pass && !fail; + + cout << (fail ? "FAILED " : "passed "); + cout << "verification check against test vector\n"; + + fail = pub.VerifyMessage((byte *)"xyz", 3, sig, sizeof(sig)); + pass = pass && !fail; + } + FileSource fs1("dsa1024.dat", true, new HexDecoder()); + DSA::Signer priv(fs1); + DSA::Verifier pub(priv); + FileSource fs2("dsa1024b.dat", true, new HexDecoder()); + DSA::Verifier pub1(fs2); + assert(pub.GetKey() == pub1.GetKey()); + pass = SignatureValidate(priv, pub, thorough) && pass; + return pass; +} + +bool ValidateLUC() +{ + cout << "\nLUC validation suite running...\n\n"; + bool pass=true; + + { + FileSource f("luc1024.dat", true, new HexDecoder); + LUCSSA_PKCS1v15_SHA_Signer priv(f); + LUCSSA_PKCS1v15_SHA_Verifier pub(priv); + pass = SignatureValidate(priv, pub) && pass; + } + { + LUCES_OAEP_SHA_Decryptor priv(GlobalRNG(), 512); + LUCES_OAEP_SHA_Encryptor pub(priv); + pass = CryptoSystemValidate(priv, pub) && pass; + } + return pass; +} + +bool ValidateLUC_DL() +{ + cout << "\nLUC-HMP validation suite running...\n\n"; + + FileSource f("lucs512.dat", true, new HexDecoder); + LUC_HMP::Signer privS(f); + LUC_HMP::Verifier pubS(privS); + bool pass = SignatureValidate(privS, pubS); + + cout << "\nLUC-IES validation suite running...\n\n"; + + FileSource fc("lucc512.dat", true, new HexDecoder); + LUC_IES<>::Decryptor privC(fc); + LUC_IES<>::Encryptor pubC(privC); + pass = CryptoSystemValidate(privC, pubC) && pass; + + return pass; +} + +bool ValidateRabin() +{ + cout << "\nRabin validation suite running...\n\n"; + bool pass=true; + + { + FileSource f("rabi1024.dat", true, new HexDecoder); + RabinSS::Signer priv(f); + RabinSS::Verifier pub(priv); + pass = SignatureValidate(priv, pub) && pass; + } + { + RabinES >::Decryptor priv(GlobalRNG(), 512); + RabinES >::Encryptor pub(priv); + pass = CryptoSystemValidate(priv, pub) && pass; + } + return pass; +} + +bool ValidateRW() +{ + cout << "\nRW validation suite running...\n\n"; + + FileSource f("rw1024.dat", true, new HexDecoder); + RWSS::Signer priv(f); + RWSS::Verifier pub(priv); + + return SignatureValidate(priv, pub); +} + +/* +bool ValidateBlumGoldwasser() +{ + cout << "\nBlumGoldwasser validation suite running...\n\n"; + + FileSource f("blum512.dat", true, new HexDecoder); + BlumGoldwasserPrivateKey priv(f); + BlumGoldwasserPublicKey pub(priv); + + return CryptoSystemValidate(priv, pub); +} +*/ + +bool ValidateECP() +{ + cout << "\nECP validation suite running...\n\n"; + + ECIES::Decryptor cpriv(GlobalRNG(), ASN1::secp192r1()); + ECIES::Encryptor cpub(cpriv); + ByteQueue bq; + cpriv.GetKey().DEREncode(bq); + cpub.AccessKey().AccessGroupParameters().SetEncodeAsOID(true); + cpub.GetKey().DEREncode(bq); + ECDSA::Signer spriv(bq); + ECDSA::Verifier spub(bq); + ECDH::Domain ecdhc(ASN1::secp192r1()); + ECMQV::Domain ecmqvc(ASN1::secp192r1()); + + spriv.AccessKey().Precompute(); + ByteQueue queue; + spriv.AccessKey().SavePrecomputation(queue); + spriv.AccessKey().LoadPrecomputation(queue); + + bool pass = SignatureValidate(spriv, spub); + cpub.AccessKey().Precompute(); + cpriv.AccessKey().Precompute(); + pass = CryptoSystemValidate(cpriv, cpub) && pass; + pass = SimpleKeyAgreementValidate(ecdhc) && pass; + pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass; + + cout << "Turning on point compression..." << endl; + cpriv.AccessKey().AccessGroupParameters().SetPointCompression(true); + cpub.AccessKey().AccessGroupParameters().SetPointCompression(true); + ecdhc.AccessGroupParameters().SetPointCompression(true); + ecmqvc.AccessGroupParameters().SetPointCompression(true); + pass = CryptoSystemValidate(cpriv, cpub) && pass; + pass = SimpleKeyAgreementValidate(ecdhc) && pass; + pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass; + + cout << "Testing SEC 2 recommended curves..." << endl; + OID oid; + while (!(oid = DL_GroupParameters_EC::GetNextRecommendedParametersOID(oid)).m_values.empty()) + { + DL_GroupParameters_EC params(oid); + bool fail = !params.Validate(GlobalRNG(), 2); + cout << (fail ? "FAILED" : "passed") << " " << dec << params.GetCurve().GetField().MaxElementBitLength() << " bits" << endl; + pass = pass && !fail; + } + + return pass; +} + +bool ValidateEC2N() +{ + cout << "\nEC2N validation suite running...\n\n"; + + ECIES::Decryptor cpriv(GlobalRNG(), ASN1::sect193r1()); + ECIES::Encryptor cpub(cpriv); + ByteQueue bq; + cpriv.DEREncode(bq); + cpub.AccessKey().AccessGroupParameters().SetEncodeAsOID(true); + cpub.DEREncode(bq); + ECDSA::Signer spriv(bq); + ECDSA::Verifier spub(bq); + ECDH::Domain ecdhc(ASN1::sect193r1()); + ECMQV::Domain ecmqvc(ASN1::sect193r1()); + + spriv.AccessKey().Precompute(); + ByteQueue queue; + spriv.AccessKey().SavePrecomputation(queue); + spriv.AccessKey().LoadPrecomputation(queue); + + bool pass = SignatureValidate(spriv, spub); + pass = CryptoSystemValidate(cpriv, cpub) && pass; + pass = SimpleKeyAgreementValidate(ecdhc) && pass; + pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass; + + cout << "Turning on point compression..." << endl; + cpriv.AccessKey().AccessGroupParameters().SetPointCompression(true); + cpub.AccessKey().AccessGroupParameters().SetPointCompression(true); + ecdhc.AccessGroupParameters().SetPointCompression(true); + ecmqvc.AccessGroupParameters().SetPointCompression(true); + pass = CryptoSystemValidate(cpriv, cpub) && pass; + pass = SimpleKeyAgreementValidate(ecdhc) && pass; + pass = AuthenticatedKeyAgreementValidate(ecmqvc) && pass; + +#if 0 // TODO: turn this back on when I make EC2N faster for pentanomial basis + cout << "Testing SEC 2 recommended curves..." << endl; + OID oid; + while (!(oid = DL_GroupParameters_EC::GetNextRecommendedParametersOID(oid)).m_values.empty()) + { + DL_GroupParameters_EC params(oid); + bool fail = !params.Validate(GlobalRNG(), 2); + cout << (fail ? "FAILED" : "passed") << " " << params.GetCurve().GetField().MaxElementBitLength() << " bits" << endl; + pass = pass && !fail; + } +#endif + + return pass; +} + +bool ValidateECDSA() +{ + cout << "\nECDSA validation suite running...\n\n"; + + // from Sample Test Vectors for P1363 + GF2NT gf2n(191, 9, 0); + byte a[]="\x28\x66\x53\x7B\x67\x67\x52\x63\x6A\x68\xF5\x65\x54\xE1\x26\x40\x27\x6B\x64\x9E\xF7\x52\x62\x67"; + byte b[]="\x2E\x45\xEF\x57\x1F\x00\x78\x6F\x67\xB0\x08\x1B\x94\x95\xA3\xD9\x54\x62\xF5\xDE\x0A\xA1\x85\xEC"; + EC2N ec(gf2n, PolynomialMod2(a,24), PolynomialMod2(b,24)); + + EC2N::Point P; + ec.DecodePoint(P, (byte *)"\x04\x36\xB3\xDA\xF8\xA2\x32\x06\xF9\xC4\xF2\x99\xD7\xB2\x1A\x9C\x36\x91\x37\xF2\xC8\x4A\xE1\xAA\x0D" + "\x76\x5B\xE7\x34\x33\xB3\xF9\x5E\x33\x29\x32\xE7\x0E\xA2\x45\xCA\x24\x18\xEA\x0E\xF9\x80\x18\xFB", ec.EncodedPointSize()); + Integer n("40000000000000000000000004a20e90c39067c893bbb9a5H"); + Integer d("340562e1dda332f9d2aec168249b5696ee39d0ed4d03760fH"); + EC2N::Point Q(ec.Multiply(d, P)); + ECDSA::Signer priv(ec, P, n, d); + ECDSA::Verifier pub(priv); + + Integer h("A9993E364706816ABA3E25717850C26C9CD0D89DH"); + Integer k("3eeace72b4919d991738d521879f787cb590aff8189d2b69H"); + byte sig[]="\x03\x8e\x5a\x11\xfb\x55\xe4\xc6\x54\x71\xdc\xd4\x99\x84\x52\xb1\xe0\x2d\x8a\xf7\x09\x9b\xb9\x30" + "\x0c\x9a\x08\xc3\x44\x68\xc2\x44\xb4\xe5\xd6\xb2\x1b\x3c\x68\x36\x28\x07\x41\x60\x20\x32\x8b\x6e"; + Integer r(sig, 24); + Integer s(sig+24, 24); + + Integer rOut, sOut; + bool fail, pass=true; + + priv.RawSign(k, h, rOut, sOut); + fail = (rOut != r) || (sOut != s); + pass = pass && !fail; + + cout << (fail ? "FAILED " : "passed "); + cout << "signature check against test vector\n"; + + fail = !pub.VerifyMessage((byte *)"abc", 3, sig, sizeof(sig)); + pass = pass && !fail; + + cout << (fail ? "FAILED " : "passed "); + cout << "verification check against test vector\n"; + + fail = pub.VerifyMessage((byte *)"xyz", 3, sig, sizeof(sig)); + pass = pass && !fail; + + pass = SignatureValidate(priv, pub) && pass; + + return pass; +} + +bool ValidateESIGN() +{ + cout << "\nESIGN validation suite running...\n\n"; + + bool pass = true, fail; + + const char *plain = "test"; + const byte *signature = (byte *) + "\xA3\xE3\x20\x65\xDE\xDA\xE7\xEC\x05\xC1\xBF\xCD\x25\x79\x7D\x99\xCD\xD5\x73\x9D\x9D\xF3\xA4\xAA\x9A\xA4\x5A\xC8\x23\x3D\x0D\x37\xFE\xBC\x76\x3F\xF1\x84\xF6\x59" + "\x14\x91\x4F\x0C\x34\x1B\xAE\x9A\x5C\x2E\x2E\x38\x08\x78\x77\xCB\xDC\x3C\x7E\xA0\x34\x44\x5B\x0F\x67\xD9\x35\x2A\x79\x47\x1A\x52\x37\x71\xDB\x12\x67\xC1\xB6\xC6" + "\x66\x73\xB3\x40\x2E\xD6\xF2\x1A\x84\x0A\xB6\x7B\x0F\xEB\x8B\x88\xAB\x33\xDD\xE4\x83\x21\x90\x63\x2D\x51\x2A\xB1\x6F\xAB\xA7\x5C\xFD\x77\x99\xF2\xE1\xEF\x67\x1A" + "\x74\x02\x37\x0E\xED\x0A\x06\xAD\xF4\x15\x65\xB8\xE1\xD1\x45\xAE\x39\x19\xB4\xFF\x5D\xF1\x45\x7B\xE0\xFE\x72\xED\x11\x92\x8F\x61\x41\x4F\x02\x00\xF2\x76\x6F\x7C" + "\x79\xA2\xE5\x52\x20\x5D\x97\x5E\xFE\x39\xAE\x21\x10\xFB\x35\xF4\x80\x81\x41\x13\xDD\xE8\x5F\xCA\x1E\x4F\xF8\x9B\xB2\x68\xFB\x28"; + + FileSource keys("esig1536.dat", true, new HexDecoder); + ESIGN::Signer signer(keys); + ESIGN::Verifier verifier(signer); + + fail = !SignatureValidate(signer, verifier); + pass = pass && !fail; + + fail = !verifier.VerifyMessage((byte *)plain, strlen(plain), signature, verifier.SignatureLength()); + pass = pass && !fail; + + cout << (fail ? "FAILED " : "passed "); + cout << "verification check against test vector\n"; + + cout << "Generating signature key from seed..." << endl; + signer.AccessKey().GenerateRandom(GlobalRNG(), MakeParameters("Seed", ConstByteArrayParameter((const byte *)"test", 4))("KeySize", 3*512)); + verifier = signer; + + fail = !SignatureValidate(signer, verifier); + pass = pass && !fail; + + return pass; +} diff --git a/CryptoPP/crypto/validat3.cpp b/CryptoPP/crypto/validat3.cpp new file mode 100644 index 0000000..698aa5b --- /dev/null +++ b/CryptoPP/crypto/validat3.cpp @@ -0,0 +1,693 @@ +// validat3.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "validate.h" + +#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 +#include "smartptr.h" +#include "crc.h" +#include "adler32.h" +#include "md2.h" +#include "md4.h" +#include "md5.h" +#include "sha.h" +#include "tiger.h" +#include "ripemd.h" + +#include "hmac.h" +#include "ttmac.h" + +#include "integer.h" +#include "pwdbased.h" +#include "filters.h" +#include "hex.h" +#include "files.h" + +#include +#include + +USING_NAMESPACE(CryptoPP) +USING_NAMESPACE(std) + +struct HashTestTuple +{ + HashTestTuple(const char *input, const char *output, unsigned int repeatTimes=1) + : input((byte *)input), output((byte *)output), inputLen(strlen(input)), repeatTimes(repeatTimes) {} + + HashTestTuple(const char *input, unsigned int inputLen, const char *output, unsigned int repeatTimes) + : input((byte *)input), output((byte *)output), inputLen(inputLen), repeatTimes(repeatTimes) {} + + const byte *input, *output; + size_t inputLen; + unsigned int repeatTimes; +}; + +bool HashModuleTest(HashTransformation &md, const HashTestTuple *testSet, unsigned int testSetSize) +{ + bool pass=true, fail; + SecByteBlock digest(md.DigestSize()); + + for (unsigned int i=0; i HMAC_MD5; + + const char* keys[]= + { + "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", + "Jefe", + "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA", + "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" + "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" + "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" + "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" + "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" + }; + + HashTestTuple testSet[] = + { + HashTestTuple("Hi There", "\x92\x94\x72\x7a\x36\x38\xbb\x1c\x13\xf4\x8e\xf8\x15\x8b\xfc\x9d"), + HashTestTuple("what do ya want for nothing?", "\x75\x0c\x78\x3e\x6a\xb0\xb5\x03\xea\xa8\x6e\x31\x0a\x5d\xb7\x38"), + HashTestTuple("\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD", + "\x56\xbe\x34\x52\x1d\x14\x4c\x88\xdb\xb8\xc7\x33\xf0\xe8\xb3\xf6"), + HashTestTuple("Test Using Larger Than Block-Size Key - Hash Key First", "\x6b\x1a\xb7\xfe\x4b\xd7\xbf\x8f\x0b\x62\xe6\xce\x61\xb9\xd0\xcd") + }; + + bool pass=true; + + cout << "\nHMAC/MD5 validation suite running...\n"; + + for (int k=0; k<4; k++) + { + HMAC_MD5 mac((byte *)keys[k], strlen(keys[k])); + cout << "\nKEY: "; + for (int j=0; keys[k][j] != 0; j++) + cout << setw(2) << setfill('0') << hex << (int)(byte)keys[k][j]; + cout << endl; + + pass = HashModuleTest(mac, testSet+k, 1) && pass; + } + + return pass; +} + +#ifdef CRYPTOPP_REMOVED +bool ValidateXMACC() +{ + typedef XMACC XMACC_MD5; + + const byte keys[2][XMACC_MD5::KEYLENGTH]={ + {0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,0xbb}, + {0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98}}; + + const word32 counters[2]={0xccddeeff, 0x76543210}; + + const char *TestVals[7]={ + "", + "a", + "abc", + "message digest", + "abcdefghijklmnopqrstuvwxyz", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + "12345678901234567890123456789012345678901234567890123456789012345678901234567890"}; + + const byte output[2][7][XMACC_MD5::DIGESTSIZE]={ + {{0xcc,0xdd,0xef,0x00,0xfa,0x89,0x54,0x92,0x86,0x32,0xda,0x2a,0x3f,0x29,0xc5,0x52,0xa0,0x0d,0x05,0x13}, + {0xcc,0xdd,0xef,0x01,0xae,0xdb,0x8b,0x7b,0x69,0x71,0xc7,0x91,0x71,0x48,0x9d,0x18,0xe7,0xdf,0x9d,0x5a}, + {0xcc,0xdd,0xef,0x02,0x5e,0x01,0x2e,0x2e,0x4b,0xc3,0x83,0x62,0xc2,0xf4,0xe6,0x18,0x1c,0x44,0xaf,0xca}, + {0xcc,0xdd,0xef,0x03,0x3e,0xa9,0xf1,0xe0,0x97,0x91,0xf8,0xe2,0xbe,0xe0,0xdf,0xf3,0x41,0x03,0xb3,0x5a}, + {0xcc,0xdd,0xef,0x04,0x2e,0x6a,0x8d,0xb9,0x72,0xe3,0xce,0x9f,0xf4,0x28,0x45,0xe7,0xbc,0x80,0xa9,0xc7}, + {0xcc,0xdd,0xef,0x05,0x1a,0xd5,0x40,0x78,0xfb,0x16,0x37,0xfc,0x7a,0x1d,0xce,0xb4,0x77,0x10,0xb2,0xa0}, + {0xcc,0xdd,0xef,0x06,0x13,0x2f,0x11,0x47,0xd7,0x1b,0xb5,0x52,0x36,0x51,0x26,0xb0,0x96,0xd7,0x60,0x81}}, + {{0x76,0x54,0x32,0x11,0xe9,0xcb,0x74,0x32,0x07,0x93,0xfe,0x01,0xdd,0x27,0xdb,0xde,0x6b,0x77,0xa4,0x56}, + {0x76,0x54,0x32,0x12,0xcd,0x55,0x87,0x5c,0xc0,0x35,0x85,0x99,0x44,0x02,0xa5,0x0b,0x8c,0xe7,0x2c,0x68}, + {0x76,0x54,0x32,0x13,0xac,0xfd,0x87,0x50,0xc3,0x8f,0xcd,0x58,0xaa,0xa5,0x7e,0x7a,0x25,0x63,0x26,0xd1}, + {0x76,0x54,0x32,0x14,0xe3,0x30,0xf5,0xdd,0x27,0x2b,0x76,0x22,0x7f,0xaa,0x90,0x73,0x6a,0x48,0xdb,0x00}, + {0x76,0x54,0x32,0x15,0xfc,0x57,0x00,0x20,0x7c,0x9d,0xf6,0x30,0x6f,0xbd,0x46,0x3e,0xfb,0x8a,0x2c,0x60}, + {0x76,0x54,0x32,0x16,0xfb,0x0f,0xd3,0xdf,0x4c,0x4b,0xc3,0x05,0x9d,0x63,0x1e,0xba,0x25,0x2b,0xbe,0x35}, + {0x76,0x54,0x32,0x17,0xc6,0xfe,0xe6,0x5f,0xb1,0x35,0x8a,0xf5,0x32,0x7a,0x80,0xbd,0xb8,0x72,0xee,0xae}}}; + + byte digest[XMACC_MD5::DIGESTSIZE]; + bool pass=true, fail; + + cout << "\nXMACC/MD5 validation suite running...\n"; + + for (int k=0; k<2; k++) + { + XMACC_MD5 mac(keys[k], counters[k]); + cout << "\nKEY: "; + for (int j=0;j pbkdf; + + cout << "\nPKCS #12 PBKDF validation suite running...\n\n"; + pass = TestPBKDF(pbkdf, testSet, sizeof(testSet)/sizeof(testSet[0])) && pass; + } + + { + // from draft-ietf-smime-password-03.txt, at http://www.imc.org/draft-ietf-smime-password + PBKDF_TestTuple testSet[] = + { + {0, 5, "70617373776f7264", "1234567878563412", "D1DAA78615F287E6"}, + {0, 500, "416C6C206E2D656E746974696573206D75737420636F6D6D756E69636174652077697468206F74686572206E2d656E74697469657320766961206E2D3120656E746974656568656568656573", "1234567878563412","6A8970BF68C92CAEA84A8DF28510858607126380CC47AB2D"} + }; + + PKCS5_PBKDF2_HMAC pbkdf; + + cout << "\nPKCS #5 PBKDF2 validation suite running...\n\n"; + pass = TestPBKDF(pbkdf, testSet, sizeof(testSet)/sizeof(testSet[0])) && pass; + } + + return pass; +} diff --git a/CryptoPP/crypto/validate.h b/CryptoPP/crypto/validate.h new file mode 100644 index 0000000..6e2cdaf --- /dev/null +++ b/CryptoPP/crypto/validate.h @@ -0,0 +1,78 @@ +#ifndef CRYPTOPP_VALIDATE_H +#define CRYPTOPP_VALIDATE_H + +#include "cryptlib.h" + +bool ValidateAll(bool thorough); +bool TestSettings(); +bool TestOS_RNG(); +bool ValidateBaseCode(); + +bool ValidateCRC32(); +bool ValidateAdler32(); +bool ValidateMD2(); +bool ValidateMD4(); +bool ValidateMD5(); +bool ValidateSHA(); +bool ValidateSHA2(); +bool ValidateTiger(); +bool ValidateRIPEMD(); +bool ValidatePanama(); +bool ValidateWhirlpool(); + +bool ValidateHMAC(); +bool ValidateTTMAC(); + +bool ValidateCipherModes(); +bool ValidatePBKDF(); + +bool ValidateDES(); +bool ValidateIDEA(); +bool ValidateSAFER(); +bool ValidateRC2(); +bool ValidateARC4(); + +bool ValidateRC5(); +bool ValidateBlowfish(); +bool ValidateThreeWay(); +bool ValidateGOST(); +bool ValidateSHARK(); +bool ValidateSEAL(); +bool ValidateCAST(); +bool ValidateSquare(); +bool ValidateSKIPJACK(); +bool ValidateRC6(); +bool ValidateMARS(); +bool ValidateRijndael(); +bool ValidateTwofish(); +bool ValidateSerpent(); +bool ValidateSHACAL2(); +bool ValidateCamellia(); +bool ValidateSalsa(); +bool ValidateSosemanuk(); +bool ValidateVMAC(); + +bool ValidateBBS(); +bool ValidateDH(); +bool ValidateMQV(); +bool ValidateRSA(); +bool ValidateElGamal(); +bool ValidateDLIES(); +bool ValidateNR(); +bool ValidateDSA(bool thorough); +bool ValidateLUC(); +bool ValidateLUC_DL(); +bool ValidateLUC_DH(); +bool ValidateXTR_DH(); +bool ValidateRabin(); +bool ValidateRW(); +//bool ValidateBlumGoldwasser(); +bool ValidateECP(); +bool ValidateEC2N(); +bool ValidateECDSA(); +bool ValidateESIGN(); + +CryptoPP::RandomNumberGenerator & GlobalRNG(); +bool RunTestDataFile(const char *filename); + +#endif diff --git a/CryptoPP/crypto/vmac.cpp b/CryptoPP/crypto/vmac.cpp new file mode 100644 index 0000000..a244917 --- /dev/null +++ b/CryptoPP/crypto/vmac.cpp @@ -0,0 +1,820 @@ +// vmac.cpp - written and placed in the public domain by Wei Dai +// based on Ted Krovetz's public domain vmac.c and draft-krovetz-vmac-01.txt + +#include "pch.h" +#include "vmac.h" +#include "argnames.h" +#include "cpu.h" + +NAMESPACE_BEGIN(CryptoPP) + +#if defined(_MSC_VER) && !defined(CRYPTOPP_SLOW_WORD64) +#include +#endif + +#define VMAC_BOOL_WORD128 (defined(CRYPTOPP_WORD128_AVAILABLE) && !defined(CRYPTOPP_X64_ASM_AVAILABLE)) +#ifdef __BORLANDC__ +#define const // Turbo C++ 2006 workaround +#endif +static const word64 p64 = W64LIT(0xfffffffffffffeff); /* 2^64 - 257 prime */ +static const word64 m62 = W64LIT(0x3fffffffffffffff); /* 62-bit mask */ +static const word64 m63 = W64LIT(0x7fffffffffffffff); /* 63-bit mask */ +static const word64 m64 = W64LIT(0xffffffffffffffff); /* 64-bit mask */ +static const word64 mpoly = W64LIT(0x1fffffff1fffffff); /* Poly key mask */ +#ifdef __BORLANDC__ +#undef const +#endif +#if VMAC_BOOL_WORD128 +static const word128 m126 = (word128(m62)<<64)|m64; /* 126-bit mask */ +#endif + +void VMAC_Base::UncheckedSetKey(const byte *userKey, unsigned int keylength, const NameValuePairs ¶ms) +{ + int digestLength = params.GetIntValueWithDefault(Name::DigestSize(), DefaultDigestSize()); + if (digestLength != 8 && digestLength != 16) + throw InvalidArgument("VMAC: DigestSize must be 8 or 16"); + m_is128 = digestLength == 16; + + m_L1KeyLength = params.GetIntValueWithDefault(Name::L1KeyLength(), 128); + if (m_L1KeyLength <= 0 || m_L1KeyLength % 128 != 0) + throw InvalidArgument("VMAC: L1KeyLength must be a positive multiple of 128"); + + AllocateBlocks(); + + BlockCipher &cipher = AccessCipher(); + cipher.SetKey(userKey, keylength, params); + unsigned int blockSize = cipher.BlockSize(); + unsigned int blockSizeInWords = blockSize / sizeof(word64); + SecBlock out(blockSizeInWords); + SecByteBlock in; + in.CleanNew(blockSize); + size_t i; + + /* Fill nh key */ + in[0] = 0x80; + for (i = 0; i < m_nhKeySize()*sizeof(word64); i += blockSize) + { + cipher.ProcessBlock(in, out.BytePtr()); + ConditionalByteReverse(BIG_ENDIAN_ORDER, m_nhKey()+i/sizeof(word64), out.begin(), blockSize); + in[15]++; + } + + /* Fill poly key */ + in[0] = 0xC0; + in[15] = 0; + for (i = 0; i <= (size_t)m_is128; i++) + { + cipher.ProcessBlock(in, out.BytePtr()); + m_polyState()[i*4+2] = GetWord(true, BIG_ENDIAN_ORDER, out.BytePtr()) & mpoly; + m_polyState()[i*4+3] = GetWord(true, BIG_ENDIAN_ORDER, out.BytePtr()+8) & mpoly; + in[15]++; + } + + /* Fill ip key */ + in[0] = 0xE0; + in[15] = 0; + word64 *l3Key = m_l3Key(); + for (i = 0; i <= (size_t)m_is128; i++) + do + { + cipher.ProcessBlock(in, out.BytePtr()); + l3Key[i*2+0] = GetWord(true, BIG_ENDIAN_ORDER, out.BytePtr()); + l3Key[i*2+1] = GetWord(true, BIG_ENDIAN_ORDER, out.BytePtr()+8); + in[15]++; + } while ((l3Key[i*2+0] >= p64) || (l3Key[i*2+1] >= p64)); + + m_padCached = false; + Resynchronize(GetIVAndThrowIfInvalid(params)); +} + +void VMAC_Base::GetNextIV(RandomNumberGenerator &rng, byte *IV) +{ + SimpleKeyingInterface::GetNextIV(rng, IV); + IV[0] &= 0x7f; +} + +void VMAC_Base::Resynchronize(const byte *IV) +{ + int s = IVSize(); + if (m_is128) + { + memcpy(m_nonce(), IV, s); + AccessCipher().ProcessBlock(m_nonce(), m_pad()); + } + else + { + m_padCached = m_padCached && (m_nonce()[s-1] | 1) == (IV[s-1] | 1) && memcmp(m_nonce(), IV, s-1) == 0; + if (!m_padCached) + { + memcpy(m_nonce(), IV, s); + m_nonce()[s-1] &= 0xfe; + AccessCipher().ProcessBlock(m_nonce(), m_pad()); + m_padCached = true; + } + m_nonce()[s-1] = IV[s-1]; + } + m_isFirstBlock = true; + Restart(); +} + +void VMAC_Base::HashEndianCorrectedBlock(const word64 *data) +{ + assert(false); +} + +#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86 +#pragma warning(disable: 4731) // frame pointer register 'ebp' modified by inline assembly code +void +#ifdef __GNUC__ +__attribute__ ((noinline)) // Intel Compiler 9.1 workaround +#endif +VMAC_Base::VHASH_Update_SSE2(const word64 *data, size_t blocksRemainingInWord64, int tagPart) +{ + const word64 *nhK = m_nhKey(); + word64 *polyS = m_polyState(); + +#ifdef __GNUC__ + word32 temp; + __asm__ __volatile__ + ( + AS2( mov %%ebx, %0) + AS2( mov %1, %%ebx) + ".intel_syntax noprefix;" +#else + #if _MSC_VER < 1300 || defined(__INTEL_COMPILER) + word32 L1KeyLength = m_L1KeyLength; + char isFirstBlock = m_isFirstBlock; + AS2( mov ebx, [L1KeyLength]) + AS2( mov dl, [isFirstBlock]) + #else + AS2( mov ecx, this) + AS2( mov ebx, [ecx+m_L1KeyLength]) + AS2( mov dl, [ecx+m_isFirstBlock]) + #endif + AS2( mov eax, tagPart) + AS2( shl eax, 4) + AS2( mov edi, nhK) + AS2( add edi, eax) + AS2( add eax, eax) + AS2( add eax, polyS) + + AS2( mov esi, data) + AS2( mov ecx, blocksRemainingInWord64) +#endif + + AS2( shr ebx, 3) + AS1( push ebp) + AS2( sub esp, 12) + ASL(4) + AS2( mov ebp, ebx) + AS2( cmp ecx, ebx) + AS2( cmovl ebp, ecx) + AS2( sub ecx, ebp) + AS2( lea ebp, [edi+8*ebp]) // end of nhK + AS2( movq mm6, [esi]) + AS2( paddq mm6, [edi]) + AS2( movq mm5, [esi+8]) + AS2( paddq mm5, [edi+8]) + AS2( add esi, 16) + AS2( add edi, 16) + AS2( movq mm4, mm6) + ASS( pshufw mm2, mm6, 1, 0, 3, 2) + AS2( pmuludq mm6, mm5) + ASS( pshufw mm3, mm5, 1, 0, 3, 2) + AS2( pmuludq mm5, mm2) + AS2( pmuludq mm2, mm3) + AS2( pmuludq mm3, mm4) + AS2( pxor mm7, mm7) + AS2( movd [esp], mm6) + AS2( psrlq mm6, 32) + AS2( movd [esp+4], mm5) + AS2( psrlq mm5, 32) + AS2( cmp edi, ebp) + ASJ( je, 1, f) + ASL(0) + AS2( movq mm0, [esi]) + AS2( paddq mm0, [edi]) + AS2( movq mm1, [esi+8]) + AS2( paddq mm1, [edi+8]) + AS2( add esi, 16) + AS2( add edi, 16) + AS2( movq mm4, mm0) + AS2( paddq mm5, mm2) + ASS( pshufw mm2, mm0, 1, 0, 3, 2) + AS2( pmuludq mm0, mm1) + AS2( movd [esp+8], mm3) + AS2( psrlq mm3, 32) + AS2( paddq mm5, mm3) + ASS( pshufw mm3, mm1, 1, 0, 3, 2) + AS2( pmuludq mm1, mm2) + AS2( pmuludq mm2, mm3) + AS2( pmuludq mm3, mm4) + AS2( movd mm4, [esp]) + AS2( paddq mm7, mm4) + AS2( movd mm4, [esp+4]) + AS2( paddq mm6, mm4) + AS2( movd mm4, [esp+8]) + AS2( paddq mm6, mm4) + AS2( movd [esp], mm0) + AS2( psrlq mm0, 32) + AS2( paddq mm6, mm0) + AS2( movd [esp+4], mm1) + AS2( psrlq mm1, 32) + AS2( paddq mm5, mm1) + AS2( cmp edi, ebp) + ASJ( jne, 0, b) + ASL(1) + AS2( paddq mm5, mm2) + AS2( movd [esp+8], mm3) + AS2( psrlq mm3, 32) + AS2( paddq mm5, mm3) + AS2( movd mm4, [esp]) + AS2( paddq mm7, mm4) + AS2( movd mm4, [esp+4]) + AS2( paddq mm6, mm4) + AS2( movd mm4, [esp+8]) + AS2( paddq mm6, mm4) + AS2( lea ebp, [8*ebx]) + AS2( sub edi, ebp) // reset edi to start of nhK + + AS2( movd [esp], mm7) + AS2( psrlq mm7, 32) + AS2( paddq mm6, mm7) + AS2( movd [esp+4], mm6) + AS2( psrlq mm6, 32) + AS2( paddq mm5, mm6) + AS2( psllq mm5, 2) + AS2( psrlq mm5, 2) + +#define a0 [eax+2*4] +#define a1 [eax+3*4] +#define a2 [eax+0*4] +#define a3 [eax+1*4] +#define k0 [eax+2*8+2*4] +#define k1 [eax+2*8+3*4] +#define k2 [eax+2*8+0*4] +#define k3 [eax+2*8+1*4] + AS2( test dl, dl) + ASJ( jz, 2, f) + AS2( movd mm1, k0) + AS2( movd mm0, [esp]) + AS2( paddq mm0, mm1) + AS2( movd a0, mm0) + AS2( psrlq mm0, 32) + AS2( movd mm1, k1) + AS2( movd mm2, [esp+4]) + AS2( paddq mm1, mm2) + AS2( paddq mm0, mm1) + AS2( movd a1, mm0) + AS2( psrlq mm0, 32) + AS2( paddq mm5, k2) + AS2( paddq mm0, mm5) + AS2( movq a2, mm0) + AS2( xor edx, edx) + ASJ( jmp, 3, f) + ASL(2) + AS2( movd mm0, a3) + AS2( movq mm4, mm0) + AS2( pmuludq mm0, k3) // a3*k3 + AS2( movd mm1, a0) + AS2( pmuludq mm1, k2) // a0*k2 + AS2( movd mm2, a1) + AS2( movd mm6, k1) + AS2( pmuludq mm2, mm6) // a1*k1 + AS2( movd mm3, a2) + AS2( psllq mm0, 1) + AS2( paddq mm0, mm5) + AS2( movq mm5, mm3) + AS2( movd mm7, k0) + AS2( pmuludq mm3, mm7) // a2*k0 + AS2( pmuludq mm4, mm7) // a3*k0 + AS2( pmuludq mm5, mm6) // a2*k1 + AS2( paddq mm0, mm1) + AS2( movd mm1, a1) + AS2( paddq mm4, mm5) + AS2( movq mm5, mm1) + AS2( pmuludq mm1, k2) // a1*k2 + AS2( paddq mm0, mm2) + AS2( movd mm2, a0) + AS2( paddq mm0, mm3) + AS2( movq mm3, mm2) + AS2( pmuludq mm2, k3) // a0*k3 + AS2( pmuludq mm3, mm7) // a0*k0 + AS2( movd [esp+8], mm0) + AS2( psrlq mm0, 32) + AS2( pmuludq mm7, mm5) // a1*k0 + AS2( pmuludq mm5, k3) // a1*k3 + AS2( paddq mm0, mm1) + AS2( movd mm1, a2) + AS2( pmuludq mm1, k2) // a2*k2 + AS2( paddq mm0, mm2) + AS2( paddq mm0, mm4) + AS2( movq mm4, mm0) + AS2( movd mm2, a3) + AS2( pmuludq mm2, mm6) // a3*k1 + AS2( pmuludq mm6, a0) // a0*k1 + AS2( psrlq mm0, 31) + AS2( paddq mm0, mm3) + AS2( movd mm3, [esp]) + AS2( paddq mm0, mm3) + AS2( movd mm3, a2) + AS2( pmuludq mm3, k3) // a2*k3 + AS2( paddq mm5, mm1) + AS2( movd mm1, a3) + AS2( pmuludq mm1, k2) // a3*k2 + AS2( paddq mm5, mm2) + AS2( movd mm2, [esp+4]) + AS2( psllq mm5, 1) + AS2( paddq mm0, mm5) + AS2( psllq mm4, 33) + AS2( movd a0, mm0) + AS2( psrlq mm0, 32) + AS2( paddq mm6, mm7) + AS2( movd mm7, [esp+8]) + AS2( paddq mm0, mm6) + AS2( paddq mm0, mm2) + AS2( paddq mm3, mm1) + AS2( psllq mm3, 1) + AS2( paddq mm0, mm3) + AS2( psrlq mm4, 1) + AS2( movd a1, mm0) + AS2( psrlq mm0, 32) + AS2( por mm4, mm7) + AS2( paddq mm0, mm4) + AS2( movq a2, mm0) +#undef a0 +#undef a1 +#undef a2 +#undef a3 +#undef k0 +#undef k1 +#undef k2 +#undef k3 + + ASL(3) + AS2( test ecx, ecx) + ASJ( jnz, 4, b) + + AS2( add esp, 12) + AS1( pop ebp) + AS1( emms) +#ifdef __GNUC__ + ".att_syntax prefix;" + AS2( mov %0, %%ebx) + : "=m" (temp) + : "m" (m_L1KeyLength), "c" (blocksRemainingInWord64), "S" (data), "D" (nhK+tagPart*2), "d" (m_isFirstBlock), "a" (polyS+tagPart*4) + : "memory", "cc" + ); +#endif +} +#endif + +#if VMAC_BOOL_WORD128 + #define DeclareNH(a) word128 a=0 + #define MUL64(rh,rl,i1,i2) {word128 p = word128(i1)*(i2); rh = word64(p>>64); rl = word64(p);} + #define AccumulateNH(a, b, c) a += word128(b)*(c) + #define Multiply128(r, i1, i2) r = word128(word64(i1)) * word64(i2) +#else + #if _MSC_VER >= 1400 && !defined(__INTEL_COMPILER) + #define MUL32(a, b) __emulu(word32(a), word32(b)) + #else + #define MUL32(a, b) ((word64)((word32)(a)) * (word32)(b)) + #endif + #if defined(CRYPTOPP_X64_ASM_AVAILABLE) + #define DeclareNH(a) word64 a##0=0, a##1=0 + #define MUL64(rh,rl,i1,i2) asm ("mulq %3" : "=a"(rl), "=d"(rh) : "a"(i1), "g"(i2) : "cc"); + #define AccumulateNH(a, b, c) asm ("mulq %3; addq %%rax, %0; adcq %%rdx, %1" : "+r"(a##0), "+r"(a##1) : "a"(b), "g"(c) : "%rdx", "cc"); + #define ADD128(rh,rl,ih,il) asm ("addq %3, %1; adcq %2, %0" : "+r"(rh),"+r"(rl) : "r"(ih),"r"(il) : "cc"); + #elif defined(_MSC_VER) && !defined(CRYPTOPP_SLOW_WORD64) + #define DeclareNH(a) word64 a##0=0, a##1=0 + #define MUL64(rh,rl,i1,i2) (rl) = _umul128(i1,i2,&(rh)); + #define AccumulateNH(a, b, c) {\ + word64 ph, pl;\ + pl = _umul128(b,c,&ph);\ + a##0 += pl;\ + a##1 += ph + (a##0 < pl);} + #else + #define VMAC_BOOL_32BIT 1 + #define DeclareNH(a) word64 a##0=0, a##1=0, a##2=0 + #define MUL64(rh,rl,i1,i2) \ + { word64 _i1 = (i1), _i2 = (i2); \ + word64 m1= MUL32(_i1,_i2>>32); \ + word64 m2= MUL32(_i1>>32,_i2); \ + rh = MUL32(_i1>>32,_i2>>32); \ + rl = MUL32(_i1,_i2); \ + ADD128(rh,rl,(m1 >> 32),(m1 << 32)); \ + ADD128(rh,rl,(m2 >> 32),(m2 << 32)); \ + } + #define AccumulateNH(a, b, c) {\ + word64 p = MUL32(b, c);\ + a##1 += word32((p)>>32);\ + a##0 += word32(p);\ + p = MUL32((b)>>32, c);\ + a##2 += word32((p)>>32);\ + a##1 += word32(p);\ + p = MUL32((b)>>32, (c)>>32);\ + a##2 += p;\ + p = MUL32(b, (c)>>32);\ + a##1 += word32(p);\ + a##2 += word32(p>>32);} + #endif +#endif +#ifndef VMAC_BOOL_32BIT + #define VMAC_BOOL_32BIT 0 +#endif +#ifndef ADD128 + #define ADD128(rh,rl,ih,il) \ + { word64 _il = (il); \ + (rl) += (_il); \ + (rh) += (ih) + ((rl) < (_il)); \ + } +#endif + +#if !(defined(_MSC_VER) && _MSC_VER < 1300) +template +#endif +void VMAC_Base::VHASH_Update_Template(const word64 *data, size_t blocksRemainingInWord64) +{ + #define INNER_LOOP_ITERATION(j) {\ + word64 d0 = ConditionalByteReverse(LITTLE_ENDIAN_ORDER, data[i+2*j+0]);\ + word64 d1 = ConditionalByteReverse(LITTLE_ENDIAN_ORDER, data[i+2*j+1]);\ + AccumulateNH(nhA, d0+nhK[i+2*j+0], d1+nhK[i+2*j+1]);\ + if (T_128BitTag)\ + AccumulateNH(nhB, d0+nhK[i+2*j+2], d1+nhK[i+2*j+3]);\ + } + +#if (defined(_MSC_VER) && _MSC_VER < 1300) + bool T_128BitTag = m_is128; +#endif + size_t L1KeyLengthInWord64 = m_L1KeyLength / 8; + size_t innerLoopEnd = L1KeyLengthInWord64; + const word64 *nhK = m_nhKey(); + word64 *polyS = m_polyState(); + bool isFirstBlock = true; + size_t i; + + #if !VMAC_BOOL_32BIT + #if VMAC_BOOL_WORD128 + word128 a1, a2; + #else + word64 ah1, al1, ah2, al2; + #endif + word64 kh1, kl1, kh2, kl2; + kh1=(polyS+0*4+2)[0]; kl1=(polyS+0*4+2)[1]; + if (T_128BitTag) + { + kh2=(polyS+1*4+2)[0]; kl2=(polyS+1*4+2)[1]; + } + #endif + + do + { + DeclareNH(nhA); + DeclareNH(nhB); + + if (blocksRemainingInWord64 < L1KeyLengthInWord64) + { + if (blocksRemainingInWord64 % 8) + { + innerLoopEnd = blocksRemainingInWord64 % 8; + for (i=0; i> 32); + nh1[0] = word32(nhA1); + nh2[0] = (nhA2 + (nhA1 >> 32)) & m62; + + if (T_128BitTag) + { + nh0[1] = word32(nhB0); + nhB1 += (nhB0 >> 32); + nh1[1] = word32(nhB1); + nh2[1] = (nhB2 + (nhB1 >> 32)) & m62; + } + + #define a0 (((word32 *)(polyS+i*4))[2+NativeByteOrder::ToEnum()]) + #define a1 (*(((word32 *)(polyS+i*4))+3-NativeByteOrder::ToEnum())) // workaround for GCC 3.2 + #define a2 (((word32 *)(polyS+i*4))[0+NativeByteOrder::ToEnum()]) + #define a3 (*(((word32 *)(polyS+i*4))+1-NativeByteOrder::ToEnum())) + #define aHi ((polyS+i*4)[0]) + #define k0 (((word32 *)(polyS+i*4+2))[2+NativeByteOrder::ToEnum()]) + #define k1 (*(((word32 *)(polyS+i*4+2))+3-NativeByteOrder::ToEnum())) + #define k2 (((word32 *)(polyS+i*4+2))[0+NativeByteOrder::ToEnum()]) + #define k3 (*(((word32 *)(polyS+i*4+2))+1-NativeByteOrder::ToEnum())) + #define kHi ((polyS+i*4+2)[0]) + + if (isFirstBlock) + { + isFirstBlock = false; + if (m_isFirstBlock) + { + m_isFirstBlock = false; + for (i=0; i<=(size_t)T_128BitTag; i++) + { + word64 t = (word64)nh0[i] + k0; + a0 = (word32)t; + t = (t >> 32) + nh1[i] + k1; + a1 = (word32)t; + aHi = (t >> 32) + nh2[i] + kHi; + } + continue; + } + } + for (i=0; i<=(size_t)T_128BitTag; i++) + { + word64 p, t; + word32 t2; + + p = MUL32(a3, 2*k3); + p += nh2[i]; + p += MUL32(a0, k2); + p += MUL32(a1, k1); + p += MUL32(a2, k0); + t2 = (word32)p; + p >>= 32; + p += MUL32(a0, k3); + p += MUL32(a1, k2); + p += MUL32(a2, k1); + p += MUL32(a3, k0); + t = (word64(word32(p) & 0x7fffffff) << 32) | t2; + p >>= 31; + p += nh0[i]; + p += MUL32(a0, k0); + p += MUL32(a1, 2*k3); + p += MUL32(a2, 2*k2); + p += MUL32(a3, 2*k1); + t2 = (word32)p; + p >>= 32; + p += nh1[i]; + p += MUL32(a0, k1); + p += MUL32(a1, k0); + p += MUL32(a2, 2*k3); + p += MUL32(a3, 2*k2); + a0 = t2; + a1 = (word32)p; + aHi = (p >> 32) + t; + } + + #undef a0 + #undef a1 + #undef a2 + #undef a3 + #undef aHi + #undef k0 + #undef k1 + #undef k2 + #undef k3 + #undef kHi + #else // #if VMAC_BOOL_32BIT + if (isFirstBlock) + { + isFirstBlock = false; + if (m_isFirstBlock) + { + m_isFirstBlock = false; + #if VMAC_BOOL_WORD128 + #define first_poly_step(a, kh, kl, m) a = (m & m126) + ((word128(kh) << 64) | kl) + + first_poly_step(a1, kh1, kl1, nhA); + if (T_128BitTag) + first_poly_step(a2, kh2, kl2, nhB); + #else + #define first_poly_step(ah, al, kh, kl, mh, ml) {\ + mh &= m62;\ + ADD128(mh, ml, kh, kl); \ + ah = mh; al = ml;} + + first_poly_step(ah1, al1, kh1, kl1, nhA1, nhA0); + if (T_128BitTag) + first_poly_step(ah2, al2, kh2, kl2, nhB1, nhB0); + #endif + continue; + } + else + { + #if VMAC_BOOL_WORD128 + a1 = (word128((polyS+0*4)[0]) << 64) | (polyS+0*4)[1]; + #else + ah1=(polyS+0*4)[0]; al1=(polyS+0*4)[1]; + #endif + if (T_128BitTag) + { + #if VMAC_BOOL_WORD128 + a2 = (word128((polyS+1*4)[0]) << 64) | (polyS+1*4)[1]; + #else + ah2=(polyS+1*4)[0]; al2=(polyS+1*4)[1]; + #endif + } + } + } + + #if VMAC_BOOL_WORD128 + #define poly_step(a, kh, kl, m) \ + { word128 t1, t2, t3, t4;\ + Multiply128(t2, a>>64, kl);\ + Multiply128(t3, a, kh);\ + Multiply128(t1, a, kl);\ + Multiply128(t4, a>>64, 2*kh);\ + t2 += t3;\ + t4 += t1;\ + t2 += t4>>64;\ + a = (word128(word64(t2)&m63) << 64) | word64(t4);\ + t2 *= 2;\ + a += m & m126;\ + a += t2>>64;} + + poly_step(a1, kh1, kl1, nhA); + if (T_128BitTag) + poly_step(a2, kh2, kl2, nhB); + #else + #define poly_step(ah, al, kh, kl, mh, ml) \ + { word64 t1h, t1l, t2h, t2l, t3h, t3l, z=0; \ + /* compute ab*cd, put bd into result registers */ \ + MUL64(t2h,t2l,ah,kl); \ + MUL64(t3h,t3l,al,kh); \ + MUL64(t1h,t1l,ah,2*kh); \ + MUL64(ah,al,al,kl); \ + /* add together ad + bc */ \ + ADD128(t2h,t2l,t3h,t3l); \ + /* add 2 * ac to result */ \ + ADD128(ah,al,t1h,t1l); \ + /* now (ah,al), (t2l,2*t2h) need summing */ \ + /* first add the high registers, carrying into t2h */ \ + ADD128(t2h,ah,z,t2l); \ + /* double t2h and add top bit of ah */ \ + t2h += t2h + (ah >> 63); \ + ah &= m63; \ + /* now add the low registers */ \ + mh &= m62; \ + ADD128(ah,al,mh,ml); \ + ADD128(ah,al,z,t2h); \ + } + + poly_step(ah1, al1, kh1, kl1, nhA1, nhA0); + if (T_128BitTag) + poly_step(ah2, al2, kh2, kl2, nhB1, nhB0); + #endif + #endif // #if VMAC_BOOL_32BIT + } while (blocksRemainingInWord64); + + #if VMAC_BOOL_WORD128 + (polyS+0*4)[0]=word64(a1>>64); (polyS+0*4)[1]=word64(a1); + if (T_128BitTag) + { + (polyS+1*4)[0]=word64(a2>>64); (polyS+1*4)[1]=word64(a2); + } + #elif !VMAC_BOOL_32BIT + (polyS+0*4)[0]=ah1; (polyS+0*4)[1]=al1; + if (T_128BitTag) + { + (polyS+1*4)[0]=ah2; (polyS+1*4)[1]=al2; + } + #endif +} + +inline void VMAC_Base::VHASH_Update(const word64 *data, size_t blocksRemainingInWord64) +{ +#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE && CRYPTOPP_BOOL_X86 + if (HasSSE2()) + { + VHASH_Update_SSE2(data, blocksRemainingInWord64, 0); + if (m_is128) + VHASH_Update_SSE2(data, blocksRemainingInWord64, 1); + m_isFirstBlock = false; + } + else +#endif + { +#if defined(_MSC_VER) && _MSC_VER < 1300 + VHASH_Update_Template(data, blocksRemainingInWord64); +#else + if (m_is128) + VHASH_Update_Template(data, blocksRemainingInWord64); + else + VHASH_Update_Template(data, blocksRemainingInWord64); +#endif + } +} + +size_t VMAC_Base::HashMultipleBlocks(const word64 *data, size_t length) +{ + size_t remaining = ModPowerOf2(length, m_L1KeyLength); + VHASH_Update(data, (length-remaining)/8); + return remaining; +} + +static word64 L3Hash(const word64 *input, const word64 *l3Key, size_t len) +{ + word64 rh, rl, t, z=0; + word64 p1 = input[0], p2 = input[1]; + word64 k1 = l3Key[0], k2 = l3Key[1]; + + /* fully reduce (p1,p2)+(len,0) mod p127 */ + t = p1 >> 63; + p1 &= m63; + ADD128(p1, p2, len, t); + /* At this point, (p1,p2) is at most 2^127+(len<<64) */ + t = (p1 > m63) + ((p1 == m63) & (p2 == m64)); + ADD128(p1, p2, z, t); + p1 &= m63; + + /* compute (p1,p2)/(2^64-2^32) and (p1,p2)%(2^64-2^32) */ + t = p1 + (p2 >> 32); + t += (t >> 32); + t += (word32)t > 0xfffffffeU; + p1 += (t >> 32); + p2 += (p1 << 32); + + /* compute (p1+k1)%p64 and (p2+k2)%p64 */ + p1 += k1; + p1 += (0 - (p1 < k1)) & 257; + p2 += k2; + p2 += (0 - (p2 < k2)) & 257; + + /* compute (p1+k1)*(p2+k2)%p64 */ + MUL64(rh, rl, p1, p2); + t = rh >> 56; + ADD128(t, rl, z, rh); + rh <<= 8; + ADD128(t, rl, z, rh); + t += t << 8; + rl += t; + rl += (0 - (rl < t)) & 257; + rl += (0 - (rl > p64-1)) & 257; + return rl; +} + +void VMAC_Base::TruncatedFinal(byte *mac, size_t size) +{ + size_t len = ModPowerOf2(GetBitCountLo()/8, m_L1KeyLength); + + if (len) + { + memset(m_data()+len, 0, (0-len)%16); + VHASH_Update(DataBuf(), ((len+15)/16)*2); + len *= 8; // convert to bits + } + else if (m_isFirstBlock) + { + // special case for empty string + m_polyState()[0] = m_polyState()[2]; + m_polyState()[1] = m_polyState()[3]; + if (m_is128) + { + m_polyState()[4] = m_polyState()[6]; + m_polyState()[5] = m_polyState()[7]; + } + } + + if (m_is128) + { + word64 t[2]; + t[0] = L3Hash(m_polyState(), m_l3Key(), len) + GetWord(true, BIG_ENDIAN_ORDER, m_pad()); + t[1] = L3Hash(m_polyState()+4, m_l3Key()+2, len) + GetWord(true, BIG_ENDIAN_ORDER, m_pad()+8); + if (size == 16) + { + PutWord(false, BIG_ENDIAN_ORDER, mac, t[0]); + PutWord(false, BIG_ENDIAN_ORDER, mac+8, t[1]); + } + else + { + t[0] = ConditionalByteReverse(BIG_ENDIAN_ORDER, t[0]); + t[1] = ConditionalByteReverse(BIG_ENDIAN_ORDER, t[1]); + memcpy(mac, t, size); + } + } + else + { + word64 t = L3Hash(m_polyState(), m_l3Key(), len); + t += GetWord(true, BIG_ENDIAN_ORDER, m_pad() + (m_nonce()[IVSize()-1]&1) * 8); + if (size == 8) + PutWord(false, BIG_ENDIAN_ORDER, mac, t); + else + { + t = ConditionalByteReverse(BIG_ENDIAN_ORDER, t); + memcpy(mac, &t, size); + } + } +} + +NAMESPACE_END diff --git a/CryptoPP/crypto/vmac.h b/CryptoPP/crypto/vmac.h new file mode 100644 index 0000000..a2c85ac --- /dev/null +++ b/CryptoPP/crypto/vmac.h @@ -0,0 +1,77 @@ +#ifndef CRYPTOPP_VMAC_H +#define CRYPTOPP_VMAC_H + +#include "iterhash.h" +#include "seckey.h" + +NAMESPACE_BEGIN(CryptoPP) + +#define CRYPTOPP_BLOCK_1(n, t, s) t* m_##n() {return (t *)(m_aggregate+0);} size_t SS1() {return sizeof(t)*(s);} size_t m_##n##Size() {return (s);} +#define CRYPTOPP_BLOCK_2(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS1());} size_t SS2() {return SS1()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);} +#define CRYPTOPP_BLOCK_3(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS2());} size_t SS3() {return SS2()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);} +#define CRYPTOPP_BLOCK_4(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS3());} size_t SS4() {return SS3()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);} +#define CRYPTOPP_BLOCK_5(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS4());} size_t SS5() {return SS4()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);} +#define CRYPTOPP_BLOCK_6(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS5());} size_t SS6() {return SS5()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);} +#define CRYPTOPP_BLOCK_7(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS6());} size_t SS7() {return SS6()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);} +#define CRYPTOPP_BLOCK_8(n, t, s) t* m_##n() {return (t *)(m_aggregate+SS7());} size_t SS8() {return SS7()+sizeof(t)*(s);} size_t m_##n##Size() {return (s);} +#define CRYPTOPP_BLOCKS_END(i) size_t SST() {return SS##i();} void AllocateBlocks() {m_aggregate.New(SST());} AlignedSecByteBlock m_aggregate; + +/// . +class VMAC_Base : public IteratedHashBase +{ +public: + std::string AlgorithmName() const {return std::string("VMAC(") + GetCipher().AlgorithmName() + ")-" + IntToString(DigestSize()*8);} + unsigned int IVSize() const {return GetCipher().BlockSize();} + void Resynchronize(const byte *IV); + void GetNextIV(RandomNumberGenerator &rng, byte *IV); + unsigned int DigestSize() const {return m_is128 ? 16 : 8;}; + void UncheckedSetKey(const byte *userKey, unsigned int keylength, const NameValuePairs ¶ms); + void TruncatedFinal(byte *mac, size_t size); + unsigned int BlockSize() const {return m_L1KeyLength;} + ByteOrder GetByteOrder() const {return LITTLE_ENDIAN_ORDER;} + +protected: + virtual BlockCipher & AccessCipher() =0; + virtual int DefaultDigestSize() const =0; + const BlockCipher & GetCipher() const {return const_cast(this)->AccessCipher();} + void HashEndianCorrectedBlock(const word64 *data); + size_t HashMultipleBlocks(const word64 *input, size_t length); + void Init() {} + word64* StateBuf() {return NULL;} + word64* DataBuf() {return (word64 *)m_data();} + + void VHASH_Update_SSE2(const word64 *data, size_t blocksRemainingInWord64, int tagPart); +#if !(defined(_MSC_VER) && _MSC_VER < 1300) // can't use function template here with VC6 + template +#endif + void VHASH_Update_Template(const word64 *data, size_t blockRemainingInWord128); + void VHASH_Update(const word64 *data, size_t blocksRemainingInWord128); + + CRYPTOPP_BLOCK_1(polyState, word64, 4*(m_is128+1)) + CRYPTOPP_BLOCK_2(nhKey, word64, m_L1KeyLength/sizeof(word64) + 2*m_is128) + CRYPTOPP_BLOCK_3(data, byte, m_L1KeyLength) + CRYPTOPP_BLOCK_4(l3Key, word64, 2*(m_is128+1)) + CRYPTOPP_BLOCK_5(nonce, byte, IVSize()) + CRYPTOPP_BLOCK_6(pad, byte, IVSize()) + CRYPTOPP_BLOCKS_END(6) + + bool m_is128, m_padCached, m_isFirstBlock; + int m_L1KeyLength; +}; + +/// VMAC +template +class VMAC : public SimpleKeyingInterfaceImpl > +{ +public: + static std::string StaticAlgorithmName() {return std::string("VMAC(") + T_BlockCipher::StaticAlgorithmName() + ")-" + IntToString(T_DigestBitSize);} + +private: + BlockCipher & AccessCipher() {return m_cipher;} + int DefaultDigestSize() const {return T_DigestBitSize/8;} + typename T_BlockCipher::Encryption m_cipher; +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/wait.cpp b/CryptoPP/crypto/wait.cpp new file mode 100644 index 0000000..e4bae04 --- /dev/null +++ b/CryptoPP/crypto/wait.cpp @@ -0,0 +1,397 @@ +// wait.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "wait.h" +#include "misc.h" + +#ifdef SOCKETS_AVAILABLE + +#ifdef USE_BERKELEY_STYLE_SOCKETS +#include +#include +#include +#include +#endif + +NAMESPACE_BEGIN(CryptoPP) + +unsigned int WaitObjectContainer::MaxWaitObjects() +{ +#ifdef USE_WINDOWS_STYLE_SOCKETS + return MAXIMUM_WAIT_OBJECTS * (MAXIMUM_WAIT_OBJECTS-1); +#else + return FD_SETSIZE; +#endif +} + +WaitObjectContainer::WaitObjectContainer(WaitObjectsTracer* tracer) + : m_tracer(tracer), m_eventTimer(Timer::MILLISECONDS) + , m_sameResultCount(0), m_noWaitTimer(Timer::MILLISECONDS) +{ + Clear(); + m_eventTimer.StartTimer(); +} + +void WaitObjectContainer::Clear() +{ +#ifdef USE_WINDOWS_STYLE_SOCKETS + m_handles.clear(); +#else + m_maxFd = 0; + FD_ZERO(&m_readfds); + FD_ZERO(&m_writefds); +#endif + m_noWait = false; + m_firstEventTime = 0; +} + +inline void WaitObjectContainer::SetLastResult(LastResultType result) +{ + if (result == m_lastResult) + m_sameResultCount++; + else + { + m_lastResult = result; + m_sameResultCount = 0; + } +} + +void WaitObjectContainer::DetectNoWait(LastResultType result, CallStack const& callStack) +{ + if (result == m_lastResult && m_noWaitTimer.ElapsedTime() > 1000) + { + if (m_sameResultCount > m_noWaitTimer.ElapsedTime()) + { + if (m_tracer) + { + std::string desc = "No wait loop detected - m_lastResult: "; + desc.append(IntToString(m_lastResult)).append(", call stack:"); + for (CallStack const* cs = &callStack; cs; cs = cs->Prev()) + desc.append("\n- ").append(cs->Format()); + m_tracer->TraceNoWaitLoop(desc); + } + try { throw 0; } catch (...) {} // help debugger break + } + + m_noWaitTimer.StartTimer(); + m_sameResultCount = 0; + } +} + +void WaitObjectContainer::SetNoWait(CallStack const& callStack) +{ + DetectNoWait(LASTRESULT_NOWAIT, CallStack("WaitObjectContainer::SetNoWait()", &callStack)); + m_noWait = true; +} + +void WaitObjectContainer::ScheduleEvent(double milliseconds, CallStack const& callStack) +{ + if (milliseconds <= 3) + DetectNoWait(LASTRESULT_SCHEDULED, CallStack("WaitObjectContainer::ScheduleEvent()", &callStack)); + double thisEventTime = m_eventTimer.ElapsedTimeAsDouble() + milliseconds; + if (!m_firstEventTime || thisEventTime < m_firstEventTime) + m_firstEventTime = thisEventTime; +} + +#ifdef USE_WINDOWS_STYLE_SOCKETS + +struct WaitingThreadData +{ + bool waitingToWait, terminate; + HANDLE startWaiting, stopWaiting; + const HANDLE *waitHandles; + unsigned int count; + HANDLE threadHandle; + DWORD threadId; + DWORD* error; +}; + +WaitObjectContainer::~WaitObjectContainer() +{ + try // don't let exceptions escape destructor + { + if (!m_threads.empty()) + { + HANDLE threadHandles[MAXIMUM_WAIT_OBJECTS]; + unsigned int i; + for (i=0; i pThread((WaitingThreadData *)lParam); + WaitingThreadData &thread = *pThread; + std::vector handles; + + while (true) + { + thread.waitingToWait = true; + ::WaitForSingleObject(thread.startWaiting, INFINITE); + thread.waitingToWait = false; + + if (thread.terminate) + break; + if (!thread.count) + continue; + + handles.resize(thread.count + 1); + handles[0] = thread.stopWaiting; + std::copy(thread.waitHandles, thread.waitHandles+thread.count, handles.begin()+1); + + DWORD result = ::WaitForMultipleObjects((DWORD)handles.size(), &handles[0], FALSE, INFINITE); + + if (result == WAIT_OBJECT_0) + continue; // another thread finished waiting first, so do nothing + SetEvent(thread.stopWaiting); + if (!(result > WAIT_OBJECT_0 && result < WAIT_OBJECT_0 + handles.size())) + { + assert(!"error in WaitingThread"); // break here so we can see which thread has an error + *thread.error = ::GetLastError(); + } + } + + return S_OK; // return a value here to avoid compiler warning +} + +void WaitObjectContainer::CreateThreads(unsigned int count) +{ + size_t currentCount = m_threads.size(); + if (currentCount == 0) + { + m_startWaiting = ::CreateEvent(NULL, TRUE, FALSE, NULL); + m_stopWaiting = ::CreateEvent(NULL, TRUE, FALSE, NULL); + } + + if (currentCount < count) + { + m_threads.resize(count); + for (size_t i=currentCount; i MAXIMUM_WAIT_OBJECTS) + { + // too many wait objects for a single WaitForMultipleObjects call, so use multiple threads + static const unsigned int WAIT_OBJECTS_PER_THREAD = MAXIMUM_WAIT_OBJECTS-1; + unsigned int nThreads = (unsigned int)((m_handles.size() + WAIT_OBJECTS_PER_THREAD - 1) / WAIT_OBJECTS_PER_THREAD); + if (nThreads > MAXIMUM_WAIT_OBJECTS) // still too many wait objects, maybe implement recursive threading later? + throw Err("WaitObjectContainer: number of wait objects exceeds limit"); + CreateThreads(nThreads); + DWORD error = S_OK; + + for (unsigned int i=0; i 0) + { + unsigned long timeAfterWait = t.ElapsedTime(); + OutputDebugString(("Handles " + IntToString(m_handles.size()) + ", Woke up by " + IntToString(result-WAIT_OBJECT_0) + ", Busied for " + IntToString(timeBeforeWait-lastTime) + " us, Waited for " + IntToString(timeAfterWait-timeBeforeWait) + " us, max " + IntToString(milliseconds) + "ms\n").c_str()); + lastTime = timeAfterWait; + } +#endif + if (result >= WAIT_OBJECT_0 && result < WAIT_OBJECT_0 + m_handles.size()) + { + if (result == m_lastResult) + m_sameResultCount++; + else + { + m_lastResult = result; + m_sameResultCount = 0; + } + return true; + } + else if (result == WAIT_TIMEOUT) + { + SetLastResult(timeoutIsScheduledEvent ? LASTRESULT_SCHEDULED : LASTRESULT_TIMEOUT); + return timeoutIsScheduledEvent; + } + else + throw Err("WaitObjectContainer: WaitForMultipleObjects failed with error " + IntToString(::GetLastError())); + } +} + +#else // #ifdef USE_WINDOWS_STYLE_SOCKETS + +void WaitObjectContainer::AddReadFd(int fd, CallStack const& callStack) // TODO: do something with callStack +{ + FD_SET(fd, &m_readfds); + m_maxFd = STDMAX(m_maxFd, fd); +} + +void WaitObjectContainer::AddWriteFd(int fd, CallStack const& callStack) // TODO: do something with callStack +{ + FD_SET(fd, &m_writefds); + m_maxFd = STDMAX(m_maxFd, fd); +} + +bool WaitObjectContainer::Wait(unsigned long milliseconds) +{ + if (m_noWait || (!m_maxFd && !m_firstEventTime)) + return true; + + bool timeoutIsScheduledEvent = false; + + if (m_firstEventTime) + { + double timeToFirstEvent = SaturatingSubtract(m_firstEventTime, m_eventTimer.ElapsedTimeAsDouble()); + if (timeToFirstEvent <= milliseconds) + { + milliseconds = (unsigned long)timeToFirstEvent; + timeoutIsScheduledEvent = true; + } + } + + timeval tv, *timeout; + + if (milliseconds == INFINITE_TIME) + timeout = NULL; + else + { + tv.tv_sec = milliseconds / 1000; + tv.tv_usec = (milliseconds % 1000) * 1000; + timeout = &tv; + } + + int result = select(m_maxFd+1, &m_readfds, &m_writefds, NULL, timeout); + + if (result > 0) + return true; + else if (result == 0) + return timeoutIsScheduledEvent; + else + throw Err("WaitObjectContainer: select failed with error " + errno); +} + +#endif + +// ******************************************************** + +std::string CallStack::Format() const +{ + return m_info; +} + +std::string CallStackWithNr::Format() const +{ + return std::string(m_info) + " / nr: " + IntToString(m_nr); +} + +std::string CallStackWithStr::Format() const +{ + return std::string(m_info) + " / " + std::string(m_z); +} + +bool Waitable::Wait(unsigned long milliseconds, CallStack const& callStack) +{ + WaitObjectContainer container; + GetWaitObjects(container, callStack); // reduce clutter by not adding this func to stack + return container.Wait(milliseconds); +} + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/wait.h b/CryptoPP/crypto/wait.h new file mode 100644 index 0000000..c01b745 --- /dev/null +++ b/CryptoPP/crypto/wait.h @@ -0,0 +1,208 @@ +#ifndef CRYPTOPP_WAIT_H +#define CRYPTOPP_WAIT_H + +#include "config.h" + +#ifdef SOCKETS_AVAILABLE + +#include "misc.h" +#include "cryptlib.h" +#include + +#ifdef USE_WINDOWS_STYLE_SOCKETS +#include +#else +#include +#endif + +#include "hrtimer.h" + +NAMESPACE_BEGIN(CryptoPP) + +class Tracer +{ +public: + Tracer(unsigned int level) : m_level(level) {} + virtual ~Tracer() {} + +protected: + //! Override this in your most-derived tracer to do the actual tracing. + virtual void Trace(unsigned int n, std::string const& s) = 0; + + /*! By default, tracers will decide which trace messages to trace according to a trace level + mechanism. If your most-derived tracer uses a different mechanism, override this to + return false. If this method returns false, the default TraceXxxx(void) methods will all + return 0 and must be overridden explicitly by your tracer for trace messages you want. */ + virtual bool UsingDefaults() const { return true; } + +protected: + unsigned int m_level; + + void TraceIf(unsigned int n, std::string const&s) + { if (n) Trace(n, s); } + + /*! Returns nr if, according to the default log settings mechanism (using log levels), + the message should be traced. Returns 0 if the default trace level mechanism is not + in use, or if it is in use but the event should not be traced. Provided as a utility + method for easier and shorter coding of default TraceXxxx(void) implementations. */ + unsigned int Tracing(unsigned int nr, unsigned int minLevel) const + { return (UsingDefaults() && m_level >= minLevel) ? nr : 0; } +}; + +// Your Tracer-derived class should inherit as virtual public from Tracer or another +// Tracer-derived class, and should pass the log level in its constructor. You can use the +// following methods to begin and end your Tracer definition. + +// This constructor macro initializes Tracer directly even if not derived directly from it; +// this is intended, virtual base classes are always initialized by the most derived class. +#define CRYPTOPP_TRACER_CONSTRUCTOR(DERIVED) \ + public: DERIVED(unsigned int level = 0) : Tracer(level) {} + +#define CRYPTOPP_BEGIN_TRACER_CLASS_1(DERIVED, BASE1) \ + class DERIVED : virtual public BASE1 { CRYPTOPP_TRACER_CONSTRUCTOR(DERIVED) + +#define CRYPTOPP_BEGIN_TRACER_CLASS_2(DERIVED, BASE1, BASE2) \ + class DERIVED : virtual public BASE1, virtual public BASE2 { CRYPTOPP_TRACER_CONSTRUCTOR(DERIVED) + +#define CRYPTOPP_END_TRACER_CLASS }; + +// In your Tracer-derived class, you should define a globally unique event number for each +// new event defined. This can be done using the following macros. + +#define CRYPTOPP_BEGIN_TRACER_EVENTS(UNIQUENR) enum { EVENTBASE = UNIQUENR, +#define CRYPTOPP_TRACER_EVENT(EVENTNAME) EventNr_##EVENTNAME, +#define CRYPTOPP_END_TRACER_EVENTS }; + +// In your own Tracer-derived class, you must define two methods per new trace event type: +// - unsigned int TraceXxxx() const +// Your default implementation of this method should return the event number if according +// to the default trace level system the event should be traced, or 0 if it should not. +// - void TraceXxxx(string const& s) +// This method should call TraceIf(TraceXxxx(), s); to do the tracing. +// For your convenience, a macro to define these two types of methods are defined below. +// If you use this macro, you should also use the TRACER_EVENTS macros above to associate +// event names with numbers. + +#define CRYPTOPP_TRACER_EVENT_METHODS(EVENTNAME, LOGLEVEL) \ + virtual unsigned int Trace##EVENTNAME() const { return Tracing(EventNr_##EVENTNAME, LOGLEVEL); } \ + virtual void Trace##EVENTNAME(std::string const& s) { TraceIf(Trace##EVENTNAME(), s); } + + +/*! A simple unidirectional linked list with m_prev == 0 to indicate the final entry. + The aim of this implementation is to provide a very lightweight and practical + tracing mechanism with a low performance impact. Functions and methods supporting + this call-stack mechanism would take a parameter of the form "CallStack const& callStack", + and would pass this parameter to subsequent functions they call using the construct: + + SubFunc(arg1, arg2, CallStack("my func at place such and such", &callStack)); + + The advantage of this approach is that it is easy to use and should be very efficient, + involving no allocation from the heap, just a linked list of stack objects containing + pointers to static ASCIIZ strings (or possibly additional but simple data if derived). */ +class CallStack +{ +public: + CallStack(char const* i, CallStack const* p) : m_info(i), m_prev(p) {} + CallStack const* Prev() const { return m_prev; } + virtual std::string Format() const; + +protected: + char const* m_info; + CallStack const* m_prev; +}; + +/*! An extended CallStack entry type with an additional numeric parameter. */ +class CallStackWithNr : public CallStack +{ +public: + CallStackWithNr(char const* i, word32 n, CallStack const* p) : CallStack(i, p), m_nr(n) {} + std::string Format() const; + +protected: + word32 m_nr; +}; + +/*! An extended CallStack entry type with an additional string parameter. */ +class CallStackWithStr : public CallStack +{ +public: + CallStackWithStr(char const* i, char const* z, CallStack const* p) : CallStack(i, p), m_z(z) {} + std::string Format() const; + +protected: + char const* m_z; +}; + +CRYPTOPP_BEGIN_TRACER_CLASS_1(WaitObjectsTracer, Tracer) + CRYPTOPP_BEGIN_TRACER_EVENTS(0x48752841) + CRYPTOPP_TRACER_EVENT(NoWaitLoop) + CRYPTOPP_END_TRACER_EVENTS + CRYPTOPP_TRACER_EVENT_METHODS(NoWaitLoop, 1) +CRYPTOPP_END_TRACER_CLASS + +struct WaitingThreadData; + +//! container of wait objects +class WaitObjectContainer : public NotCopyable +{ +public: + //! exception thrown by WaitObjectContainer + class Err : public Exception + { + public: + Err(const std::string& s) : Exception(IO_ERROR, s) {} + }; + + static unsigned int MaxWaitObjects(); + + WaitObjectContainer(WaitObjectsTracer* tracer = 0); + + void Clear(); + void SetNoWait(CallStack const& callStack); + void ScheduleEvent(double milliseconds, CallStack const& callStack); + // returns false if timed out + bool Wait(unsigned long milliseconds); + +#ifdef USE_WINDOWS_STYLE_SOCKETS + ~WaitObjectContainer(); + void AddHandle(HANDLE handle, CallStack const& callStack); +#else + void AddReadFd(int fd, CallStack const& callStack); + void AddWriteFd(int fd, CallStack const& callStack); +#endif + +private: + WaitObjectsTracer* m_tracer; + +#ifdef USE_WINDOWS_STYLE_SOCKETS + void CreateThreads(unsigned int count); + std::vector m_handles; + std::vector m_threads; + HANDLE m_startWaiting; + HANDLE m_stopWaiting; +#else + fd_set m_readfds, m_writefds; + int m_maxFd; +#endif + bool m_noWait; + double m_firstEventTime; + Timer m_eventTimer; + +#ifdef USE_WINDOWS_STYLE_SOCKETS + typedef size_t LastResultType; +#else + typedef int LastResultType; +#endif + enum { LASTRESULT_NOWAIT = -1, LASTRESULT_SCHEDULED = -2, LASTRESULT_TIMEOUT = -3 }; + LastResultType m_lastResult; + unsigned int m_sameResultCount; + Timer m_noWaitTimer; + void SetLastResult(LastResultType result); + void DetectNoWait(LastResultType result, CallStack const& callStack); +}; + +NAMESPACE_END + +#endif + +#endif diff --git a/CryptoPP/crypto/wake.cpp b/CryptoPP/crypto/wake.cpp new file mode 100644 index 0000000..41d0675 --- /dev/null +++ b/CryptoPP/crypto/wake.cpp @@ -0,0 +1,125 @@ +// wake.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "wake.h" + +NAMESPACE_BEGIN(CryptoPP) + +void WAKE_TestInstantiations() +{ + Weak::WAKE_CFB<>::Encryption x1; + Weak::WAKE_CFB<>::Decryption x3; + WAKE_OFB<>::Encryption x2; + WAKE_OFB<>::Decryption x4; +} + +inline word32 WAKE_Base::M(word32 x, word32 y) +{ + word32 w = x+y; + return (w>>8) ^ t[(byte)w]; +} + +void WAKE_Base::GenKey(word32 k0, word32 k1, word32 k2, word32 k3) +{ + long x, z; + int p ; + static long tt[10]= { + 0x726a8f3bL, // table + 0xe69a3b5cL, + 0xd3c71fe5L, + 0xab3c73d2L, + 0x4d3a8eb3L, + 0x0396d6e8L, + 0x3d4c2f7aL, + 0x9ee27cf3L, } ; + t[0] = k0; + t[1] = k1; + t[2] = k2; + t[3] = k3; + for (p=4 ; p<256 ; p++) + { + x=t[p-4]+t[p-1] ; // fill t + t[p]= (x>>3) ^ tt[byte(x&7)] ; + } + + for (p=0 ; p<23 ; p++) + t[p]+=t[p+89] ; // mix first entries + x=t[33] ; z=t[59] | 0x01000001L ; + z=z&0xff7fffffL ; + for (p=0 ; p<256 ; p++) { //change top byte to + x=(x&0xff7fffffL)+z ; // a permutation etc + t[p]=(t[p] & 0x00ffffffL) ^ x ; } + + t[256]=t[0] ; + byte y=byte(x); + for (p=0 ; p<256 ; p++) { // further change perm. + t[p]=t[y=byte(t[p^y]^y)] ; // and other digits + t[y]=t[p+1] ; } +} + +template +void WAKE_Policy::CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length) +{ + word32 k0, k1, k2, k3; + BlockGetAndPut::Get(key)(r3)(r4)(r5)(r6)(k0)(k1)(k2)(k3); + GenKey(k0, k1, k2, k3); +} + +// CFB +template +void WAKE_Policy::Iterate(byte *output, const byte *input, CipherDir dir, size_t iterationCount) +{ + RegisterOutput registerOutput(output, input, dir); + + while (iterationCount--) + { + r3 = M(r3, ConditionalByteReverse(B::ToEnum(), r6)); + r4 = M(r4, r3); + r5 = M(r5, r4); + r6 = M(r6, r5); + registerOutput(r6); + } +} + +// OFB +template +void WAKE_Policy::OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount) +{ +#define WAKE_OUTPUT(x)\ + while (iterationCount--)\ + {\ + CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 0, r6);\ + r3 = M(r3, r6);\ + r4 = M(r4, r3);\ + r5 = M(r5, r4);\ + r6 = M(r6, r5);\ + output += 4;\ + if (x == XOR_KEYSTREAM)\ + input += 4;\ + } + + typedef word32 WordType; + CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(WAKE_OUTPUT, 0); +} +/* +template +void WAKE_ROFB_Policy::Iterate(KeystreamOperation operation, byte *output, const byte *input, unsigned int iterationCount) +{ + KeystreamOutput keystreamOperation(operation, output, input); + + while (iterationCount--) + { + keystreamOperation(r6); + r3 = M(r3, r6); + r4 = M(r4, r3); + r5 = M(r5, r4); + r6 = M(r6, r5); + } +} +*/ +template class WAKE_Policy; +template class WAKE_Policy; +//template class WAKE_ROFB_Policy; +//template class WAKE_ROFB_Policy; + +NAMESPACE_END diff --git a/CryptoPP/crypto/wake.h b/CryptoPP/crypto/wake.h new file mode 100644 index 0000000..6c6c05c --- /dev/null +++ b/CryptoPP/crypto/wake.h @@ -0,0 +1,86 @@ +#ifndef CRYPTOPP_WAKE_H +#define CRYPTOPP_WAKE_H + +#include "seckey.h" +#include "secblock.h" +#include "strciphr.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! _ +template +struct WAKE_CFB_Info : public FixedKeyLength<32> +{ + static const char *StaticAlgorithmName() {return B::ToEnum() == LITTLE_ENDIAN_ORDER ? "WAKE-CFB-LE" : "WAKE-CFB-BE";} +}; + +//! _ +template +struct WAKE_OFB_Info : public FixedKeyLength<32> +{ + static const char *StaticAlgorithmName() {return B::ToEnum() == LITTLE_ENDIAN_ORDER ? "WAKE-OFB-LE" : "WAKE-OFB-BE";} +}; + +class CRYPTOPP_NO_VTABLE WAKE_Base +{ +protected: + word32 M(word32 x, word32 y); + void GenKey(word32 k0, word32 k1, word32 k2, word32 k3); + + word32 t[257]; + word32 r3, r4, r5, r6; +}; + +template +class CRYPTOPP_NO_VTABLE WAKE_Policy + : public CFB_CipherConcretePolicy + , public AdditiveCipherConcretePolicy + , protected WAKE_Base +{ +protected: + void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length); + // CFB + byte * GetRegisterBegin() {return (byte *)&r6;} + void Iterate(byte *output, const byte *input, CipherDir dir, size_t iterationCount); + // OFB + void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount); + bool IsRandomAccess() const {return false;} +}; + +namespace Weak { +//! WAKE-CFB-BE +template +struct WAKE_CFB : public WAKE_CFB_Info, public SymmetricCipherDocumentation +{ + typedef SymmetricCipherFinal, CFB_EncryptionTemplate<> >, WAKE_CFB_Info > Encryption; + typedef SymmetricCipherFinal, CFB_DecryptionTemplate<> >, WAKE_CFB_Info > Decryption; +}; +} + +//! WAKE-OFB +template +struct WAKE_OFB : public WAKE_OFB_Info, public SymmetricCipherDocumentation +{ + typedef SymmetricCipherFinal, AdditiveCipherTemplate<> >, WAKE_OFB_Info > Encryption; + typedef Encryption Decryption; +}; + +/* +template +class WAKE_ROFB_Policy : public WAKE_Policy +{ +protected: + void Iterate(KeystreamOperation operation, byte *output, const byte *input, unsigned int iterationCount); +}; + +template +struct WAKE_ROFB : public WAKE_Info +{ + typedef SymmetricCipherTemplate, WAKE_ROFB_Policy > > Encryption; + typedef Encryption Decryption; +}; +*/ + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/whrlpool.cpp b/CryptoPP/crypto/whrlpool.cpp new file mode 100644 index 0000000..33a32e2 --- /dev/null +++ b/CryptoPP/crypto/whrlpool.cpp @@ -0,0 +1,706 @@ +// whrlpool.cpp - originally modified by Kevin Springle from +// Paulo Barreto and Vincent Rijmen's public domain code, whirlpool.c. +// Updated to Whirlpool version 3.0, optimized and SSE version added by Wei Dai +// All modifications are placed in the public domain + +// This is the original introductory comment: + +/** + * The Whirlpool hashing function. + * + *

+ * References + * + *

+ * The Whirlpool algorithm was developed by + * Paulo S. L. M. Barreto and + * Vincent Rijmen. + * + * See + * P.S.L.M. Barreto, V. Rijmen, + * ``The Whirlpool hashing function,'' + * NESSIE submission, 2000 (tweaked version, 2001), + * + * + * @author Paulo S.L.M. Barreto + * @author Vincent Rijmen. + * + * @version 3.0 (2003.03.12) + * + * ============================================================================= + * + * Differences from version 2.1: + * + * - Suboptimal diffusion matrix replaced by cir(1, 1, 4, 1, 8, 5, 2, 9). + * + * ============================================================================= + * + * Differences from version 2.0: + * + * - Generation of ISO/IEC 10118-3 test vectors. + * - Bug fix: nonzero carry was ignored when tallying the data length + * (this bug apparently only manifested itself when feeding data + * in pieces rather than in a single chunk at once). + * - Support for MS Visual C++ 64-bit integer arithmetic. + * + * Differences from version 1.0: + * + * - Original S-box replaced by the tweaked, hardware-efficient version. + * + * ============================================================================= + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "pch.h" + +#ifdef WORD64_AVAILABLE + +#include "whrlpool.h" +#include "misc.h" +#include "cpu.h" + +#if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE +#include +#endif + +NAMESPACE_BEGIN(CryptoPP) + +void Whirlpool_TestInstantiations() +{ + Whirlpool x; +} + +void Whirlpool::InitState(HashWordType *state) +{ + memset(state, 0, 8*sizeof(state[0])); +} + +void Whirlpool::TruncatedFinal(byte *hash, size_t size) +{ + ThrowIfInvalidTruncatedSize(size); + + PadLastBlock(32); + CorrectEndianess(m_data, m_data, 32); + + m_data[m_data.size()-4] = 0; + m_data[m_data.size()-3] = 0; + m_data[m_data.size()-2] = GetBitCountHi(); + m_data[m_data.size()-1] = GetBitCountLo(); + + Transform(m_state, m_data); + CorrectEndianess(m_state, m_state, DigestSize()); + memcpy(hash, m_state, size); + + Restart(); // reinit for next use +} + +/* + * The number of rounds of the internal dedicated block cipher. + */ +#define R 10 + +/* + * Though Whirlpool is endianness-neutral, the encryption tables are listed + * in BIG-ENDIAN format, which is adopted throughout this implementation + * (but little-endian notation would be equally suitable if consistently + * employed). + */ + +CRYPTOPP_ALIGN_DATA(16) static const word64 Whirlpool_C[4*256+R] CRYPTOPP_SECTION_ALIGN16 = { + W64LIT(0x18186018c07830d8), W64LIT(0x23238c2305af4626), W64LIT(0xc6c63fc67ef991b8), W64LIT(0xe8e887e8136fcdfb), + W64LIT(0x878726874ca113cb), W64LIT(0xb8b8dab8a9626d11), W64LIT(0x0101040108050209), W64LIT(0x4f4f214f426e9e0d), + W64LIT(0x3636d836adee6c9b), W64LIT(0xa6a6a2a6590451ff), W64LIT(0xd2d26fd2debdb90c), W64LIT(0xf5f5f3f5fb06f70e), + W64LIT(0x7979f979ef80f296), W64LIT(0x6f6fa16f5fcede30), W64LIT(0x91917e91fcef3f6d), W64LIT(0x52525552aa07a4f8), + W64LIT(0x60609d6027fdc047), W64LIT(0xbcbccabc89766535), W64LIT(0x9b9b569baccd2b37), W64LIT(0x8e8e028e048c018a), + W64LIT(0xa3a3b6a371155bd2), W64LIT(0x0c0c300c603c186c), W64LIT(0x7b7bf17bff8af684), W64LIT(0x3535d435b5e16a80), + W64LIT(0x1d1d741de8693af5), W64LIT(0xe0e0a7e05347ddb3), W64LIT(0xd7d77bd7f6acb321), W64LIT(0xc2c22fc25eed999c), + W64LIT(0x2e2eb82e6d965c43), W64LIT(0x4b4b314b627a9629), W64LIT(0xfefedffea321e15d), W64LIT(0x575741578216aed5), + W64LIT(0x15155415a8412abd), W64LIT(0x7777c1779fb6eee8), W64LIT(0x3737dc37a5eb6e92), W64LIT(0xe5e5b3e57b56d79e), + W64LIT(0x9f9f469f8cd92313), W64LIT(0xf0f0e7f0d317fd23), W64LIT(0x4a4a354a6a7f9420), W64LIT(0xdada4fda9e95a944), + W64LIT(0x58587d58fa25b0a2), W64LIT(0xc9c903c906ca8fcf), W64LIT(0x2929a429558d527c), W64LIT(0x0a0a280a5022145a), + W64LIT(0xb1b1feb1e14f7f50), W64LIT(0xa0a0baa0691a5dc9), W64LIT(0x6b6bb16b7fdad614), W64LIT(0x85852e855cab17d9), + W64LIT(0xbdbdcebd8173673c), W64LIT(0x5d5d695dd234ba8f), W64LIT(0x1010401080502090), W64LIT(0xf4f4f7f4f303f507), + W64LIT(0xcbcb0bcb16c08bdd), W64LIT(0x3e3ef83eedc67cd3), W64LIT(0x0505140528110a2d), W64LIT(0x676781671fe6ce78), + W64LIT(0xe4e4b7e47353d597), W64LIT(0x27279c2725bb4e02), W64LIT(0x4141194132588273), W64LIT(0x8b8b168b2c9d0ba7), + W64LIT(0xa7a7a6a7510153f6), W64LIT(0x7d7de97dcf94fab2), W64LIT(0x95956e95dcfb3749), W64LIT(0xd8d847d88e9fad56), + W64LIT(0xfbfbcbfb8b30eb70), W64LIT(0xeeee9fee2371c1cd), W64LIT(0x7c7ced7cc791f8bb), W64LIT(0x6666856617e3cc71), + W64LIT(0xdddd53dda68ea77b), W64LIT(0x17175c17b84b2eaf), W64LIT(0x4747014702468e45), W64LIT(0x9e9e429e84dc211a), + W64LIT(0xcaca0fca1ec589d4), W64LIT(0x2d2db42d75995a58), W64LIT(0xbfbfc6bf9179632e), W64LIT(0x07071c07381b0e3f), + W64LIT(0xadad8ead012347ac), W64LIT(0x5a5a755aea2fb4b0), W64LIT(0x838336836cb51bef), W64LIT(0x3333cc3385ff66b6), + W64LIT(0x636391633ff2c65c), W64LIT(0x02020802100a0412), W64LIT(0xaaaa92aa39384993), W64LIT(0x7171d971afa8e2de), + W64LIT(0xc8c807c80ecf8dc6), W64LIT(0x19196419c87d32d1), W64LIT(0x494939497270923b), W64LIT(0xd9d943d9869aaf5f), + W64LIT(0xf2f2eff2c31df931), W64LIT(0xe3e3abe34b48dba8), W64LIT(0x5b5b715be22ab6b9), W64LIT(0x88881a8834920dbc), + W64LIT(0x9a9a529aa4c8293e), W64LIT(0x262698262dbe4c0b), W64LIT(0x3232c8328dfa64bf), W64LIT(0xb0b0fab0e94a7d59), + W64LIT(0xe9e983e91b6acff2), W64LIT(0x0f0f3c0f78331e77), W64LIT(0xd5d573d5e6a6b733), W64LIT(0x80803a8074ba1df4), + W64LIT(0xbebec2be997c6127), W64LIT(0xcdcd13cd26de87eb), W64LIT(0x3434d034bde46889), W64LIT(0x48483d487a759032), + W64LIT(0xffffdbffab24e354), W64LIT(0x7a7af57af78ff48d), W64LIT(0x90907a90f4ea3d64), W64LIT(0x5f5f615fc23ebe9d), + W64LIT(0x202080201da0403d), W64LIT(0x6868bd6867d5d00f), W64LIT(0x1a1a681ad07234ca), W64LIT(0xaeae82ae192c41b7), + W64LIT(0xb4b4eab4c95e757d), W64LIT(0x54544d549a19a8ce), W64LIT(0x93937693ece53b7f), W64LIT(0x222288220daa442f), + W64LIT(0x64648d6407e9c863), W64LIT(0xf1f1e3f1db12ff2a), W64LIT(0x7373d173bfa2e6cc), W64LIT(0x12124812905a2482), + W64LIT(0x40401d403a5d807a), W64LIT(0x0808200840281048), W64LIT(0xc3c32bc356e89b95), W64LIT(0xecec97ec337bc5df), + W64LIT(0xdbdb4bdb9690ab4d), W64LIT(0xa1a1bea1611f5fc0), W64LIT(0x8d8d0e8d1c830791), W64LIT(0x3d3df43df5c97ac8), + W64LIT(0x97976697ccf1335b), W64LIT(0x0000000000000000), W64LIT(0xcfcf1bcf36d483f9), W64LIT(0x2b2bac2b4587566e), + W64LIT(0x7676c57697b3ece1), W64LIT(0x8282328264b019e6), W64LIT(0xd6d67fd6fea9b128), W64LIT(0x1b1b6c1bd87736c3), + W64LIT(0xb5b5eeb5c15b7774), W64LIT(0xafaf86af112943be), W64LIT(0x6a6ab56a77dfd41d), W64LIT(0x50505d50ba0da0ea), + W64LIT(0x45450945124c8a57), W64LIT(0xf3f3ebf3cb18fb38), W64LIT(0x3030c0309df060ad), W64LIT(0xefef9bef2b74c3c4), + W64LIT(0x3f3ffc3fe5c37eda), W64LIT(0x55554955921caac7), W64LIT(0xa2a2b2a2791059db), W64LIT(0xeaea8fea0365c9e9), + W64LIT(0x656589650fecca6a), W64LIT(0xbabad2bab9686903), W64LIT(0x2f2fbc2f65935e4a), W64LIT(0xc0c027c04ee79d8e), + W64LIT(0xdede5fdebe81a160), W64LIT(0x1c1c701ce06c38fc), W64LIT(0xfdfdd3fdbb2ee746), W64LIT(0x4d4d294d52649a1f), + W64LIT(0x92927292e4e03976), W64LIT(0x7575c9758fbceafa), W64LIT(0x06061806301e0c36), W64LIT(0x8a8a128a249809ae), + W64LIT(0xb2b2f2b2f940794b), W64LIT(0xe6e6bfe66359d185), W64LIT(0x0e0e380e70361c7e), W64LIT(0x1f1f7c1ff8633ee7), + W64LIT(0x6262956237f7c455), W64LIT(0xd4d477d4eea3b53a), W64LIT(0xa8a89aa829324d81), W64LIT(0x96966296c4f43152), + W64LIT(0xf9f9c3f99b3aef62), W64LIT(0xc5c533c566f697a3), W64LIT(0x2525942535b14a10), W64LIT(0x59597959f220b2ab), + W64LIT(0x84842a8454ae15d0), W64LIT(0x7272d572b7a7e4c5), W64LIT(0x3939e439d5dd72ec), W64LIT(0x4c4c2d4c5a619816), + W64LIT(0x5e5e655eca3bbc94), W64LIT(0x7878fd78e785f09f), W64LIT(0x3838e038ddd870e5), W64LIT(0x8c8c0a8c14860598), + W64LIT(0xd1d163d1c6b2bf17), W64LIT(0xa5a5aea5410b57e4), W64LIT(0xe2e2afe2434dd9a1), W64LIT(0x616199612ff8c24e), + W64LIT(0xb3b3f6b3f1457b42), W64LIT(0x2121842115a54234), W64LIT(0x9c9c4a9c94d62508), W64LIT(0x1e1e781ef0663cee), + W64LIT(0x4343114322528661), W64LIT(0xc7c73bc776fc93b1), W64LIT(0xfcfcd7fcb32be54f), W64LIT(0x0404100420140824), + W64LIT(0x51515951b208a2e3), W64LIT(0x99995e99bcc72f25), W64LIT(0x6d6da96d4fc4da22), W64LIT(0x0d0d340d68391a65), + W64LIT(0xfafacffa8335e979), W64LIT(0xdfdf5bdfb684a369), W64LIT(0x7e7ee57ed79bfca9), W64LIT(0x242490243db44819), + W64LIT(0x3b3bec3bc5d776fe), W64LIT(0xabab96ab313d4b9a), W64LIT(0xcece1fce3ed181f0), W64LIT(0x1111441188552299), + W64LIT(0x8f8f068f0c890383), W64LIT(0x4e4e254e4a6b9c04), W64LIT(0xb7b7e6b7d1517366), W64LIT(0xebeb8beb0b60cbe0), + W64LIT(0x3c3cf03cfdcc78c1), W64LIT(0x81813e817cbf1ffd), W64LIT(0x94946a94d4fe3540), W64LIT(0xf7f7fbf7eb0cf31c), + W64LIT(0xb9b9deb9a1676f18), W64LIT(0x13134c13985f268b), W64LIT(0x2c2cb02c7d9c5851), W64LIT(0xd3d36bd3d6b8bb05), + W64LIT(0xe7e7bbe76b5cd38c), W64LIT(0x6e6ea56e57cbdc39), W64LIT(0xc4c437c46ef395aa), W64LIT(0x03030c03180f061b), + W64LIT(0x565645568a13acdc), W64LIT(0x44440d441a49885e), W64LIT(0x7f7fe17fdf9efea0), W64LIT(0xa9a99ea921374f88), + W64LIT(0x2a2aa82a4d825467), W64LIT(0xbbbbd6bbb16d6b0a), W64LIT(0xc1c123c146e29f87), W64LIT(0x53535153a202a6f1), + W64LIT(0xdcdc57dcae8ba572), W64LIT(0x0b0b2c0b58271653), W64LIT(0x9d9d4e9d9cd32701), W64LIT(0x6c6cad6c47c1d82b), + W64LIT(0x3131c43195f562a4), W64LIT(0x7474cd7487b9e8f3), W64LIT(0xf6f6fff6e309f115), W64LIT(0x464605460a438c4c), + W64LIT(0xacac8aac092645a5), W64LIT(0x89891e893c970fb5), W64LIT(0x14145014a04428b4), W64LIT(0xe1e1a3e15b42dfba), + W64LIT(0x16165816b04e2ca6), W64LIT(0x3a3ae83acdd274f7), W64LIT(0x6969b9696fd0d206), W64LIT(0x09092409482d1241), + W64LIT(0x7070dd70a7ade0d7), W64LIT(0xb6b6e2b6d954716f), W64LIT(0xd0d067d0ceb7bd1e), W64LIT(0xeded93ed3b7ec7d6), + W64LIT(0xcccc17cc2edb85e2), W64LIT(0x424215422a578468), W64LIT(0x98985a98b4c22d2c), W64LIT(0xa4a4aaa4490e55ed), + W64LIT(0x2828a0285d885075), W64LIT(0x5c5c6d5cda31b886), W64LIT(0xf8f8c7f8933fed6b), W64LIT(0x8686228644a411c2), + + W64LIT(0xd818186018c07830), W64LIT(0x2623238c2305af46), W64LIT(0xb8c6c63fc67ef991), W64LIT(0xfbe8e887e8136fcd), + W64LIT(0xcb878726874ca113), W64LIT(0x11b8b8dab8a9626d), W64LIT(0x0901010401080502), W64LIT(0x0d4f4f214f426e9e), + W64LIT(0x9b3636d836adee6c), W64LIT(0xffa6a6a2a6590451), W64LIT(0x0cd2d26fd2debdb9), W64LIT(0x0ef5f5f3f5fb06f7), + W64LIT(0x967979f979ef80f2), W64LIT(0x306f6fa16f5fcede), W64LIT(0x6d91917e91fcef3f), W64LIT(0xf852525552aa07a4), + W64LIT(0x4760609d6027fdc0), W64LIT(0x35bcbccabc897665), W64LIT(0x379b9b569baccd2b), W64LIT(0x8a8e8e028e048c01), + W64LIT(0xd2a3a3b6a371155b), W64LIT(0x6c0c0c300c603c18), W64LIT(0x847b7bf17bff8af6), W64LIT(0x803535d435b5e16a), + W64LIT(0xf51d1d741de8693a), W64LIT(0xb3e0e0a7e05347dd), W64LIT(0x21d7d77bd7f6acb3), W64LIT(0x9cc2c22fc25eed99), + W64LIT(0x432e2eb82e6d965c), W64LIT(0x294b4b314b627a96), W64LIT(0x5dfefedffea321e1), W64LIT(0xd5575741578216ae), + W64LIT(0xbd15155415a8412a), W64LIT(0xe87777c1779fb6ee), W64LIT(0x923737dc37a5eb6e), W64LIT(0x9ee5e5b3e57b56d7), + W64LIT(0x139f9f469f8cd923), W64LIT(0x23f0f0e7f0d317fd), W64LIT(0x204a4a354a6a7f94), W64LIT(0x44dada4fda9e95a9), + W64LIT(0xa258587d58fa25b0), W64LIT(0xcfc9c903c906ca8f), W64LIT(0x7c2929a429558d52), W64LIT(0x5a0a0a280a502214), + W64LIT(0x50b1b1feb1e14f7f), W64LIT(0xc9a0a0baa0691a5d), W64LIT(0x146b6bb16b7fdad6), W64LIT(0xd985852e855cab17), + W64LIT(0x3cbdbdcebd817367), W64LIT(0x8f5d5d695dd234ba), W64LIT(0x9010104010805020), W64LIT(0x07f4f4f7f4f303f5), + W64LIT(0xddcbcb0bcb16c08b), W64LIT(0xd33e3ef83eedc67c), W64LIT(0x2d0505140528110a), W64LIT(0x78676781671fe6ce), + W64LIT(0x97e4e4b7e47353d5), W64LIT(0x0227279c2725bb4e), W64LIT(0x7341411941325882), W64LIT(0xa78b8b168b2c9d0b), + W64LIT(0xf6a7a7a6a7510153), W64LIT(0xb27d7de97dcf94fa), W64LIT(0x4995956e95dcfb37), W64LIT(0x56d8d847d88e9fad), + W64LIT(0x70fbfbcbfb8b30eb), W64LIT(0xcdeeee9fee2371c1), W64LIT(0xbb7c7ced7cc791f8), W64LIT(0x716666856617e3cc), + W64LIT(0x7bdddd53dda68ea7), W64LIT(0xaf17175c17b84b2e), W64LIT(0x454747014702468e), W64LIT(0x1a9e9e429e84dc21), + W64LIT(0xd4caca0fca1ec589), W64LIT(0x582d2db42d75995a), W64LIT(0x2ebfbfc6bf917963), W64LIT(0x3f07071c07381b0e), + W64LIT(0xacadad8ead012347), W64LIT(0xb05a5a755aea2fb4), W64LIT(0xef838336836cb51b), W64LIT(0xb63333cc3385ff66), + W64LIT(0x5c636391633ff2c6), W64LIT(0x1202020802100a04), W64LIT(0x93aaaa92aa393849), W64LIT(0xde7171d971afa8e2), + W64LIT(0xc6c8c807c80ecf8d), W64LIT(0xd119196419c87d32), W64LIT(0x3b49493949727092), W64LIT(0x5fd9d943d9869aaf), + W64LIT(0x31f2f2eff2c31df9), W64LIT(0xa8e3e3abe34b48db), W64LIT(0xb95b5b715be22ab6), W64LIT(0xbc88881a8834920d), + W64LIT(0x3e9a9a529aa4c829), W64LIT(0x0b262698262dbe4c), W64LIT(0xbf3232c8328dfa64), W64LIT(0x59b0b0fab0e94a7d), + W64LIT(0xf2e9e983e91b6acf), W64LIT(0x770f0f3c0f78331e), W64LIT(0x33d5d573d5e6a6b7), W64LIT(0xf480803a8074ba1d), + W64LIT(0x27bebec2be997c61), W64LIT(0xebcdcd13cd26de87), W64LIT(0x893434d034bde468), W64LIT(0x3248483d487a7590), + W64LIT(0x54ffffdbffab24e3), W64LIT(0x8d7a7af57af78ff4), W64LIT(0x6490907a90f4ea3d), W64LIT(0x9d5f5f615fc23ebe), + W64LIT(0x3d202080201da040), W64LIT(0x0f6868bd6867d5d0), W64LIT(0xca1a1a681ad07234), W64LIT(0xb7aeae82ae192c41), + W64LIT(0x7db4b4eab4c95e75), W64LIT(0xce54544d549a19a8), W64LIT(0x7f93937693ece53b), W64LIT(0x2f222288220daa44), + W64LIT(0x6364648d6407e9c8), W64LIT(0x2af1f1e3f1db12ff), W64LIT(0xcc7373d173bfa2e6), W64LIT(0x8212124812905a24), + W64LIT(0x7a40401d403a5d80), W64LIT(0x4808082008402810), W64LIT(0x95c3c32bc356e89b), W64LIT(0xdfecec97ec337bc5), + W64LIT(0x4ddbdb4bdb9690ab), W64LIT(0xc0a1a1bea1611f5f), W64LIT(0x918d8d0e8d1c8307), W64LIT(0xc83d3df43df5c97a), + W64LIT(0x5b97976697ccf133), W64LIT(0x0000000000000000), W64LIT(0xf9cfcf1bcf36d483), W64LIT(0x6e2b2bac2b458756), + W64LIT(0xe17676c57697b3ec), W64LIT(0xe68282328264b019), W64LIT(0x28d6d67fd6fea9b1), W64LIT(0xc31b1b6c1bd87736), + W64LIT(0x74b5b5eeb5c15b77), W64LIT(0xbeafaf86af112943), W64LIT(0x1d6a6ab56a77dfd4), W64LIT(0xea50505d50ba0da0), + W64LIT(0x5745450945124c8a), W64LIT(0x38f3f3ebf3cb18fb), W64LIT(0xad3030c0309df060), W64LIT(0xc4efef9bef2b74c3), + W64LIT(0xda3f3ffc3fe5c37e), W64LIT(0xc755554955921caa), W64LIT(0xdba2a2b2a2791059), W64LIT(0xe9eaea8fea0365c9), + W64LIT(0x6a656589650fecca), W64LIT(0x03babad2bab96869), W64LIT(0x4a2f2fbc2f65935e), W64LIT(0x8ec0c027c04ee79d), + W64LIT(0x60dede5fdebe81a1), W64LIT(0xfc1c1c701ce06c38), W64LIT(0x46fdfdd3fdbb2ee7), W64LIT(0x1f4d4d294d52649a), + W64LIT(0x7692927292e4e039), W64LIT(0xfa7575c9758fbcea), W64LIT(0x3606061806301e0c), W64LIT(0xae8a8a128a249809), + W64LIT(0x4bb2b2f2b2f94079), W64LIT(0x85e6e6bfe66359d1), W64LIT(0x7e0e0e380e70361c), W64LIT(0xe71f1f7c1ff8633e), + W64LIT(0x556262956237f7c4), W64LIT(0x3ad4d477d4eea3b5), W64LIT(0x81a8a89aa829324d), W64LIT(0x5296966296c4f431), + W64LIT(0x62f9f9c3f99b3aef), W64LIT(0xa3c5c533c566f697), W64LIT(0x102525942535b14a), W64LIT(0xab59597959f220b2), + W64LIT(0xd084842a8454ae15), W64LIT(0xc57272d572b7a7e4), W64LIT(0xec3939e439d5dd72), W64LIT(0x164c4c2d4c5a6198), + W64LIT(0x945e5e655eca3bbc), W64LIT(0x9f7878fd78e785f0), W64LIT(0xe53838e038ddd870), W64LIT(0x988c8c0a8c148605), + W64LIT(0x17d1d163d1c6b2bf), W64LIT(0xe4a5a5aea5410b57), W64LIT(0xa1e2e2afe2434dd9), W64LIT(0x4e616199612ff8c2), + W64LIT(0x42b3b3f6b3f1457b), W64LIT(0x342121842115a542), W64LIT(0x089c9c4a9c94d625), W64LIT(0xee1e1e781ef0663c), + W64LIT(0x6143431143225286), W64LIT(0xb1c7c73bc776fc93), W64LIT(0x4ffcfcd7fcb32be5), W64LIT(0x2404041004201408), + W64LIT(0xe351515951b208a2), W64LIT(0x2599995e99bcc72f), W64LIT(0x226d6da96d4fc4da), W64LIT(0x650d0d340d68391a), + W64LIT(0x79fafacffa8335e9), W64LIT(0x69dfdf5bdfb684a3), W64LIT(0xa97e7ee57ed79bfc), W64LIT(0x19242490243db448), + W64LIT(0xfe3b3bec3bc5d776), W64LIT(0x9aabab96ab313d4b), W64LIT(0xf0cece1fce3ed181), W64LIT(0x9911114411885522), + W64LIT(0x838f8f068f0c8903), W64LIT(0x044e4e254e4a6b9c), W64LIT(0x66b7b7e6b7d15173), W64LIT(0xe0ebeb8beb0b60cb), + W64LIT(0xc13c3cf03cfdcc78), W64LIT(0xfd81813e817cbf1f), W64LIT(0x4094946a94d4fe35), W64LIT(0x1cf7f7fbf7eb0cf3), + W64LIT(0x18b9b9deb9a1676f), W64LIT(0x8b13134c13985f26), W64LIT(0x512c2cb02c7d9c58), W64LIT(0x05d3d36bd3d6b8bb), + W64LIT(0x8ce7e7bbe76b5cd3), W64LIT(0x396e6ea56e57cbdc), W64LIT(0xaac4c437c46ef395), W64LIT(0x1b03030c03180f06), + W64LIT(0xdc565645568a13ac), W64LIT(0x5e44440d441a4988), W64LIT(0xa07f7fe17fdf9efe), W64LIT(0x88a9a99ea921374f), + W64LIT(0x672a2aa82a4d8254), W64LIT(0x0abbbbd6bbb16d6b), W64LIT(0x87c1c123c146e29f), W64LIT(0xf153535153a202a6), + W64LIT(0x72dcdc57dcae8ba5), W64LIT(0x530b0b2c0b582716), W64LIT(0x019d9d4e9d9cd327), W64LIT(0x2b6c6cad6c47c1d8), + W64LIT(0xa43131c43195f562), W64LIT(0xf37474cd7487b9e8), W64LIT(0x15f6f6fff6e309f1), W64LIT(0x4c464605460a438c), + W64LIT(0xa5acac8aac092645), W64LIT(0xb589891e893c970f), W64LIT(0xb414145014a04428), W64LIT(0xbae1e1a3e15b42df), + W64LIT(0xa616165816b04e2c), W64LIT(0xf73a3ae83acdd274), W64LIT(0x066969b9696fd0d2), W64LIT(0x4109092409482d12), + W64LIT(0xd77070dd70a7ade0), W64LIT(0x6fb6b6e2b6d95471), W64LIT(0x1ed0d067d0ceb7bd), W64LIT(0xd6eded93ed3b7ec7), + W64LIT(0xe2cccc17cc2edb85), W64LIT(0x68424215422a5784), W64LIT(0x2c98985a98b4c22d), W64LIT(0xeda4a4aaa4490e55), + W64LIT(0x752828a0285d8850), W64LIT(0x865c5c6d5cda31b8), W64LIT(0x6bf8f8c7f8933fed), W64LIT(0xc28686228644a411), + + W64LIT(0x30d818186018c078), W64LIT(0x462623238c2305af), W64LIT(0x91b8c6c63fc67ef9), W64LIT(0xcdfbe8e887e8136f), + W64LIT(0x13cb878726874ca1), W64LIT(0x6d11b8b8dab8a962), W64LIT(0x0209010104010805), W64LIT(0x9e0d4f4f214f426e), + W64LIT(0x6c9b3636d836adee), W64LIT(0x51ffa6a6a2a65904), W64LIT(0xb90cd2d26fd2debd), W64LIT(0xf70ef5f5f3f5fb06), + W64LIT(0xf2967979f979ef80), W64LIT(0xde306f6fa16f5fce), W64LIT(0x3f6d91917e91fcef), W64LIT(0xa4f852525552aa07), + W64LIT(0xc04760609d6027fd), W64LIT(0x6535bcbccabc8976), W64LIT(0x2b379b9b569baccd), W64LIT(0x018a8e8e028e048c), + W64LIT(0x5bd2a3a3b6a37115), W64LIT(0x186c0c0c300c603c), W64LIT(0xf6847b7bf17bff8a), W64LIT(0x6a803535d435b5e1), + W64LIT(0x3af51d1d741de869), W64LIT(0xddb3e0e0a7e05347), W64LIT(0xb321d7d77bd7f6ac), W64LIT(0x999cc2c22fc25eed), + W64LIT(0x5c432e2eb82e6d96), W64LIT(0x96294b4b314b627a), W64LIT(0xe15dfefedffea321), W64LIT(0xaed5575741578216), + W64LIT(0x2abd15155415a841), W64LIT(0xeee87777c1779fb6), W64LIT(0x6e923737dc37a5eb), W64LIT(0xd79ee5e5b3e57b56), + W64LIT(0x23139f9f469f8cd9), W64LIT(0xfd23f0f0e7f0d317), W64LIT(0x94204a4a354a6a7f), W64LIT(0xa944dada4fda9e95), + W64LIT(0xb0a258587d58fa25), W64LIT(0x8fcfc9c903c906ca), W64LIT(0x527c2929a429558d), W64LIT(0x145a0a0a280a5022), + W64LIT(0x7f50b1b1feb1e14f), W64LIT(0x5dc9a0a0baa0691a), W64LIT(0xd6146b6bb16b7fda), W64LIT(0x17d985852e855cab), + W64LIT(0x673cbdbdcebd8173), W64LIT(0xba8f5d5d695dd234), W64LIT(0x2090101040108050), W64LIT(0xf507f4f4f7f4f303), + W64LIT(0x8bddcbcb0bcb16c0), W64LIT(0x7cd33e3ef83eedc6), W64LIT(0x0a2d050514052811), W64LIT(0xce78676781671fe6), + W64LIT(0xd597e4e4b7e47353), W64LIT(0x4e0227279c2725bb), W64LIT(0x8273414119413258), W64LIT(0x0ba78b8b168b2c9d), + W64LIT(0x53f6a7a7a6a75101), W64LIT(0xfab27d7de97dcf94), W64LIT(0x374995956e95dcfb), W64LIT(0xad56d8d847d88e9f), + W64LIT(0xeb70fbfbcbfb8b30), W64LIT(0xc1cdeeee9fee2371), W64LIT(0xf8bb7c7ced7cc791), W64LIT(0xcc716666856617e3), + W64LIT(0xa77bdddd53dda68e), W64LIT(0x2eaf17175c17b84b), W64LIT(0x8e45474701470246), W64LIT(0x211a9e9e429e84dc), + W64LIT(0x89d4caca0fca1ec5), W64LIT(0x5a582d2db42d7599), W64LIT(0x632ebfbfc6bf9179), W64LIT(0x0e3f07071c07381b), + W64LIT(0x47acadad8ead0123), W64LIT(0xb4b05a5a755aea2f), W64LIT(0x1bef838336836cb5), W64LIT(0x66b63333cc3385ff), + W64LIT(0xc65c636391633ff2), W64LIT(0x041202020802100a), W64LIT(0x4993aaaa92aa3938), W64LIT(0xe2de7171d971afa8), + W64LIT(0x8dc6c8c807c80ecf), W64LIT(0x32d119196419c87d), W64LIT(0x923b494939497270), W64LIT(0xaf5fd9d943d9869a), + W64LIT(0xf931f2f2eff2c31d), W64LIT(0xdba8e3e3abe34b48), W64LIT(0xb6b95b5b715be22a), W64LIT(0x0dbc88881a883492), + W64LIT(0x293e9a9a529aa4c8), W64LIT(0x4c0b262698262dbe), W64LIT(0x64bf3232c8328dfa), W64LIT(0x7d59b0b0fab0e94a), + W64LIT(0xcff2e9e983e91b6a), W64LIT(0x1e770f0f3c0f7833), W64LIT(0xb733d5d573d5e6a6), W64LIT(0x1df480803a8074ba), + W64LIT(0x6127bebec2be997c), W64LIT(0x87ebcdcd13cd26de), W64LIT(0x68893434d034bde4), W64LIT(0x903248483d487a75), + W64LIT(0xe354ffffdbffab24), W64LIT(0xf48d7a7af57af78f), W64LIT(0x3d6490907a90f4ea), W64LIT(0xbe9d5f5f615fc23e), + W64LIT(0x403d202080201da0), W64LIT(0xd00f6868bd6867d5), W64LIT(0x34ca1a1a681ad072), W64LIT(0x41b7aeae82ae192c), + W64LIT(0x757db4b4eab4c95e), W64LIT(0xa8ce54544d549a19), W64LIT(0x3b7f93937693ece5), W64LIT(0x442f222288220daa), + W64LIT(0xc86364648d6407e9), W64LIT(0xff2af1f1e3f1db12), W64LIT(0xe6cc7373d173bfa2), W64LIT(0x248212124812905a), + W64LIT(0x807a40401d403a5d), W64LIT(0x1048080820084028), W64LIT(0x9b95c3c32bc356e8), W64LIT(0xc5dfecec97ec337b), + W64LIT(0xab4ddbdb4bdb9690), W64LIT(0x5fc0a1a1bea1611f), W64LIT(0x07918d8d0e8d1c83), W64LIT(0x7ac83d3df43df5c9), + W64LIT(0x335b97976697ccf1), W64LIT(0x0000000000000000), W64LIT(0x83f9cfcf1bcf36d4), W64LIT(0x566e2b2bac2b4587), + W64LIT(0xece17676c57697b3), W64LIT(0x19e68282328264b0), W64LIT(0xb128d6d67fd6fea9), W64LIT(0x36c31b1b6c1bd877), + W64LIT(0x7774b5b5eeb5c15b), W64LIT(0x43beafaf86af1129), W64LIT(0xd41d6a6ab56a77df), W64LIT(0xa0ea50505d50ba0d), + W64LIT(0x8a5745450945124c), W64LIT(0xfb38f3f3ebf3cb18), W64LIT(0x60ad3030c0309df0), W64LIT(0xc3c4efef9bef2b74), + W64LIT(0x7eda3f3ffc3fe5c3), W64LIT(0xaac755554955921c), W64LIT(0x59dba2a2b2a27910), W64LIT(0xc9e9eaea8fea0365), + W64LIT(0xca6a656589650fec), W64LIT(0x6903babad2bab968), W64LIT(0x5e4a2f2fbc2f6593), W64LIT(0x9d8ec0c027c04ee7), + W64LIT(0xa160dede5fdebe81), W64LIT(0x38fc1c1c701ce06c), W64LIT(0xe746fdfdd3fdbb2e), W64LIT(0x9a1f4d4d294d5264), + W64LIT(0x397692927292e4e0), W64LIT(0xeafa7575c9758fbc), W64LIT(0x0c3606061806301e), W64LIT(0x09ae8a8a128a2498), + W64LIT(0x794bb2b2f2b2f940), W64LIT(0xd185e6e6bfe66359), W64LIT(0x1c7e0e0e380e7036), W64LIT(0x3ee71f1f7c1ff863), + W64LIT(0xc4556262956237f7), W64LIT(0xb53ad4d477d4eea3), W64LIT(0x4d81a8a89aa82932), W64LIT(0x315296966296c4f4), + W64LIT(0xef62f9f9c3f99b3a), W64LIT(0x97a3c5c533c566f6), W64LIT(0x4a102525942535b1), W64LIT(0xb2ab59597959f220), + W64LIT(0x15d084842a8454ae), W64LIT(0xe4c57272d572b7a7), W64LIT(0x72ec3939e439d5dd), W64LIT(0x98164c4c2d4c5a61), + W64LIT(0xbc945e5e655eca3b), W64LIT(0xf09f7878fd78e785), W64LIT(0x70e53838e038ddd8), W64LIT(0x05988c8c0a8c1486), + W64LIT(0xbf17d1d163d1c6b2), W64LIT(0x57e4a5a5aea5410b), W64LIT(0xd9a1e2e2afe2434d), W64LIT(0xc24e616199612ff8), + W64LIT(0x7b42b3b3f6b3f145), W64LIT(0x42342121842115a5), W64LIT(0x25089c9c4a9c94d6), W64LIT(0x3cee1e1e781ef066), + W64LIT(0x8661434311432252), W64LIT(0x93b1c7c73bc776fc), W64LIT(0xe54ffcfcd7fcb32b), W64LIT(0x0824040410042014), + W64LIT(0xa2e351515951b208), W64LIT(0x2f2599995e99bcc7), W64LIT(0xda226d6da96d4fc4), W64LIT(0x1a650d0d340d6839), + W64LIT(0xe979fafacffa8335), W64LIT(0xa369dfdf5bdfb684), W64LIT(0xfca97e7ee57ed79b), W64LIT(0x4819242490243db4), + W64LIT(0x76fe3b3bec3bc5d7), W64LIT(0x4b9aabab96ab313d), W64LIT(0x81f0cece1fce3ed1), W64LIT(0x2299111144118855), + W64LIT(0x03838f8f068f0c89), W64LIT(0x9c044e4e254e4a6b), W64LIT(0x7366b7b7e6b7d151), W64LIT(0xcbe0ebeb8beb0b60), + W64LIT(0x78c13c3cf03cfdcc), W64LIT(0x1ffd81813e817cbf), W64LIT(0x354094946a94d4fe), W64LIT(0xf31cf7f7fbf7eb0c), + W64LIT(0x6f18b9b9deb9a167), W64LIT(0x268b13134c13985f), W64LIT(0x58512c2cb02c7d9c), W64LIT(0xbb05d3d36bd3d6b8), + W64LIT(0xd38ce7e7bbe76b5c), W64LIT(0xdc396e6ea56e57cb), W64LIT(0x95aac4c437c46ef3), W64LIT(0x061b03030c03180f), + W64LIT(0xacdc565645568a13), W64LIT(0x885e44440d441a49), W64LIT(0xfea07f7fe17fdf9e), W64LIT(0x4f88a9a99ea92137), + W64LIT(0x54672a2aa82a4d82), W64LIT(0x6b0abbbbd6bbb16d), W64LIT(0x9f87c1c123c146e2), W64LIT(0xa6f153535153a202), + W64LIT(0xa572dcdc57dcae8b), W64LIT(0x16530b0b2c0b5827), W64LIT(0x27019d9d4e9d9cd3), W64LIT(0xd82b6c6cad6c47c1), + W64LIT(0x62a43131c43195f5), W64LIT(0xe8f37474cd7487b9), W64LIT(0xf115f6f6fff6e309), W64LIT(0x8c4c464605460a43), + W64LIT(0x45a5acac8aac0926), W64LIT(0x0fb589891e893c97), W64LIT(0x28b414145014a044), W64LIT(0xdfbae1e1a3e15b42), + W64LIT(0x2ca616165816b04e), W64LIT(0x74f73a3ae83acdd2), W64LIT(0xd2066969b9696fd0), W64LIT(0x124109092409482d), + W64LIT(0xe0d77070dd70a7ad), W64LIT(0x716fb6b6e2b6d954), W64LIT(0xbd1ed0d067d0ceb7), W64LIT(0xc7d6eded93ed3b7e), + W64LIT(0x85e2cccc17cc2edb), W64LIT(0x8468424215422a57), W64LIT(0x2d2c98985a98b4c2), W64LIT(0x55eda4a4aaa4490e), + W64LIT(0x50752828a0285d88), W64LIT(0xb8865c5c6d5cda31), W64LIT(0xed6bf8f8c7f8933f), W64LIT(0x11c28686228644a4), + + W64LIT(0x7830d818186018c0), W64LIT(0xaf462623238c2305), W64LIT(0xf991b8c6c63fc67e), W64LIT(0x6fcdfbe8e887e813), + W64LIT(0xa113cb878726874c), W64LIT(0x626d11b8b8dab8a9), W64LIT(0x0502090101040108), W64LIT(0x6e9e0d4f4f214f42), + W64LIT(0xee6c9b3636d836ad), W64LIT(0x0451ffa6a6a2a659), W64LIT(0xbdb90cd2d26fd2de), W64LIT(0x06f70ef5f5f3f5fb), + W64LIT(0x80f2967979f979ef), W64LIT(0xcede306f6fa16f5f), W64LIT(0xef3f6d91917e91fc), W64LIT(0x07a4f852525552aa), + W64LIT(0xfdc04760609d6027), W64LIT(0x766535bcbccabc89), W64LIT(0xcd2b379b9b569bac), W64LIT(0x8c018a8e8e028e04), + W64LIT(0x155bd2a3a3b6a371), W64LIT(0x3c186c0c0c300c60), W64LIT(0x8af6847b7bf17bff), W64LIT(0xe16a803535d435b5), + W64LIT(0x693af51d1d741de8), W64LIT(0x47ddb3e0e0a7e053), W64LIT(0xacb321d7d77bd7f6), W64LIT(0xed999cc2c22fc25e), + W64LIT(0x965c432e2eb82e6d), W64LIT(0x7a96294b4b314b62), W64LIT(0x21e15dfefedffea3), W64LIT(0x16aed55757415782), + W64LIT(0x412abd15155415a8), W64LIT(0xb6eee87777c1779f), W64LIT(0xeb6e923737dc37a5), W64LIT(0x56d79ee5e5b3e57b), + W64LIT(0xd923139f9f469f8c), W64LIT(0x17fd23f0f0e7f0d3), W64LIT(0x7f94204a4a354a6a), W64LIT(0x95a944dada4fda9e), + W64LIT(0x25b0a258587d58fa), W64LIT(0xca8fcfc9c903c906), W64LIT(0x8d527c2929a42955), W64LIT(0x22145a0a0a280a50), + W64LIT(0x4f7f50b1b1feb1e1), W64LIT(0x1a5dc9a0a0baa069), W64LIT(0xdad6146b6bb16b7f), W64LIT(0xab17d985852e855c), + W64LIT(0x73673cbdbdcebd81), W64LIT(0x34ba8f5d5d695dd2), W64LIT(0x5020901010401080), W64LIT(0x03f507f4f4f7f4f3), + W64LIT(0xc08bddcbcb0bcb16), W64LIT(0xc67cd33e3ef83eed), W64LIT(0x110a2d0505140528), W64LIT(0xe6ce78676781671f), + W64LIT(0x53d597e4e4b7e473), W64LIT(0xbb4e0227279c2725), W64LIT(0x5882734141194132), W64LIT(0x9d0ba78b8b168b2c), + W64LIT(0x0153f6a7a7a6a751), W64LIT(0x94fab27d7de97dcf), W64LIT(0xfb374995956e95dc), W64LIT(0x9fad56d8d847d88e), + W64LIT(0x30eb70fbfbcbfb8b), W64LIT(0x71c1cdeeee9fee23), W64LIT(0x91f8bb7c7ced7cc7), W64LIT(0xe3cc716666856617), + W64LIT(0x8ea77bdddd53dda6), W64LIT(0x4b2eaf17175c17b8), W64LIT(0x468e454747014702), W64LIT(0xdc211a9e9e429e84), + W64LIT(0xc589d4caca0fca1e), W64LIT(0x995a582d2db42d75), W64LIT(0x79632ebfbfc6bf91), W64LIT(0x1b0e3f07071c0738), + W64LIT(0x2347acadad8ead01), W64LIT(0x2fb4b05a5a755aea), W64LIT(0xb51bef838336836c), W64LIT(0xff66b63333cc3385), + W64LIT(0xf2c65c636391633f), W64LIT(0x0a04120202080210), W64LIT(0x384993aaaa92aa39), W64LIT(0xa8e2de7171d971af), + W64LIT(0xcf8dc6c8c807c80e), W64LIT(0x7d32d119196419c8), W64LIT(0x70923b4949394972), W64LIT(0x9aaf5fd9d943d986), + W64LIT(0x1df931f2f2eff2c3), W64LIT(0x48dba8e3e3abe34b), W64LIT(0x2ab6b95b5b715be2), W64LIT(0x920dbc88881a8834), + W64LIT(0xc8293e9a9a529aa4), W64LIT(0xbe4c0b262698262d), W64LIT(0xfa64bf3232c8328d), W64LIT(0x4a7d59b0b0fab0e9), + W64LIT(0x6acff2e9e983e91b), W64LIT(0x331e770f0f3c0f78), W64LIT(0xa6b733d5d573d5e6), W64LIT(0xba1df480803a8074), + W64LIT(0x7c6127bebec2be99), W64LIT(0xde87ebcdcd13cd26), W64LIT(0xe468893434d034bd), W64LIT(0x75903248483d487a), + W64LIT(0x24e354ffffdbffab), W64LIT(0x8ff48d7a7af57af7), W64LIT(0xea3d6490907a90f4), W64LIT(0x3ebe9d5f5f615fc2), + W64LIT(0xa0403d202080201d), W64LIT(0xd5d00f6868bd6867), W64LIT(0x7234ca1a1a681ad0), W64LIT(0x2c41b7aeae82ae19), + W64LIT(0x5e757db4b4eab4c9), W64LIT(0x19a8ce54544d549a), W64LIT(0xe53b7f93937693ec), W64LIT(0xaa442f222288220d), + W64LIT(0xe9c86364648d6407), W64LIT(0x12ff2af1f1e3f1db), W64LIT(0xa2e6cc7373d173bf), W64LIT(0x5a24821212481290), + W64LIT(0x5d807a40401d403a), W64LIT(0x2810480808200840), W64LIT(0xe89b95c3c32bc356), W64LIT(0x7bc5dfecec97ec33), + W64LIT(0x90ab4ddbdb4bdb96), W64LIT(0x1f5fc0a1a1bea161), W64LIT(0x8307918d8d0e8d1c), W64LIT(0xc97ac83d3df43df5), + W64LIT(0xf1335b97976697cc), W64LIT(0x0000000000000000), W64LIT(0xd483f9cfcf1bcf36), W64LIT(0x87566e2b2bac2b45), + W64LIT(0xb3ece17676c57697), W64LIT(0xb019e68282328264), W64LIT(0xa9b128d6d67fd6fe), W64LIT(0x7736c31b1b6c1bd8), + W64LIT(0x5b7774b5b5eeb5c1), W64LIT(0x2943beafaf86af11), W64LIT(0xdfd41d6a6ab56a77), W64LIT(0x0da0ea50505d50ba), + W64LIT(0x4c8a574545094512), W64LIT(0x18fb38f3f3ebf3cb), W64LIT(0xf060ad3030c0309d), W64LIT(0x74c3c4efef9bef2b), + W64LIT(0xc37eda3f3ffc3fe5), W64LIT(0x1caac75555495592), W64LIT(0x1059dba2a2b2a279), W64LIT(0x65c9e9eaea8fea03), + W64LIT(0xecca6a656589650f), W64LIT(0x686903babad2bab9), W64LIT(0x935e4a2f2fbc2f65), W64LIT(0xe79d8ec0c027c04e), + W64LIT(0x81a160dede5fdebe), W64LIT(0x6c38fc1c1c701ce0), W64LIT(0x2ee746fdfdd3fdbb), W64LIT(0x649a1f4d4d294d52), + W64LIT(0xe0397692927292e4), W64LIT(0xbceafa7575c9758f), W64LIT(0x1e0c360606180630), W64LIT(0x9809ae8a8a128a24), + W64LIT(0x40794bb2b2f2b2f9), W64LIT(0x59d185e6e6bfe663), W64LIT(0x361c7e0e0e380e70), W64LIT(0x633ee71f1f7c1ff8), + W64LIT(0xf7c4556262956237), W64LIT(0xa3b53ad4d477d4ee), W64LIT(0x324d81a8a89aa829), W64LIT(0xf4315296966296c4), + W64LIT(0x3aef62f9f9c3f99b), W64LIT(0xf697a3c5c533c566), W64LIT(0xb14a102525942535), W64LIT(0x20b2ab59597959f2), + W64LIT(0xae15d084842a8454), W64LIT(0xa7e4c57272d572b7), W64LIT(0xdd72ec3939e439d5), W64LIT(0x6198164c4c2d4c5a), + W64LIT(0x3bbc945e5e655eca), W64LIT(0x85f09f7878fd78e7), W64LIT(0xd870e53838e038dd), W64LIT(0x8605988c8c0a8c14), + W64LIT(0xb2bf17d1d163d1c6), W64LIT(0x0b57e4a5a5aea541), W64LIT(0x4dd9a1e2e2afe243), W64LIT(0xf8c24e616199612f), + W64LIT(0x457b42b3b3f6b3f1), W64LIT(0xa542342121842115), W64LIT(0xd625089c9c4a9c94), W64LIT(0x663cee1e1e781ef0), + W64LIT(0x5286614343114322), W64LIT(0xfc93b1c7c73bc776), W64LIT(0x2be54ffcfcd7fcb3), W64LIT(0x1408240404100420), + W64LIT(0x08a2e351515951b2), W64LIT(0xc72f2599995e99bc), W64LIT(0xc4da226d6da96d4f), W64LIT(0x391a650d0d340d68), + W64LIT(0x35e979fafacffa83), W64LIT(0x84a369dfdf5bdfb6), W64LIT(0x9bfca97e7ee57ed7), W64LIT(0xb44819242490243d), + W64LIT(0xd776fe3b3bec3bc5), W64LIT(0x3d4b9aabab96ab31), W64LIT(0xd181f0cece1fce3e), W64LIT(0x5522991111441188), + W64LIT(0x8903838f8f068f0c), W64LIT(0x6b9c044e4e254e4a), W64LIT(0x517366b7b7e6b7d1), W64LIT(0x60cbe0ebeb8beb0b), + W64LIT(0xcc78c13c3cf03cfd), W64LIT(0xbf1ffd81813e817c), W64LIT(0xfe354094946a94d4), W64LIT(0x0cf31cf7f7fbf7eb), + W64LIT(0x676f18b9b9deb9a1), W64LIT(0x5f268b13134c1398), W64LIT(0x9c58512c2cb02c7d), W64LIT(0xb8bb05d3d36bd3d6), + W64LIT(0x5cd38ce7e7bbe76b), W64LIT(0xcbdc396e6ea56e57), W64LIT(0xf395aac4c437c46e), W64LIT(0x0f061b03030c0318), + W64LIT(0x13acdc565645568a), W64LIT(0x49885e44440d441a), W64LIT(0x9efea07f7fe17fdf), W64LIT(0x374f88a9a99ea921), + W64LIT(0x8254672a2aa82a4d), W64LIT(0x6d6b0abbbbd6bbb1), W64LIT(0xe29f87c1c123c146), W64LIT(0x02a6f153535153a2), + W64LIT(0x8ba572dcdc57dcae), W64LIT(0x2716530b0b2c0b58), W64LIT(0xd327019d9d4e9d9c), W64LIT(0xc1d82b6c6cad6c47), + W64LIT(0xf562a43131c43195), W64LIT(0xb9e8f37474cd7487), W64LIT(0x09f115f6f6fff6e3), W64LIT(0x438c4c464605460a), + W64LIT(0x2645a5acac8aac09), W64LIT(0x970fb589891e893c), W64LIT(0x4428b414145014a0), W64LIT(0x42dfbae1e1a3e15b), + W64LIT(0x4e2ca616165816b0), W64LIT(0xd274f73a3ae83acd), W64LIT(0xd0d2066969b9696f), W64LIT(0x2d12410909240948), + W64LIT(0xade0d77070dd70a7), W64LIT(0x54716fb6b6e2b6d9), W64LIT(0xb7bd1ed0d067d0ce), W64LIT(0x7ec7d6eded93ed3b), + W64LIT(0xdb85e2cccc17cc2e), W64LIT(0x578468424215422a), W64LIT(0xc22d2c98985a98b4), W64LIT(0x0e55eda4a4aaa449), + W64LIT(0x8850752828a0285d), W64LIT(0x31b8865c5c6d5cda), W64LIT(0x3fed6bf8f8c7f893), W64LIT(0xa411c28686228644), + + W64LIT(0x1823c6e887b8014f), + W64LIT(0x36a6d2f5796f9152), + W64LIT(0x60bc9b8ea30c7b35), + W64LIT(0x1de0d7c22e4bfe57), + W64LIT(0x157737e59ff04ada), + W64LIT(0x58c9290ab1a06b85), + W64LIT(0xbd5d10f4cb3e0567), + W64LIT(0xe427418ba77d95d8), + W64LIT(0xfbee7c66dd17479e), + W64LIT(0xca2dbf07ad5a8333) +}; + +// Whirlpool basic transformation. Transforms state based on block. +void Whirlpool::Transform(word64 *digest, const word64 *block) +{ +#if CRYPTOPP_BOOL_SSE2_ASM_AVAILABLE + if (HasISSE()) + { + // MMX version has the same structure as C version below +#ifdef __GNUC__ + #if CRYPTOPP_BOOL_X64 + __m128i workspace[8]; + #endif + __asm__ __volatile__ + ( + ".intel_syntax noprefix;" + AS_PUSH_IF86( bx) + AS2( mov AS_REG_6, WORD_REG(ax)) +#else + #if _MSC_VER < 1300 + AS_PUSH_IF86( bx) + #endif + AS2( lea AS_REG_6, [Whirlpool_C]) + AS2( mov WORD_REG(cx), digest) + AS2( mov WORD_REG(dx), block) +#endif +#if CRYPTOPP_BOOL_X86 + AS2( mov eax, esp) + AS2( and esp, -16) + AS2( sub esp, 16*8) + AS1( push eax) + #define SSE2_workspace esp+WORD_SZ +#else + #define SSE2_workspace %3 +#endif + AS2( xor esi, esi) + ASL(0) + AS2( movq mm0, [WORD_REG(cx)+8*WORD_REG(si)]) + AS2( movq [SSE2_workspace+8*WORD_REG(si)], mm0) // k + AS2( pxor mm0, [WORD_REG(dx)+8*WORD_REG(si)]) + AS2( movq [SSE2_workspace+64+8*WORD_REG(si)], mm0) // s + AS2( movq [WORD_REG(cx)+8*WORD_REG(si)], mm0) + AS1( inc WORD_REG(si)) + AS2( cmp WORD_REG(si), 8) + ASJ( jne, 0, b) + + AS2( xor esi, esi) + ASL(1) + +#define KSL0(a, b) AS2(movq mm##a, b) +#define KSL1(a, b) AS2(pxor mm##a, b) + +#define KSL(op, i, a, b, c, d) \ + AS2(mov eax, [SSE2_workspace+8*i])\ + AS2(movzx edi, al)\ + KSL##op(a, [AS_REG_6+3*2048+8*WORD_REG(di)])\ + AS2(movzx edi, ah)\ + KSL##op(b, [AS_REG_6+2*2048+8*WORD_REG(di)])\ + AS2(shr eax, 16)\ + AS2(movzx edi, al)\ + AS2(shr eax, 8)\ + KSL##op(c, [AS_REG_6+1*2048+8*WORD_REG(di)])\ + KSL##op(d, [AS_REG_6+0*2048+8*WORD_REG(ax)]) + +#define KSH0(a, b) \ + ASS(pshufw mm##a, mm##a, 1, 0, 3, 2)\ + AS2(pxor mm##a, b) +#define KSH1(a, b) \ + AS2(pxor mm##a, b) +#define KSH2(a, b) \ + AS2(pxor mm##a, b)\ + AS2(movq [SSE2_workspace+8*a], mm##a) + +#define KSH(op, i, a, b, c, d) \ + AS2(mov eax, [SSE2_workspace+8*((i+4)-8*((i+4)/8))+4])\ + AS2(movzx edi, al)\ + KSH##op(a, [AS_REG_6+3*2048+8*WORD_REG(di)])\ + AS2(movzx edi, ah)\ + KSH##op(b, [AS_REG_6+2*2048+8*WORD_REG(di)])\ + AS2(shr eax, 16)\ + AS2(movzx edi, al)\ + AS2(shr eax, 8)\ + KSH##op(c, [AS_REG_6+1*2048+8*WORD_REG(di)])\ + KSH##op(d, [AS_REG_6+0*2048+8*WORD_REG(ax)]) + +#define TSL(op, i, a, b, c, d) \ + AS2(mov eax, [SSE2_workspace+64+8*i])\ + AS2(movzx edi, al)\ + KSL##op(a, [AS_REG_6+3*2048+8*WORD_REG(di)])\ + AS2(movzx edi, ah)\ + KSL##op(b, [AS_REG_6+2*2048+8*WORD_REG(di)])\ + AS2(shr eax, 16)\ + AS2(movzx edi, al)\ + AS2(shr eax, 8)\ + KSL##op(c, [AS_REG_6+1*2048+8*WORD_REG(di)])\ + KSL##op(d, [AS_REG_6+0*2048+8*WORD_REG(ax)]) + +#define TSH0(a, b) \ + ASS(pshufw mm##a, mm##a, 1, 0, 3, 2)\ + AS2(pxor mm##a, [SSE2_workspace+8*a])\ + AS2(pxor mm##a, b) +#define TSH1(a, b) \ + AS2(pxor mm##a, b) +#define TSH2(a, b) \ + AS2(pxor mm##a, b)\ + AS2(movq [SSE2_workspace+64+8*a], mm##a) +#define TSH3(a, b) \ + AS2(pxor mm##a, b)\ + AS2(pxor mm##a, [WORD_REG(cx)+8*a])\ + AS2(movq [WORD_REG(cx)+8*a], mm##a) + +#define TSH(op, i, a, b, c, d) \ + AS2(mov eax, [SSE2_workspace+64+8*((i+4)-8*((i+4)/8))+4])\ + AS2(movzx edi, al)\ + TSH##op(a, [AS_REG_6+3*2048+8*WORD_REG(di)])\ + AS2(movzx edi, ah)\ + TSH##op(b, [AS_REG_6+2*2048+8*WORD_REG(di)])\ + AS2(shr eax, 16)\ + AS2(movzx edi, al)\ + AS2(shr eax, 8)\ + TSH##op(c, [AS_REG_6+1*2048+8*WORD_REG(di)])\ + TSH##op(d, [AS_REG_6+0*2048+8*WORD_REG(ax)]) + + KSL(0, 4, 3, 2, 1, 0) + KSL(0, 0, 7, 6, 5, 4) + KSL(1, 1, 0, 7, 6, 5) + KSL(1, 2, 1, 0, 7, 6) + KSL(1, 3, 2, 1, 0, 7) + KSL(1, 5, 4, 3, 2, 1) + KSL(1, 6, 5, 4, 3, 2) + KSL(1, 7, 6, 5, 4, 3) + KSH(0, 0, 7, 6, 5, 4) + KSH(0, 4, 3, 2, 1, 0) + KSH(1, 1, 0, 7, 6, 5) + KSH(1, 2, 1, 0, 7, 6) + KSH(1, 5, 4, 3, 2, 1) + KSH(1, 6, 5, 4, 3, 2) + KSH(2, 3, 2, 1, 0, 7) + KSH(2, 7, 6, 5, 4, 3) + + AS2( pxor mm0, [AS_REG_6 + 8*1024 + WORD_REG(si)*8]) + AS2( movq [SSE2_workspace], mm0) + + TSL(0, 4, 3, 2, 1, 0) + TSL(0, 0, 7, 6, 5, 4) + TSL(1, 1, 0, 7, 6, 5) + TSL(1, 2, 1, 0, 7, 6) + TSL(1, 3, 2, 1, 0, 7) + TSL(1, 5, 4, 3, 2, 1) + TSL(1, 6, 5, 4, 3, 2) + TSL(1, 7, 6, 5, 4, 3) + TSH(0, 0, 7, 6, 5, 4) + TSH(0, 4, 3, 2, 1, 0) + TSH(1, 1, 0, 7, 6, 5) + TSH(1, 2, 1, 0, 7, 6) + TSH(1, 5, 4, 3, 2, 1) + TSH(1, 6, 5, 4, 3, 2) + + AS1( inc WORD_REG(si)) + AS2( cmp WORD_REG(si), 10) + ASJ( je, 2, f) + + TSH(2, 3, 2, 1, 0, 7) + TSH(2, 7, 6, 5, 4, 3) + + ASJ( jmp, 1, b) + ASL(2) + + TSH(3, 3, 2, 1, 0, 7) + TSH(3, 7, 6, 5, 4, 3) + +#undef KSL +#undef KSH +#undef TSL +#undef TSH + + AS_POP_IF86( sp) + AS1( emms) + +#if defined(__GNUC__) || (defined(_MSC_VER) && _MSC_VER < 1300) + AS_POP_IF86( bx) +#endif +#ifdef __GNUC__ + ".att_syntax prefix;" + : + : "a" (Whirlpool_C), "c" (digest), "d" (block) + #if CRYPTOPP_BOOL_X64 + , "r" (workspace) + #endif + : "%esi", "%edi", "memory", "cc" + #if CRYPTOPP_BOOL_X64 + , "%r9" + #endif + ); +#endif + } + else +#endif // #ifdef CRYPTOPP_X86_ASM_AVAILABLE + { + word64 s[8]; // the cipher state + word64 k[8]; // the round key + + // Compute and apply K^0 to the cipher state + // Also apply part of the Miyaguchi-Preneel compression function + for (int i=0; i<8; i++) + digest[i] = s[i] = block[i] ^ (k[i] = digest[i]); + +#define KSL(op, i, a, b, c, d) \ + t = (word32)k[i];\ + w##a = Whirlpool_C[3*256 + (byte)t] ^ (op ? w##a : 0);\ + t >>= 8;\ + w##b = Whirlpool_C[2*256 + (byte)t] ^ (op ? w##b : 0);\ + t >>= 8;\ + w##c = Whirlpool_C[1*256 + (byte)t] ^ (op ? w##c : 0);\ + t >>= 8;\ + w##d = Whirlpool_C[0*256 + t] ^ (op ? w##d : 0); + +#define KSH(op, i, a, b, c, d) \ + t = (word32)(k[(i+4)%8]>>32);\ + w##a = Whirlpool_C[3*256 + (byte)t] ^ (op ? w##a : rotrFixed(w##a, 32));\ + if (op==2) k[a] = w##a;\ + t >>= 8;\ + w##b = Whirlpool_C[2*256 + (byte)t] ^ (op ? w##b : rotrFixed(w##b, 32));\ + if (op==2) k[b] = w##b;\ + t >>= 8;\ + w##c = Whirlpool_C[1*256 + (byte)t] ^ (op ? w##c : rotrFixed(w##c, 32));\ + if (op==2) k[c] = w##c;\ + t >>= 8;\ + w##d = Whirlpool_C[0*256 + t] ^ (op ? w##d : rotrFixed(w##d, 32));\ + if (op==2) k[d] = w##d;\ + +#define TSL(op, i, a, b, c, d) \ + t = (word32)s[i];\ + w##a = Whirlpool_C[3*256 + (byte)t] ^ (op ? w##a : 0);\ + t >>= 8;\ + w##b = Whirlpool_C[2*256 + (byte)t] ^ (op ? w##b : 0);\ + t >>= 8;\ + w##c = Whirlpool_C[1*256 + (byte)t] ^ (op ? w##c : 0);\ + t >>= 8;\ + w##d = Whirlpool_C[0*256 + t] ^ (op ? w##d : 0); + +#define TSH_OP(op, a, b) \ + w##a = Whirlpool_C[b*256 + (byte)t] ^ (op ? w##a : rotrFixed(w##a, 32) ^ k[a]);\ + if (op==2) s[a] = w##a;\ + if (op==3) digest[a] ^= w##a;\ + +#define TSH(op, i, a, b, c, d) \ + t = (word32)(s[(i+4)%8]>>32);\ + TSH_OP(op, a, 3);\ + t >>= 8;\ + TSH_OP(op, b, 2);\ + t >>= 8;\ + TSH_OP(op, c, 1);\ + t >>= 8;\ + TSH_OP(op, d, 0);\ + + // Iterate over all rounds: + int r=0; + while (true) + { + word64 w0, w1, w2, w3, w4, w5, w6, w7; // temporary storage + word32 t; + + KSL(0, 4, 3, 2, 1, 0) + KSL(0, 0, 7, 6, 5, 4) + KSL(1, 1, 0, 7, 6, 5) + KSL(1, 2, 1, 0, 7, 6) + KSL(1, 3, 2, 1, 0, 7) + KSL(1, 5, 4, 3, 2, 1) + KSL(1, 6, 5, 4, 3, 2) + KSL(1, 7, 6, 5, 4, 3) + KSH(0, 0, 7, 6, 5, 4) + KSH(0, 4, 3, 2, 1, 0) + KSH(1, 1, 0, 7, 6, 5) + KSH(1, 2, 1, 0, 7, 6) + KSH(1, 5, 4, 3, 2, 1) + KSH(1, 6, 5, 4, 3, 2) + KSH(2, 3, 2, 1, 0, 7) + KSH(2, 7, 6, 5, 4, 3) + + k[0] ^= Whirlpool_C[1024+r]; + + TSL(0, 4, 3, 2, 1, 0) + TSL(0, 0, 7, 6, 5, 4) + TSL(1, 1, 0, 7, 6, 5) + TSL(1, 2, 1, 0, 7, 6) + TSL(1, 3, 2, 1, 0, 7) + TSL(1, 5, 4, 3, 2, 1) + TSL(1, 6, 5, 4, 3, 2) + TSL(1, 7, 6, 5, 4, 3) + TSH(0, 0, 7, 6, 5, 4) + TSH(0, 4, 3, 2, 1, 0) + TSH(1, 1, 0, 7, 6, 5) + TSH(1, 2, 1, 0, 7, 6) + TSH(1, 5, 4, 3, 2, 1) + TSH(1, 6, 5, 4, 3, 2) + + if (++r < R) + { + TSH(2, 3, 2, 1, 0, 7) + TSH(2, 7, 6, 5, 4, 3) + } + else + { + TSH(3, 3, 2, 1, 0, 7) + TSH(3, 7, 6, 5, 4, 3) + break; + } + } + } +} + +NAMESPACE_END + +#endif // WORD64_AVAILABLE diff --git a/CryptoPP/crypto/whrlpool.h b/CryptoPP/crypto/whrlpool.h new file mode 100644 index 0000000..32f3a2d --- /dev/null +++ b/CryptoPP/crypto/whrlpool.h @@ -0,0 +1,26 @@ +#ifndef CRYPTOPP_WHIRLPOOL_H +#define CRYPTOPP_WHIRLPOOL_H + +#include "config.h" + +#ifdef WORD64_AVAILABLE + +#include "iterhash.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! Whirlpool +class Whirlpool : public IteratedHashWithStaticTransform +{ +public: + static void InitState(HashWordType *state); + static void Transform(word64 *digest, const word64 *data); + void TruncatedFinal(byte *hash, size_t size); + static const char * StaticAlgorithmName() {return "Whirlpool";} +}; + +NAMESPACE_END + +#endif + +#endif diff --git a/CryptoPP/crypto/winpipes.cpp b/CryptoPP/crypto/winpipes.cpp new file mode 100644 index 0000000..ea98439 --- /dev/null +++ b/CryptoPP/crypto/winpipes.cpp @@ -0,0 +1,205 @@ +// winpipes.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "winpipes.h" + +#ifdef WINDOWS_PIPES_AVAILABLE + +#include "wait.h" + +NAMESPACE_BEGIN(CryptoPP) + +WindowsHandle::WindowsHandle(HANDLE h, bool own) + : m_h(h), m_own(own) +{ +} + +WindowsHandle::~WindowsHandle() +{ + if (m_own) + { + try + { + CloseHandle(); + } + catch (...) + { + } + } +} + +bool WindowsHandle::HandleValid() const +{ + return m_h && m_h != INVALID_HANDLE_VALUE; +} + +void WindowsHandle::AttachHandle(HANDLE h, bool own) +{ + if (m_own) + CloseHandle(); + + m_h = h; + m_own = own; + HandleChanged(); +} + +HANDLE WindowsHandle::DetachHandle() +{ + HANDLE h = m_h; + m_h = INVALID_HANDLE_VALUE; + HandleChanged(); + return h; +} + +void WindowsHandle::CloseHandle() +{ + if (m_h != INVALID_HANDLE_VALUE) + { + ::CloseHandle(m_h); + m_h = INVALID_HANDLE_VALUE; + HandleChanged(); + } +} + +// ******************************************************** + +void WindowsPipe::HandleError(const char *operation) const +{ + DWORD err = GetLastError(); + throw Err(GetHandle(), operation, err); +} + +WindowsPipe::Err::Err(HANDLE s, const std::string& operation, int error) + : OS_Error(IO_ERROR, "WindowsPipe: " + operation + " operation failed with error 0x" + IntToString(error, 16), operation, error) + , m_h(s) +{ +} + +// ************************************************************* + +WindowsPipeReceiver::WindowsPipeReceiver() + : m_resultPending(false), m_eofReceived(false) +{ + m_event.AttachHandle(CreateEvent(NULL, true, false, NULL), true); + CheckAndHandleError("CreateEvent", m_event.HandleValid()); + memset(&m_overlapped, 0, sizeof(m_overlapped)); + m_overlapped.hEvent = m_event; +} + +bool WindowsPipeReceiver::Receive(byte* buf, size_t bufLen) +{ + assert(!m_resultPending && !m_eofReceived); + + HANDLE h = GetHandle(); + // don't queue too much at once, or we might use up non-paged memory + if (ReadFile(h, buf, UnsignedMin((DWORD)128*1024, bufLen), &m_lastResult, &m_overlapped)) + { + if (m_lastResult == 0) + m_eofReceived = true; + } + else + { + switch (GetLastError()) + { + default: + CheckAndHandleError("ReadFile", false); + case ERROR_BROKEN_PIPE: + case ERROR_HANDLE_EOF: + m_lastResult = 0; + m_eofReceived = true; + break; + case ERROR_IO_PENDING: + m_resultPending = true; + } + } + return !m_resultPending; +} + +void WindowsPipeReceiver::GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack) +{ + if (m_resultPending) + container.AddHandle(m_event, CallStack("WindowsPipeReceiver::GetWaitObjects() - result pending", &callStack)); + else if (!m_eofReceived) + container.SetNoWait(CallStack("WindowsPipeReceiver::GetWaitObjects() - result ready", &callStack)); +} + +unsigned int WindowsPipeReceiver::GetReceiveResult() +{ + if (m_resultPending) + { + HANDLE h = GetHandle(); + if (GetOverlappedResult(h, &m_overlapped, &m_lastResult, false)) + { + if (m_lastResult == 0) + m_eofReceived = true; + } + else + { + switch (GetLastError()) + { + default: + CheckAndHandleError("GetOverlappedResult", false); + case ERROR_BROKEN_PIPE: + case ERROR_HANDLE_EOF: + m_lastResult = 0; + m_eofReceived = true; + } + } + m_resultPending = false; + } + return m_lastResult; +} + +// ************************************************************* + +WindowsPipeSender::WindowsPipeSender() + : m_resultPending(false), m_lastResult(0) +{ + m_event.AttachHandle(CreateEvent(NULL, true, false, NULL), true); + CheckAndHandleError("CreateEvent", m_event.HandleValid()); + memset(&m_overlapped, 0, sizeof(m_overlapped)); + m_overlapped.hEvent = m_event; +} + +void WindowsPipeSender::Send(const byte* buf, size_t bufLen) +{ + DWORD written = 0; + HANDLE h = GetHandle(); + // don't queue too much at once, or we might use up non-paged memory + if (WriteFile(h, buf, UnsignedMin((DWORD)128*1024, bufLen), &written, &m_overlapped)) + { + m_resultPending = false; + m_lastResult = written; + } + else + { + if (GetLastError() != ERROR_IO_PENDING) + CheckAndHandleError("WriteFile", false); + + m_resultPending = true; + } +} + +void WindowsPipeSender::GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack) +{ + if (m_resultPending) + container.AddHandle(m_event, CallStack("WindowsPipeSender::GetWaitObjects() - result pending", &callStack)); + else + container.SetNoWait(CallStack("WindowsPipeSender::GetWaitObjects() - result ready", &callStack)); +} + +unsigned int WindowsPipeSender::GetSendResult() +{ + if (m_resultPending) + { + HANDLE h = GetHandle(); + BOOL result = GetOverlappedResult(h, &m_overlapped, &m_lastResult, false); + CheckAndHandleError("GetOverlappedResult", result); + m_resultPending = false; + } + return m_lastResult; +} + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/winpipes.h b/CryptoPP/crypto/winpipes.h new file mode 100644 index 0000000..75ac3a8 --- /dev/null +++ b/CryptoPP/crypto/winpipes.h @@ -0,0 +1,142 @@ +#ifndef CRYPTOPP_WINPIPES_H +#define CRYPTOPP_WINPIPES_H + +#include "config.h" + +#ifdef WINDOWS_PIPES_AVAILABLE + +#include "network.h" +#include "queue.h" +#include + +NAMESPACE_BEGIN(CryptoPP) + +//! Windows Handle +class WindowsHandle +{ +public: + WindowsHandle(HANDLE h = INVALID_HANDLE_VALUE, bool own=false); + WindowsHandle(const WindowsHandle &h) : m_h(h.m_h), m_own(false) {} + virtual ~WindowsHandle(); + + bool GetOwnership() const {return m_own;} + void SetOwnership(bool own) {m_own = own;} + + operator HANDLE() {return m_h;} + HANDLE GetHandle() const {return m_h;} + bool HandleValid() const; + void AttachHandle(HANDLE h, bool own=false); + HANDLE DetachHandle(); + void CloseHandle(); + +protected: + virtual void HandleChanged() {} + + HANDLE m_h; + bool m_own; +}; + +//! Windows Pipe +class WindowsPipe +{ +public: + class Err : public OS_Error + { + public: + Err(HANDLE h, const std::string& operation, int error); + HANDLE GetHandle() const {return m_h;} + + private: + HANDLE m_h; + }; + +protected: + virtual HANDLE GetHandle() const =0; + virtual void HandleError(const char *operation) const; + void CheckAndHandleError(const char *operation, BOOL result) const + {assert(result==TRUE || result==FALSE); if (!result) HandleError(operation);} +}; + +//! pipe-based implementation of NetworkReceiver +class WindowsPipeReceiver : public WindowsPipe, public NetworkReceiver +{ +public: + WindowsPipeReceiver(); + + bool MustWaitForResult() {return true;} + bool Receive(byte* buf, size_t bufLen); + unsigned int GetReceiveResult(); + bool EofReceived() const {return m_eofReceived;} + + unsigned int GetMaxWaitObjectCount() const {return 1;} + void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack); + +private: + WindowsHandle m_event; + OVERLAPPED m_overlapped; + bool m_resultPending; + DWORD m_lastResult; + bool m_eofReceived; +}; + +//! pipe-based implementation of NetworkSender +class WindowsPipeSender : public WindowsPipe, public NetworkSender +{ +public: + WindowsPipeSender(); + + bool MustWaitForResult() {return true;} + void Send(const byte* buf, size_t bufLen); + unsigned int GetSendResult(); + bool MustWaitForEof() { return false; } + void SendEof() {} + + unsigned int GetMaxWaitObjectCount() const {return 1;} + void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack); + +private: + WindowsHandle m_event; + OVERLAPPED m_overlapped; + bool m_resultPending; + DWORD m_lastResult; +}; + +//! Windows Pipe Source +class WindowsPipeSource : public WindowsHandle, public NetworkSource, public WindowsPipeReceiver +{ +public: + WindowsPipeSource(HANDLE h=INVALID_HANDLE_VALUE, bool pumpAll=false, BufferedTransformation *attachment=NULL) + : WindowsHandle(h), NetworkSource(attachment) + { + if (pumpAll) + PumpAll(); + } + + NetworkSource::GetMaxWaitObjectCount; + NetworkSource::GetWaitObjects; + +private: + HANDLE GetHandle() const {return WindowsHandle::GetHandle();} + NetworkReceiver & AccessReceiver() {return *this;} +}; + +//! Windows Pipe Sink +class WindowsPipeSink : public WindowsHandle, public NetworkSink, public WindowsPipeSender +{ +public: + WindowsPipeSink(HANDLE h=INVALID_HANDLE_VALUE, unsigned int maxBufferSize=0, unsigned int autoFlushBound=16*1024) + : WindowsHandle(h), NetworkSink(maxBufferSize, autoFlushBound) {} + + NetworkSink::GetMaxWaitObjectCount; + NetworkSink::GetWaitObjects; + +private: + HANDLE GetHandle() const {return WindowsHandle::GetHandle();} + NetworkSender & AccessSender() {return *this;} +}; + +NAMESPACE_END + +#endif + +#endif diff --git a/CryptoPP/crypto/words.h b/CryptoPP/crypto/words.h new file mode 100644 index 0000000..f76e849 --- /dev/null +++ b/CryptoPP/crypto/words.h @@ -0,0 +1,103 @@ +#ifndef CRYPTOPP_WORDS_H +#define CRYPTOPP_WORDS_H + +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +inline size_t CountWords(const word *X, size_t N) +{ + while (N && X[N-1]==0) + N--; + return N; +} + +inline void SetWords(word *r, word a, size_t n) +{ + for (size_t i=0; i> (WORD_BITS-shiftBits); + } + return carry; +} + +inline word ShiftWordsRightByBits(word *r, size_t n, unsigned int shiftBits) +{ + assert (shiftBits0; i--) + { + u = r[i-1]; + r[i-1] = (u >> shiftBits) | carry; + carry = u << (WORD_BITS-shiftBits); + } + return carry; +} + +inline void ShiftWordsLeftByWords(word *r, size_t n, size_t shiftWords) +{ + shiftWords = STDMIN(shiftWords, n); + if (shiftWords) + { + for (size_t i=n-1; i>=shiftWords; i--) + r[i] = r[i-shiftWords]; + SetWords(r, 0, shiftWords); + } +} + +inline void ShiftWordsRightByWords(word *r, size_t n, size_t shiftWords) +{ + shiftWords = STDMIN(shiftWords, n); + if (shiftWords) + { + for (size_t i=0; i+shiftWords struct DigestSizeSubtract4Workaround // VC60 workaround +{ + CRYPTOPP_CONSTANT(RESULT = T::DIGESTSIZE-4) +}; + +template +class CRYPTOPP_NO_VTABLE XMACC_Base : public FixedKeyLength::RESULT, SimpleKeyingInterface::INTERNALLY_GENERATED_IV>, + public IteratedHash +{ +public: + static std::string StaticAlgorithmName() {return std::string("XMAC(") + T::StaticAlgorithmName() + ")";} + CRYPTOPP_CONSTANT(DIGESTSIZE = 4+T::DIGESTSIZE) + typedef typename T::HashWordType HashWordType; + + XMACC_Base() {SetStateSize(T::DIGESTSIZE);} + + void UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms); + void Resynchronize(const byte *IV) + { + GetWord(false, BIG_ENDIAN_ORDER, m_counter, IV); + this->Restart(); + } + unsigned int IVSize() const + {return 4;} + void GetNextIV(byte *IV) + { + if (m_counter == 0xffffffff) + throw NotImplemented("XMACC: must have a valid counter to get next IV"); + PutWord(false, BIG_ENDIAN_ORDER, IV, m_counter+1); + } + + word32 CurrentCounter() const {return m_counter;} + + void TruncatedFinal(byte *mac, size_t size); + bool TruncatedVerify(const byte *mac, size_t length); + unsigned int DigestSize() const {return DIGESTSIZE;} // need to override this + +private: + void Init(); + static void WriteWord32(byte *output, word32 value); + static void XorDigest(HashWordType *digest, const HashWordType *buffer); + void HashEndianCorrectedBlock(const HashWordType *data); + + FixedSizeSecBlock::RESULT> m_key; + CRYPTOPP_CONSTANT(BUFFER_SIZE = (T::DIGESTSIZE / sizeof(HashWordType))) // VC60 workaround +#ifdef __BORLANDC__ + FixedSizeSecBlock m_buffer; +#else + FixedSizeSecBlock m_buffer; +#endif + word32 m_counter, m_index; +}; + +//! XMAC +/*! If you need to generate MACs with XMACC (instead of just verifying them), + you must save the counter before destroying an XMACC object + and reinitialize it the next time you create an XMACC with the same key. + Start counter at 0 when using a key for the first time. */ +template +class XMACC : public ClonableImpl, MessageAuthenticationCodeImpl > > +{ +public: + XMACC() {} + XMACC(const byte *key, word32 counter = 0xffffffff) + {this->SetKey(key, this->KEYLENGTH, MakeParameters(Name::XMACC_Counter(), counter));} +}; + +template void XMACC_Base::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms) +{ + this->AssertValidKeyLength(length); + m_counter = 0xffffffff; + const byte *iv = NULL; + if (params.GetValue(Name::IV(), iv)) + GetWord(false, BIG_ENDIAN_ORDER, m_counter, iv); + else + params.GetValue(Name::XMACC_Counter(), m_counter); + memcpy_s(m_key, m_key.SizeInBytes(), key, this->KEYLENGTH); + Init(); +} + +template void XMACC_Base::Init() +{ + m_index = 0x80000000; + memset(this->m_digest, 0, T::DIGESTSIZE); +} + +template inline void XMACC_Base::WriteWord32(byte *output, word32 value) +{ + output[0] = byte(value >> 24); + output[1] = byte(value >> 16); + output[2] = byte(value >> 8); + output[3] = byte(value); +} + +template inline void XMACC_Base::XorDigest(HashWordType *digest, const HashWordType *buffer) +{ + for (unsigned i=0; i<(T::DIGESTSIZE/sizeof(HashWordType)); i++) + digest[i] ^= buffer[i]; +} + +template void XMACC_Base::HashEndianCorrectedBlock(const HashWordType *input) +{ + memcpy_s(m_buffer, m_buffer.SizeInBytes(), m_key, this->KEYLENGTH); + WriteWord32((byte *)m_buffer.begin()+this->KEYLENGTH, ++m_index); + T::CorrectEndianess(m_buffer, m_buffer, T::DIGESTSIZE); + T::Transform(m_buffer, input); + XorDigest(this->m_digest, m_buffer); +} + +template void XMACC_Base::TruncatedFinal(byte *mac, size_t size) +{ + this->ThrowIfInvalidTruncatedSize(size); + if (size < 4) + throw InvalidArgument("XMACC: truncating the MAC to less than 4 bytes will cause it to be unverifiable"); + if (m_counter == 0xffffffff) + throw InvalidArgument("XMACC: the counter must be initialized to a valid value for MAC generation"); + + PadLastBlock(this->BLOCKSIZE - 2*sizeof(HashWordType)); + CorrectEndianess(this->m_data, this->m_data, this->BLOCKSIZE - 2*sizeof(HashWordType)); + this->m_data[this->m_data.size()-2] = ByteReverse(this->GetBitCountHi()); // ByteReverse for backwards compatibility + this->m_data[this->m_data.size()-1] = ByteReverse(this->GetBitCountLo()); + HashEndianCorrectedBlock(this->m_data); + + memcpy_s(m_buffer, m_buffer.SizeInBytes(), m_key, this->KEYLENGTH); + WriteWord32((byte *)m_buffer.begin()+this->KEYLENGTH, 0); + memset(this->m_data, 0, this->BLOCKSIZE-4); + WriteWord32((byte *)this->m_data.begin()+this->BLOCKSIZE-4, ++m_counter); + T::CorrectEndianess(m_buffer, m_buffer, T::DIGESTSIZE); + T::CorrectEndianess(this->m_data, this->m_data, this->BLOCKSIZE); + T::Transform(m_buffer, this->m_data); + XorDigest(this->m_digest, m_buffer); + + WriteWord32(mac, m_counter); + T::CorrectEndianess(this->m_digest, this->m_digest, T::DIGESTSIZE); + memcpy_s(mac+4, size-4, this->m_digest, size-4); + + this->Restart(); // reinit for next use +} + +template bool XMACC_Base::TruncatedVerify(const byte *mac, size_t size) +{ + assert(4 <= size && size <= DIGESTSIZE); + + PadLastBlock(this->BLOCKSIZE - 2*sizeof(HashWordType)); + CorrectEndianess(this->m_data, this->m_data, this->BLOCKSIZE - 2*sizeof(HashWordType)); + this->m_data[this->m_data.size()-2] = ByteReverse(this->GetBitCountHi()); // ByteReverse for backwards compatibility + this->m_data[this->m_data.size()-1] = ByteReverse(this->GetBitCountLo()); + HashEndianCorrectedBlock(this->m_data); + + memcpy_s(m_buffer, m_buffer.SizeInBytes(), m_key, this->KEYLENGTH); + WriteWord32((byte *)m_buffer.begin()+this->KEYLENGTH, 0); + memset(this->m_data, 0, this->BLOCKSIZE-4); + memcpy_s((byte *)this->m_data.begin()+this->BLOCKSIZE-4, 4, mac, 4); + T::CorrectEndianess(m_buffer, m_buffer, T::DIGESTSIZE); + T::CorrectEndianess(this->m_data, this->m_data, this->BLOCKSIZE); + T::Transform(m_buffer, this->m_data); + XorDigest(this->m_digest, m_buffer); + + T::CorrectEndianess(this->m_digest, this->m_digest, T::DIGESTSIZE); + bool macValid = (memcmp(mac+4, this->m_digest, size-4) == 0); + this->Restart(); // reinit for next use + return macValid; +} + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/xtr.cpp b/CryptoPP/crypto/xtr.cpp new file mode 100644 index 0000000..d2f3fb0 --- /dev/null +++ b/CryptoPP/crypto/xtr.cpp @@ -0,0 +1,100 @@ +// cryptlib.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "xtr.h" +#include "nbtheory.h" + +#include "algebra.cpp" + +NAMESPACE_BEGIN(CryptoPP) + +const GFP2Element & GFP2Element::Zero() +{ + return Singleton().Ref(); +} + +void XTR_FindPrimesAndGenerator(RandomNumberGenerator &rng, Integer &p, Integer &q, GFP2Element &g, unsigned int pbits, unsigned int qbits) +{ + assert(qbits > 9); // no primes exist for pbits = 10, qbits = 9 + assert(pbits > qbits); + + const Integer minQ = Integer::Power2(qbits - 1); + const Integer maxQ = Integer::Power2(qbits) - 1; + const Integer minP = Integer::Power2(pbits - 1); + const Integer maxP = Integer::Power2(pbits) - 1; + + Integer r1, r2; + do + { + bool qFound = q.Randomize(rng, minQ, maxQ, Integer::PRIME, 7, 12); + assert(qFound); + bool solutionsExist = SolveModularQuadraticEquation(r1, r2, 1, -1, 1, q); + assert(solutionsExist); + } while (!p.Randomize(rng, minP, maxP, Integer::PRIME, CRT(rng.GenerateBit()?r1:r2, q, 2, 3), 3*q)); + assert(((p.Squared() - p + 1) % q).IsZero()); + + GFP2_ONB gfp2(p); + GFP2Element three = gfp2.ConvertIn(3), t; + + while (true) + { + g.c1.Randomize(rng, Integer::Zero(), p-1); + g.c2.Randomize(rng, Integer::Zero(), p-1); + t = XTR_Exponentiate(g, p+1, p); + if (t.c1 == t.c2) + continue; + g = XTR_Exponentiate(g, (p.Squared()-p+1)/q, p); + if (g != three) + break; + } + assert(XTR_Exponentiate(g, q, p) == three); +} + +GFP2Element XTR_Exponentiate(const GFP2Element &b, const Integer &e, const Integer &p) +{ + unsigned int bitCount = e.BitCount(); + if (bitCount == 0) + return GFP2Element(-3, -3); + + // find the lowest bit of e that is 1 + unsigned int lowest1bit; + for (lowest1bit=0; e.GetBit(lowest1bit) == 0; lowest1bit++) {} + + GFP2_ONB gfp2(p); + GFP2Element c = gfp2.ConvertIn(b); + GFP2Element cp = gfp2.PthPower(c); + GFP2Element S[5] = {gfp2.ConvertIn(3), c, gfp2.SpecialOperation1(c)}; + + // do all exponents bits except the lowest zeros starting from the top + unsigned int i; + for (i = e.BitCount() - 1; i>lowest1bit; i--) + { + if (e.GetBit(i)) + { + gfp2.RaiseToPthPower(S[0]); + gfp2.Accumulate(S[0], gfp2.SpecialOperation2(S[2], c, S[1])); + S[1] = gfp2.SpecialOperation1(S[1]); + S[2] = gfp2.SpecialOperation1(S[2]); + S[0].swap(S[1]); + } + else + { + gfp2.RaiseToPthPower(S[2]); + gfp2.Accumulate(S[2], gfp2.SpecialOperation2(S[0], cp, S[1])); + S[1] = gfp2.SpecialOperation1(S[1]); + S[0] = gfp2.SpecialOperation1(S[0]); + S[2].swap(S[1]); + } + } + + // now do the lowest zeros + while (i--) + S[1] = gfp2.SpecialOperation1(S[1]); + + return gfp2.ConvertOut(S[1]); +} + +template class AbstractRing; +template class AbstractGroup; + +NAMESPACE_END diff --git a/CryptoPP/crypto/xtr.h b/CryptoPP/crypto/xtr.h new file mode 100644 index 0000000..40ca8a1 --- /dev/null +++ b/CryptoPP/crypto/xtr.h @@ -0,0 +1,215 @@ +#ifndef CRYPTOPP_XTR_H +#define CRYPTOPP_XTR_H + +/** \file + "The XTR public key system" by Arjen K. Lenstra and Eric R. Verheul +*/ + +#include "modarith.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! an element of GF(p^2) +class GFP2Element +{ +public: + GFP2Element() {} + GFP2Element(const Integer &c1, const Integer &c2) : c1(c1), c2(c2) {} + GFP2Element(const byte *encodedElement, unsigned int size) + : c1(encodedElement, size/2), c2(encodedElement+size/2, size/2) {} + + void Encode(byte *encodedElement, unsigned int size) + { + c1.Encode(encodedElement, size/2); + c2.Encode(encodedElement+size/2, size/2); + } + + bool operator==(const GFP2Element &rhs) const {return c1 == rhs.c1 && c2 == rhs.c2;} + bool operator!=(const GFP2Element &rhs) const {return !operator==(rhs);} + + void swap(GFP2Element &a) + { + c1.swap(a.c1); + c2.swap(a.c2); + } + + static const GFP2Element & Zero(); + + Integer c1, c2; +}; + +//! GF(p^2), optimal normal basis +template +class GFP2_ONB : public AbstractRing +{ +public: + typedef F BaseField; + + GFP2_ONB(const Integer &p) : modp(p) + { + if (p%3 != 2) + throw InvalidArgument("GFP2_ONB: modulus must be equivalent to 2 mod 3"); + } + + const Integer& GetModulus() const {return modp.GetModulus();} + + GFP2Element ConvertIn(const Integer &a) const + { + t = modp.Inverse(modp.ConvertIn(a)); + return GFP2Element(t, t); + } + + GFP2Element ConvertIn(const GFP2Element &a) const + {return GFP2Element(modp.ConvertIn(a.c1), modp.ConvertIn(a.c2));} + + GFP2Element ConvertOut(const GFP2Element &a) const + {return GFP2Element(modp.ConvertOut(a.c1), modp.ConvertOut(a.c2));} + + bool Equal(const GFP2Element &a, const GFP2Element &b) const + { + return modp.Equal(a.c1, b.c1) && modp.Equal(a.c2, b.c2); + } + + const Element& Identity() const + { + return GFP2Element::Zero(); + } + + const Element& Add(const Element &a, const Element &b) const + { + result.c1 = modp.Add(a.c1, b.c1); + result.c2 = modp.Add(a.c2, b.c2); + return result; + } + + const Element& Inverse(const Element &a) const + { + result.c1 = modp.Inverse(a.c1); + result.c2 = modp.Inverse(a.c2); + return result; + } + + const Element& Double(const Element &a) const + { + result.c1 = modp.Double(a.c1); + result.c2 = modp.Double(a.c2); + return result; + } + + const Element& Subtract(const Element &a, const Element &b) const + { + result.c1 = modp.Subtract(a.c1, b.c1); + result.c2 = modp.Subtract(a.c2, b.c2); + return result; + } + + Element& Accumulate(Element &a, const Element &b) const + { + modp.Accumulate(a.c1, b.c1); + modp.Accumulate(a.c2, b.c2); + return a; + } + + Element& Reduce(Element &a, const Element &b) const + { + modp.Reduce(a.c1, b.c1); + modp.Reduce(a.c2, b.c2); + return a; + } + + bool IsUnit(const Element &a) const + { + return a.c1.NotZero() || a.c2.NotZero(); + } + + const Element& MultiplicativeIdentity() const + { + result.c1 = result.c2 = modp.Inverse(modp.MultiplicativeIdentity()); + return result; + } + + const Element& Multiply(const Element &a, const Element &b) const + { + t = modp.Add(a.c1, a.c2); + t = modp.Multiply(t, modp.Add(b.c1, b.c2)); + result.c1 = modp.Multiply(a.c1, b.c1); + result.c2 = modp.Multiply(a.c2, b.c2); + result.c1.swap(result.c2); + modp.Reduce(t, result.c1); + modp.Reduce(t, result.c2); + modp.Reduce(result.c1, t); + modp.Reduce(result.c2, t); + return result; + } + + const Element& MultiplicativeInverse(const Element &a) const + { + return result = Exponentiate(a, modp.GetModulus()-2); + } + + const Element& Square(const Element &a) const + { + const Integer &ac1 = (&a == &result) ? (t = a.c1) : a.c1; + result.c1 = modp.Multiply(modp.Subtract(modp.Subtract(a.c2, a.c1), a.c1), a.c2); + result.c2 = modp.Multiply(modp.Subtract(modp.Subtract(ac1, a.c2), a.c2), ac1); + return result; + } + + Element Exponentiate(const Element &a, const Integer &e) const + { + Integer edivp, emodp; + Integer::Divide(emodp, edivp, e, modp.GetModulus()); + Element b = PthPower(a); + return AbstractRing::CascadeExponentiate(a, emodp, b, edivp); + } + + const Element & PthPower(const Element &a) const + { + result = a; + result.c1.swap(result.c2); + return result; + } + + void RaiseToPthPower(Element &a) const + { + a.c1.swap(a.c2); + } + + // a^2 - 2a^p + const Element & SpecialOperation1(const Element &a) const + { + assert(&a != &result); + result = Square(a); + modp.Reduce(result.c1, a.c2); + modp.Reduce(result.c1, a.c2); + modp.Reduce(result.c2, a.c1); + modp.Reduce(result.c2, a.c1); + return result; + } + + // x * z - y * z^p + const Element & SpecialOperation2(const Element &x, const Element &y, const Element &z) const + { + assert(&x != &result && &y != &result && &z != &result); + t = modp.Add(x.c2, y.c2); + result.c1 = modp.Multiply(z.c1, modp.Subtract(y.c1, t)); + modp.Accumulate(result.c1, modp.Multiply(z.c2, modp.Subtract(t, x.c1))); + t = modp.Add(x.c1, y.c1); + result.c2 = modp.Multiply(z.c2, modp.Subtract(y.c2, t)); + modp.Accumulate(result.c2, modp.Multiply(z.c1, modp.Subtract(t, x.c2))); + return result; + } + +protected: + BaseField modp; + mutable GFP2Element result; + mutable Integer t; +}; + +void XTR_FindPrimesAndGenerator(RandomNumberGenerator &rng, Integer &p, Integer &q, GFP2Element &g, unsigned int pbits, unsigned int qbits); + +GFP2Element XTR_Exponentiate(const GFP2Element &b, const Integer &e, const Integer &p); + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/xtrcrypt.cpp b/CryptoPP/crypto/xtrcrypt.cpp new file mode 100644 index 0000000..ce3ed76 --- /dev/null +++ b/CryptoPP/crypto/xtrcrypt.cpp @@ -0,0 +1,108 @@ +// xtrcrypt.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" +#include "xtrcrypt.h" +#include "nbtheory.h" +#include "asn.h" +#include "argnames.h" + +NAMESPACE_BEGIN(CryptoPP) + +XTR_DH::XTR_DH(const Integer &p, const Integer &q, const GFP2Element &g) + : m_p(p), m_q(q), m_g(g) +{ +} + +XTR_DH::XTR_DH(RandomNumberGenerator &rng, unsigned int pbits, unsigned int qbits) +{ + XTR_FindPrimesAndGenerator(rng, m_p, m_q, m_g, pbits, qbits); +} + +XTR_DH::XTR_DH(BufferedTransformation &bt) +{ + BERSequenceDecoder seq(bt); + m_p.BERDecode(seq); + m_q.BERDecode(seq); + m_g.c1.BERDecode(seq); + m_g.c2.BERDecode(seq); + seq.MessageEnd(); +} + +void XTR_DH::DEREncode(BufferedTransformation &bt) const +{ + DERSequenceEncoder seq(bt); + m_p.DEREncode(seq); + m_q.DEREncode(seq); + m_g.c1.DEREncode(seq); + m_g.c2.DEREncode(seq); + seq.MessageEnd(); +} + +bool XTR_DH::Validate(RandomNumberGenerator &rng, unsigned int level) const +{ + bool pass = true; + pass = pass && m_p > Integer::One() && m_p.IsOdd(); + pass = pass && m_q > Integer::One() && m_q.IsOdd(); + GFP2Element three = GFP2_ONB(m_p).ConvertIn(3); + pass = pass && !(m_g.c1.IsNegative() || m_g.c2.IsNegative() || m_g.c1 >= m_p || m_g.c2 >= m_p || m_g == three); + if (level >= 1) + pass = pass && ((m_p.Squared()-m_p+1)%m_q).IsZero(); + if (level >= 2) + { + pass = pass && VerifyPrime(rng, m_p, level-2) && VerifyPrime(rng, m_q, level-2); + pass = pass && XTR_Exponentiate(m_g, (m_p.Squared()-m_p+1)/m_q, m_p) != three; + pass = pass && XTR_Exponentiate(m_g, m_q, m_p) == three; + } + return pass; +} + +bool XTR_DH::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const +{ + return GetValueHelper(this, name, valueType, pValue).Assignable() + CRYPTOPP_GET_FUNCTION_ENTRY(Modulus) + CRYPTOPP_GET_FUNCTION_ENTRY(SubgroupOrder) + CRYPTOPP_GET_FUNCTION_ENTRY(SubgroupGenerator) + ; +} + +void XTR_DH::AssignFrom(const NameValuePairs &source) +{ + AssignFromHelper(this, source) + CRYPTOPP_SET_FUNCTION_ENTRY(Modulus) + CRYPTOPP_SET_FUNCTION_ENTRY(SubgroupOrder) + CRYPTOPP_SET_FUNCTION_ENTRY(SubgroupGenerator) + ; +} + +void XTR_DH::GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const +{ + Integer x(rng, Integer::Zero(), m_q-1); + x.Encode(privateKey, PrivateKeyLength()); +} + +void XTR_DH::GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const +{ + Integer x(privateKey, PrivateKeyLength()); + GFP2Element y = XTR_Exponentiate(m_g, x, m_p); + y.Encode(publicKey, PublicKeyLength()); +} + +bool XTR_DH::Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey) const +{ + GFP2Element w(otherPublicKey, PublicKeyLength()); + if (validateOtherPublicKey) + { + GFP2_ONB gfp2(m_p); + GFP2Element three = gfp2.ConvertIn(3); + if (w.c1.IsNegative() || w.c2.IsNegative() || w.c1 >= m_p || w.c2 >= m_p || w == three) + return false; + if (XTR_Exponentiate(w, m_q, m_p) != three) + return false; + } + Integer s(privateKey, PrivateKeyLength()); + GFP2Element z = XTR_Exponentiate(w, s, m_p); + z.Encode(agreedValue, AgreedValueLength()); + return true; +} + +NAMESPACE_END diff --git a/CryptoPP/crypto/xtrcrypt.h b/CryptoPP/crypto/xtrcrypt.h new file mode 100644 index 0000000..2f51b11 --- /dev/null +++ b/CryptoPP/crypto/xtrcrypt.h @@ -0,0 +1,54 @@ +#ifndef CRYPTOPP_XTRCRYPT_H +#define CRYPTOPP_XTRCRYPT_H + +/** \file + "The XTR public key system" by Arjen K. Lenstra and Eric R. Verheul +*/ + +#include "xtr.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! XTR-DH with key validation + +class XTR_DH : public SimpleKeyAgreementDomain, public CryptoParameters +{ + typedef XTR_DH ThisClass; + +public: + XTR_DH(const Integer &p, const Integer &q, const GFP2Element &g); + XTR_DH(RandomNumberGenerator &rng, unsigned int pbits, unsigned int qbits); + XTR_DH(BufferedTransformation &domainParams); + + void DEREncode(BufferedTransformation &domainParams) const; + + bool Validate(RandomNumberGenerator &rng, unsigned int level) const; + bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const; + void AssignFrom(const NameValuePairs &source); + CryptoParameters & AccessCryptoParameters() {return *this;} + unsigned int AgreedValueLength() const {return 2*m_p.ByteCount();} + unsigned int PrivateKeyLength() const {return m_q.ByteCount();} + unsigned int PublicKeyLength() const {return 2*m_p.ByteCount();} + + void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const; + void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const; + bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const; + + const Integer &GetModulus() const {return m_p;} + const Integer &GetSubgroupOrder() const {return m_q;} + const GFP2Element &GetSubgroupGenerator() const {return m_g;} + + void SetModulus(const Integer &p) {m_p = p;} + void SetSubgroupOrder(const Integer &q) {m_q = q;} + void SetSubgroupGenerator(const GFP2Element &g) {m_g = g;} + +private: + unsigned int ExponentBitLength() const; + + Integer m_p, m_q; + GFP2Element m_g; +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/xtrdh171.dat b/CryptoPP/crypto/xtrdh171.dat new file mode 100644 index 0000000..ba784ca --- /dev/null +++ b/CryptoPP/crypto/xtrdh171.dat @@ -0,0 +1,3 @@ +305F02160559DCD66A95A57249A15BAD6B431BF2CD58615B901D02153365CFA0D3B1B6577B2DB243 +DDE45EDB91C18B0F5F0216032F4EBA0911B3D0B14F6F1292A74DFFD4A8FCF22C1802160211CB3EDA +809FA0FF8C3A8AE691EC4C95A06A3395CF diff --git a/CryptoPP/crypto/xtrdh342.dat b/CryptoPP/crypto/xtrdh342.dat new file mode 100644 index 0000000..5f7eecd --- /dev/null +++ b/CryptoPP/crypto/xtrdh342.dat @@ -0,0 +1,5 @@ +3081A6022B28E3FED51D3D861D962B0A16A92ACDB380ADAFB478CA555004C3AF387F853F9DE9921C +7DCB40098D25C757021D03094844F135A3A50049A848C3FC02412FCBED6040FB1BDE99A4D93E3B02 +2B13F411960B85F9B031A247E072046892B1EE6C95A47242A839F8E24B96B88F37B4BDA2C6D253BC +0AAF29F1022B0D2AFE639D324E558B2B312E435E03957769D745C881D259DDFD2F48F9C08F82ECCF +F4E7ADD47C705896D0 diff --git a/CryptoPP/crypto/zdeflate.cpp b/CryptoPP/crypto/zdeflate.cpp new file mode 100644 index 0000000..e2b60ee --- /dev/null +++ b/CryptoPP/crypto/zdeflate.cpp @@ -0,0 +1,791 @@ +// zdeflate.cpp - written and placed in the public domain by Wei Dai + +// Many of the algorithms and tables used here came from the deflate implementation +// by Jean-loup Gailly, which was included in Crypto++ 4.0 and earlier. I completely +// rewrote it in order to fix a bug that I could not figure out. This code +// is less clever, but hopefully more understandable and maintainable. + +#include "pch.h" +#include "zdeflate.h" +#include + +NAMESPACE_BEGIN(CryptoPP) + +using namespace std; + +LowFirstBitWriter::LowFirstBitWriter(BufferedTransformation *attachment) + : Filter(attachment), m_counting(false), m_buffer(0), m_bitsBuffered(0), m_bytesBuffered(0) +{ +} + +void LowFirstBitWriter::StartCounting() +{ + assert(!m_counting); + m_counting = true; + m_bitCount = 0; +} + +unsigned long LowFirstBitWriter::FinishCounting() +{ + assert(m_counting); + m_counting = false; + return m_bitCount; +} + +void LowFirstBitWriter::PutBits(unsigned long value, unsigned int length) +{ + if (m_counting) + m_bitCount += length; + else + { + m_buffer |= value << m_bitsBuffered; + m_bitsBuffered += length; + assert(m_bitsBuffered <= sizeof(unsigned long)*8); + while (m_bitsBuffered >= 8) + { + m_outputBuffer[m_bytesBuffered++] = (byte)m_buffer; + if (m_bytesBuffered == m_outputBuffer.size()) + { + AttachedTransformation()->PutModifiable(m_outputBuffer, m_bytesBuffered); + m_bytesBuffered = 0; + } + m_buffer >>= 8; + m_bitsBuffered -= 8; + } + } +} + +void LowFirstBitWriter::FlushBitBuffer() +{ + if (m_counting) + m_bitCount += 8*(m_bitsBuffered > 0); + else + { + if (m_bytesBuffered > 0) + { + AttachedTransformation()->PutModifiable(m_outputBuffer, m_bytesBuffered); + m_bytesBuffered = 0; + } + if (m_bitsBuffered > 0) + { + AttachedTransformation()->Put((byte)m_buffer); + m_buffer = 0; + m_bitsBuffered = 0; + } + } +} + +void LowFirstBitWriter::ClearBitBuffer() +{ + m_buffer = 0; + m_bytesBuffered = 0; + m_bitsBuffered = 0; +} + +HuffmanEncoder::HuffmanEncoder(const unsigned int *codeBits, unsigned int nCodes) +{ + Initialize(codeBits, nCodes); +} + +struct HuffmanNode +{ + size_t symbol; + union {size_t parent; unsigned depth, freq;}; +}; + +struct FreqLessThan +{ + inline bool operator()(unsigned int lhs, const HuffmanNode &rhs) {return lhs < rhs.freq;} + inline bool operator()(const HuffmanNode &lhs, const HuffmanNode &rhs) const {return lhs.freq < rhs.freq;} + // needed for MSVC .NET 2005 + inline bool operator()(const HuffmanNode &lhs, unsigned int rhs) {return lhs.freq < rhs;} +}; + +void HuffmanEncoder::GenerateCodeLengths(unsigned int *codeBits, unsigned int maxCodeBits, const unsigned int *codeCounts, size_t nCodes) +{ + assert(nCodes > 0); + assert(nCodes <= ((size_t)1 << maxCodeBits)); + + size_t i; + SecBlockWithHint tree(nCodes); + for (i=0; i= 2) + for (i=tree.size()-2; i>=nCodes; i--) + tree[i].depth = tree[tree[i].parent].depth + 1; + unsigned int sum = 0; + SecBlockWithHint blCount(maxCodeBits+1); + fill(blCount.begin(), blCount.end(), 0); + for (i=treeBegin; i (unsigned int)(1 << maxCodeBits) ? sum - (1 << maxCodeBits) : 0; + + while (overflow--) + { + unsigned int bits = maxCodeBits-1; + while (blCount[bits] == 0) + bits--; + blCount[bits]--; + blCount[bits+1] += 2; + assert(blCount[maxCodeBits] > 0); + blCount[maxCodeBits]--; + } + + for (i=0; i 0); + unsigned int maxCodeBits = *max_element(codeBits, codeBits+nCodes); + if (maxCodeBits == 0) + return; // assume this object won't be used + + SecBlockWithHint blCount(maxCodeBits+1); + fill(blCount.begin(), blCount.end(), 0); + unsigned int i; + for (i=0; i nextCode(maxCodeBits+1); + nextCode[1] = 0; + for (i=2; i<=maxCodeBits; i++) + { + code = (code + blCount[i-1]) << 1; + nextCode[i] = code; + } + assert(maxCodeBits == 1 || code == (1 << maxCodeBits) - blCount[maxCodeBits]); + + m_valueToCode.resize(nCodes); + for (i=0; i> (8*sizeof(code_t)-len); + } +} + +inline void HuffmanEncoder::Encode(LowFirstBitWriter &writer, value_t value) const +{ + assert(m_valueToCode[value].len > 0); + writer.PutBits(m_valueToCode[value].code, m_valueToCode[value].len); +} + +Deflator::Deflator(BufferedTransformation *attachment, int deflateLevel, int log2WindowSize, bool detectUncompressible) + : LowFirstBitWriter(attachment) +{ + InitializeStaticEncoders(); + IsolatedInitialize(MakeParameters("DeflateLevel", deflateLevel)("Log2WindowSize", log2WindowSize)("DetectUncompressible", detectUncompressible)); +} + +Deflator::Deflator(const NameValuePairs ¶meters, BufferedTransformation *attachment) + : LowFirstBitWriter(attachment) + , m_deflateLevel(-1) +{ + InitializeStaticEncoders(); + IsolatedInitialize(parameters); +} + +void Deflator::InitializeStaticEncoders() +{ + unsigned int codeLengths[288]; + fill(codeLengths + 0, codeLengths + 144, 8); + fill(codeLengths + 144, codeLengths + 256, 9); + fill(codeLengths + 256, codeLengths + 280, 7); + fill(codeLengths + 280, codeLengths + 288, 8); + m_staticLiteralEncoder.Initialize(codeLengths, 288); + fill(codeLengths + 0, codeLengths + 32, 5); + m_staticDistanceEncoder.Initialize(codeLengths, 32); +} + +void Deflator::IsolatedInitialize(const NameValuePairs ¶meters) +{ + int log2WindowSize = parameters.GetIntValueWithDefault("Log2WindowSize", DEFAULT_LOG2_WINDOW_SIZE); + if (!(MIN_LOG2_WINDOW_SIZE <= log2WindowSize && log2WindowSize <= MAX_LOG2_WINDOW_SIZE)) + throw InvalidArgument("Deflator: " + IntToString(log2WindowSize) + " is an invalid window size"); + + m_log2WindowSize = log2WindowSize; + DSIZE = 1 << m_log2WindowSize; + DMASK = DSIZE - 1; + HSIZE = 1 << m_log2WindowSize; + HMASK = HSIZE - 1; + m_byteBuffer.New(2*DSIZE); + m_head.New(HSIZE); + m_prev.New(DSIZE); + m_matchBuffer.New(DSIZE/2); + Reset(true); + + SetDeflateLevel(parameters.GetIntValueWithDefault("DeflateLevel", DEFAULT_DEFLATE_LEVEL)); + bool detectUncompressible = parameters.GetValueWithDefault("DetectUncompressible", true); + m_compressibleDeflateLevel = detectUncompressible ? m_deflateLevel : 0; +} + +void Deflator::Reset(bool forceReset) +{ + if (forceReset) + ClearBitBuffer(); + else + assert(m_bitsBuffered == 0); + + m_headerWritten = false; + m_matchAvailable = false; + m_dictionaryEnd = 0; + m_stringStart = 0; + m_lookahead = 0; + m_minLookahead = MAX_MATCH; + m_matchBufferEnd = 0; + m_blockStart = 0; + m_blockLength = 0; + + m_detectCount = 1; + m_detectSkip = 0; + + // m_prev will be initialized automaticly in InsertString + fill(m_head.begin(), m_head.end(), 0); + + fill(m_literalCounts.begin(), m_literalCounts.end(), 0); + fill(m_distanceCounts.begin(), m_distanceCounts.end(), 0); +} + +void Deflator::SetDeflateLevel(int deflateLevel) +{ + if (!(MIN_DEFLATE_LEVEL <= deflateLevel && deflateLevel <= MAX_DEFLATE_LEVEL)) + throw InvalidArgument("Deflator: " + IntToString(deflateLevel) + " is an invalid deflate level"); + + if (deflateLevel == m_deflateLevel) + return; + + EndBlock(false); + + static const unsigned int configurationTable[10][4] = { + /* good lazy nice chain */ + /* 0 */ {0, 0, 0, 0}, /* store only */ + /* 1 */ {4, 3, 8, 4}, /* maximum speed, no lazy matches */ + /* 2 */ {4, 3, 16, 8}, + /* 3 */ {4, 3, 32, 32}, + /* 4 */ {4, 4, 16, 16}, /* lazy matches */ + /* 5 */ {8, 16, 32, 32}, + /* 6 */ {8, 16, 128, 128}, + /* 7 */ {8, 32, 128, 256}, + /* 8 */ {32, 128, 258, 1024}, + /* 9 */ {32, 258, 258, 4096}}; /* maximum compression */ + + GOOD_MATCH = configurationTable[deflateLevel][0]; + MAX_LAZYLENGTH = configurationTable[deflateLevel][1]; + MAX_CHAIN_LENGTH = configurationTable[deflateLevel][3]; + + m_deflateLevel = deflateLevel; +} + +unsigned int Deflator::FillWindow(const byte *str, size_t length) +{ + unsigned int maxBlockSize = (unsigned int)STDMIN(2UL*DSIZE, 0xffffUL); + + if (m_stringStart >= maxBlockSize - MAX_MATCH) + { + if (m_blockStart < DSIZE) + EndBlock(false); + + memcpy(m_byteBuffer, m_byteBuffer + DSIZE, DSIZE); + + m_dictionaryEnd = m_dictionaryEnd < DSIZE ? 0 : m_dictionaryEnd-DSIZE; + assert(m_stringStart >= DSIZE); + m_stringStart -= DSIZE; + assert(!m_matchAvailable || m_previousMatch >= DSIZE); + m_previousMatch -= DSIZE; + assert(m_blockStart >= DSIZE); + m_blockStart -= DSIZE; + + unsigned int i; + + for (i=0; i m_stringStart+m_lookahead); + unsigned int accepted = UnsignedMin(maxBlockSize-(m_stringStart+m_lookahead), length); + assert(accepted > 0); + memcpy(m_byteBuffer + m_stringStart + m_lookahead, str, accepted); + m_lookahead += accepted; + return accepted; +} + +inline unsigned int Deflator::ComputeHash(const byte *str) const +{ + assert(str+3 <= m_byteBuffer + m_stringStart + m_lookahead); + return ((str[0] << 10) ^ (str[1] << 5) ^ str[2]) & HMASK; +} + +unsigned int Deflator::LongestMatch(unsigned int &bestMatch) const +{ + assert(m_previousLength < MAX_MATCH); + + bestMatch = 0; + unsigned int bestLength = STDMAX(m_previousLength, (unsigned int)MIN_MATCH-1); + if (m_lookahead <= bestLength) + return 0; + + const byte *scan = m_byteBuffer + m_stringStart, *scanEnd = scan + STDMIN((unsigned int)MAX_MATCH, m_lookahead); + unsigned int limit = m_stringStart > (DSIZE-MAX_MATCH) ? m_stringStart - (DSIZE-MAX_MATCH) : 0; + unsigned int current = m_head[ComputeHash(scan)]; + + unsigned int chainLength = MAX_CHAIN_LENGTH; + if (m_previousLength >= GOOD_MATCH) + chainLength >>= 2; + + while (current > limit && --chainLength > 0) + { + const byte *match = m_byteBuffer + current; + assert(scan + bestLength < m_byteBuffer + m_stringStart + m_lookahead); + if (scan[bestLength-1] == match[bestLength-1] && scan[bestLength] == match[bestLength] && scan[0] == match[0] && scan[1] == match[1]) + { + assert(scan[2] == match[2]); + unsigned int len = (unsigned int)( +#if defined(_STDEXT_BEGIN) && !(defined(_MSC_VER) && _MSC_VER < 1400) && !defined(_STLPORT_VERSION) + stdext::unchecked_mismatch +#else + std::mismatch +#endif + (scan+3, scanEnd, match+3).first - scan); + assert(len != bestLength); + if (len > bestLength) + { + bestLength = len; + bestMatch = current; + if (len == (scanEnd - scan)) + break; + } + } + current = m_prev[current & DMASK]; + } + return (bestMatch > 0) ? bestLength : 0; +} + +inline void Deflator::InsertString(unsigned int start) +{ + unsigned int hash = ComputeHash(m_byteBuffer + start); + m_prev[start & DMASK] = m_head[hash]; + m_head[hash] = start; +} + +void Deflator::ProcessBuffer() +{ + if (!m_headerWritten) + { + WritePrestreamHeader(); + m_headerWritten = true; + } + + if (m_deflateLevel == 0) + { + m_stringStart += m_lookahead; + m_lookahead = 0; + m_blockLength = m_stringStart - m_blockStart; + m_matchAvailable = false; + return; + } + + while (m_lookahead > m_minLookahead) + { + while (m_dictionaryEnd < m_stringStart && m_dictionaryEnd+3 <= m_stringStart+m_lookahead) + InsertString(m_dictionaryEnd++); + + if (m_matchAvailable) + { + unsigned int matchPosition, matchLength; + bool usePreviousMatch; + if (m_previousLength >= MAX_LAZYLENGTH) + usePreviousMatch = true; + else + { + matchLength = LongestMatch(matchPosition); + usePreviousMatch = (matchLength == 0); + } + if (usePreviousMatch) + { + MatchFound(m_stringStart-1-m_previousMatch, m_previousLength); + m_stringStart += m_previousLength-1; + m_lookahead -= m_previousLength-1; + m_matchAvailable = false; + } + else + { + m_previousLength = matchLength; + m_previousMatch = matchPosition; + LiteralByte(m_byteBuffer[m_stringStart-1]); + m_stringStart++; + m_lookahead--; + } + } + else + { + m_previousLength = 0; + m_previousLength = LongestMatch(m_previousMatch); + if (m_previousLength) + m_matchAvailable = true; + else + LiteralByte(m_byteBuffer[m_stringStart]); + m_stringStart++; + m_lookahead--; + } + + assert(m_stringStart - (m_blockStart+m_blockLength) == (unsigned int)m_matchAvailable); + } + + if (m_minLookahead == 0 && m_matchAvailable) + { + LiteralByte(m_byteBuffer[m_stringStart-1]); + m_matchAvailable = false; + } +} + +size_t Deflator::Put2(const byte *str, size_t length, int messageEnd, bool blocking) +{ + if (!blocking) + throw BlockingInputOnly("Deflator"); + + size_t accepted = 0; + while (accepted < length) + { + unsigned int newAccepted = FillWindow(str+accepted, length-accepted); + ProcessBuffer(); + // call ProcessUncompressedData() after WritePrestreamHeader() + ProcessUncompressedData(str+accepted, newAccepted); + accepted += newAccepted; + } + assert(accepted == length); + + if (messageEnd) + { + m_minLookahead = 0; + ProcessBuffer(); + EndBlock(true); + FlushBitBuffer(); + WritePoststreamTail(); + Reset(); + } + + Output(0, NULL, 0, messageEnd, blocking); + return 0; +} + +bool Deflator::IsolatedFlush(bool hardFlush, bool blocking) +{ + if (!blocking) + throw BlockingInputOnly("Deflator"); + + m_minLookahead = 0; + ProcessBuffer(); + m_minLookahead = MAX_MATCH; + EndBlock(false); + if (hardFlush) + EncodeBlock(false, STORED); + return false; +} + +void Deflator::LiteralByte(byte b) +{ + if (m_matchBufferEnd == m_matchBuffer.size()) + EndBlock(false); + + m_matchBuffer[m_matchBufferEnd++].literalCode = b; + m_literalCounts[b]++; + m_blockLength++; +} + +void Deflator::MatchFound(unsigned int distance, unsigned int length) +{ + if (m_matchBufferEnd == m_matchBuffer.size()) + EndBlock(false); + + static const unsigned int lengthCodes[] = { + 257, 258, 259, 260, 261, 262, 263, 264, 265, 265, 266, 266, 267, 267, 268, 268, + 269, 269, 269, 269, 270, 270, 270, 270, 271, 271, 271, 271, 272, 272, 272, 272, + 273, 273, 273, 273, 273, 273, 273, 273, 274, 274, 274, 274, 274, 274, 274, 274, + 275, 275, 275, 275, 275, 275, 275, 275, 276, 276, 276, 276, 276, 276, 276, 276, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278, + 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, 279, + 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, 280, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, + 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, + 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, + 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, + 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, + 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, + 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 285}; + static const unsigned int lengthBases[] = {3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258}; + static const unsigned int distanceBases[30] = + {1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577}; + + EncodedMatch &m = m_matchBuffer[m_matchBufferEnd++]; + assert(length >= 3); + unsigned int lengthCode = lengthCodes[length-3]; + m.literalCode = lengthCode; + m.literalExtra = length - lengthBases[lengthCode-257]; + unsigned int distanceCode = (unsigned int)(upper_bound(distanceBases, distanceBases+30, distance) - distanceBases - 1); + m.distanceCode = distanceCode; + m.distanceExtra = distance - distanceBases[distanceCode]; + + m_literalCounts[lengthCode]++; + m_distanceCounts[distanceCode]++; + m_blockLength += length; +} + +inline unsigned int CodeLengthEncode(const unsigned int *begin, + const unsigned int *end, + const unsigned int *& p, + unsigned int &extraBits, + unsigned int &extraBitsLength) +{ + unsigned int v = *p; + if ((end-p) >= 3) + { + const unsigned int *oldp = p; + if (v==0 && p[1]==0 && p[2]==0) + { + for (p=p+3; p!=end && *p==0 && p!=oldp+138; p++) {} + unsigned int repeat = (unsigned int)(p - oldp); + if (repeat <= 10) + { + extraBits = repeat-3; + extraBitsLength = 3; + return 17; + } + else + { + extraBits = repeat-11; + extraBitsLength = 7; + return 18; + } + } + else if (p!=begin && v==p[-1] && v==p[1] && v==p[2]) + { + for (p=p+3; p!=end && *p==v && p!=oldp+6; p++) {} + unsigned int repeat = (unsigned int)(p - oldp); + extraBits = repeat-3; + extraBitsLength = 2; + return 16; + } + } + p++; + extraBits = 0; + extraBitsLength = 0; + return v; +} + +void Deflator::EncodeBlock(bool eof, unsigned int blockType) +{ + PutBits(eof, 1); + PutBits(blockType, 2); + + if (blockType == STORED) + { + assert(m_blockStart + m_blockLength <= m_byteBuffer.size()); + assert(m_blockLength <= 0xffff); + FlushBitBuffer(); + AttachedTransformation()->PutWord16(m_blockLength, LITTLE_ENDIAN_ORDER); + AttachedTransformation()->PutWord16(~m_blockLength, LITTLE_ENDIAN_ORDER); + AttachedTransformation()->Put(m_byteBuffer + m_blockStart, m_blockLength); + } + else + { + if (blockType == DYNAMIC) + { +#if defined(_MSC_VER) && !defined(__MWERKS__) && (_MSC_VER <= 1300) + // VC60 and VC7 workaround: built-in reverse_iterator has two template parameters, Dinkumware only has one + typedef reverse_bidirectional_iterator RevIt; +#elif defined(_RWSTD_NO_CLASS_PARTIAL_SPEC) + typedef reverse_iterator RevIt; +#else + typedef reverse_iterator RevIt; +#endif + + FixedSizeSecBlock literalCodeLengths; + FixedSizeSecBlock distanceCodeLengths; + + m_literalCounts[256] = 1; + HuffmanEncoder::GenerateCodeLengths(literalCodeLengths, 15, m_literalCounts, 286); + m_dynamicLiteralEncoder.Initialize(literalCodeLengths, 286); + unsigned int hlit = (unsigned int)(find_if(RevIt(literalCodeLengths.end()), RevIt(literalCodeLengths.begin()+257), bind2nd(not_equal_to(), 0)).base() - (literalCodeLengths.begin()+257)); + + HuffmanEncoder::GenerateCodeLengths(distanceCodeLengths, 15, m_distanceCounts, 30); + m_dynamicDistanceEncoder.Initialize(distanceCodeLengths, 30); + unsigned int hdist = (unsigned int)(find_if(RevIt(distanceCodeLengths.end()), RevIt(distanceCodeLengths.begin()+1), bind2nd(not_equal_to(), 0)).base() - (distanceCodeLengths.begin()+1)); + + SecBlockWithHint combinedLengths(hlit+257+hdist+1); + memcpy(combinedLengths, literalCodeLengths, (hlit+257)*sizeof(unsigned int)); + memcpy(combinedLengths+hlit+257, distanceCodeLengths, (hdist+1)*sizeof(unsigned int)); + + FixedSizeSecBlock codeLengthCodeCounts, codeLengthCodeLengths; + fill(codeLengthCodeCounts.begin(), codeLengthCodeCounts.end(), 0); + const unsigned int *p = combinedLengths.begin(), *begin = combinedLengths.begin(), *end = combinedLengths.end(); + while (p != end) + { + unsigned int code, extraBits, extraBitsLength; + code = CodeLengthEncode(begin, end, p, extraBits, extraBitsLength); + codeLengthCodeCounts[code]++; + } + HuffmanEncoder::GenerateCodeLengths(codeLengthCodeLengths, 7, codeLengthCodeCounts, 19); + HuffmanEncoder codeLengthEncoder(codeLengthCodeLengths, 19); + static const unsigned int border[] = { // Order of the bit length code lengths + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + unsigned int hclen = 19; + while (hclen > 4 && codeLengthCodeLengths[border[hclen-1]] == 0) + hclen--; + hclen -= 4; + + PutBits(hlit, 5); + PutBits(hdist, 5); + PutBits(hclen, 4); + + for (unsigned int i=0; i= 257) + { + assert(literalCode <= 285); + PutBits(m_matchBuffer[i].literalExtra, lengthExtraBits[literalCode-257]); + unsigned int distanceCode = m_matchBuffer[i].distanceCode; + distanceEncoder.Encode(*this, distanceCode); + PutBits(m_matchBuffer[i].distanceExtra, distanceExtraBits[distanceCode]); + } + } + literalEncoder.Encode(*this, 256); // end of block + } +} + +void Deflator::EndBlock(bool eof) +{ + if (m_blockLength == 0 && !eof) + return; + + if (m_deflateLevel == 0) + { + EncodeBlock(eof, STORED); + + if (m_compressibleDeflateLevel > 0 && ++m_detectCount == m_detectSkip) + { + m_deflateLevel = m_compressibleDeflateLevel; + m_detectCount = 1; + } + } + else + { + unsigned long storedLen = 8*((unsigned long)m_blockLength+4) + RoundUpToMultipleOf(m_bitsBuffered+3, 8U)-m_bitsBuffered; + + StartCounting(); + EncodeBlock(eof, STATIC); + unsigned long staticLen = FinishCounting(); + + unsigned long dynamicLen; + if (m_blockLength < 128 && m_deflateLevel < 8) + dynamicLen = ULONG_MAX; + else + { + StartCounting(); + EncodeBlock(eof, DYNAMIC); + dynamicLen = FinishCounting(); + } + + if (storedLen <= staticLen && storedLen <= dynamicLen) + { + EncodeBlock(eof, STORED); + + if (m_compressibleDeflateLevel > 0) + { + if (m_detectSkip) + m_deflateLevel = 0; + m_detectSkip = m_detectSkip ? STDMIN(2*m_detectSkip, 128U) : 1; + } + } + else + { + if (staticLen <= dynamicLen) + EncodeBlock(eof, STATIC); + else + EncodeBlock(eof, DYNAMIC); + + if (m_compressibleDeflateLevel > 0) + m_detectSkip = 0; + } + } + + m_matchBufferEnd = 0; + m_blockStart += m_blockLength; + m_blockLength = 0; + fill(m_literalCounts.begin(), m_literalCounts.end(), 0); + fill(m_distanceCounts.begin(), m_distanceCounts.end(), 0); +} + +NAMESPACE_END diff --git a/CryptoPP/crypto/zdeflate.h b/CryptoPP/crypto/zdeflate.h new file mode 100644 index 0000000..60b8533 --- /dev/null +++ b/CryptoPP/crypto/zdeflate.h @@ -0,0 +1,121 @@ +#ifndef CRYPTOPP_ZDEFLATE_H +#define CRYPTOPP_ZDEFLATE_H + +#include "filters.h" +#include "misc.h" + +NAMESPACE_BEGIN(CryptoPP) + +//! _ +class LowFirstBitWriter : public Filter +{ +public: + LowFirstBitWriter(BufferedTransformation *attachment); + void PutBits(unsigned long value, unsigned int length); + void FlushBitBuffer(); + void ClearBitBuffer(); + + void StartCounting(); + unsigned long FinishCounting(); + +protected: + bool m_counting; + unsigned long m_bitCount; + unsigned long m_buffer; + unsigned int m_bitsBuffered, m_bytesBuffered; + FixedSizeSecBlock m_outputBuffer; +}; + +//! Huffman Encoder +class HuffmanEncoder +{ +public: + typedef unsigned int code_t; + typedef unsigned int value_t; + + HuffmanEncoder() {} + HuffmanEncoder(const unsigned int *codeBits, unsigned int nCodes); + void Initialize(const unsigned int *codeBits, unsigned int nCodes); + + static void GenerateCodeLengths(unsigned int *codeBits, unsigned int maxCodeBits, const unsigned int *codeCounts, size_t nCodes); + + void Encode(LowFirstBitWriter &writer, value_t value) const; + + struct Code + { + unsigned int code; + unsigned int len; + }; + + SecBlock m_valueToCode; +}; + +//! DEFLATE (RFC 1951) compressor + +class Deflator : public LowFirstBitWriter +{ +public: + enum {MIN_DEFLATE_LEVEL = 0, DEFAULT_DEFLATE_LEVEL = 6, MAX_DEFLATE_LEVEL = 9}; + enum {MIN_LOG2_WINDOW_SIZE = 9, DEFAULT_LOG2_WINDOW_SIZE = 15, MAX_LOG2_WINDOW_SIZE = 15}; + /*! \note detectUncompressible makes it faster to process uncompressible files, but + if a file has both compressible and uncompressible parts, it may fail to compress some of the + compressible parts. */ + Deflator(BufferedTransformation *attachment=NULL, int deflateLevel=DEFAULT_DEFLATE_LEVEL, int log2WindowSize=DEFAULT_LOG2_WINDOW_SIZE, bool detectUncompressible=true); + //! possible parameter names: Log2WindowSize, DeflateLevel, DetectUncompressible + Deflator(const NameValuePairs ¶meters, BufferedTransformation *attachment=NULL); + + //! this function can be used to set the deflate level in the middle of compression + void SetDeflateLevel(int deflateLevel); + int GetDeflateLevel() const {return m_deflateLevel;} + int GetLog2WindowSize() const {return m_log2WindowSize;} + + void IsolatedInitialize(const NameValuePairs ¶meters); + size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking); + bool IsolatedFlush(bool hardFlush, bool blocking); + +protected: + virtual void WritePrestreamHeader() {} + virtual void ProcessUncompressedData(const byte *string, size_t length) {} + virtual void WritePoststreamTail() {} + + enum {STORED = 0, STATIC = 1, DYNAMIC = 2}; + enum {MIN_MATCH = 3, MAX_MATCH = 258}; + + void InitializeStaticEncoders(); + void Reset(bool forceReset = false); + unsigned int FillWindow(const byte *str, size_t length); + unsigned int ComputeHash(const byte *str) const; + unsigned int LongestMatch(unsigned int &bestMatch) const; + void InsertString(unsigned int start); + void ProcessBuffer(); + + void LiteralByte(byte b); + void MatchFound(unsigned int distance, unsigned int length); + void EncodeBlock(bool eof, unsigned int blockType); + void EndBlock(bool eof); + + struct EncodedMatch + { + unsigned literalCode : 9; + unsigned literalExtra : 5; + unsigned distanceCode : 5; + unsigned distanceExtra : 13; + }; + + int m_deflateLevel, m_log2WindowSize, m_compressibleDeflateLevel; + unsigned int m_detectSkip, m_detectCount; + unsigned int DSIZE, DMASK, HSIZE, HMASK, GOOD_MATCH, MAX_LAZYLENGTH, MAX_CHAIN_LENGTH; + bool m_headerWritten, m_matchAvailable; + unsigned int m_dictionaryEnd, m_stringStart, m_lookahead, m_minLookahead, m_previousMatch, m_previousLength; + HuffmanEncoder m_staticLiteralEncoder, m_staticDistanceEncoder, m_dynamicLiteralEncoder, m_dynamicDistanceEncoder; + SecByteBlock m_byteBuffer; + SecBlock m_head, m_prev; + FixedSizeSecBlock m_literalCounts; + FixedSizeSecBlock m_distanceCounts; + SecBlock m_matchBuffer; + unsigned int m_matchBufferEnd, m_blockStart, m_blockLength; +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/zinflate.cpp b/CryptoPP/crypto/zinflate.cpp new file mode 100644 index 0000000..7a0c8aa --- /dev/null +++ b/CryptoPP/crypto/zinflate.cpp @@ -0,0 +1,621 @@ +// zinflate.cpp - written and placed in the public domain by Wei Dai + +// This is a complete reimplementation of the DEFLATE decompression algorithm. +// It should not be affected by any security vulnerabilities in the zlib +// compression library. In particular it is not affected by the double free bug +// (http://www.kb.cert.org/vuls/id/368819). + +#include "pch.h" +#include "zinflate.h" + +NAMESPACE_BEGIN(CryptoPP) + +struct CodeLessThan +{ + inline bool operator()(CryptoPP::HuffmanDecoder::code_t lhs, const CryptoPP::HuffmanDecoder::CodeInfo &rhs) + {return lhs < rhs.code;} + // needed for MSVC .NET 2005 + inline bool operator()(const CryptoPP::HuffmanDecoder::CodeInfo &lhs, const CryptoPP::HuffmanDecoder::CodeInfo &rhs) + {return lhs.code < rhs.code;} +}; + +inline bool LowFirstBitReader::FillBuffer(unsigned int length) +{ + while (m_bitsBuffered < length) + { + byte b; + if (!m_store.Get(b)) + return false; + m_buffer |= (unsigned long)b << m_bitsBuffered; + m_bitsBuffered += 8; + } + assert(m_bitsBuffered <= sizeof(unsigned long)*8); + return true; +} + +inline unsigned long LowFirstBitReader::PeekBits(unsigned int length) +{ + bool result = FillBuffer(length); + assert(result); + return m_buffer & (((unsigned long)1 << length) - 1); +} + +inline void LowFirstBitReader::SkipBits(unsigned int length) +{ + assert(m_bitsBuffered >= length); + m_buffer >>= length; + m_bitsBuffered -= length; +} + +inline unsigned long LowFirstBitReader::GetBits(unsigned int length) +{ + unsigned long result = PeekBits(length); + SkipBits(length); + return result; +} + +inline HuffmanDecoder::code_t HuffmanDecoder::NormalizeCode(HuffmanDecoder::code_t code, unsigned int codeBits) +{ + return code << (MAX_CODE_BITS - codeBits); +} + +void HuffmanDecoder::Initialize(const unsigned int *codeBits, unsigned int nCodes) +{ + // the Huffman codes are represented in 3 ways in this code: + // + // 1. most significant code bit (i.e. top of code tree) in the least significant bit position + // 2. most significant code bit (i.e. top of code tree) in the most significant bit position + // 3. most significant code bit (i.e. top of code tree) in n-th least significant bit position, + // where n is the maximum code length for this code tree + // + // (1) is the way the codes come in from the deflate stream + // (2) is used to sort codes so they can be binary searched + // (3) is used in this function to compute codes from code lengths + // + // a code in representation (2) is called "normalized" here + // The BitReverse() function is used to convert between (1) and (2) + // The NormalizeCode() function is used to convert from (3) to (2) + + if (nCodes == 0) + throw Err("null code"); + + m_maxCodeBits = *std::max_element(codeBits, codeBits+nCodes); + + if (m_maxCodeBits > MAX_CODE_BITS) + throw Err("code length exceeds maximum"); + + if (m_maxCodeBits == 0) + throw Err("null code"); + + // count number of codes of each length + SecBlockWithHint blCount(m_maxCodeBits+1); + std::fill(blCount.begin(), blCount.end(), 0); + unsigned int i; + for (i=0; i nextCode(m_maxCodeBits+1); + nextCode[1] = 0; + for (i=2; i<=m_maxCodeBits; i++) + { + // compute this while checking for overflow: code = (code + blCount[i-1]) << 1 + if (code > code + blCount[i-1]) + throw Err("codes oversubscribed"); + code += blCount[i-1]; + if (code > (code << 1)) + throw Err("codes oversubscribed"); + code <<= 1; + nextCode[i] = code; + } + + if (code > (1 << m_maxCodeBits) - blCount[m_maxCodeBits]) + throw Err("codes oversubscribed"); + else if (m_maxCodeBits != 1 && code < (1 << m_maxCodeBits) - blCount[m_maxCodeBits]) + throw Err("codes incomplete"); + + // compute a vector of triples sorted by code + m_codeToValue.resize(nCodes - blCount[0]); + unsigned int j=0; + for (i=0; ilen) + { + entry.type = 2; + entry.len = codeInfo.len; + } + else + { + entry.type = 3; + entry.end = last+1; + } + } +} + +inline unsigned int HuffmanDecoder::Decode(code_t code, /* out */ value_t &value) const +{ + assert(m_codeToValue.size() > 0); + LookupEntry &entry = m_cache[code & m_cacheMask]; + + code_t normalizedCode; + if (entry.type != 1) + normalizedCode = BitReverse(code); + + if (entry.type == 0) + FillCacheEntry(entry, normalizedCode); + + if (entry.type == 1) + { + value = entry.value; + return entry.len; + } + else + { + const CodeInfo &codeInfo = (entry.type == 2) + ? entry.begin[(normalizedCode << m_cacheBits) >> (MAX_CODE_BITS - (entry.len - m_cacheBits))] + : *(std::upper_bound(entry.begin, entry.end, normalizedCode, CodeLessThan())-1); + value = codeInfo.value; + return codeInfo.len; + } +} + +bool HuffmanDecoder::Decode(LowFirstBitReader &reader, value_t &value) const +{ + reader.FillBuffer(m_maxCodeBits); + unsigned int codeBits = Decode(reader.PeekBuffer(), value); + if (codeBits > reader.BitsBuffered()) + return false; + reader.SkipBits(codeBits); + return true; +} + +// ************************************************************* + +Inflator::Inflator(BufferedTransformation *attachment, bool repeat, int propagation) + : AutoSignaling(propagation) + , m_state(PRE_STREAM), m_repeat(repeat), m_reader(m_inQueue) +{ + Detach(attachment); +} + +void Inflator::IsolatedInitialize(const NameValuePairs ¶meters) +{ + m_state = PRE_STREAM; + parameters.GetValue("Repeat", m_repeat); + m_inQueue.Clear(); + m_reader.SkipBits(m_reader.BitsBuffered()); +} + +void Inflator::OutputByte(byte b) +{ + m_window[m_current++] = b; + if (m_current == m_window.size()) + { + ProcessDecompressedData(m_window + m_lastFlush, m_window.size() - m_lastFlush); + m_lastFlush = 0; + m_current = 0; + m_wrappedAround = true; + } +} + +void Inflator::OutputString(const byte *string, size_t length) +{ + while (length) + { + size_t len = UnsignedMin(length, m_window.size() - m_current); + memcpy(m_window + m_current, string, len); + m_current += len; + if (m_current == m_window.size()) + { + ProcessDecompressedData(m_window + m_lastFlush, m_window.size() - m_lastFlush); + m_lastFlush = 0; + m_current = 0; + m_wrappedAround = true; + } + string += len; + length -= len; + } +} + +void Inflator::OutputPast(unsigned int length, unsigned int distance) +{ + size_t start; + if (distance <= m_current) + start = m_current - distance; + else if (m_wrappedAround && distance <= m_window.size()) + start = m_current + m_window.size() - distance; + else + throw BadBlockErr(); + + if (start + length > m_window.size()) + { + for (; start < m_window.size(); start++, length--) + OutputByte(m_window[start]); + start = 0; + } + + if (start + length > m_current || m_current + length >= m_window.size()) + { + while (length--) + OutputByte(m_window[start++]); + } + else + { + memcpy(m_window + m_current, m_window + start, length); + m_current += length; + } +} + +size_t Inflator::Put2(const byte *inString, size_t length, int messageEnd, bool blocking) +{ + if (!blocking) + throw BlockingInputOnly("Inflator"); + + LazyPutter lp(m_inQueue, inString, length); + ProcessInput(messageEnd != 0); + + if (messageEnd) + if (!(m_state == PRE_STREAM || m_state == AFTER_END)) + throw UnexpectedEndErr(); + + Output(0, NULL, 0, messageEnd, blocking); + return 0; +} + +bool Inflator::IsolatedFlush(bool hardFlush, bool blocking) +{ + if (!blocking) + throw BlockingInputOnly("Inflator"); + + if (hardFlush) + ProcessInput(true); + FlushOutput(); + + return false; +} + +void Inflator::ProcessInput(bool flush) +{ + while (true) + { + switch (m_state) + { + case PRE_STREAM: + if (!flush && m_inQueue.CurrentSize() < MaxPrestreamHeaderSize()) + return; + ProcessPrestreamHeader(); + m_state = WAIT_HEADER; + m_wrappedAround = false; + m_current = 0; + m_lastFlush = 0; + m_window.New(1 << GetLog2WindowSize()); + break; + case WAIT_HEADER: + { + // maximum number of bytes before actual compressed data starts + const size_t MAX_HEADER_SIZE = BitsToBytes(3+5+5+4+19*7+286*15+19*15); + if (m_inQueue.CurrentSize() < (flush ? 1 : MAX_HEADER_SIZE)) + return; + DecodeHeader(); + break; + } + case DECODING_BODY: + if (!DecodeBody()) + return; + break; + case POST_STREAM: + if (!flush && m_inQueue.CurrentSize() < MaxPoststreamTailSize()) + return; + ProcessPoststreamTail(); + m_state = m_repeat ? PRE_STREAM : AFTER_END; + Output(0, NULL, 0, GetAutoSignalPropagation(), true); // TODO: non-blocking + if (m_inQueue.IsEmpty()) + return; + break; + case AFTER_END: + m_inQueue.TransferTo(*AttachedTransformation()); + return; + } + } +} + +void Inflator::DecodeHeader() +{ + if (!m_reader.FillBuffer(3)) + throw UnexpectedEndErr(); + m_eof = m_reader.GetBits(1) != 0; + m_blockType = (byte)m_reader.GetBits(2); + switch (m_blockType) + { + case 0: // stored + { + m_reader.SkipBits(m_reader.BitsBuffered() % 8); + if (!m_reader.FillBuffer(32)) + throw UnexpectedEndErr(); + m_storedLen = (word16)m_reader.GetBits(16); + word16 nlen = (word16)m_reader.GetBits(16); + if (nlen != (word16)~m_storedLen) + throw BadBlockErr(); + break; + } + case 1: // fixed codes + m_nextDecode = LITERAL; + break; + case 2: // dynamic codes + { + if (!m_reader.FillBuffer(5+5+4)) + throw UnexpectedEndErr(); + unsigned int hlit = m_reader.GetBits(5); + unsigned int hdist = m_reader.GetBits(5); + unsigned int hclen = m_reader.GetBits(4); + + FixedSizeSecBlock codeLengths; + unsigned int i; + static const unsigned int border[] = { // Order of the bit length code lengths + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + std::fill(codeLengths.begin(), codeLengths+19, 0); + for (i=0; i hlit+257+hdist+1) + throw BadBlockErr(); + std::fill(codeLengths + i, codeLengths + i + count, repeater); + i += count; + } + m_dynamicLiteralDecoder.Initialize(codeLengths, hlit+257); + if (hdist == 0 && codeLengths[hlit+257] == 0) + { + if (hlit != 0) // a single zero distance code length means all literals + throw BadBlockErr(); + } + else + m_dynamicDistanceDecoder.Initialize(codeLengths+hlit+257, hdist+1); + m_nextDecode = LITERAL; + } + catch (HuffmanDecoder::Err &) + { + throw BadBlockErr(); + } + break; + } + default: + throw BadBlockErr(); // reserved block type + } + m_state = DECODING_BODY; +} + +bool Inflator::DecodeBody() +{ + bool blockEnd = false; + switch (m_blockType) + { + case 0: // stored + assert(m_reader.BitsBuffered() == 0); + while (!m_inQueue.IsEmpty() && !blockEnd) + { + size_t size; + const byte *block = m_inQueue.Spy(size); + size = UnsignedMin(m_storedLen, size); + OutputString(block, size); + m_inQueue.Skip(size); + m_storedLen -= (word16)size; + if (m_storedLen == 0) + blockEnd = true; + } + break; + case 1: // fixed codes + case 2: // dynamic codes + static const unsigned int lengthStarts[] = { + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258}; + static const unsigned int lengthExtraBits[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0}; + static const unsigned int distanceStarts[] = { + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577}; + static const unsigned int distanceExtraBits[] = { + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, + 12, 12, 13, 13}; + + const HuffmanDecoder& literalDecoder = GetLiteralDecoder(); + const HuffmanDecoder& distanceDecoder = GetDistanceDecoder(); + + switch (m_nextDecode) + { + case LITERAL: + while (true) + { + if (!literalDecoder.Decode(m_reader, m_literal)) + { + m_nextDecode = LITERAL; + break; + } + if (m_literal < 256) + OutputByte((byte)m_literal); + else if (m_literal == 256) // end of block + { + blockEnd = true; + break; + } + else + { + if (m_literal > 285) + throw BadBlockErr(); + unsigned int bits; + case LENGTH_BITS: + bits = lengthExtraBits[m_literal-257]; + if (!m_reader.FillBuffer(bits)) + { + m_nextDecode = LENGTH_BITS; + break; + } + m_literal = m_reader.GetBits(bits) + lengthStarts[m_literal-257]; + case DISTANCE: + if (!distanceDecoder.Decode(m_reader, m_distance)) + { + m_nextDecode = DISTANCE; + break; + } + case DISTANCE_BITS: + bits = distanceExtraBits[m_distance]; + if (!m_reader.FillBuffer(bits)) + { + m_nextDecode = DISTANCE_BITS; + break; + } + m_distance = m_reader.GetBits(bits) + distanceStarts[m_distance]; + OutputPast(m_literal, m_distance); + } + } + } + } + if (blockEnd) + { + if (m_eof) + { + FlushOutput(); + m_reader.SkipBits(m_reader.BitsBuffered()%8); + if (m_reader.BitsBuffered()) + { + // undo too much lookahead + SecBlockWithHint buffer(m_reader.BitsBuffered() / 8); + for (unsigned int i=0; i= m_lastFlush); + ProcessDecompressedData(m_window + m_lastFlush, m_current - m_lastFlush); + m_lastFlush = m_current; + } +} + +struct NewFixedLiteralDecoder +{ + HuffmanDecoder * operator()() const + { + unsigned int codeLengths[288]; + std::fill(codeLengths + 0, codeLengths + 144, 8); + std::fill(codeLengths + 144, codeLengths + 256, 9); + std::fill(codeLengths + 256, codeLengths + 280, 7); + std::fill(codeLengths + 280, codeLengths + 288, 8); + std::auto_ptr pDecoder(new HuffmanDecoder); + pDecoder->Initialize(codeLengths, 288); + return pDecoder.release(); + } +}; + +struct NewFixedDistanceDecoder +{ + HuffmanDecoder * operator()() const + { + unsigned int codeLengths[32]; + std::fill(codeLengths + 0, codeLengths + 32, 5); + std::auto_ptr pDecoder(new HuffmanDecoder); + pDecoder->Initialize(codeLengths, 32); + return pDecoder.release(); + } +}; + +const HuffmanDecoder& Inflator::GetLiteralDecoder() const +{ + return m_blockType == 1 ? Singleton().Ref() : m_dynamicLiteralDecoder; +} + +const HuffmanDecoder& Inflator::GetDistanceDecoder() const +{ + return m_blockType == 1 ? Singleton().Ref() : m_dynamicDistanceDecoder; +} + +NAMESPACE_END diff --git a/CryptoPP/crypto/zinflate.h b/CryptoPP/crypto/zinflate.h new file mode 100644 index 0000000..4d536be --- /dev/null +++ b/CryptoPP/crypto/zinflate.h @@ -0,0 +1,149 @@ +#ifndef CRYPTOPP_ZINFLATE_H +#define CRYPTOPP_ZINFLATE_H + +#include "filters.h" +#include + +NAMESPACE_BEGIN(CryptoPP) + +//! _ +class LowFirstBitReader +{ +public: + LowFirstBitReader(BufferedTransformation &store) + : m_store(store), m_buffer(0), m_bitsBuffered(0) {} +// unsigned long BitsLeft() const {return m_store.MaxRetrievable() * 8 + m_bitsBuffered;} + unsigned int BitsBuffered() const {return m_bitsBuffered;} + unsigned long PeekBuffer() const {return m_buffer;} + bool FillBuffer(unsigned int length); + unsigned long PeekBits(unsigned int length); + void SkipBits(unsigned int length); + unsigned long GetBits(unsigned int length); + +private: + BufferedTransformation &m_store; + unsigned long m_buffer; + unsigned int m_bitsBuffered; +}; + +struct CodeLessThan; + +//! Huffman Decoder +class HuffmanDecoder +{ +public: + typedef unsigned int code_t; + typedef unsigned int value_t; + enum {MAX_CODE_BITS = sizeof(code_t)*8}; + + class Err : public Exception {public: Err(const std::string &what) : Exception(INVALID_DATA_FORMAT, "HuffmanDecoder: " + what) {}}; + + HuffmanDecoder() {} + HuffmanDecoder(const unsigned int *codeBitLengths, unsigned int nCodes) {Initialize(codeBitLengths, nCodes);} + + void Initialize(const unsigned int *codeBitLengths, unsigned int nCodes); + unsigned int Decode(code_t code, /* out */ value_t &value) const; + bool Decode(LowFirstBitReader &reader, value_t &value) const; + +private: + friend struct CodeLessThan; + + struct CodeInfo + { + CodeInfo(code_t code=0, unsigned int len=0, value_t value=0) : code(code), len(len), value(value) {} + inline bool operator<(const CodeInfo &rhs) const {return code < rhs.code;} + code_t code; + unsigned int len; + value_t value; + }; + + struct LookupEntry + { + unsigned int type; + union + { + value_t value; + const CodeInfo *begin; + }; + union + { + unsigned int len; + const CodeInfo *end; + }; + }; + + static code_t NormalizeCode(code_t code, unsigned int codeBits); + void FillCacheEntry(LookupEntry &entry, code_t normalizedCode) const; + + unsigned int m_maxCodeBits, m_cacheBits, m_cacheMask, m_normalizedCacheMask; + std::vector > m_codeToValue; + mutable std::vector > m_cache; +}; + +//! DEFLATE (RFC 1951) decompressor + +class Inflator : public AutoSignaling +{ +public: + class Err : public Exception + { + public: + Err(ErrorType e, const std::string &s) + : Exception(e, s) {} + }; + class UnexpectedEndErr : public Err {public: UnexpectedEndErr() : Err(INVALID_DATA_FORMAT, "Inflator: unexpected end of compressed block") {}}; + class BadBlockErr : public Err {public: BadBlockErr() : Err(INVALID_DATA_FORMAT, "Inflator: error in compressed block") {}}; + + /*! \param repeat decompress multiple compressed streams in series + \param autoSignalPropagation 0 to turn off MessageEnd signal + */ + Inflator(BufferedTransformation *attachment = NULL, bool repeat = false, int autoSignalPropagation = -1); + + void IsolatedInitialize(const NameValuePairs ¶meters); + size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking); + bool IsolatedFlush(bool hardFlush, bool blocking); + + virtual unsigned int GetLog2WindowSize() const {return 15;} + +protected: + ByteQueue m_inQueue; + +private: + virtual unsigned int MaxPrestreamHeaderSize() const {return 0;} + virtual void ProcessPrestreamHeader() {} + virtual void ProcessDecompressedData(const byte *string, size_t length) + {AttachedTransformation()->Put(string, length);} + virtual unsigned int MaxPoststreamTailSize() const {return 0;} + virtual void ProcessPoststreamTail() {} + + void ProcessInput(bool flush); + void DecodeHeader(); + bool DecodeBody(); + void FlushOutput(); + void OutputByte(byte b); + void OutputString(const byte *string, size_t length); + void OutputPast(unsigned int length, unsigned int distance); + + static const HuffmanDecoder *FixedLiteralDecoder(); + static const HuffmanDecoder *FixedDistanceDecoder(); + + const HuffmanDecoder& GetLiteralDecoder() const; + const HuffmanDecoder& GetDistanceDecoder() const; + + enum State {PRE_STREAM, WAIT_HEADER, DECODING_BODY, POST_STREAM, AFTER_END}; + State m_state; + bool m_repeat, m_eof, m_wrappedAround; + byte m_blockType; + word16 m_storedLen; + enum NextDecode {LITERAL, LENGTH_BITS, DISTANCE, DISTANCE_BITS}; + NextDecode m_nextDecode; + unsigned int m_literal, m_distance; // for LENGTH_BITS or DISTANCE_BITS + HuffmanDecoder m_dynamicLiteralDecoder, m_dynamicDistanceDecoder; + LowFirstBitReader m_reader; + SecByteBlock m_window; + size_t m_current, m_lastFlush; +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/crypto/zlib.cpp b/CryptoPP/crypto/zlib.cpp new file mode 100644 index 0000000..528f809 --- /dev/null +++ b/CryptoPP/crypto/zlib.cpp @@ -0,0 +1,90 @@ +// zlib.cpp - written and placed in the public domain by Wei Dai + +// "zlib" is the name of a well known C language compression library +// (http://www.zlib.org) and also the name of a compression format +// (RFC 1950) that the library implements. This file is part of a +// complete reimplementation of the zlib compression format. + +#include "pch.h" +#include "zlib.h" +#include "zdeflate.h" +#include "zinflate.h" + +NAMESPACE_BEGIN(CryptoPP) + +static const byte DEFLATE_METHOD = 8; +static const byte FDICT_FLAG = 1 << 5; + +// ************************************************************* + +void ZlibCompressor::WritePrestreamHeader() +{ + m_adler32.Restart(); + byte cmf = DEFLATE_METHOD | ((GetLog2WindowSize()-8) << 4); + byte flags = GetCompressionLevel() << 6; + AttachedTransformation()->PutWord16(RoundUpToMultipleOf(cmf*256+flags, 31)); +} + +void ZlibCompressor::ProcessUncompressedData(const byte *inString, size_t length) +{ + m_adler32.Update(inString, length); +} + +void ZlibCompressor::WritePoststreamTail() +{ + FixedSizeSecBlock adler32; + m_adler32.Final(adler32); + AttachedTransformation()->Put(adler32, 4); +} + +unsigned int ZlibCompressor::GetCompressionLevel() const +{ + static const unsigned int deflateToCompressionLevel[] = {0, 1, 1, 1, 2, 2, 2, 2, 2, 3}; + return deflateToCompressionLevel[GetDeflateLevel()]; +} + +// ************************************************************* + +ZlibDecompressor::ZlibDecompressor(BufferedTransformation *attachment, bool repeat, int propagation) + : Inflator(attachment, repeat, propagation) +{ +} + +void ZlibDecompressor::ProcessPrestreamHeader() +{ + m_adler32.Restart(); + + byte cmf; + byte flags; + + if (!m_inQueue.Get(cmf) || !m_inQueue.Get(flags)) + throw HeaderErr(); + + if ((cmf*256+flags) % 31 != 0) + throw HeaderErr(); // if you hit this exception, you're probably trying to decompress invalid data + + if ((cmf & 0xf) != DEFLATE_METHOD) + throw UnsupportedAlgorithm(); + + if (flags & FDICT_FLAG) + throw UnsupportedPresetDictionary(); + + m_log2WindowSize = 8 + (cmf >> 4); +} + +void ZlibDecompressor::ProcessDecompressedData(const byte *inString, size_t length) +{ + AttachedTransformation()->Put(inString, length); + m_adler32.Update(inString, length); +} + +void ZlibDecompressor::ProcessPoststreamTail() +{ + FixedSizeSecBlock adler32; + if (m_inQueue.Get(adler32, 4) != 4) + throw Adler32Err(); + if (!m_adler32.Verify(adler32)) + throw Adler32Err(); +} + +NAMESPACE_END diff --git a/CryptoPP/crypto/zlib.h b/CryptoPP/crypto/zlib.h new file mode 100644 index 0000000..a9acc7d --- /dev/null +++ b/CryptoPP/crypto/zlib.h @@ -0,0 +1,58 @@ +#ifndef CRYPTOPP_ZLIB_H +#define CRYPTOPP_ZLIB_H + +#include "adler32.h" +#include "zdeflate.h" +#include "zinflate.h" + +NAMESPACE_BEGIN(CryptoPP) + +/// ZLIB Compressor (RFC 1950) +class ZlibCompressor : public Deflator +{ +public: + ZlibCompressor(BufferedTransformation *attachment=NULL, unsigned int deflateLevel=DEFAULT_DEFLATE_LEVEL, unsigned int log2WindowSize=DEFAULT_LOG2_WINDOW_SIZE, bool detectUncompressible=true) + : Deflator(attachment, deflateLevel, log2WindowSize, detectUncompressible) {} + ZlibCompressor(const NameValuePairs ¶meters, BufferedTransformation *attachment=NULL) + : Deflator(parameters, attachment) {} + + unsigned int GetCompressionLevel() const; + +protected: + void WritePrestreamHeader(); + void ProcessUncompressedData(const byte *string, size_t length); + void WritePoststreamTail(); + + Adler32 m_adler32; +}; + +/// ZLIB Decompressor (RFC 1950) +class ZlibDecompressor : public Inflator +{ +public: + typedef Inflator::Err Err; + class HeaderErr : public Err {public: HeaderErr() : Err(INVALID_DATA_FORMAT, "ZlibDecompressor: header decoding error") {}}; + class Adler32Err : public Err {public: Adler32Err() : Err(DATA_INTEGRITY_CHECK_FAILED, "ZlibDecompressor: ADLER32 check error") {}}; + class UnsupportedAlgorithm : public Err {public: UnsupportedAlgorithm() : Err(INVALID_DATA_FORMAT, "ZlibDecompressor: unsupported algorithm") {}}; + class UnsupportedPresetDictionary : public Err {public: UnsupportedPresetDictionary() : Err(INVALID_DATA_FORMAT, "ZlibDecompressor: unsupported preset dictionary") {}}; + + /*! \param repeat decompress multiple compressed streams in series + \param autoSignalPropagation 0 to turn off MessageEnd signal + */ + ZlibDecompressor(BufferedTransformation *attachment = NULL, bool repeat = false, int autoSignalPropagation = -1); + unsigned int GetLog2WindowSize() const {return m_log2WindowSize;} + +private: + unsigned int MaxPrestreamHeaderSize() const {return 2;} + void ProcessPrestreamHeader(); + void ProcessDecompressedData(const byte *string, size_t length); + unsigned int MaxPoststreamTailSize() const {return 4;} + void ProcessPoststreamTail(); + + unsigned int m_log2WindowSize; + Adler32 m_adler32; +}; + +NAMESPACE_END + +#endif diff --git a/CryptoPP/cryptopp.dep b/CryptoPP/cryptopp.dep new file mode 100644 index 0000000..57466bc --- /dev/null +++ b/CryptoPP/cryptopp.dep @@ -0,0 +1,80 @@ +# Microsoft Developer Studio Generated Dependency File, included by cryptopp.mak + +.\commonheaders.cpp : \ + "..\..\include\m_database.h"\ + "..\..\include\m_netlib.h"\ + "..\..\include\m_plugins.h"\ + "..\..\include\m_protocols.h"\ + "..\..\include\m_protomod.h"\ + "..\..\include\m_protosvc.h"\ + "..\..\include\m_stdhdr.h"\ + "..\..\include\m_system.h"\ + "..\..\include\m_utils.h"\ + "..\..\include\newpluginapi.h"\ + "..\..\include\statusmodes.h"\ + ".\base16.h"\ + ".\base64.h"\ + ".\commonheaders.h"\ + ".\cpp_rsam.h"\ + ".\cpp_rsau.h"\ + ".\crypto\adler32.h"\ + ".\crypto\aes.h"\ + ".\crypto\algebra.h"\ + ".\crypto\algparam.h"\ + ".\crypto\argnames.h"\ + ".\crypto\asn.h"\ + ".\crypto\config.h"\ + ".\crypto\crc.h"\ + ".\crypto\cryptlib.h"\ + ".\crypto\dh.h"\ + ".\crypto\emsa2.h"\ + ".\crypto\eprecomp.h"\ + ".\crypto\files.h"\ + ".\crypto\filters.h"\ + ".\crypto\fips140.h"\ + ".\crypto\gfpcrypt.h"\ + ".\crypto\gzip.h"\ + ".\crypto\hmac.h"\ + ".\crypto\integer.h"\ + ".\crypto\iterhash.h"\ + ".\crypto\misc.h"\ + ".\crypto\modarith.h"\ + ".\crypto\modes.h"\ + ".\crypto\modexppc.h"\ + ".\crypto\oaep.h"\ + ".\crypto\osrng.h"\ + ".\crypto\pkcspad.h"\ + ".\crypto\pubkey.h"\ + ".\crypto\randpool.h"\ + ".\crypto\rijndael.h"\ + ".\crypto\ripemd.h"\ + ".\crypto\rng.h"\ + ".\crypto\rsa.h"\ + ".\crypto\secblock.h"\ + ".\crypto\seckey.h"\ + ".\crypto\sha.h"\ + ".\crypto\simple.h"\ + ".\crypto\smartptr.h"\ + ".\crypto\stdcpp.h"\ + ".\crypto\strciphr.h"\ + ".\crypto\tiger.h"\ + ".\crypto\zdeflate.h"\ + ".\crypto\zinflate.h"\ + ".\crypto\zlib.h"\ + ".\cryptopp.h"\ + ".\dllloader.h"\ + ".\gettime.h"\ + ".\mmi.h"\ + ".\sdk\m_updater.h"\ + ".\utf8.h"\ + ".\version.h"\ + "d:\program files\microsoft visual studio\vc98\include\basetsd.h"\ + + +.\resource.rc : \ + ".\gpgw\release\gnupgw.dll"\ + ".\pgpw\release6\pgpsdkw6.dll"\ + ".\pgpw\release8\pgpsdkw8.dll"\ + ".\version.h"\ + ".\version.rc"\ + diff --git a/CryptoPP/cryptopp.dsp b/CryptoPP/cryptopp.dsp new file mode 100644 index 0000000..3b418e6 --- /dev/null +++ b/CryptoPP/cryptopp.dsp @@ -0,0 +1,233 @@ +# Microsoft Developer Studio Project File - Name="cryptopp" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 + +CFG=cryptopp - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "cryptopp.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "cryptopp.mak" CFG="cryptopp - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "cryptopp - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "cryptopp - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "cryptopp - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CRYPTOPP_EXPORTS" /YX /FD /c +# ADD CPP /nologo /MD /W3 /GX /O1 /I "\source\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"commonheaders.h" /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "NDEBUG" +# ADD RSC /l 0x419 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib advapi32.lib shell32.lib uuid.lib /nologo /base:"0x46000000" /dll /map /machine:I386 +# SUBTRACT LINK32 /pdb:none /incremental:yes + +!ELSEIF "$(CFG)" == "cryptopp - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CRYPTOPP_EXPORTS" /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "\source\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CRYPTOPP_EXPORTS" /YX"commonheaders.h" /FD /GZ /c +# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x419 /d "_DEBUG" +# ADD RSC /l 0x419 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib advapi32.lib shell32.lib uuid.lib /nologo /base:"0x46000000" /dll /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "cryptopp - Win32 Release" +# Name "cryptopp - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\base16.cpp +# End Source File +# Begin Source File + +SOURCE=.\base64.cpp +# End Source File +# Begin Source File + +SOURCE=.\commonheaders.cpp + +!IF "$(CFG)" == "cryptopp - Win32 Release" + +# ADD CPP /Yc"commonheaders.h" + +!ELSEIF "$(CFG)" == "cryptopp - Win32 Debug" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\cpp_cntx.cpp +# End Source File +# Begin Source File + +SOURCE=.\cpp_gpgw.cpp +# End Source File +# Begin Source File + +SOURCE=.\cpp_gzip.cpp +# End Source File +# Begin Source File + +SOURCE=.\cpp_keys.cpp +# End Source File +# Begin Source File + +SOURCE=.\cpp_misc.cpp +# End Source File +# Begin Source File + +SOURCE=.\cpp_pgpw.cpp +# End Source File +# Begin Source File + +SOURCE=.\cpp_rsam.cpp +# End Source File +# Begin Source File + +SOURCE=.\cpp_rsau.cpp +# End Source File +# Begin Source File + +SOURCE=.\cpp_svcs.cpp +# End Source File +# Begin Source File + +SOURCE=.\dllloader.cpp +# End Source File +# Begin Source File + +SOURCE=.\gettime.cpp +# End Source File +# Begin Source File + +SOURCE=.\main.cpp +# End Source File +# Begin Source File + +SOURCE=.\mmi.cpp +# End Source File +# Begin Source File + +SOURCE=.\utf8.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\base16.h +# End Source File +# Begin Source File + +SOURCE=.\base64.h +# End Source File +# Begin Source File + +SOURCE=.\commonheaders.h +# End Source File +# Begin Source File + +SOURCE=.\cpp_rsam.h +# End Source File +# Begin Source File + +SOURCE=.\cpp_rsau.h +# End Source File +# Begin Source File + +SOURCE=.\cryptopp.h +# End Source File +# Begin Source File + +SOURCE=.\dllloader.h +# End Source File +# Begin Source File + +SOURCE=.\gettime.h +# End Source File +# Begin Source File + +SOURCE=.\mmi.h +# End Source File +# Begin Source File + +SOURCE=.\resource.h +# End Source File +# Begin Source File + +SOURCE=.\utf8.h +# End Source File +# Begin Source File + +SOURCE=.\version.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\resource.rc +# End Source File +# End Group +# End Target +# End Project diff --git a/CryptoPP/cryptopp.dsw b/CryptoPP/cryptopp.dsw new file mode 100644 index 0000000..53b280e --- /dev/null +++ b/CryptoPP/cryptopp.dsw @@ -0,0 +1,44 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "cryptopp"=.\cryptopp.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name cryptlib + End Project Dependency +}}} +############################################################################### + +Project: "cryptlib"=.\crypto\cryptlib.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/CryptoPP/cryptopp.h b/CryptoPP/cryptopp.h new file mode 100644 index 0000000..8648d7b --- /dev/null +++ b/CryptoPP/cryptopp.h @@ -0,0 +1,216 @@ +#ifndef __CRYPTOPP_H__ +#define __CRYPTOPP_H__ + +#include +#include +#include +#include + +//#pragma warning(push) +// 4231: nonstandard extension used : 'extern' before template explicit instantiation +// 4250: dominance +// 4251: member needs to have dll-interface +// 4275: base needs to have dll-interface +// 4660: explicitly instantiating a class that's already implicitly instantiated +// 4661: no suitable definition provided for explicit template instantiation request +// 4700: unused variable names... +// 4706: long names... +// 4786: identifer was truncated in debug information +// 4355: 'this' : used in base member initializer list +#pragma warning(disable: 4231 4250 4251 4275 4660 4661 4700 4706 4786 4355) +#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1 +#include "crypto/modes.h" +#include "crypto/osrng.h" +#include "crypto/rsa.h" +#include "crypto/aes.h" +#include "crypto/dh.h" +#include "crypto/crc.h" +#include "crypto/ripemd.h" +#include "crypto/sha.h" +#include "crypto/tiger.h" +#include "crypto/gzip.h" +#include "crypto/zlib.h" +#include "crypto/files.h" +//#pragma warning(pop) + +USING_NAMESPACE(CryptoPP); +USING_NAMESPACE(std) + +#define KEYSIZE 256 +#define DEFMSGS 4096 + +#define HEADER 0xABCD1234 +#define FOOTER 0x9876FEDC +#define EMPTYH 0xF1E2D3C4 + +typedef struct __CNTX { + u_int header; // HEADER + short mode; // mode of encoding + short features; // features of client + short error; // error code of last operation + PBYTE pdata; // data block + PVOID udata; // user data + LPSTR tmp; // return string + u_int deleted; // delete time&flag to delete + u_int footer; // FOOTER +} CNTX; +typedef CNTX* pCNTX; + + +#define FEATURES_UTF8 0x01 +#define FEATURES_BASE64 0x02 +#define FEATURES_GZIP 0x04 +#define FEATURES_CRC32 0x08 +#define FEATURES_PSK 0x10 +#define FEATURES_NEWPG 0x20 +#define FEATURES_RSA 0x40 + +#define MODE_BASE16 0x0000 +#define MODE_BASE64 0x0001 +#define MODE_PGP 0x0002 +#define MODE_GPG 0x0004 +#define MODE_GPG_ANSI 0x0008 +#define MODE_PRIV_KEY 0x0010 +#define MODE_RSA_2048 0x0020 +#define MODE_RSA_4096 0x0040 +#define MODE_RSA MODE_RSA_4096 +#define MODE_RSA_ONLY 0x0080 +#define MODE_RSA_ZLIB 0x0100 +#define MODE_RSA_BER 0x0200 + +#define DATA_GZIP 1 + +typedef struct __SIMDATA { + DH *dh; // diffie-hellman + PBYTE PubA; // public keyA 2048 bit + PBYTE KeyA; // private keyA 2048 bit + PBYTE KeyB; // public keyB 2048 bit + PBYTE KeyX; // secret keyX 192 bit + PBYTE KeyP; // pre-shared keyP 192 bit +} SIMDATA; +typedef SIMDATA* pSIMDATA; + + +typedef struct __PGPDATA { + PBYTE pgpKeyID; // PGP KeyID + PBYTE pgpKey; // PGP Key +} PGPDATA; +typedef PGPDATA* pPGPDATA; + + +typedef struct __GPGDATA { + BYTE *gpgKeyID; // GPG KeyID +} GPGDATA; +typedef GPGDATA* pGPGDATA; + + +#define RSA_KEYSIZE SHA1::DIGESTSIZE +#define RSA_CalculateDigest SHA1().CalculateDigest + + +typedef struct __RSAPRIV { + string priv_k; // private key string + string priv_s; // hash(priv_k) + RSA::PrivateKey priv; // private key + string pub_k; // public key string + string pub_s; // hash(pub_k) +} RSAPRIV; +typedef RSAPRIV* pRSAPRIV; + + +typedef deque > STRINGDEQUE; +typedef queue STRINGQUEUE; + + +typedef struct __RSADATA { + short state; // 0 - нифига нет, 1..6 - keyexchange, 7 - соединение установлено + u_int time; // для прерывания keyexchange, если долго нет ответа + string pub_k; // public key string + string pub_s; // hash(pub_k) + RSA::PublicKey pub; // public key + string aes_k; // aes key + string aes_v; // aes iv + HANDLE thread; // thread handle + BOOL thread_exit; + HANDLE event; // thread event + STRINGQUEUE *queue; // thread queue +} RSADATA; +typedef RSADATA* pRSADATA; + + +#define ERROR_NONE 0 +#define ERROR_SEH 1 +#define ERROR_NO_KEYA 2 +#define ERROR_NO_KEYB 3 +#define ERROR_NO_KEYX 4 +#define ERROR_BAD_LEN 5 +#define ERROR_BAD_CRC 6 +#define ERROR_NO_PSK 7 +#define ERROR_BAD_PSK 8 +#define ERROR_BAD_KEYB 9 +#define ERROR_NO_PGP_KEY 10 +#define ERROR_NO_PGP_PASS 11 +#define ERROR_NO_GPG_KEY 12 +#define ERROR_NO_GPG_PASS 13 + +#if defined(_DEBUG) +#define FEATURES (FEATURES_UTF8 | FEATURES_BASE64 | FEATURES_GZIP | FEATURES_CRC32 | FEATURES_NEWPG) +#else +#define FEATURES (FEATURES_UTF8 | FEATURES_BASE64 | FEATURES_GZIP | FEATURES_CRC32 | FEATURES_NEWPG | FEATURES_RSA) +#endif + +#define DLLEXPORT __declspec(dllexport) + +extern LPCSTR szModuleName; +extern LPCSTR szVersionStr; +extern HINSTANCE g_hInst; + +pCNTX get_context_on_id(int); +pCNTX get_context_on_id(HANDLE); +void cpp_free_keys(pCNTX); +BYTE *cpp_gzip(BYTE*,int,int&); +BYTE *cpp_gunzip(BYTE*,int,int&); +string cpp_zlibc(string&); +string cpp_zlibd(string&); + +typedef struct { + int (__cdecl *rsa_gen_keypair)(short); // генерит RSA-ключи для указанной длины (либо тока 2048, либо 2048 и 4096) + int (__cdecl *rsa_get_keypair)(short,PBYTE,int*,PBYTE,int*); // возвращает пару ключей для указанной длины + int (__cdecl *rsa_get_keyhash)(short,PBYTE,int*,PBYTE,int*); // возвращает hash пары ключей для указанной длины + int (__cdecl *rsa_set_keypair)(short,PBYTE,int); // устанавливает ключи, указанной длины + int (__cdecl *rsa_get_pubkey)(HANDLE,PBYTE,int*); // возвращает паблик ключ из указанного контекста + int (__cdecl *rsa_set_pubkey)(HANDLE,PBYTE,int); // загружает паблик ключ для указанного контекста + void (__cdecl *rsa_set_timeout)(int); // установить таймаут для установки секюрного соединения + int (__cdecl *rsa_get_state)(HANDLE); // получить статус указанного контекста + int (__cdecl *rsa_get_hash)(PBYTE,int,PBYTE,int*); // вычисляет SHA1(key) + int (__cdecl *rsa_connect)(HANDLE); // запускает процесс установки содинения с указанным контекстом + int (__cdecl *rsa_disconnect)(HANDLE); // разрывает соединение с указанным контекстом + int (__cdecl *rsa_disabled)(HANDLE); // разрывает соединение по причине "disabled" + LPSTR (__cdecl *rsa_recv)(HANDLE,LPCSTR); // необходимо передавать сюда все входящие протокольные сообщения + int (__cdecl *rsa_send)(HANDLE,LPCSTR); // вызываем для отправки сообщения клиенту + int (__cdecl *rsa_encrypt_file)(HANDLE,LPCSTR,LPCSTR); + int (__cdecl *rsa_decrypt_file)(HANDLE,LPCSTR,LPCSTR); + LPSTR (__cdecl *utf8encode)(LPCWSTR); + LPWSTR (__cdecl *utf8decode)(LPCSTR); + int (__cdecl *is_7bit_string)(LPCSTR); + int (__cdecl *is_utf8_string)(LPCSTR); + int (__cdecl *rsa_export_keypair)(short,LPSTR,LPSTR,LPSTR); // export private key + int (__cdecl *rsa_import_keypair)(short,LPSTR,LPSTR); // import & activate private key + int (__cdecl *rsa_export_pubkey)(HANDLE,LPSTR); // export public key from context + int (__cdecl *rsa_import_pubkey)(HANDLE,LPSTR); // import public key into context +} RSA_EXPORT; +typedef RSA_EXPORT* pRSA_EXPORT; + +typedef struct { + int (__cdecl *rsa_inject)(HANDLE,LPCSTR); // вставляет сообщение в очередь на отправку + int (__cdecl *rsa_check_pub)(HANDLE,PBYTE,int,PBYTE,int); // проверяет интерактивно SHA и сохраняет ключ, если все нормально + void (__cdecl *rsa_notify)(HANDLE,int); // нотификация о смене состояния +} RSA_IMPORT; +typedef RSA_IMPORT* pRSA_IMPORT; + +NAMESPACE_BEGIN(CryptoPP) +typedef RSASS::Signer RSASSA_PKCS1v15_SHA256_Signer; +typedef RSASS::Verifier RSASSA_PKCS1v15_SHA256_Verifier; +NAMESPACE_END + +#endif diff --git a/CryptoPP/cryptopp.mak b/CryptoPP/cryptopp.mak new file mode 100644 index 0000000..7c3cd9a --- /dev/null +++ b/CryptoPP/cryptopp.mak @@ -0,0 +1,420 @@ +# Microsoft Developer Studio Generated NMAKE File, Based on cryptopp.dsp +!IF "$(CFG)" == "" +CFG=cryptopp - Win32 Release +!MESSAGE No configuration specified. Defaulting to cryptopp - Win32 Release. +!ENDIF + +!IF "$(CFG)" != "cryptopp - Win32 Release" && "$(CFG)" != "cryptopp - Win32 Debug" +!MESSAGE Invalid configuration "$(CFG)" specified. +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "cryptopp.mak" CFG="cryptopp - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "cryptopp - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE "cryptopp - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") +!MESSAGE +!ERROR An invalid configuration is specified. +!ENDIF + +!IF "$(OS)" == "Windows_NT" +NULL= +!ELSE +NULL=nul +!ENDIF + +!IF "$(CFG)" == "cryptopp - Win32 Release" + +OUTDIR=.\Release +INTDIR=.\Release +# Begin Custom Macros +OutDir=.\Release +# End Custom Macros + +!IF "$(RECURSE)" == "0" + +ALL : "$(OUTDIR)\cryptopp.dll" + +!ELSE + +ALL : "cryptlib - Win32 Release" "$(OUTDIR)\cryptopp.dll" + +!ENDIF + +!IF "$(RECURSE)" == "1" +CLEAN :"cryptlib - Win32 ReleaseCLEAN" +!ELSE +CLEAN : +!ENDIF + -@erase "$(INTDIR)\base16.obj" + -@erase "$(INTDIR)\base64.obj" + -@erase "$(INTDIR)\commonheaders.obj" + -@erase "$(INTDIR)\cpp_cntx.obj" + -@erase "$(INTDIR)\cpp_gpgw.obj" + -@erase "$(INTDIR)\cpp_gzip.obj" + -@erase "$(INTDIR)\cpp_keys.obj" + -@erase "$(INTDIR)\cpp_misc.obj" + -@erase "$(INTDIR)\cpp_pgpw.obj" + -@erase "$(INTDIR)\cpp_rsam.obj" + -@erase "$(INTDIR)\cpp_rsau.obj" + -@erase "$(INTDIR)\cpp_svcs.obj" + -@erase "$(INTDIR)\cryptopp.pch" + -@erase "$(INTDIR)\dllloader.obj" + -@erase "$(INTDIR)\gettime.obj" + -@erase "$(INTDIR)\main.obj" + -@erase "$(INTDIR)\mmi.obj" + -@erase "$(INTDIR)\resource.res" + -@erase "$(INTDIR)\utf8.obj" + -@erase "$(INTDIR)\vc60.idb" + -@erase "$(OUTDIR)\cryptopp.dll" + -@erase "$(OUTDIR)\cryptopp.exp" + -@erase "$(OUTDIR)\cryptopp.lib" + -@erase "$(OUTDIR)\cryptopp.map" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +CPP_PROJ=/nologo /MD /W3 /GX /O1 /I "\source\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Fp"$(INTDIR)\cryptopp.pch" /Yu"commonheaders.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c + +.c{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +MTL=midl.exe +MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 +RSC=rc.exe +RSC_PROJ=/l 0x419 /fo"$(INTDIR)\resource.res" /d "NDEBUG" +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\cryptopp.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib comdlg32.lib advapi32.lib shell32.lib uuid.lib /nologo /base:"0x46000000" /dll /incremental:no /pdb:"$(OUTDIR)\cryptopp.pdb" /map:"$(INTDIR)\cryptopp.map" /machine:I386 /out:"$(OUTDIR)\cryptopp.dll" /implib:"$(OUTDIR)\cryptopp.lib" +LINK32_OBJS= \ + "$(INTDIR)\base16.obj" \ + "$(INTDIR)\base64.obj" \ + "$(INTDIR)\commonheaders.obj" \ + "$(INTDIR)\cpp_cntx.obj" \ + "$(INTDIR)\cpp_gpgw.obj" \ + "$(INTDIR)\cpp_gzip.obj" \ + "$(INTDIR)\cpp_keys.obj" \ + "$(INTDIR)\cpp_misc.obj" \ + "$(INTDIR)\cpp_pgpw.obj" \ + "$(INTDIR)\cpp_rsam.obj" \ + "$(INTDIR)\cpp_rsau.obj" \ + "$(INTDIR)\cpp_svcs.obj" \ + "$(INTDIR)\dllloader.obj" \ + "$(INTDIR)\gettime.obj" \ + "$(INTDIR)\main.obj" \ + "$(INTDIR)\mmi.obj" \ + "$(INTDIR)\utf8.obj" \ + "$(INTDIR)\resource.res" \ + ".\crypto\Release\cryptlib.lib" + +"$(OUTDIR)\cryptopp.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ELSEIF "$(CFG)" == "cryptopp - Win32 Debug" + +OUTDIR=.\Debug +INTDIR=.\Debug +# Begin Custom Macros +OutDir=.\Debug +# End Custom Macros + +!IF "$(RECURSE)" == "0" + +ALL : "$(OUTDIR)\cryptopp.dll" + +!ELSE + +ALL : "cryptlib - Win32 Debug" "$(OUTDIR)\cryptopp.dll" + +!ENDIF + +!IF "$(RECURSE)" == "1" +CLEAN :"cryptlib - Win32 DebugCLEAN" +!ELSE +CLEAN : +!ENDIF + -@erase "$(INTDIR)\base16.obj" + -@erase "$(INTDIR)\base64.obj" + -@erase "$(INTDIR)\commonheaders.obj" + -@erase "$(INTDIR)\cpp_cntx.obj" + -@erase "$(INTDIR)\cpp_gpgw.obj" + -@erase "$(INTDIR)\cpp_gzip.obj" + -@erase "$(INTDIR)\cpp_keys.obj" + -@erase "$(INTDIR)\cpp_misc.obj" + -@erase "$(INTDIR)\cpp_pgpw.obj" + -@erase "$(INTDIR)\cpp_rsam.obj" + -@erase "$(INTDIR)\cpp_rsau.obj" + -@erase "$(INTDIR)\cpp_svcs.obj" + -@erase "$(INTDIR)\dllloader.obj" + -@erase "$(INTDIR)\gettime.obj" + -@erase "$(INTDIR)\main.obj" + -@erase "$(INTDIR)\mmi.obj" + -@erase "$(INTDIR)\resource.res" + -@erase "$(INTDIR)\utf8.obj" + -@erase "$(INTDIR)\vc60.idb" + -@erase "$(INTDIR)\vc60.pdb" + -@erase "$(OUTDIR)\cryptopp.dll" + -@erase "$(OUTDIR)\cryptopp.exp" + -@erase "$(OUTDIR)\cryptopp.ilk" + -@erase "$(OUTDIR)\cryptopp.lib" + -@erase "$(OUTDIR)\cryptopp.pdb" + +"$(OUTDIR)" : + if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" + +CPP=cl.exe +CPP_PROJ=/nologo /MDd /W3 /Gm /GX /ZI /Od /I "\source\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CRYPTOPP_EXPORTS" /Fp"$(INTDIR)\cryptopp.pch" /YX"commonheaders.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c + +.c{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.c{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx{$(INTDIR)}.sbr:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +MTL=midl.exe +MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32 +RSC=rc.exe +RSC_PROJ=/l 0x419 /fo"$(INTDIR)\resource.res" /d "_DEBUG" +BSC32=bscmake.exe +BSC32_FLAGS=/nologo /o"$(OUTDIR)\cryptopp.bsc" +BSC32_SBRS= \ + +LINK32=link.exe +LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib comdlg32.lib advapi32.lib shell32.lib uuid.lib /nologo /base:"0x46000000" /dll /incremental:yes /pdb:"$(OUTDIR)\cryptopp.pdb" /debug /machine:I386 /out:"$(OUTDIR)\cryptopp.dll" /implib:"$(OUTDIR)\cryptopp.lib" /pdbtype:sept +LINK32_OBJS= \ + "$(INTDIR)\base16.obj" \ + "$(INTDIR)\base64.obj" \ + "$(INTDIR)\commonheaders.obj" \ + "$(INTDIR)\cpp_cntx.obj" \ + "$(INTDIR)\cpp_gpgw.obj" \ + "$(INTDIR)\cpp_gzip.obj" \ + "$(INTDIR)\cpp_keys.obj" \ + "$(INTDIR)\cpp_misc.obj" \ + "$(INTDIR)\cpp_pgpw.obj" \ + "$(INTDIR)\cpp_rsam.obj" \ + "$(INTDIR)\cpp_rsau.obj" \ + "$(INTDIR)\cpp_svcs.obj" \ + "$(INTDIR)\dllloader.obj" \ + "$(INTDIR)\gettime.obj" \ + "$(INTDIR)\main.obj" \ + "$(INTDIR)\mmi.obj" \ + "$(INTDIR)\utf8.obj" \ + "$(INTDIR)\resource.res" \ + ".\crypto\Debug\cryptlib.lib" + +"$(OUTDIR)\cryptopp.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) + $(LINK32) @<< + $(LINK32_FLAGS) $(LINK32_OBJS) +<< + +!ENDIF + + +!IF "$(NO_EXTERNAL_DEPS)" != "1" +!IF EXISTS("cryptopp.dep") +!INCLUDE "cryptopp.dep" +!ELSE +!MESSAGE Warning: cannot find "cryptopp.dep" +!ENDIF +!ENDIF + + +!IF "$(CFG)" == "cryptopp - Win32 Release" || "$(CFG)" == "cryptopp - Win32 Debug" +SOURCE=.\base16.cpp + +"$(INTDIR)\base16.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptopp.pch" + + +SOURCE=.\base64.cpp + +"$(INTDIR)\base64.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptopp.pch" + + +SOURCE=.\commonheaders.cpp + +!IF "$(CFG)" == "cryptopp - Win32 Release" + +CPP_SWITCHES=/nologo /MD /W3 /GX /O1 /I "\source\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Fp"$(INTDIR)\cryptopp.pch" /Yc"commonheaders.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c + +"$(INTDIR)\commonheaders.obj" "$(INTDIR)\cryptopp.pch" : $(SOURCE) "$(INTDIR)" + $(CPP) @<< + $(CPP_SWITCHES) $(SOURCE) +<< + + +!ELSEIF "$(CFG)" == "cryptopp - Win32 Debug" + +CPP_SWITCHES=/nologo /MDd /W3 /Gm /GX /ZI /Od /I "\source\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "CRYPTOPP_EXPORTS" /Fp"$(INTDIR)\cryptopp.pch" /YX"commonheaders.h" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /GZ /c + +"$(INTDIR)\commonheaders.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) @<< + $(CPP_SWITCHES) $(SOURCE) +<< + + +!ENDIF + +SOURCE=.\cpp_cntx.cpp + +"$(INTDIR)\cpp_cntx.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptopp.pch" + + +SOURCE=.\cpp_gpgw.cpp + +"$(INTDIR)\cpp_gpgw.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptopp.pch" + + +SOURCE=.\cpp_gzip.cpp + +"$(INTDIR)\cpp_gzip.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptopp.pch" + + +SOURCE=.\cpp_keys.cpp + +"$(INTDIR)\cpp_keys.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptopp.pch" + + +SOURCE=.\cpp_misc.cpp + +"$(INTDIR)\cpp_misc.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptopp.pch" + + +SOURCE=.\cpp_pgpw.cpp + +"$(INTDIR)\cpp_pgpw.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptopp.pch" + + +SOURCE=.\cpp_rsam.cpp + +"$(INTDIR)\cpp_rsam.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptopp.pch" + + +SOURCE=.\cpp_rsau.cpp + +"$(INTDIR)\cpp_rsau.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptopp.pch" + + +SOURCE=.\cpp_svcs.cpp + +"$(INTDIR)\cpp_svcs.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptopp.pch" + + +SOURCE=.\dllloader.cpp + +"$(INTDIR)\dllloader.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptopp.pch" + + +SOURCE=.\gettime.cpp + +"$(INTDIR)\gettime.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptopp.pch" + + +SOURCE=.\main.cpp + +"$(INTDIR)\main.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptopp.pch" + + +SOURCE=.\mmi.cpp + +"$(INTDIR)\mmi.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptopp.pch" + + +SOURCE=.\utf8.cpp + +"$(INTDIR)\utf8.obj" : $(SOURCE) "$(INTDIR)" "$(INTDIR)\cryptopp.pch" + + +SOURCE=.\resource.rc + +"$(INTDIR)\resource.res" : $(SOURCE) "$(INTDIR)" + $(RSC) $(RSC_PROJ) $(SOURCE) + + +!IF "$(CFG)" == "cryptopp - Win32 Release" + +"cryptlib - Win32 Release" : + cd ".\crypto" + $(MAKE) /$(MAKEFLAGS) /F .\cryptlib.mak CFG="cryptlib - Win32 Release" + cd ".." + +"cryptlib - Win32 ReleaseCLEAN" : + cd ".\crypto" + $(MAKE) /$(MAKEFLAGS) /F .\cryptlib.mak CFG="cryptlib - Win32 Release" RECURSE=1 CLEAN + cd ".." + +!ELSEIF "$(CFG)" == "cryptopp - Win32 Debug" + +"cryptlib - Win32 Debug" : + cd ".\crypto" + $(MAKE) /$(MAKEFLAGS) /F .\cryptlib.mak CFG="cryptlib - Win32 Debug" + cd ".." + +"cryptlib - Win32 DebugCLEAN" : + cd ".\crypto" + $(MAKE) /$(MAKEFLAGS) /F .\cryptlib.mak CFG="cryptlib - Win32 Debug" RECURSE=1 CLEAN + cd ".." + +!ENDIF + + +!ENDIF + diff --git a/CryptoPP/cryptopp_9.sln b/CryptoPP/cryptopp_9.sln new file mode 100644 index 0000000..9589bf3 --- /dev/null +++ b/CryptoPP/cryptopp_9.sln @@ -0,0 +1,28 @@ +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cryptlib", "crypto\cryptlib_9.vcproj", "{290C5ED4-71A7-4040-AD26-4820CF7A9E60}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cryptopp", "cryptopp_9.vcproj", "{4AC1E062-0236-4E49-AA04-F732043D2DCF}" + ProjectSection(ProjectDependencies) = postProject + {290C5ED4-71A7-4040-AD26-4820CF7A9E60} = {290C5ED4-71A7-4040-AD26-4820CF7A9E60} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {290C5ED4-71A7-4040-AD26-4820CF7A9E60}.Debug|Win32.ActiveCfg = Debug|Win32 + {290C5ED4-71A7-4040-AD26-4820CF7A9E60}.Debug|Win32.Build.0 = Debug|Win32 + {290C5ED4-71A7-4040-AD26-4820CF7A9E60}.Release|Win32.ActiveCfg = Release|Win32 + {290C5ED4-71A7-4040-AD26-4820CF7A9E60}.Release|Win32.Build.0 = Release|Win32 + {4AC1E062-0236-4E49-AA04-F732043D2DCF}.Debug|Win32.ActiveCfg = Debug|Win32 + {4AC1E062-0236-4E49-AA04-F732043D2DCF}.Debug|Win32.Build.0 = Debug|Win32 + {4AC1E062-0236-4E49-AA04-F732043D2DCF}.Release|Win32.ActiveCfg = Release|Win32 + {4AC1E062-0236-4E49-AA04-F732043D2DCF}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/CryptoPP/cryptopp_9.vcproj b/CryptoPP/cryptopp_9.vcproj new file mode 100644 index 0000000..fb7a174 --- /dev/null +++ b/CryptoPP/cryptopp_9.vcproj @@ -0,0 +1,656 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CryptoPP/dllloader.cpp b/CryptoPP/dllloader.cpp new file mode 100644 index 0000000..7dfea7e --- /dev/null +++ b/CryptoPP/dllloader.cpp @@ -0,0 +1,280 @@ +/* +* Loading dll from memory +* +* Written by Vitaliy Shitts (vit@shittz.ru) +* Copyright (c) 2004 Vitaliy Shittz. +* +* THIS CODE IS PROVIDED "AS IS". NO WARRANTY OF ANY KIND IS EXPRESSED +* OR IMPLIED. YOU USE AT YOUR OWN RISK. THE AUTHOR ACCEPTS NO LIABILITY +* IF IT CAUSES ANY DAMAGE TO YOU OR YOUR COMPUTER WHATSOEVER. +* +* Beware of bugs. +*/ + +#include "commonheaders.h" + +#ifdef DLL_FROM_RESOURCE + +#ifndef MIN +# define MIN(a,b) ((a)<(b)?(a):(b)) +#endif + +typedef BOOL (WINAPI *DLLMAIN)(HINSTANCE,DWORD,LPVOID); + +#pragma warning (push) +#pragma warning (disable: 4311; disable: 4312; disable: 4018) + +DWORD GetSectionProtection(DWORD sc) +{ + DWORD dwResult=0; + if (sc & IMAGE_SCN_MEM_NOT_CACHED) + dwResult |= PAGE_NOCACHE; + + if (sc & IMAGE_SCN_MEM_EXECUTE) + { + if (sc & IMAGE_SCN_MEM_READ) + { + if (sc & IMAGE_SCN_MEM_WRITE) + dwResult |= PAGE_EXECUTE_READWRITE; + else + dwResult |= PAGE_EXECUTE_READ; + } + else + { + if (sc & IMAGE_SCN_MEM_WRITE) + dwResult |= PAGE_EXECUTE_WRITECOPY; + else + dwResult |= PAGE_EXECUTE; + } + } + else + { + if (sc & IMAGE_SCN_MEM_READ) + { + if (sc & IMAGE_SCN_MEM_WRITE) + dwResult|=PAGE_READWRITE; + else + dwResult|=PAGE_READONLY; + } + else + { + if (sc & IMAGE_SCN_MEM_WRITE) + dwResult|=PAGE_WRITECOPY; + else + dwResult|=PAGE_NOACCESS; + } + } + + return dwResult; +} + +inline BOOL IsImportByOrdinal(DWORD ImportDescriptor) +{ + return (ImportDescriptor & IMAGE_ORDINAL_FLAG32)!=0; +} + + +HMODULE MemLoadLibrary(PBYTE data) +{ + IMAGE_FILE_HEADER *pFileHeader = NULL; + IMAGE_OPTIONAL_HEADER *pOptionalHeader = NULL; + IMAGE_SECTION_HEADER *pSectionHeader = NULL; + IMAGE_IMPORT_DESCRIPTOR *pImportDscrtr = NULL; + USHORT e_lfanew = *((USHORT*)(data+0x3c)); + PCHAR ImageBase = NULL; + PCHAR SectionBase = NULL; + + DWORD dwSize, dwOldProt, ImageBaseDelta; + int i; + + pFileHeader = (IMAGE_FILE_HEADER *)(data+e_lfanew+4); + pOptionalHeader = (IMAGE_OPTIONAL_HEADER *)(data+e_lfanew+4+sizeof(IMAGE_FILE_HEADER)); + if (pOptionalHeader->Magic!=IMAGE_NT_OPTIONAL_HDR32_MAGIC) + return NULL; + + // Let's try to reserv memory + ImageBase = (PCHAR)VirtualAlloc( + (PVOID)pOptionalHeader->ImageBase, + pOptionalHeader->SizeOfImage, + MEM_RESERVE,PAGE_NOACCESS); + + if(ImageBase==NULL) + { + ImageBase=(PCHAR)VirtualAlloc(NULL, + pOptionalHeader->SizeOfImage, + MEM_RESERVE,PAGE_NOACCESS); + if(ImageBase==NULL) + return NULL; + } + + // copy the header + SectionBase=(PCHAR)VirtualAlloc(ImageBase, + pOptionalHeader->SizeOfHeaders, + MEM_COMMIT,PAGE_READWRITE); + memcpy(SectionBase,data,pOptionalHeader->SizeOfHeaders); + // Do headers read-only (to be on the safe side) + VirtualProtect(SectionBase,pOptionalHeader->SizeOfHeaders,PAGE_READONLY,&dwOldProt); + + // find sections ... + pSectionHeader = (IMAGE_SECTION_HEADER *)(pOptionalHeader+1); + for (i=0; iNumberOfSections; i++) + { + SectionBase = (PCHAR)VirtualAlloc( + ImageBase+pSectionHeader[i].VirtualAddress, + pSectionHeader[i].Misc.VirtualSize, + MEM_COMMIT,PAGE_READWRITE); + if (SectionBase==NULL) + { + VirtualFree(ImageBase, 0, MEM_RELEASE); + return NULL; + } + // ... and copy initialization data + SectionBase = ImageBase+pSectionHeader[i].VirtualAddress; + dwSize = MIN(pSectionHeader[i].SizeOfRawData,pSectionHeader[i].Misc.VirtualSize); + memcpy(SectionBase, data+pSectionHeader[i].PointerToRawData,dwSize); + } + + // check addersses + ImageBaseDelta = (DWORD)ImageBase-pOptionalHeader->ImageBase; + if (ImageBaseDelta!=0 && + pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress!=0 + ) + { + IMAGE_BASE_RELOCATION *pBaseReloc = (IMAGE_BASE_RELOCATION *)(ImageBase+ + pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress); + IMAGE_BASE_RELOCATION *pBaseReloc0 = pBaseReloc; + WORD *wPointer = NULL; + DWORD dwModCount; + int i; + + while ((DWORD)pBaseReloc0-(DWORD)pBaseReloc < pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size) + { + dwModCount = (pBaseReloc0->SizeOfBlock-sizeof(pBaseReloc))/2; + wPointer = (WORD *)(pBaseReloc+1); + for (i=0; iVirtualAddress+((*wPointer)&0xfff)); + (*pdw)+=ImageBaseDelta; + } + pBaseReloc = (IMAGE_BASE_RELOCATION *)wPointer; + } + } + else if (ImageBaseDelta!=0) + { + VirtualFree(ImageBase, 0, MEM_RELEASE); + return NULL; + } + + pImportDscrtr = (IMAGE_IMPORT_DESCRIPTOR *)(ImageBase+ + pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); + + for (;pImportDscrtr->Name!=0; pImportDscrtr++) + { + PCHAR pLibName = (PCHAR)(ImageBase+pImportDscrtr->Name); + PCHAR pImortName = NULL; + HMODULE hLibModule = LoadLibrary(pLibName); + DWORD *pImport = NULL, + *pAddress = NULL; + DWORD ProcAddress; + + pAddress=(DWORD *)(ImageBase+pImportDscrtr->/*Original*/FirstThunk); + if (pImportDscrtr->TimeDateStamp==0) + pImport=(DWORD *)(ImageBase+pImportDscrtr->FirstThunk); + else + pImport=(DWORD *)(ImageBase+pImportDscrtr->OriginalFirstThunk); + for (i=0; pImport[i]!=0; i++) + { + if (IsImportByOrdinal(pImport[i])) + ProcAddress=(DWORD)GetProcAddress(hLibModule, (PCHAR)(pImport[i]&0xFFFF)); + else // import by name + { + pImortName=(PCHAR)(ImageBase+(pImport[i])+2); + ProcAddress=(DWORD)GetProcAddress(hLibModule, pImortName); + } + pAddress[i]=ProcAddress; + } + } + + // set section protection + for (i=0; iNumberOfSections; i++) + VirtualProtect((PVOID)(ImageBase+pSectionHeader[i].VirtualAddress), + pSectionHeader[i].Misc.VirtualSize, + GetSectionProtection(pSectionHeader[i].Characteristics), + &dwOldProt); + + // call DLLMain + if (pOptionalHeader->AddressOfEntryPoint!=0) + { + DLLMAIN dllMain=(DLLMAIN)(ImageBase+pOptionalHeader->AddressOfEntryPoint); + if (!dllMain((HMODULE)ImageBase, DLL_PROCESS_ATTACH, NULL)) + { + VirtualFree(ImageBase, 0, MEM_RELEASE); + return NULL; + } + } + + return (HMODULE)ImageBase; +} + + +BOOL MemFreeLibrary(HMODULE hDll) +{ + PIMAGE_DOS_HEADER pDosHeader = NULL; + PIMAGE_FILE_HEADER pFileHeader = NULL; + PIMAGE_OPTIONAL_HEADER pOptionalHeader = NULL; + + pDosHeader=(PIMAGE_DOS_HEADER)hDll; + pFileHeader=(PIMAGE_FILE_HEADER)(((PBYTE)hDll)+pDosHeader->e_lfanew+4); + pOptionalHeader=(PIMAGE_OPTIONAL_HEADER)(pFileHeader+1); + +// Call to DllMain + if (pOptionalHeader->AddressOfEntryPoint!=0) + { + DLLMAIN dllMain=(DLLMAIN)((PBYTE)hDll+pOptionalHeader->AddressOfEntryPoint); + dllMain(hDll, DLL_PROCESS_DETACH, NULL); + } +// free loaded librares + PIMAGE_IMPORT_DESCRIPTOR pImportDscrtr = (IMAGE_IMPORT_DESCRIPTOR *)((PBYTE)hDll+ + pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); + for (;pImportDscrtr->Name!=0; pImportDscrtr++) + { + PCHAR pLibName = (PCHAR)((PBYTE)hDll+pImportDscrtr->Name); + HMODULE hLib = GetModuleHandle(pLibName); + FreeLibrary(hLib); + } + + return VirtualFree((PVOID)hDll, 0, MEM_RELEASE); +} + +FARPROC MemGetProcAddress(HMODULE hDll, LPCTSTR fname) +{ + PIMAGE_DOS_HEADER pDosHeader = NULL; + PIMAGE_FILE_HEADER pFileHeader = NULL; + PIMAGE_OPTIONAL_HEADER pOptionalHeader = NULL; + + pDosHeader=(PIMAGE_DOS_HEADER)hDll; + pFileHeader=(PIMAGE_FILE_HEADER)(((PBYTE)hDll)+pDosHeader->e_lfanew+4); + pOptionalHeader=(PIMAGE_OPTIONAL_HEADER)(pFileHeader+1); + + DWORD dwExpRVA = pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; + PBYTE pb = (PBYTE)hDll; + PIMAGE_EXPORT_DIRECTORY pExportDir=(PIMAGE_EXPORT_DIRECTORY)(pb+dwExpRVA); + PDWORD pNamesRVA=(PDWORD)(pb+pExportDir->AddressOfNames); + PDWORD pFuncRVA=(PDWORD)(pb+pExportDir->AddressOfFunctions); + PWORD ord=(PWORD)(pb+pExportDir->AddressOfNameOrdinals); + + DWORD dwFunc=pExportDir->NumberOfNames; + for (int i=0; i + +u_int gettime(void); + +#endif diff --git a/CryptoPP/main.cpp b/CryptoPP/main.cpp new file mode 100644 index 0000000..99fc56f --- /dev/null +++ b/CryptoPP/main.cpp @@ -0,0 +1,87 @@ +#include "commonheaders.h" + + +// dllmain +BOOL WINAPI DllMain(HINSTANCE hInst, DWORD dwReason, LPVOID) { + g_hInst = hInst; + if( dwReason == DLL_PROCESS_ATTACH ) { + { + char temp[MAX_PATH]; + GetTempPath(sizeof(temp),temp); + GetLongPathName(temp,TEMP,sizeof(TEMP)); + TEMP_SIZE = strlen(TEMP); + if(TEMP[TEMP_SIZE-1]=='\\') { + TEMP_SIZE--; + TEMP[TEMP_SIZE]='\0'; + } + } + InitializeCriticalSection(&localQueueMutex); + InitializeCriticalSection(&localContextMutex); +#ifdef _DEBUG + isVista = 1; +#else + isVista = ( (DWORD)(LOBYTE(LOWORD(GetVersion()))) == 6 ); +#endif + } + //DLL_THREAD_ATTACH + return TRUE; +} + + +PLUGININFO *MirandaPluginInfo(DWORD mirandaVersion) { + return &pluginInfo; +} + + +PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion) +{ + return &pluginInfoEx; +} + + +MUUID* MirandaPluginInterfaces(void) +{ + return interfaces; +} + + +int onModulesLoaded(WPARAM wParam,LPARAM lParam) { + // updater plugin support +#if defined(_DEBUG) || defined(NETLIB_LOG) + InitNetlib(); +#endif + if(ServiceExists(MS_UPDATE_REGISTERFL)) { + CallService(MS_UPDATE_REGISTERFL, (WPARAM)2669, (LPARAM)&pluginInfo); + } + return 0; +} + + +int Load(PLUGINLINK *link) { + + pluginLink = link; + DisableThreadLibraryCalls(g_hInst); + + // get memoryManagerInterface address + mir_getMMI( &mmi ); + + // register plugin module + PROTOCOLDESCRIPTOR pd; + memset(&pd,0,sizeof(pd)); + pd.cbSize = sizeof(pd); + pd.szName = (char*)szModuleName; + pd.type = PROTOTYPE_ENCRYPTION; + CallService(MS_PROTO_REGISTERMODULE, 0, (LPARAM)&pd); + + // hook events + HookEvent(ME_SYSTEM_MODULESLOADED,onModulesLoaded); + return 0; +} + + +int Unload() { + return 0; +} + + +// EOF diff --git a/CryptoPP/mmi.cpp b/CryptoPP/mmi.cpp new file mode 100644 index 0000000..03294c6 --- /dev/null +++ b/CryptoPP/mmi.cpp @@ -0,0 +1,88 @@ +#include "commonheaders.h" + +/* +void m_check(void *ptr, const char *module) { + if(ptr==NULL) { + char buffer[128]; + strcpy(buffer,module); strcat(buffer,": NULL pointer detected !"); + MessageBoxA(0,buffer,szModuleName,MB_OK|MB_ICONSTOP); + __asm{ int 3 }; + exit(1); + } +} + + +void *m_alloc(size_t size) { + void *ptr; + ptr = malloc(size); + m_check(ptr,"m_alloc"); + ZeroMemory(ptr,size); + return ptr; +} + + +void m_free(void *ptr) { +// m_check(ptr,"m_free"); + if(ptr) { + free(ptr); + } +} + + +void *m_realloc(void *ptr,size_t size) { + r = realloc(ptr,size); + m_check(ptr,"m_realloc"); + return ptr; +} + + +#ifndef _DEBUG +void *operator new(size_t size) { + return malloc(size); +} +#endif + + +void operator delete(void *p) { + free(p); +} + + +void *operator new[](size_t size) { + return operator new(size); +} + + +void operator delete[](void *p) { + operator delete(p); +} + + +char *m_strdup(const char *str) { + if(str==NULL) return NULL; + int len = (int)strlen(str)+1; + char *dup = (char*) m_alloc(len); + MoveMemory((void*)dup,(void*)str,len); + return dup; +} +*/ + +void __fastcall safe_free(void** p) +{ + if (*p) { + free(*p); + *p = NULL; + } +} + + +void __fastcall safe_delete(void** p) +{ + if (*p) { + delete(*p); + *p = NULL; + } +} + + +// EOF diff --git a/CryptoPP/mmi.h b/CryptoPP/mmi.h new file mode 100644 index 0000000..1ea57eb --- /dev/null +++ b/CryptoPP/mmi.h @@ -0,0 +1,22 @@ +#ifndef __MMI_H__ +#define __MMI_H__ +/* +void *m_alloc(size_t); +void m_free(void *); +void *m_realloc(void *,size_t); +char *m_strdup(const char *); + +void *operator new(size_t sz); +void operator delete(void *p); +void *operator new[](size_t size); +void operator delete[](void * p); +*/ + +#define SAFE_INIT(t,p) t p=NULL; +#define SAFE_FREE(p) safe_free((void **)&(p)); +#define SAFE_DELETE(p) safe_delete((void **)&(p)); + +void __fastcall safe_free(void** p); +void __fastcall safe_delete(void** p); + +#endif diff --git a/CryptoPP/readme.txt b/CryptoPP/readme.txt new file mode 100644 index 0000000..9030e21 --- /dev/null +++ b/CryptoPP/readme.txt @@ -0,0 +1,103 @@ + +-*-*-*-*-*-*-*-*- Описание RSA/AES алгоритма (наиболее свежее) -*-*-*-*-*-*-*-*- + + +Реализовано только RSA4096/AES256, без выбора длин ключей + + +стороны (1) и (2) - участнки установки криптосессии +sha(1) и sha(2) - sha от пабликов (или md5) +tlv() - type length value (формат упаковки значений) + +priv = privkey +pub = tlv(1,mod)+tlv(2,exp) + + +rsa_init(pRSA_EXPORT* e,pRSA_IMPORT i) +rsa_done() + +(cpp) rsa_gen_keypair(PBYTE priv, int* len, PBYTE pub, int* len) cntx==-2 +(cpp) rsa_set_keypair(priv,len,pub,len) cntx==-2 + +(cpp) rsa_connect(cntx,pub,len) - установить криптосессию +(cpp) rsa_disconnect(cntx) - разорвать криптосессию +(cpp) rsa_recv(cntx,msg) - все принятые сообщения засоваем сюда, возвращает 0, или расшифрованное сообщение +(cpp) rsa_send(cntx,msg) - все отправляемые сообщения засоваем сюда, возвращает статус отправлено или нет + +(sim) rsa_inject(cntx,msg) - вставляет сообщение в очередь на отправку на ту сторону, возвращает ок или не ок +(sim) rsa_check_pub(cntx,sha,sha_len,pub,pub_len) - диалог для проверки sha и если ок - то надо сохранить ключ в базе, возвращает ок или не ок +(sim) rsa_notify(cntx,int) - нотификация о установке/разрыве криптосессии (event) + + +RSA_EXPORT rsa; +RSA_IMPORT cb = { + rsa_inject, + rsa_check_pub, + rsa_notify +}; + + +сторона (1|2): пришла преамбула(0) +if( state ) { + state=0 + send(преамбула(0)) - завершаем сессию, если была открыта + "не могу установить соединение!" +} + +сторона (1): преамбула(1), base64(поддерживаемые фичи, sha(1), sha(2)) [2] + +сторона (2): пришла преамбула(1) +1 обе sha совпали? преамбула(2.1), base64(rsa(aes ключ и вектор), подпись rsa) [5] +2 совпала только sha(1)? преамбула(2.2), base64(выбранные фичи, rsa-паблик свой(2), sha) [3.2] +3 совпала только sha(2)? преамбула(2.3), base64(выбранные фичи, запрос rsa-паблика(1), sha) [3.3] +4 не совпало ничего! преамбула(2.4), base64(выбранные фичи, rsa-паблик свой(2), sha) [3.4] + +сторона (1): пришла преамбула(2) +1 преамбула(2.1) - преамбула(5), base64(aes("random"),sha) [6] +2 преамбула(2.2) - выдали sha(2) для проверки. преамбула(3.2), base64(rsa(aes ключ и вектор), подпись rsa) [5] +3 преамбула(2.3) - преамбула(3.3), base64(rsa-паблик свой(1), sha) [4] +4 преамбула(2.4) - выдали sha(2) для проверки. преамбула(3.4), base64(rsa-паблик свой(1), sha) [4] + +сторона (2): пришла преамбула(3) +1 +2 преамбула(3.2) - преамбула(5), base64(aes("random"),sha) [6] +3 преамбула(3.3) - выдали sha(1) для проверки. преамбула(4), base64(rsa(aes ключ и вектор), подпись rsa) [5] +4 преамбула(3.4) - выдали sha(1) для проверки. преамбула(4), base64(rsa(aes ключ и вектор), подпись rsa) [5] + +сторона (1): пришла преамбула(4) +1 преамбула(4) - преамбула(5), base64(aes("random"),sha) [6] + +сторона (1|2): пришла преамбула(5) +преамбула(6), base64(aes("random_new"),sha) [7] +"!!!криптосессия открыта!!!" + +сторона (1|2): пришла преамбула(6) +"!!!криптосессия открыта!!!" [7] + +сторона (1|2): пришла преамбула(7) - зашифрованное сообщение + +сторона (1|2): пришла преамбула(F) +if( state ) { + state=0 + "disconnected by other side" +} + + +Заметка0: вводим счетчик и увеличиваем его на каждом шаге, если приходит сообщение не с этого шага или не проходит проверка, + обрываем обмен ключами и посылаем преамбула(0) + заводим таймер после отправки каждого сообщения, если истекло время - то шлем преамбула(0) и прерываем сесиию + +Заметка1: Пользователь должен быть вкурсе о выбранных фичах и в интерфейс хорошо ссыпать каждое из возможных + 5-ти событий, чтобы можно было контролировать возможный спам (мало ли). Информирование о шагах также + благоприятствует уведомлению о переустановке сессии - для пользователя повышение внимания. + +Заметка2: Для криптосессии - преамбула(7), aes(zlib(сообщение)) + zlib - без заголовка, сброс потока перед каждым сообщением. Сжимается вне зависимости от избыточности + (можно вынести в фичи, но по-моему не зачем). + +Заметка3: выбранные фичи относятся к поддерживаемым алгоритмам симетричным (если будешь делать поддержку + других, то можно и асим туда включить): размер ключа и блока. + Минимальные: RSA-2048, AES-128/128. + + +// EOF diff --git a/CryptoPP/resource.h b/CryptoPP/resource.h new file mode 100644 index 0000000..106d77a --- /dev/null +++ b/CryptoPP/resource.h @@ -0,0 +1,17 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by resource.rc +// +// Next default values for new objects +// + +#define DLL_FROM_RESOURCE 1 + +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 100 +#define _APS_NEXT_COMMAND_VALUE 40000 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 100 +#endif +#endif diff --git a/CryptoPP/resource.rc b/CryptoPP/resource.rc new file mode 100644 index 0000000..4ebdb73 --- /dev/null +++ b/CryptoPP/resource.rc @@ -0,0 +1,39 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" +#include "afxres.h" +#include "version.rc" + +///////////////////////////////////////////////////////////////////////////// +// Russian resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS) +#ifdef _WIN32 +LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT +#pragma code_page(1251) + +#ifdef DLL_FROM_RESOURCE +1 666 "gpgw\\release\\gnupgw.dll" +6 666 "pgpw\\release6\\pgpsdkw6.dll" +8 666 "pgpw\\release8\\pgpsdkw8.dll" +#endif + +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" + "afxres.h\0" + "version.rc\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // Russian resources +///////////////////////////////////////////////////////////////////////////// diff --git a/CryptoPP/utf8.cpp b/CryptoPP/utf8.cpp new file mode 100644 index 0000000..e071e3a --- /dev/null +++ b/CryptoPP/utf8.cpp @@ -0,0 +1,149 @@ +#include "commonheaders.h" + +LPSTR szOut = NULL; +LPWSTR wszOut = NULL; + +LPSTR __cdecl utf8encode(LPCWSTR str) { + +// LPSTR szOut; + LPWSTR wszTemp, w; + int len, i; + + if (str == NULL) + return NULL; + + wszTemp = (LPWSTR)str; + + len = 0; + for (w=wszTemp; *w; w++) { + if (*w < 0x0080) len++; + else if (*w < 0x0800) len += 2; + else len += 3; + } + + SAFE_FREE(szOut); + if ((szOut = (LPSTR) malloc(len + 1)) == NULL) + return NULL; + + i = 0; + for (w=wszTemp; *w; w++) { + if (*w < 0x0080) + szOut[i++] = (BYTE) *w; + else if (*w < 0x0800) { + szOut[i++] = 0xc0 | (((*w) >> 6) &0x3f); + szOut[i++] = 0x80 | ((*w) & 0x3f); + } + else { + szOut[i++] = 0xe0 | ((*w) >> 12); + szOut[i++] = 0x80 | (((*w) >> 6) & 0x3f); + szOut[i++] = 0x80 | ((*w) & 0x3f); + } + } + szOut[i] = '\0'; + return szOut; +} + +LPWSTR __cdecl utf8decode(LPCSTR str) { + + int i, len; + LPSTR p; +// LPWSTR wszOut; + + if (str == NULL) return NULL; + + len = strlen(str)+1; + + SAFE_FREE(wszOut); + if ((wszOut = (LPWSTR) malloc(len*sizeof(WCHAR))) == NULL) + return NULL; + p = (LPSTR)str; + i = 0; + while (*p) { + if ((p[0] & 0x80) == 0) { + wszOut[i++] = *(p++); + continue; + } + if ((p[0] & 0xe0) == 0xe0 && (p[1] & 0xc0) == 0x80 && (p[2] & 0xc0) == 0x80) { + wszOut[i] = (*(p++) & 0x0f) << 12; + wszOut[i] |= (*(p++) & 0x3f) << 6; + wszOut[i++] |= (*(p++) & 0x3f); + continue; + } + if ((p[0] & 0xe0) == 0xc0 && (p[1] & 0xc0) == 0x80) { + wszOut[i] = (*(p++) & 0x1f) << 6; + wszOut[i++] |= (*(p++) & 0x3f); + continue; + } + wszOut[i++] = *p++; + } + wszOut[i] = '\0'; + + return wszOut; +} + + +// Returns true if the buffer only contains 7-bit characters. +int __cdecl is_7bit_string(LPCSTR str) { + while( *str ) { + if ( *str & 0x80 ) { + return FALSE; + break; + } + str++; + } + + return TRUE; +} + + +//Copyright (C) 2001, 2002 Peter Verthez +//under GNU LGPL +int __cdecl is_utf8_string(LPCSTR str) { + int expect_bytes = 0; + + if (!str) return 0; + + while (*str) { + if ((*str & 0x80) == 0) { + /* Looks like an ASCII character */ + if (expect_bytes) + /* byte of UTF-8 character expected */ + return 0; + else { + /* OK, ASCII character expected */ + str++; + } + } + else { + /* Looks like byte of an UTF-8 character */ + if (expect_bytes) { + /* expect_bytes already set: first byte of UTF-8 char already seen */ + if ((*str & 0xC0) == 0x80) { + /* OK, next byte of UTF-8 character */ + /* Decrement number of expected bytes */ + expect_bytes--; + str++; + } + else { + /* again first byte ?!?! */ + return 0; + } + } + else { + /* First byte of the UTF-8 character */ + /* count initial one bits and set expect_bytes to 1 less */ + char ch = *str; + while (ch & 0x80) { + expect_bytes++; + ch = (ch & 0x7f) << 1; + } + expect_bytes--; + str++; + } + } + } + + return (expect_bytes == 0); +} + +// EOF diff --git a/CryptoPP/utf8.h b/CryptoPP/utf8.h new file mode 100644 index 0000000..5a9b3ea --- /dev/null +++ b/CryptoPP/utf8.h @@ -0,0 +1,9 @@ +#ifndef __UTF_8__ +#define __UTF_8__ + +LPSTR __cdecl utf8encode(LPCWSTR str); +LPWSTR __cdecl utf8decode(LPCSTR str); +int __cdecl is_7bit_string(LPCSTR); +int __cdecl is_utf8_string(LPCSTR); + +#endif diff --git a/CryptoPP/version.h b/CryptoPP/version.h new file mode 100644 index 0000000..27cbf73 --- /dev/null +++ b/CryptoPP/version.h @@ -0,0 +1,16 @@ +#ifndef __VERSION_H_INCLUDED +#define __VERSION_H_INCLUDED + +#define __MAJOR_VERSION 1 +#define __MINOR_VERSION 0 +#define __RELEASE_NUM 4 +#define __BUILD_NUM 4 + +#define __FILEVERSION_STRING __MAJOR_VERSION,__MINOR_VERSION,__RELEASE_NUM,__BUILD_NUM +#define __FILEVERSION_STRING_DOTS __MAJOR_VERSION.__MINOR_VERSION.__RELEASE_NUM.__BUILD_NUM +#define __STRINGIFY(x) #x +#define __TOSTRING(x) __STRINGIFY(x) +#define __VERSION_STRING __TOSTRING(__FILEVERSION_STRING_DOTS) +#define __VERSION_DWORD ((__MAJOR_VERSION<<24) | (__MINOR_VERSION<<16) | (__RELEASE_NUM<<8) | __BUILD_NUM) + +#endif //__VERSION_H_INCLUDED diff --git a/CryptoPP/version.rc b/CryptoPP/version.rc new file mode 100644 index 0000000..ad1470c --- /dev/null +++ b/CryptoPP/version.rc @@ -0,0 +1,41 @@ +#include "version.h" + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION __FILEVERSION_STRING + PRODUCTVERSION __FILEVERSION_STRING + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004b0" + BEGIN + VALUE "Comments", "Licensed under the terms of the GNU General Public License" + VALUE "FileDescription", "Crypto++ implementation for SecureIM" + VALUE "FileVersion", __VERSION_STRING + VALUE "InternalName", "Crypto++" + VALUE "LegalCopyright", "Copyright й 2006-09 Baloo" + VALUE "OriginalFilename", "cryptopp.dll" + VALUE "ProductName", "Crypto++ library" + VALUE "ProductVersion", __VERSION_STRING + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1200 + END +END + + -- cgit v1.2.3