diff options
author | lloyd <[email protected]> | 2010-06-17 21:48:55 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2010-06-17 21:48:55 +0000 |
commit | c06b260b3328c5ce4be44c4f1a88feb55ee3dbc4 (patch) | |
tree | 41b05df5982b5b2e8a23b55972263d2172d6a9fd | |
parent | 0eecae9f21172c0a74ad62acaf77148c94a25be7 (diff) | |
parent | 3dde5683f69b9cb9f558bfb18087ce35fbbec78a (diff) |
propagate from branch 'net.randombit.botan' (head 294e2082ce9231d6165276e2f2a4153a0116aca3)
to branch 'net.randombit.botan.c++0x' (head 0b695fad10f924601e07b009fcd781191fafcb28)
345 files changed, 3482 insertions, 3524 deletions
diff --git a/Attic/mutex/mutex.h b/Attic/mutex/mutex.h index fcb0e9982..f209466d5 100644 --- a/Attic/mutex/mutex.h +++ b/Attic/mutex/mutex.h @@ -12,33 +12,48 @@ namespace Botan { -/* +/** * Mutex Base Class */ class Mutex { public: + /** + * Lock the mutex + */ virtual void lock() = 0; + + /** + * Unlock the mutex + */ virtual void unlock() = 0; virtual ~Mutex() {} }; -/* +/** * Mutex Factory */ class Mutex_Factory { public: + /** + * @return newly allocated mutex + */ virtual Mutex* make() = 0; + virtual ~Mutex_Factory() {} }; -/* -* Mutex Holding Class +/** +* Mutex Holding Class for RAII */ class Mutex_Holder { public: + /** + * Hold onto a mutex until we leave scope + * @param m the mutex to lock + */ Mutex_Holder(Mutex* m) : mux(m) { if(!mux) diff --git a/Attic/mutex/noop_mutex/mux_noop.h b/Attic/mutex/noop_mutex/mux_noop.h index a1bd57858..20989a635 100644 --- a/Attic/mutex/noop_mutex/mux_noop.h +++ b/Attic/mutex/noop_mutex/mux_noop.h @@ -12,7 +12,7 @@ namespace Botan { -/* +/** * No-Op Mutex Factory */ class Noop_Mutex_Factory : public Mutex_Factory diff --git a/Attic/mutex/pthreads/mux_pthr.h b/Attic/mutex/pthreads/mux_pthr.h index 27b854265..5cecd09ad 100644 --- a/Attic/mutex/pthreads/mux_pthr.h +++ b/Attic/mutex/pthreads/mux_pthr.h @@ -12,7 +12,7 @@ namespace Botan { -/* +/** * Pthread Mutex Factory */ class Pthread_Mutex_Factory : public Mutex_Factory diff --git a/Attic/mutex/qt_mutex/mux_qt.h b/Attic/mutex/qt_mutex/mux_qt.h index cb396b81d..3805acc3b 100644 --- a/Attic/mutex/qt_mutex/mux_qt.h +++ b/Attic/mutex/qt_mutex/mux_qt.h @@ -13,7 +13,7 @@ namespace Botan { -/* +/** * Qt Mutex */ class Qt_Mutex_Factory : public Mutex_Factory diff --git a/Attic/mutex/win32_crit_section/mux_win32.h b/Attic/mutex/win32_crit_section/mux_win32.h index 4bbf6a540..2aa51e18b 100644 --- a/Attic/mutex/win32_crit_section/mux_win32.h +++ b/Attic/mutex/win32_crit_section/mux_win32.h @@ -13,7 +13,7 @@ namespace Botan { -/* +/** * Win32 Mutex Factory */ class Win32_Mutex_Factory : public Mutex_Factory diff --git a/checks/bench.cpp b/checks/bench.cpp index d03193971..5214c7160 100644 --- a/checks/bench.cpp +++ b/checks/bench.cpp @@ -108,7 +108,6 @@ const std::string algos[] = { /* Hashes */ "BMW-512", - "FORK-256", "GOST-34.11", "HAS-160", "MD2", @@ -149,8 +148,12 @@ void report_results(const std::string& algo, std::cout << algo; - for(std::map<double, std::string>::const_reverse_iterator i = results.rbegin(); - i != results.rend(); ++i) +#if defined(__GNUC__) && __GNUC__ <= 3 + // Work around GCC 3.x bug, reverse iterators don't work + for(std::map<double, std::string>::const_iterator i = results.begin(); i != results.end(); ++i) +#else + for(std::map<double, std::string>::const_reverse_iterator i = results.rbegin(); i != results.rend(); ++i) +#endif { std::cout << " [" << i->second << "] " << std::fixed << std::setprecision(2) << i->first; diff --git a/checks/check.cpp b/checks/check.cpp index 952384a19..476886661 100644 --- a/checks/check.cpp +++ b/checks/check.cpp @@ -109,7 +109,8 @@ int main(int argc, char* argv[]) if(opts.is_set("help") || argc <= 1) { std::cerr << "Test driver for " - << Botan::version_string() << "\n" + << Botan::version_string() + << " (released " << Botan::version_datestamp() << ")\n" << "Options:\n" << " --test || --validate: Run tests (do this at least once)\n" << " --benchmark: Benchmark everything\n" diff --git a/checks/validate.dat b/checks/validate.dat index ed5723506..aaeb7f013 100644 --- a/checks/validate.dat +++ b/checks/validate.dat @@ -47959,941 +47959,6 @@ FD1A64F7BC61608FD054303AFA2E31608AA3F3788E3034821D63A0288A70B573 2B5F61CB57F94E7C7E6D7439FFF2600286658539\ 88224E0AD8C08C2FAA61963C8F761654AC529325 -# FORK-256 vectors generated by the implementation in Botan; there is only one -# test vector, and it only covers the compression function, not the entire -# hash. The implementation of FORK-256 used to generate these vectors did pass -# the one known official vector, but there may have been problems not found by -# that vector. -[FORK-256] -:E6A3C4881D6B1EE37F70847D9C8424A3E2AC408079570ED5ED9D20D0214D7599 - -1D:90753CE547CE7FAE1A736D6D38E8C6F14D93897D106FA63CA32BFD1219E06A62 - -3E07:D5C380F39876FB9836D492ED520E2F6929C302133BCB9F2A5080204DECE3583A - -A8F001:13428BD3C7368C8EB0B890A0FA3461ADD5202FD23257EEAF1559079344123046 - -EA8F7A2C:65DD3204D3C9E9CE5EF21CECB3421F59351D5ECF0B928D199887BFDAB1906A0F - -2E19859C9E:DC5DEF85475A372F3E16A0893302A3C77218C4EFBCF6D9331DB7A2D3CEC5E8C4 - -2AF0BDBB8363:88AFC377D3630E6B686EC48F9030DCC78E64F7DA1023CC34D49F01861487525E - -82F8A36D0A7979:\ -9D96C6B2ED8B50A2153A89BBC861718C4744547F2AF24F648235E553BDC03E13 - -78F37E4B9235DFFB:\ -CB3367A41C64D73EE024FD9F9BCB59ED66F6F9CB370BE0354D9C6ACFFFEE5D6A - -FB85C864108365961B:\ -B657CF6B34422A945A870FEED5468FE052F046626A4D9EA8DE0F6C9837E72429 - -793BA844BCDD71B1B750:\ -0371387237C9300AC6E4CDBB1E33904561225D3DCBED9E9EDDE710BE34C72084 - -19781F1B1394459A3EF407:\ -B53815CC5F494D0983475EF4FCA87AADA732D10DE1E89E62BE397BEB53496545 - -55B5FD2344A64809C7608A57:\ -3BC33C0FFD68E3DE47D5C1E85AF732C94EA390999B0D10C428CE655A023699C6 - -AD14F3D82E4349DC3B8C1B2A9B:\ -428111A57BF802669AC9EC7BAEF3929036FCAD03979F2151CE3F8C19B7430529 - -7C6FCD56927F530DD8E27C661ECB:\ -098FF664FDD45068D5B51F2AAEF738BF35AEE8945270663A179FBD8C62184D97 - -270303C1B3E754DB1B8A388632B79B:\ -BD6E8FE6F4F0D67FE6EA76774F8049FCB3E9FB9C490467CEFAE793900AA86C2D - -70B7BAB2A9BB809F9A74311B562BF43D:\ -611DFAC246B16D3D6A359FC580E477D474751C24A78225D93009A910BEFC7A5C - -5E01E5540B5B6F371F642D15B4F412C190:\ -DD75FD419466A998B7B460E093224A7DD82A630B6E88BBC8437589FE68764E4F - -3557FD9C93B37B3E484E55242105EEF9EB64:\ -D86D755CAF29D6DD1E339F4F3D8DA2FCFA26FAE62FF27851F8DBBA942DB8093E - -C851F162EDFB2E5D9CF7BEB5369B423B049120:\ -10095694CF4940D5512FA27975FADCBEFB4F96C4DA321A3F35F6B24DE2A2C879 - -D5DDEFF9F8C8921DCA1820C4368F28C4945B0402:\ -D0235CA1FA883DC7BD2F8E018FC51739FC644D49BD9B6FCF0D4434873C7F466C - -8F5D3CCFA13AE2710E293638068A8936D9B2887D8A:\ -5135B14FD4DD8BA1BCBB0E613F71077EBD6B41B0608F495365D442D213ABB5D4 - -F4247F6724C9832FF65B9D98EBBC091241DE8C9CDC57:\ -FD9A2FE9D7D59F793BFF7BE343A6EA70C37DAAE0B0162B9BD8050DB99975DE8A - -C8A3DFBFAF08F34B258C6BC33E826ECD5F808CEEB88E43:\ -CFDD70E8344315DA659697E6B929F7E5410BBF2BFAA46D911CA4D548F6A80648 - -3F40DEC3198D7EF8D7AF8DAAA86C6246B464BCE6878D7D91:\ -A6A0D6461C505C70050235F89E88EC7C0E6B3DE130E198E2EFDCE562D4E354A9 - -5D61E8C5431A0578175AF50F2D0D27D41D16E1C397F73EFF15:\ -DB064D53411169A3928C8C7B62CA538BBA5276FD83E93667195735F88EC4A7EA - -8DA080EC9907AC188208DED4D7F634DAC6B1382AE3BDB721B665:\ -ADA78594D6230C9587F0EE87F17AA21CFBF4C82DFDFB8473A8529F3DE6C14895 - -865F5D01E678E4FEA91ED39B8B9B1C4B8B17459BC4B4A3D677BC49:\ -2641A6AA41499952DD1ECBF5AF4426A4DAAD233127F3AC56F308B2E9D5F25B7B - -D787FFA504B1470076F898CC0D2CB65CC23B5B02437539F54826BA61:\ -D29DF8910ECE7FDE01B2FA5D8641DEDE6E8DBDA44143ACC58AA2CE01D2406455 - -595199257CB4178EF928983A6E822846C1B024328A3B1FFB6E242E3661:\ -AE72575D2EF2664C75E0538165AEACB24B80A3B28546096DABB2642A7AE959F7 - -5EFBD43D66A7A1D23382E1757241AA5679B4C0F9F78419985B65D70A6E8C:\ -F707AB7EBCFFB3F78EF1AAB7FEB832D2651E82889AA95FD02958F326AF975D93 - -32C2BF9FBF3871314F84F17949882E4BBDB530C8808FB58648BB811ADDCB8C:\ -8D3E1FE5840130D141A68991C9321719F4D50E13C52ACA0BBF6D218773871544 - -7820ACB94D6A8A2E7B7273C6C528E2088F60B6E57CB4494BDAAA4B7877202862:\ -DDE3C2EDE2D0AEB9F80FC6F8C54CC6A108F5F693EE8EDE2C755AD20FCF011C1F - -A14BAAC3891D78465A9798ABC984407072BD209D80A7550DB1FA63EB922300F43B:\ -FAD764D75BB72296BE85979A4F57C89E51D9AEA8280DD87D18CA5ABFFD3553A2 - -1166A4CEBBFA31E715B19FEB15D4FF84C35112E4876D7182E3EF97147606760FD23C:\ -57B507F04922E9E2ABE3D8DD8205579715AD0276F2179360C092966D3E335B1B - -AE7C2882888543E7206BD57350F33985322DED8508BBC70BA961C3ED35075CAD439732:\ -DA545CEF32F141181F07AE275FBFA6C9D8A299FD40660EEF3C344657EB22E8B3 - -48F1A035DC0FE6D0BE1F2D1233B08714D404682DD8CB39F66E8FE163AAC79F7241E9BFC6:\ -20ACC36E9788C4E7484BA8C166E93953124F703ECC15369943BF81AF10062D2A - -ED596E8DC5A9AF7FF123D886589592D5FA0FF86151B8634DF4C4C1F1450E5323D6228BBEDA:\ -6E85CCA98D2CD2591018E303330ED12F3434DD9706A1194ACA4E60866F78291B - -EABAEFE3421D3BFB668B390430ACBA72E4EE6F2C92142A93F0BAC595906579C64E2A3EA33D0C:\ -7A7564C0053A3630FEFA5C3A2DC80B99341C05903BFB6765777112F96DE7D3AC - -F71C08AFD45891723E61BD9241DAC454A2333D2ACF21B3848EA47BF01FE524E4E6E1D47A635A\ -F8:04A03842A1E8E916781CBA312A65C3C99DC949895CD48567FC3C836F39CF8EEF - -E2895A841C03629710EFB16B6C921E31B86A882A56C63914E631446A91FA0092A2AA570DCE0A75\ -2F:737E62D552B437F0E46EBD69A2BBC3B8AC4A4992AE64830077B8E0A9946B0454 - -002E5C6DF7AD9BFF9E6E08AE68EDE886B39BF6365CA081A25576741708ECB5B64D80F640EB26AB\ -69F5:609CE0C785C2BE58F1E76CDFBD903C48BFE385EE035C7604715CA86EF9B38D1C - -FEA76D123D4EA976912A521763F6588E56D694791398C6DB760E5BFF381A6506EF4280008A5948\ -5B5943:53598D2271C83D3238AA9FD90DE0B5037525854770337FEFBA0FB636A1623E1E - -AD53132CD9C61018CEC4B07278D5667DDFB4EE9A839DBF584962D1880345951007DEC5E0F52FFD\ -9AD0FD9B:E8FF3DDB2CBAF8B220DEC63B5F1320E02A47A5ED02297FDE7C0788E5A7306082 - -D11C82ED861EB312B69AF9A372B8F41D0BD9B0BF2F03D9F1F13D54CAFC475B97C39A169369EEA0\ -D92606377F:544180FA5E0FDA3054596B7ABC0C6B7F0CF5ED755C5C490E7C93FC00B4CB0C8C - -7C438726B3E3AC24D06F1AC23494F030655A4E5DC5D523641B0BCBBD8339B3DD8A0632520BDCCC\ -29DE6654B5FE:\ -5F00EC9E215EBC9F7669627B6C91FEA12DE0E4D475F49AED7EA937AF490A599E - -9D934509A19691DF7555BEA1A244AB503D278918AE8A0D984300CDF5ED7962A8FA5EDB01E8D38E\ -830976BD4F6800:\ -40135DEA3BC67E8C4295856C8B30B9AADAA904A5106CCE597A49912DB64CC8E0 - -9C0EEBCE97B82482CF742A88F3671F85A84239D70A9A03D07B67876FE7C103A787A941955D2149\ -662F57CC29C93ACA:\ -8EE3D2595A3427BA24E14D610246CDF354FFE1704C42B1CA50B22E400AE0321A - -D159C512621C4E59F0F2D63534E62E66C0AC8665F37FE51213305598A53148A28F410DACAA103F\ -F204372EA0CA1A0023:\ -C0148D8A4688A49E35014EBC61786F00743788A4B9529C2C02ECCFED5B00BB08 - -89724F1F0A6377DD6AD938CDB297F247BF09CEFADEBA43F5769799948D6D5D160DE142A7417315\ -6FCA9A237573076D1655:\ -4DD08B4E2401168ADEC0E05A341EC69A27890D0DBE48D898C9B657AA6D753860 - -89308DC7FABEB7E264E283819D6742A1FA9DFA076CF7D607D7B10E9996F3C1349404D01737FA32\ -ED58555A00935F54C309F5:\ -0D8E3B5C1C8876DF9021ECCAF0D0221E4F156A9EA75624335C39DBD7F96960FC - -41FB354861A111C2169C18F5E29824E0E80A47CB8C30D828369C6C2456125B685B8CF11D092532\ -E844D55C8A492D660504C908:\ -4BF1967D6772CBD680C01F244EBCDE85EBD402E6CF9B5EBCE8A00B0733D09132 - -3B4D0D2D8926B376A5CE3421CCE1F4E5D4A1818ED55996CF2EAE935D0E41CA7621CC009BE7FDA4\ -AB371594177DBA06670A521321:\ -A0146AFB474623D6559E8011E112F1DA7E3F0140327B2C8205899C2A0B611022 - -2175F02F451F59DD84156218AE9A949ADDC0428FFD980F23CAC66570160637A40819481F528C62\ -A4A7F1B5A092C7FB4B9101C5E8C1:\ -44787DF2F8F0E4203E3EBAF8304744DFBE6DF6D53C33D4BB6B9A3A40766A2CDE - -9F836DC75A54F209E4FE423F6C08A1E3565732E8642DEA0C17E59D27C63A8ED80C6E18E48DAEDC\ -5FAD99E27DC63F426C6F6BE02EE03B:\ -0379CF92A8627230F274731CB269E5DE24A91435D39E7C461E9E0AEC9CA1C30B - -FB1678C2D4A5262046B0B7A9B11B5F069E4C0297C1698DC6766AEDF936303B3DBA1FC229F1C1F1\ -FAF54A32D72400514274A741B7AB3F43:\ -08826C3E6319A2E9CC3B23E0ECCD3AD2CAF30640D1250158D8E4ADDB46217AD5 - -24D4117E61379F5E55CC6C311B140CA4FECC300909BB3BC05FDB68B961187F3DE2BA18FF7F4522\ -012DFA073122902D691A824F6EF08AC9E8:\ -36D90AAF4107C7790231FEDD5332027AA45540908F7881BFA6DBF6CA26CD220A - -1C4052964E9796FC030EED644C4661F242BF0AA3D2E93141B85D0383AB29C0025FFB160EC413F0\ -4591B18F3F892639EA57B5558ED8DA358961:\ -CEE495F4969D81025AEFDCF40A20E54B060F13B755633AC2350569DBAB97BF35 - -00743CE2A53D08393B32BF3F8EEB081FB684DE4905834AEBF966ADD0EC484FD5F0D15131E5674B\ -15380C11554EF823838D931EC010BCCBF928CD:\ -BB7279D1120515D472EC9CE71BDC32BC7CFE8F3BA7D5CAA371816C3AD23DAAA9 - -6C7D10949194F2C22BB9CE620FBBFDEF0B61BA1960B580BCB29DDE81A3D5F0BD6722046191823B\ -2297CB1017503342A353D2523B427086BB2DF313:\ -199B856E5AD193591859688E316E09D6942582DFA984CD8EBB8FA262920F2645 - -8D2789C6885A275FDEC50B7B37065B6F681BCDC0030E1C582BCF3247133D293834443A3FEB8F38\ -8D67C729F92633AAC54CAF6D8857C1B0FA151064BC:\ -FB6A7F1878E278BE80564FFC190097724A870F09660FD3BE72878713BF13E618 - -1235B88BA03D232060450C91F3374A44FD4C40A03BEB54523AF85F7A5ADE59E31E23AD0B0FAF7A\ -438D5F3F981C03D2C900BC2A9C5B1B979145ED3C7214:\ -B8089EF455C50D5F3C4DF616C032E6A593CE74D05990FFC9CCF5BFED8C7B002F - -511DACA4F9FDD439D14FC91E3350CEA754E8B32E1CA9B45C27006967D86C2D5A826D6606588E63\ -3781411F627127DD135DE7CBC03025CC34B5601D4CB7B5:\ -CE0F3874027B7573BB829CC054E63EEB9EC46BEF340213DAF5333791C3D3556B - -08AA26D82CAFC07026B19DE0EE09D74B84C4AEFE969D60F76B7A819E4E8F1CF8A687E2E9CC4124\ -041DE331A4D078D836881C430101A89FD89BCAF6C3AB425C:\ -BFD882A8BA5A0A22CD63466958A9C169F40068ACBF7514B71B79438855E004E4 - -530E88B454E963D5C46F2D58713BA9CD1792D1B262BC4696BF8AF0451D4E34555F7CF83C94B7D6\ -ED1FF924603F80F36CE994A41D308F5D4367C895104BCB1E7CE6E16E6EA1991B245851BA28D915\ -86FBFA9B295EFC15C5277711D738F8B061ABC5F8A2257F85F4BEC0E37B53A42B7A3A10D11370FE\ -B4DCB29E6C0E17E15EC41BC695C72B7200785C7B3DACADB7682441E29DD3D0029AAB241CADB2A4\ -DD92997A93BF01DF6605A8CB776789F12A5D402A1DDC4DCED50FF449CEE65EE7296E88D61758A9\ -7D0DE90F9CD9C44D165C504F61F32800CC48DE51CC1FDB3CBC5E2C3F200733B2E266049945CFAB\ -F41A665A3CF8C65E13D784E3C5D40AFDB1E1526DA87B27035CA65CB368457E627A6EB5962DE24C\ -FFE29A723F03A7A0409BD1ADD5B6A2D0B39C2372E29686CE5032CE1473CC1661B06A3243714265\ -698667B7BE6688922676AC9042AB6A1785D732B2F4EA288DE4AE8CEAE26DE59231FF04ACFB447A\ -71679EB96320B22BB0F730E17DEB159B661D8DC6D397B5C9ECC722BE2AC48000B830CF7DA06572\ -8138A8EDFCBD04E97E6915825CA08A7AA4B5BF96CC2FCA7E391222C6B3247830E77BE9AE10230A\ -2A97099A4344A7203F47689418C72626435DCD59208E679C6B387AC88B39D50335E3479FA62CE6\ -94E4E3CF65018A0938911BBCA21A28C8B54BB43C42B9A868309428A89930CCD71D74A425A30578\ -2CDAF4847500035E53985472F4CA1C4A78240BA9DC9E2E4FAA636871D827B02454CB8C209F9F2D\ -F5D7A62D3B720CF9D9B21B1FAD6FBB34FB6B3A7E89014C54927044135465F0F42AFBF6E77AA6A8\ -498B7917D130DE7E7035577BA4C9F6400ED183767155348A9A2C1A4BD63D1CB9ECACC34ECC2D80\ -E2CA077B0B53A9FDB225624E6774D3ADA17688B6040C53D39D3545C4B20D6C4A0432C18B0A1E3F\ -3AC14CB7E90E4642A1A890FED7D8E725065D52C8DA6942BF9CE0916F3538EF63C327594940BE98\ -7F36764AB59BB6B42CC4C42DC3F7BE7DA7B8AD1DA51462C0A72B9ACBDE65029B2DE0809C1AE230\ -B76014F42A41E1B7B3332851DC46E82704B01CA0F1417539AA8C0BAA547838A6443826E12CF993\ -C891BF6F303C4C20D2DFA07DD14B7560C608CC3B8FD8AB7D825EC2834D08289360B613C7F435F4\ -78A641D7DD115940BF1C5200D6DD54F612DF6136DAF5F95FF6BCB9D9480E60BC8020B9C9154B25\ -4860EBB4FD3112B33A18FCEA742487D79401CBCB07761EC3874663A4791D5508BBA41CB14BE22B\ -98826462194D7943C61E2C3C01A8868E121429B4C49D9B42EFBB10685CB6AFB1B11EC17D7CF2E7\ -1482325F3C16F9C25EC3FC7229B4DC3F82162E3E2E04DFA670AC617E4274D73163D24E43D06687\ -47D1017948E4BE0D0722B6830F415A409DC7A2B15B521FB19790B9EA07883AB000D13AE2E6D62D\ -99DA32577B6037338E5E:\ -06308BA4E79A2CF117A1D5BC027A7492F50138FE4750DBF51F08913ABC40CCE5 - -83F47CEEFB4E8306A59CEBC0BBECBB88174E17497C1BF33E9047B74D486A255EF79F1555E8E889\ -D0311CCA0B9EF678D976AA02103EDA58CA7A33CE9B7C994348A1641B3954FFCC1AA97832248C47\ -3187D69CCD10A4F553CF73964DBAB05006F0BAC17226E7E98DA3FFA0B8A8F241FFE54A0FD5CF4E\ -B9E5327CACE16B445A65FCA2CF6F9F99B000B0A18D7F3634A00AE49B9A79753C61E3C1453C6C0C\ -F210D6FEA9EEDB12D8F79275FAA4438B765DA316DCA0A8C5E084BB422883C2C195BF49130FFA10\ -D291D69FA362E2B96A6E2A4C9695154BC6A4C4CB194420D3AFDE1035A2CF57E54FACAF2DEAE3AC\ -790A0FEF68290DEE590DF70DB61AA7BB94015F18E6DDFBDD50602110D7FCB5B97612E6FFE5EC16\ -CE738BDDDF71726972E80860BC04CDBFCB67C5AE91E7F4F7913C16769A043F46A986AEF327C5D3\ -FE4AE2525815C162565048D99C559A8F0E9DF8BF88E178E339AC39EA836A9652955B3F440E090A\ -D28A8E14E29E78711A1744E8CAE85F55FA7EC643F4CD1989323F0E049A3BFCBBF254F2583361A2\ -798BAC6411D1FD837D7B64C7A7D93DE278E1D8562621D8B04BBD0CD4D7425C6FA909B3A6241FE8\ -C1A8D67FE616802C69694A318A5D47F97555458F753A960CA9A1DFEC13C8716EAB62603C07A10C\ -67CFFEACE6A1D81A4C4558258C8C14CE75961482B2A34BFB1C81C8474151434186ADF205855DB5\ -F5CEBCB7280C4C9D6CF08167DC2B5B1F112EC3AEA996953465377DD883889D164DEEDD33A012AE\ -3F474417384EFB98D8FF3B757F2B8A8ADE184D443AD1945C14273D4733108083DAB38811AF3708\ -79F8702780D041238B6E5D4AC6D5506AE03B5EC0C76CC16C15E33EFFBCBB877151AB79F2F13F2C\ -AA51ED3B441B7AD204CD209AA19E569B7B5D67EA549F70572ACA4CDC3F438EC78AF5C4B832415A\ -CBE71E1E918310EC9685595F1A62FBA2BC7FC933CEBF1EA6FC00151E33FAC0BBB121C168E7AC9E\ -C4F78B18B7A122D1801298C5D1268AA66CEEC75A5795F3048E6763762C98746CF763A2AD9E78E6\ -30D9402C482656223F21958AA045CB90027338858363EA97A639F239963A8D76622D42E069E813\ -ACD776879FA1344A2C08522D0B53C62E4377FD8504817778CBCCD074099E097A2E361F138FF7FC\ -B60ECCEC6029549F0489022379145A5EF7A7781A1B201B6012E125F9969D57459ED08D21773718\ -AB2B58F7EF41E2FF850AD8194D37324F59B50E85123AA972AD28587C526F05D81057A6BED26AF1\ -E174AC90645BA624287209AA108C6CA3FC6D3532AC28D8314939C1E320A04146D0A68EAE82D5CB\ -8B368E69CAE0040A33BDC3D0DABFA26D70E99D4A40E7675443E22FE51FD2FB5AF0091060DDF96E\ -4C4024D1F1359A95C1B93CCB25DDA483363AD73C4FA952C433809B4C1FC0F3D140E3A6856C9CEA\ -46EA438CED188E0BAD7BF4:\ -226404B39155EC9D9CAF51BFC6A7F0115355FD83104FF66FBBDEB5BF0370EA99 - -70BEE2D1E703CF4D8872E6E63BFA59A218F8830FEEADE6D2412507386C9CC90EA83312D4565E84\ -9CC6FFFD58A90D3719D1C0AAC147B20033E9F40E515CAA938453CC2EA6D848801B8F6A31721334\ -DAFEF40DE5C8E7C33B1190DC6A33F66CDA2D7174E2CAC423C96DA4BCB399863760EDB44990C2F1\ -D0031D56A9DE624FF3658FF14D33CEF67D9752678A9F18AB64E4551EBC54F96688856AE25C13EA\ -C5A2E92A43E32590509705DA31F7B5A750E6D493D6F3BC7CA0F5E9B1782100E9BB6A4DF4E5934D\ -97BC0D75C1A2341B93024AB1D997F270922C7E2A8D1F6F453FF2C4AA73C69A4D16B50DBF8C1FCB\ -27B1002E4EDD5C3EAAE1DE241214F2E50457551EA42A9A6D515B7224011F9F51D20BCE07FDC533\ -080AF6A0217A2F679D60FBACCDE2659F637481BA75FABC1E224C52B77F74379BDD6002AB917A8F\ -77CEAAC83B134EA14A5AD92780C84CFD08CE4956659900D9F57278A2F074648AB857089F204150\ -899CAC987F522E5CFF41C2289F7DC079B1E7C9F10E41E3B31CEE52195B3E49AB6C4D2B5613BD0B\ -BA01A76E824408BADAECE8BF22AA0469506DC88AE469AD679BFA254ECD06C99F8453B720D4BF05\ -36F3C6272CB8FD8B0F1B995FE75E0DE6DCEBA87EAB8C822325951FB024D0230A569E4CCE190F72\ -A16637A3D3865D33C0ABBC0A3182C915AAD6B4CB22A648703F164026481E6505C6D80A5C7BFC0F\ -32557704563399317F1A1DCF0CE425F20E9290FECE77831D60FF3472874C1F4BDFE18A0A00218D\ -0B428EC195BB221D1C49FDDB68039980AFFE6EDD7C166E944AFB71499CDFC96EC95BC28DE747EA\ -72E031E83D8405A8DB1B6AAEAD15087FE75DB7471E2BC49F9E9418C6BD52B32D747B2ACC1F0F7F\ -0B21EC4DE2879B249D6FBDDF5B85FFF8A4861FE7206F9F84F5B761398055038FC100794FCE09E9\ -96794DB1CB30FBFAE4B183D0BB0D1C10920DEA7B7D3234F6FCB682375D8C36401A9F67FB3A8615\ -E3F649B7AE4D6586865A1D8CAD6DA45B694977B4F378FE610C4F943D41A223BC7318ECF98515B9\ -2168DCCBA7411AFB84AA6E35C473D6F595ACE62336AF52298040FEB2DF462FA30E039FC4AD80AD\ -D3B420D8CE0675E0DEA46884AAB203699B65DB309E71615728A44E80EAC271541C6D85A3160C7E\ -5274F624DD288C387DF342619B751E15615E464249CEC80FF132FFBFDAB5827CC4DE01FF506F29\ -CEABD8DB256DEBD26D519F6210E3956F95D7ECF1E48DE31839360C2985815348D1A451FB4683EE\ -5C06C362725C97E8BA8F9926691B32B38441D49B4032D9239033A72288FC98B26BEE3461F6147E\ -1C6C1D93A4B857E53A5B9B25AE03E5741C673E7D1757B165F36B21170A5B3B9DDACC015554E132\ -38B987DF9F236A689FC79450CBF3B611660267816D3152CE6B75A2D6EFBCFDA900AA3DDCD5B684\ -5448DF2F0C089A436D3C7290:\ -93F020C6617AEF37E1E53D0558AE8E8731E9B79DDEF0C3BF931973955175D957 - -20BE956038BE1F4F76697367DA55A382B082DCF66A6EBEE838E10D41AD87D0F1A83723467AAD5C\ -4AECF39480ED5E47A9143AE6F9AC5BC46E7AC83428DE404E1A89D3783FC38BA0B16FD912D118F8\ -3C4631375D39CC220A278485BEE01F8B45AB57C9564566F49C3584C455919095713A75BA91CF03\ -CC9BE013CF9D69266071EAE64C2C07DEA0C117271D349DB1A940BF3B2C91F3AAF407DBB97FACA4\ -7B909ADC6F1EDC1398015048359E0A831AADEA251F8BDFB88C6B9EA073BB238134483952D0F8B0\ -E9C0629E55E5F5DD47072E9C5D0FBD6B4C5326C11CB2734CA4DAD6E2D8BBA212F6E67F570290B2\ -1F1D69D146A140C57125D169EAF6B91913E5841F2442E0AB40BA77D8F376E4C45C95BC9B4797F8\ -DBF941C66252539E63E001D139FD4A59E7AC4817B73879A2522714979F536F481B76582653B482\ -4DD76A1441A8A1525E8192F1F273F95DD564CDB4853B682E87693EB2B544950BCCD27BB664E323\ -1080A486884F235DF20A7E6639B40DF4D63D0A2112B5E6BBA21838380DD4E49C1F4965B45A335C\ -557860EDE58AA283CD176285DAB929DBA3260B5FEBA261FD9814D09BE315FE1493A5AEE3CE6071\ -259982EEF9716409A09E28091F23E1DE08E7B89962CF354201247C15D75281ACB079A51A9F3992\ -F9BC88727658E8E1BA6932C18184EC3BE572B98642BBD886242F781AB13362B389423B39B27E69\ -E6D91488A280E1040110E037FB0D55B12DF029B7D577B0F7FC7BE884D3FDCC066A57D1A0DC86F4\ -12BAC3079696DA7AB3DA894BF399D9B56685FB405FDAA681AE09D8B53D0CC661092F9A13F89173\ -1205CA3F7CF939DF632406D37C444ECAE7A2A293DCBA2F647FF9C775465B70D663878090B0FAA2\ -C48F5D681FA1B0FDCA11FDDC779B47AD2814657585C9A4EBC5748B48AD7B72FA5E07040DE0914D\ -4F8AE04806835879FC0BD0B5B150A157C0273192B0779D37D0B1AEE1043BECCECD80A8690EE4A9\ -207564E5B703559C79FDD16C040E8E60AC42DD4E2E9B66C14F2C44BFE7A360638ABBFBDF1C4B31\ -53B81BA783BDE2B41EAC104E24ABAA66C83D69F7F5143F776C359335AED8C5AB47256139834C32\ -085A351ECAC6AB4F8DC4F097B91FA156F093A93C7CD5EF5CDD5F4BC1A650C2FB0E7ABCC97947A8\ -7620D619DC999CEEC1796D0325B0533BC08E870DFAD00FD518CFCC38587CA225A965594C88B969\ -0D63F37231BE9BEFB54427F76E230792DB580C7835F60E4744D4B9FA2F8BCCD7CF35B6345666E1\ -753B538E276E09966D41F3B1AD3E249031775B448A1BF1C6DBFDC643BFC5F6CE3D670F4736ED9E\ -A546D9351429DFB9098FBB06EF908391A6BCDFDC6E1DD3C5CDDB0E157A26C8D7DF8BC9808C7032\ -9FB0CBDACF5B6D4BC7A5C69B231A145F15B1BCDD16F9BAC45EAD69D54281FE1DFAD35CECA9320C\ -068714F99A21BD61EFAC4B64D3:\ -7D08AD57B93CC590A028ED1EC9C32BE0713C82EDDF6A593616E681DA0F0E6E00 - -95315A26C618D637F1A28403406D9E81C76D33F8BA62F55F2EDAC56883534DEBD8B83F2675C58D\ -455747473F92178B2A3E356B3D02455ABDBF32E9AA934A5A2D85BC87799F45C068C137E170E8D1\ -D26F2BAF3551CF367AF42208DC66316A93D4B594C96AE0D4C5B4843D80464C35357926A3FC7531\ -AB7E0A0C3FA899481B5EEDA5FD3193A13019DB382860EC6F6C842A1B5F9E90337403031FB4BAB1\ -F2AF12171793DBC5058E8D53675A6422A6BD9472828922FC36F05A4989FD48658AF04DD0B26FE5\ -D614BDBC05A2046E28502F531938AA3076200EA90641FBA11DAF84A670DABDCE3831D50D9DC46F\ -F3D302B339ECD9D2465EB65A6BD0C65220025DA2BA27AAEF32D4567884A76688322CC997AF5FB2\ -DC15EFEE3011E4069CFC3E04DE84D181C7D2FB48E156E0CF46B0B8A68E8A2F2EE49BF5F75FDFA7\ -B0E615A0B8311614668AB8EF68FFE2D72A074F3FCD5384F8482DFCCA534DF2434AEB2E2D3CA69B\ -D98BEB1479C48620A8AB64B31D94EE0934DCC3E1B459D3A5CA345A7B91DC0B797542BBC3AD3559\ -C5ECA7E85B427457299B57F236CE7D836BD850D8024C50165D3594B9F68464C0C16AD7997825A6\ -E0792D0277C21FCE28C34148D65C2CAF04C4A1852B79F365DDB50CC038B3C0B8CEA6B6BF64F083\ -0465724CE5A2CDE6EE03C4BBF6ED02F4385156AFF9EB9323B820AAF32B511DEA73226FF6514049\ -AFC462DD093267A861CB3C77DF626BE8CBE5C36AFF3ADEB4C51A4E58F8E2F2DE896452F49F4AE2\ -EBE07D9EBE7B84DA4AB48829451F6F0EFA6B0775991B3E8271C5F898514B47F5E1FFA24EC91AA9\ -E261E69EB9BBC77C75B928B6B70B8BDEBBCAE270B225D0E8FEF3451A202B82A6864776C3B4DFB5\ -6EF99D2FABD30D0BD00E2D77EBB1B47B6DE59C8D82D60149E772B2F8FF73898658207DBCCD402B\ -26BBE2F044AF68E05ED5835EC787B359C6BD4E10D13418E6552BF31F39F5B5F224F578AACE7CE3\ -1C4F19CE8ABFDF2F5CD1B2402A94A8B07B1A887A1AEFF95FBB0F1E4F56AEEB4E3861366ABAC0B5\ -F1E8B76A079F5835FDFCD9AEC107E68EB00B024FA537766BFB9EC7B211257CD894B74A216FAABC\ -7937742A8548FABB60417B467F9583D8800CE965305D56E17AB6E5A78593E07178F6B3CDEACB74\ -D39A909F7745033BAB6F048480375683F5595887F6CDD5476BCF016878CB991A5C2E05E5B7D08F\ -CC0388573D75284B1F374B97388792EBA1DB97206BA34377A5EC482B83A58D3D113D886464C9DA\ -F7FA3E7CC34C17BAF560FA1363BB766C4822DCCE82F391A759870E28BC0C3FEA07D85ED67AD2F5\ -7CA5868A38EE2582EBB3981044EB4C9DE914759BDFC48511611AD61A7E4DFFF23C55453E03627F\ -08CE2D8F8547E43C42892464A729DCBDD01B3E9C7ECD63853A7A6C0AFC21610AA3CE40E9ED5860\ -C1CB4A607255B9C68D211F3EBCA1:\ -4B34FD24F0F9938C0D3FE66CC29F90963B03543087D1C9D91ECBA5C963C3A5E6 - -695E1DB4DBD8CAA02EE634A3FD177C3A2E9287C4A5B2AA19170E0BEB3BC064659412218EE812ED\ -18B44A23CAC021CA32CDE74239EBE51CD8A585B8349E3C93943F09997836A3835AEC57DAF7A828\ -D9B797F9D293CDD5357FD65F54C4FC525E442BF85319BD682308C7D72328E7EEB36CB926640EEA\ -F116EDC014A6933BE5ADCA3733F13CE240C41F50601930E14B3A26ACAAFA25F1B4D0971993D533\ -FC9698DC97F1A932A0A543596296AAA1E09C33B15086E5EBAC4733C3679AD7FECBAF9F056E82B4\ -A854A71AFD5C6BC51A938752346DEB2E06C54F11AE829B99880B8859C4779C33239B8B526E0E61\ -B75033A9C09DFC533D906C5AB6F617B46F199B42964E92D6FFCB31033930F1CAA74A74F41E64C0\ -03232C6D6D75E7209FF538DAFED90899BB6425E2FB77178CFF14863025D3503954B5FAFC7E4C02\ -FA8110B131E79BD7B120C8757E1BB9BB72856896CBDA5642F2624BE64404201515C493CC1A5906\ -CC6BF4370A5A60BE18F398C570B901CE0945C84AB2AC55627AAD6540BA461BE9848FD96F8B53EC\ -9DF4970C8831D2ABF0E92357437416AABA2FAC81470358B3C42389D6317ECF65F41B5EA676E06A\ -1BEC4C83CAE628349956608603AF32C4B292A05F518C6B5127F216245D80DF929BFD28C89DDD64\ -D9AB0A9ED24FBC60A75FFFAF8118160F75B64D7D5A3968D1200D484CB67ECE27FD2EC4299A2E3C\ -A58066570BF3B2F214A131377515FF589B1EAE4D78BCC68DEB1004244AB811252AF791E61E5589\ -CA07091F5F9117535592B3991A9BD27AD791732C777A15DFBE309286CC77CE61A2711DE5EA58CE\ -5EA5A60BE2BFB41C1EC7ABCA0D7C51E7045A0C01F07419E277BCBF7EB0EEC20D9D06156BCDC377\ -7BD3A56A1B58028E7CA20E1FD51F41C8DBBE7A9FDE46EB5DB3580DAB00B9637DF4E3BAD671564B\ -E93E73CAAC580A21566E9C7248F2A313B094BF03D904FCB1D04E64801A6A22A703DEF08DC0B540\ -20C31C0137C77A4CE189933C451216DF38569303FE75CC80DDACD26BF2E09A3D43683E7CB0AA52\ -6EDD2F88FD1D6EC54EADEB0734103D24BC58A158ED23B7CD05CF59F4427FC1AC26F2C4710389A4\ -E4F1818B25F19C59A742C6233D92B34F4490A5ED52A4151269CB7006F70A787CEA40C044088554\ -97BF0C3F8C24A19E8AEACA1367A8C37BD4AFBE2FF2A4BCDDE413616C245E2D50AABE967ACA4E0E\ -C6D5747265A38298BAB9B920F4DEE454377CD899A82536ECA7B3A021FF1E05648B6257D270F1CC\ -01A9CA609602D9284CDB17C65445D623108A9D5EF86EDFC2C85F2A27B005B85109E01A1E716B30\ -51B801484A1C1F7CCC30931F99F7FD41ACADD68BFD0F89487172A7971626DFF0A877974892DA86\ -F9A616DAF67F73DE452C6A984F9C82DA61FC023A60F43373AF900EEAE581AF403F55AB1A3CC12E\ -39E35A7785405E8DE5BCBDA2E7E734:\ -40F535BD7C0542A3ED6E30440504B78770B48D31F05A6AEF8747F4D280E47B82 - -ED5F341CF8E2D40A804DAC57107019902C7598CD296923718AC8BFAA3952F9FFBBB3A47C460FB4\ -EE29C847B4E1CC22C4693C5C6903AF633FD73BA16A1D9F42EF3B4B5B16B7CD45AA5E83C4335AFE\ -14DAA263B267D7B01653335A99E69EEEEDBC93CFE453856850775A7A17CC27A2ACF82614BC4BFB\ -5118C937A52DE8FE4FCC7B0F8249B80620A17AAA8C103BB0A026F668BAB5A18F1AED0798CDC2F1\ -A77EBC8EB772046FF2327F4DF04DA3BC16B132AC76BF2E20723DADA7C4997702FA06AB191FC0EE\ -0B50EB2F9374B08F8CC4E06F6F57502AC3A55EDE1AE5D9FC28D95A1BBEC77503E443627458EEE2\ -18E87A3AD66E8D169D1F2544B8F4C6F4FC43B1A5795CF1E5D300B6038768303C8E6A3E983A9448\ -A5FC45C39B43E715FD87C63E4F593A420471E771083D0543FA834B6332372D7CC90AEBE96960F7\ -078D95A3F2785A918DCC9801269B7BB967C7FA40805FC91B83526E3B477C7F48D7535EB34193C7\ -2B14EB6A7E7933323AB52BA887BC91C497EA2AE61B824F9C17BCABDA07E35F9616BD75C89399FD\ -8A968EAD40B15B20A1B80334246EFDF3D651B5381988C1685CA229A01869CAAC03D41D2C7C2FF8\ -CC5628C66A749FC7EB69D8D462BFE87E2DD5D7C399377A8E5F5C06D6264D228389266F2EB78292\ -C429D7DB5667EDD578E4A87819069D912A3E2DBCE9D6ACA568A84F331B649F4D16596CA6500C79\ -3AD9FA82D8916A2077ECBB22ABBF5EA5C2B7CAB4C8BA0E360F3F4562C009DA71E23174A45A0457\ -A30A4B2A0B46DF213A64ACF038B1A882FD7E349DE10FF0F7D3579A75E15831AE597C2CB1C64834\ -9C4F5E340063B84361D94C5C4243D4C2A5818EFD0F043F424798932FD1F2DD6E44442DD3894AF1\ -D77549B146D43847293DE9BE5CC0069F341302409B33B0724C6D95A5566C267EBE623781595D72\ -A461FF8CBAA40B3C4259766D7F4F61ED404B2D8C651F6A38F6F757E219864500EEFB9DB9E9F1AF\ -0D5197A1A2D615A64C03DF7D7E15AD48CF22E75D1DEE51A44CA15025F4A9849C8D0126CD4B74FB\ -E444A0DEAEAAB2D11229DF6982F5F0AF95D672D0C84BB005D9FF5846E7C8703E439CA9941AE7E7\ -0E076E907BCBDC209C9284FBD6A1CF8549C90DDCA992E60FD29E876C30E6500EE8ED31FC752385\ -6F84C22A2553542F2494038953633ACB8FBE11B87646D81D366DE4657A85BAE1DD7EB820676928\ -227518C719A310C9AA97E5FB39FB4EF03631BF0D2F51C82565841B3E39C5E7D0CAF07D9BD49CE2\ -AAE1EFDAA9E8D9C6572B0155BD9C6474EE97B9FF7FA167A06DB2D3CF5C2FA0DC8CD780CB0E1F04\ -539E24D1559F0295DE3802DFAD3DCADA8274980C6620B39147B5BA75C7C1D65684573FA1FCF26C\ -4310D24ADBCD39FF34EB2D616A7FD997FCAF4BBAFF356978D675767E2CBCBCF772B55A71D94EC7\ -D50166EC608FC171BFD96DCE340D1446:\ -6D71EC68FF4949433604E7699092096B38169E18AC91CA5B24A2BD63011C031E - -C126AEAED489F433D325FA396A69920B4940CE3D8993369F8B776126CF31D9CDEAB316C3028342\ -8BFAD19CEFFE9AB9F9FC589FB7C0658C5FB58BD127F9A90C4C60311D4AC435AE0FEDD241A31091\ -C55B8ACFA4D89DD0053C43085E395C85935327040D950779B3D6E58BA668EBB191149331BA68CE\ -7AF35EA27CB68AECF9D6EFE29BC2072FB47E54DAD157DD17BBE7F09748AD257DF67B1A6553A366\ -E31BBBEB5D969D4B7CD348D1968D84813FB5E1981E873ACB17348D4B31C56690101AC361E5AD2C\ -4BEE75B3DD1AFB68512D30A226F514D38CE51A2047E53D3CA91A4794368F6FEC1C191E2C205915\ -E1B8056547C667AB77223BC7A22464FAE4F1F5058F5AEABA1461F4B4E97861DF37535CD487AA5B\ -9845DE89AF6DF844AB86BB5893D03ECAE0DBBF1ECCD04F8CC286C40A732E4C9373BEBB969609E2\ -3A236C3B74129B893DA55C114432032DD32DE7304FDDCEDDA0C6217C11EC9347D7423F7DB1B94A\ -1B8686EC6B626CC22198C1DA6FF01E7BF447F3AF32E55AF453CB500EF9EEA4C866CAEF142091C7\ -F11034C1A755E01A35D5C9C57770238239B7A0402FD8F0589B0596E019F8472A5173E86DFF657C\ -0A8B5A65F85DB43AEC400C9A0F7C26A489026CF8D59E7FA867EB5B3B89F01B77C371C96E65B52E\ -2F8F6C362C766C83582D51CF89040ADDABE70396E81569897BD21C5F6B50B95E62A6D10761A957\ -F172EBB30E28D192AB19AECF1FB8041B5C95B07FEE75AEABAF4668018A157F8C8246D886E30C29\ -4466209CA296AA79F01D99CA518196DC107CC73B4F1134BDAE068159C9D5D68BDCA71B2143E096\ -96209A597752DD880572082409D198A9DDB8257FAD0A47CDEDF80584FC5487BA94CE02271B21A7\ -8B371A2B8C9B6FF0EBBAFD608EB593255ADE224E213114F94BFDC985019D413065762A1D8738CD\ -EB84D5E24C6CDBB68F2C9BBB16C9ECBE2B796A51FE23BF5C945EE3519F50BE6438F83012492290\ -093E18D6BD69C677AE9A66EB25FA8FA22D080AD89B3BE356A0A9FAEFF764234128B11FD07F3CC2\ -E4D3921D0D04ED4BB1206EB63B7C17F173FCC2F88F47297BB33B7AB3D0DDBCDD1934988B87E089\ -B090EC6381CBE7EB07AFD0406FB11610305400B3C2659905542D98D697BDD7652BA039F9D8F8B6\ -22A41490A7CBD7E8EA4DB50E8225094ED8052165F3DB97366CAA3A97C3CED84F0DFE18FCE254AB\ -A0C8D12EB46E7713D62D404D67F9178FD13DAC633C7092A0E27B148BD972B0BAC0D7C8E61A56F2\ -C27E6E4A29B48029224A62F617A97B265F6AFA8DA77A7C0EF080BAD36F8124C787C3D2C318C7AF\ -B9974F596E38C9765DE921728A3C495D13FEF0D99CE269979AD075703F1C784BAA6FF6105337A2\ -70DF2244AD2F19EB243E3B623382260607546ECEF1CCF3C5B6A5425EE9D565CA8AA70A5E1AAF56\ -F3B93E5D7F8E763D4BC2EBD2C25997BF11:\ -84CE84165BBB95175543526DEA5F0C97A4308D2776108D22ABF842ABD1AE968D - -9F46C2E21D2366A40CAF149524BB4CC51DD7E8D221F86E68090EB9B72BCADF0DBD1E00C8167149\ -86EEC2CD8B9A38D8061746BEAAB4F81141CC57FBDB4DEFF3FF67439F451ACB4655A7A1665894F7\ -B01450E8CF23FD443B107B4CB83C62A0E4369584B59AA57A4AA758EF200D0B48E50D926A185C0C\ -691EAA2A5B30B1656469798120981393A2DE461BCFF6E78656C22E5BB599BF92D16AE1788D0DEB\ -2891083FE095D7B3A6C8257A07EBB59EB517E0090C372BCC0ED25DDE88803F35FDAF12C657717B\ -10C1C1B647EAF9787237B445B4BEA460F1541B44B2E288591CC75FBA04222946C2DBD9BDC674BF\ -5C8D4BFFAD17248881460C7A95EEDA2548902069A81A48C84D6366FA248F4751871EFB8F238B31\ -0965EEF21C1D0D0ACD5D50D059B6B66CAB482585125E46D5B637D937649D795911EB1DBC4C27A6\ -988AFAAAA23D79FFD1251F5B46BCDE7A0A19DD2F2597FE3BACDA148BC6244938846D9EA16455E2\ -6E1590B6B428025B8114AA60936C7BC904B47689A4F4451F0BB3210EC7BC65CEDB6621BC10D937\ -94DD969F5CAD5236A1F0E4ED224C6DA106EF63C175881F7EF4AA96B9D61666D30F643E53C9E3EB\ -701847C0A62263EEA4094338D8DF317FBD5C8D6339816D8F2BBBCAB7E8E877810FE89B6FBEC7C6\ -1A3F0BE7488096FBF807615CA8AF1057FFD467AB836956A1FCF4DE073FA1B8E2C55E75873AF1C3\ -4251CC288BF669F75157D2D0A79885FEB46791AD61E7459B3D532E88E04B564ED4FA72860A74CD\ -4342FC2E35190B1C588B997ED11148726D4B943A123F34B7C6248836D54EDFB9416F84106E4305\ -6CEB62618BDE8DE862D6F972069F7AA8B11D5380A13451B4E8AD998ACAE76E809465AA2BBD56E4\ -8F4EEBEC27BEC0CAF07CF00F9FB2CADD2E8E3E15B851F49B262277033C4F1EE0989D928EB93D94\ -654E389ACB8213A2FE8786D9C783E09EC9693E5916A1D5BEEBCEC342756971A8DC573960CD9A2E\ -50EE53BEC7EBB9B1C3789DB2290930771DE7149C13E192B9CAE5C81CF8D7551CDC7650243E3058\ -E4C3F9422C5E46764F10EE19B7346078F0CF3E4D65BBFAAFDEDBC55B91E9F071FF8E143F98B60D\ -669D8A80A9902080AA05657892BFBA92DED6852DFCC3805850E2D952C9E77ECDB2696F44E722D1\ -BFF3049E7F9F55491AF44FCA64F17CA6DC1C1A980371E9F43E4DA07B7D8C28E4C0A77FED054EDD\ -4C88C7635CD63539926C961C1182A243F680898E34BE3EAACC8DB4545BA623DB0F2DBA2C747541\ -01A952A8BE54C5F2985F088C98CB00527BB42984E8C609A73C5ACA0B575A2B4A914EA6B782B14F\ -CF858E1B3172624BA4CE0943DC70AF09029A755E8A613C66C5B29270494E1960080A0FFE8697BD\ -56019E4F1F42F99A83C23CB53DEEF877955A653E2621CD267C4705935569BFCDC2B87AA191E5AC\ -5588F0961E39E9B668825BE62DA329D6EC44:\ -0FBF1D93D23BF1474C044E9BD979EC7120F98604EE006EFFD8C33C0FC59C649C - -0F8D71AEFB9E58C7D41B456852145204B4F3D998EE65A47161815478CB2E88E94350135C331126\ -78D40A7585E9C519C25ABFF0F1927717DC9BF411E8D12ABA65F34B9927A652EDB8F129DACF3C74\ -4FFCDBCEC171E862164B241D63090DDAFADF41910C3A61EDE7CE62427950EE15A3368192038395\ -A98BCBC6FEC064241F165B645CE9B2974D854DFD1D8C3BA6B294B8AA91A049A7FBE85ACA6F224C\ -AE72DD42CCEDCF76159569DF29CA02F4DF914B875E87895FDF2740DAD1671E6866F9DD7CF173DD\ -FC88890B0235FA483873685DBAD323945CBD2448803D54AC79C16AA90D26DC70A84308AC019A93\ -93D78A09503F62B7819860C3397211E56C615621950361DB16D22BC8F9F316D12FB4D492AE142B\ -42DCE04958F6840D2A48F055A2F68C32F786597FEB04D1E1261DE7CBCA5D34A085025B66A7D78A\ -34F0DE8619A136C71ED86730834E88E9D2826CA87B016ADA70A9F06844D62D44A86D1EA8E872C4\ -06F4542CDE275D0CC9E6F8A4F05CD3814D8A50DBB8117C0E731E9A80AF34B6B3435000DBBE81B7\ -1E715962073057B2011637EAFC6B45C71CE5EE97558EBF171CC4AF74BF1D2747CE5DE49557F686\ -740BF993E3E208AF7C033C23FB2616047935E8AB73563FF47C7A1DF274CACC96EC77F5186E3E42\ -3625C817831B2F0BFAD273AE893E59CA08F8B9031238817781B52243CD6A382197C71140BF5A21\ -A3E2B3E8B6779AFF965ABE7EB135C87EE974D7D8AD3902FD65F55E01D8D9878F24F6BA4C1DE634\ -98ED65A2ACD9C29194F30B41FC5B2C0EA0C86758970EBA68AF455B358DFA3E9FFBEDE4ADFF9FCF\ -B184E99A70DE24D65B0019E98F9F00B0001E64BDD39B3D0866F6F1DFCE5A8160DC3520C940262C\ -24B2D06A461B48D1311FD2BD83FE229ED9617EA6B7C880D7852DB2B74966EF951D0B46F02D8F4B\ -E1603681B4ECCF17CB4F7BD3552BFD2EAD2C41001A52883707C2C4382576EECF0406FE84993888\ -9688061DA54EF59808CD947125D29C27DCA01A67B0C9DA4211EACF9EFE1B274BA4250AECD07C2B\ -5994E0997367818C2750447EA3E671911622B2FDC0C84CF11A1345420C2D2B9D1161E0760BF666\ -9A36D6F5A571B11B68C98E485CF2256A8DCB50CAA2FE74CF99530A1B51265D3EACAB5FDD27793E\ -18479B4EA782FA24901A80B6434108DD1DE0F1B4C80C665EF6B52B8403DBB3A553D550D43DF311\ -8BB7862D4AD002E87FADA601728DFA97ACA4A15590265D825BBBECA73ED15A4E62A3AB7DBCFA74\ -56CE2D1F3B1B6E8756E33F6DA52EF56C35BA574E6D250900841EC42C6596B8F135C3D61AD98C54\ -8E6448975FD5EB5C9E69BC7B6B646FAE0DE1AA96AEB2058491123B17BCFEF67DA21BD13027FF9D\ -1F36B2C91DB41BF756442C3B72326C6A02EE087A75A73552CBE231C06B5B0C7D3E9180F9445542\ -8FF8AE90B08F61E929BE4ABFA35D7CA39E8D74:\ -CB0A81684E5369ED90D222E5CE73E899DCE5CC763A044D908D99B9F754D915EA - -3B81E34BFDF7EB8F91A1BF748053E95D304B4857A563C8FABC509DB7C40F2D0C44F98FDCBD1711\ -164E186F885C720AE6FE4CFCB4DF85E4BBE30540FB472338CFF09DD725B88F4EAD30640A48C0CC\ -8F948CE70649946E6AECF38BD4228CBFA874E6D652B9728DF1FA08FC0E80BADEDCC74042A6ED13\ -D2A64E5E595946920CB7EFFA2960A2EEFE20871D215970233E1EEC8F2F3F1D7A32D5500414A2F9\ -D161EDB8CD2D48966532D4E091F704A440C3C35697D6C3199AEB839DBADCDBDDA8E08EBD440339\ -D1CBFCCAFBEA6C1EDFC9443BCBF692EE4052DCC014A1DD529FC86A4FA35D72E63A5A45783B3030\ -6F7609402DFC77787C360E400C0BDA451562CE098EA9F671C637BED7E254DB2E75C0E1D2C3A285\ -03007069F5F54EF776185F50A034D4A2AFD919EDD984139A9ED070DA9259C5C1A091334361C35B\ -5183EDCC7B312420993D2C7592A693491B6C0834EC293028112DFF0A5B8ACCFB197E996E97D594\ -DBD63DBFAAC2EBECD96F73EE3CED050282AB9053EC9B3463DDA1C5EC7C8936BAC9742E9DDA82D6\ -6D544CBA9B4F80CE8DC32C80AA430C00DCEF65EB9720ADA8B1B762E502C3C1F923F2679CCC74FA\ -430907ED37CE17B89ED75DA0A7B32A376D4345E7FE3587B43AD23FB380067C9AE736C65656610F\ -02F58D1F78D84C8EF058E6A7312932AF4A48E0E0BDAAA9C37F41E82276C3E2AC47F774F1422B2C\ -031BD6BC630168524604C5D65D00656F863B997C8FD9E8EC99B16016528C229EE81D0E20F01BB1\ -C5CD512A105BFAE82FDA1715F6DAF6F6E044184A09AFE96DBDD7D2EB7729D56440656989E0D4E4\ -21D951A5F68EB5B4E3FD4E5F1953A4ED29FE5E265F2D7BF56C3FDE493AECC8169AD265A38EEC98\ -6DF7934389040F52877221C34A846668F33EDD663E4B6D08ABDF66925EDD743DA3BCCCBBB98997\ -4201FFD633ED693131762B6D2790DC65AA050532E692CD7DD2E0FA793B5E4020C802717932D3C9\ -4163DCD84E1D93F3562D240E3FD74C28B014192F1520F5EB69ECB33D2904A76EB95947A7D74654\ -3A0E09E1362239838871FB117F4B1ED20E6CCF30524B3DAF592E3BD8F15002E0A10557C12DF27A\ -55374781AAB0B2A20A980BFBB72589333A3C16C3DDE19F727B324F3DED460062EB78402E303FB1\ -846ED84E6AA01CEFAF2C07569AC04CAC024F50B511AFF91D22391AA81E7C521DFFE12812BB34CC\ -6D0CE560820BB219D2063826614A9AE8557F34DD5C8E0DFC46AB1C321D3B3A4A7CDAC40BD1D728\ -0F2469FDCB6CBA607816D668057CEA4CA64F881CC31F9308A1FC84606C1C28E3E0BD7DBF45E430\ -81C04B07804F5E0F91B1EE298AA6B9DED88B1FD920D6804FAA8D6D0840A4476894ADBCA71B66C8\ -AB46DA39D0849FE4F1134220B4315A1C7BB622D95B6838D0561D65219D902989472ECDD0F9B31E\ -273C95B96BE1AE42089639F72915829E629A2E15:\ -F978717338E5BB3F578BBD8C4587CB0BF84D9A55A129485250D257338E1D5A5C - -88DA2C023A73898CC6EC26A0901F71C388B18D213699D1247A23C00704880C6B0CF835CF5C5CDD\ -6644D9FA95369B4A1E673162FE84065929B79E7718F53C7556B1A3A7BEDD95B68B57C5024070D3\ -0E73B48AB44D98A172DE22AC1CC28F0A64CD6ACF5A5CD6E1A7B42AEBD69D61209C32F942EEA253\ -0224ACF0A7BAED6CFD1CBCF074506D5AA20E1D8A8AF192C319F519753267599AD8C6E8BC1432C0\ -ED9302B3A72A77CB4109C2E312A3E2017CAD78425AC2DBF4E4286AA9411A98FE769E988FD60025\ -08B193D605499E120CDE012DBCDE8DCADE91A7978F7BB6E5071257189291951E6D2AF09EE0B435\ -B944AB4E2D9BB342EF570966448214389D1978B0AF8B9729E6200C583FF1926D998906628ABA8A\ -1AE58CA5BE7CEC73593B2E7CCD8E33C4803AE3FA07374F1DD5AD0D883A84C76E54A6C733BF9205\ -A9B6446E2F5015ACDDF52D7239C4DF8AE11F2BB02C09A87F88CB56CF63D5AB8451961C06B8361C\ -148785F6D7F2BA78E27B33785BE64C403A4C9DA51948573405EAB99C0778F3B1AC5B877B2CBB79\ -38833FC4DAC613D40352FE2428FCC6D3152F46F99E206FDD7618A3025112E6A4A1982CEC8315FC\ -59759EDC3C7D8BDB211A6BB5088CBF65F2A54D6E3B54D75DE5561041E2317EAE392E18847316B4\ -184A80D31C97109322095728728AB923210DA7734469E9B8E762EC28A2783A504EF57C84C1DAA9\ -F873AA7C968CA27D78DEE8CCF4BAAF24685803CF748456702899F3181A199C95E5878ADAF0AB52\ -37CE8D9BB3962B3BCF511826F20AF064A5B50420AC32C81937FE6A318009C4F92CE35FF501887E\ -0F902FD8D9B5BF7E0D30B40619D2E9832C6BA02A2872E57BA4B5A533659CCF034D8E72C9E23EBB\ -3778A0A7F102361C79F25273EDC27B7D63155C0A70644A0EBEC634954C7BECE6CE027A8A74E72A\ -BD1B7311D033DBA9F22B798518822A7383DCA72ED70D00700E9BEB677C5F0D5D3D110D179F407C\ -C1F00D06E67063DFCEA0E113C1D7F5822CB81CB9D89FC53B8A679FCD83A1774BBF2B76792819DE\ -03909AB7F38FE447600B453AF0E261EA5496F91E00BC594C9CD37ACA8F8D784D44766E58D9C36A\ -0C73EFF2C2D67014E6F80D3B55D77B8B97BA2C30DE7D3C4C0386771FB6AF3B21F433F102016409\ -BE94638452A9B2AA79B52F8A6D2439DB7C71F57E2AA1A6915EA0993E5D203BF85EF5E914A21C5F\ -8ED05B290DF3BE28A5861398402C4114DBCA88A17FA0ADEBCC223A86F35B989DD046E31F130282\ -D2FBA623636173B71AC85D45FCBCC39E4D71D817038BB50BE88E91717311E35AFE5C58B57392F3\ -D1443AD25483003F02573653878B0D3271931704EC0AC5E47ABBA1B57DE9BBD0611708E6A7B2E1\ -FB8A468814541357381A5D24BF1042AC9BF0CE48A674DF9CE54D5A0F107B7DE23E28D3F6B87E93\ -87CCEDA9C2402041E8C5454DDFF083F99A83045FBC:\ -503186570B08E394FF436ECE9E353A899D32506689AFD3343F0EA72AD6446D0D - -58755EEF96A6E5CB9904BBB82508C0D67040B90C60DDD27EF96586175B6F23E60D5B186CA6C2C4\ -EF08752D5D5F4A4FD8D62D5D108A2BA0471FC2E6DCA7C9E4C95812E50073EBC8A6D0E3F5D01E99\ -427428A0965E97FB5442F13755E19B575780D380A362D9EB6713550756AC9B2C2895614C865810\ -6E99A222ED710A0272B23C5AFE1EB3022B258D18CE4DCE181FEB79261497EE61A89178D332431E\ -C02065FFAC5FD76EC059D8A3C2BAA5E739D0EC020E4E0685047EAC4B53C54CFCF799753FF61552\ -DC1363C06DBF48F3598BD1E5ACFCB0E13F102614F6F4DBF2CFA197209ECEEA428F44FC74B83EE9\ -58BED64107E8FB6C18A5EDCC3F4888D5A872751A71B07591BE273788A656C4AE162E5A7B0EB43A\ -30295B61A8100B337D8483B62DB2414EA534A4E4C0F1D7FB13F25C0068E104B4A92E88F579B6BC\ -A424DA036227B5FFCF75D4BCCDC91A97D32ED8F781BDC33D0F572744DC1D1A2F356CC2ED23AE2C\ -B22B149D885461B61650E4BEBD3153A15B5064B3CB1863903D795A1986B6F13ACCE1B2026D431A\ -0F60306D35933C067C25B93C465D76CA117234057298840163E93C4BE77EEE2EEA24E398FF50AF\ -7702263FF34E88BEC7292973130DD3150C3BAAC695681B0D2C6804B40D80CDDA9C00C12B7D811A\ -7969888CE29FD20F897196471050DFA9985156F6732F66F3F4F128A84FCAA3A4C92E20543C4EAC\ -58AAF14FD6EF769306AD5C490C14AF969686FAC100CFC49570684423648F74F5D69F7917052465\ -B92453F934E911838BCA1021C71FD1390C2613127F93B31CC80B7DD2CD8EF58E341740F5467B35\ -19D01E2827FC0A65BF902FCBD94CE8B09BB78ABCAF6E7EB7E693994535D15E8CCFBC3D21AB82DE\ -DC3AC3081DA7D84BE13C8B0E99181E63E9E9FB1765DF1116FCBC2BF3B67C8749812ECEA1AA4964\ -29AAA8519F61DEBD2E6050ED9BDFFDBF2CF800321B5FBE37930873BFE189148F70D0A1ADA523CD\ -E42A1401D7E439D5324B045675466C3E8EC22845D19D368F0FCEAAC3FA7F3D5355BCF7ED8FC233\ -2A87A413744A010283EEA276D02C7CC6D6A50FBD8B66A8FAE9C67381C0CDDB56FA456F6DB4940D\ -28C76898DE93150073C348F450C497F259EEF6CE4D9B36DC8DFA4096CDE7AB1DC3E0B6282DFB42\ -ED2B85041FD7DB2AB1BE12F63EA15053BF6C665BE0E58D9B2D936C9070064CDAF4CD0709249D42\ -6060BCA9EBF9426CA3FC1DD5B68B8B9A37BBEFF5297717AE668A9E8E861532972DB6047442945B\ -84C639366863871129CBA3E20652D6D89899D2E8B7548F989C7BE81F4355E5619AEB4206A0E04B\ -D1227DDA12ACE2FED4168DF9DD025219F436CFF47D977BEAFFE1E3B7157D7AB7ACF8DB2152F8E3\ -10F5AAE7CECA51E70D402D4757D9349223619C345B83F2C74EE497B957362FEE549E991B84162B\ -8E232EAA6514E726226297C103D2638F2A1DC951B4C6:\ -CAA390A8A09EE7B7D32346D3644E95BBF77EDF017775B8AD47F58722C2BAAE48 - -0ECFB8586C18DE7B9BB2E223D93ED47EE12964582480F8703D10F603BA655DD0DD21A9E2864972\ -FFF914E921857C6962717AC82518581241F1EE13FF515D0B73F6A13AAF4F69064E061112EB4CC5\ -DD30EE53438EB8E4A5A2E56DA0049A750341D23D660B69F43A976267C53781A47501173697213E\ -BF3AD79C394353E40B074B3F0D9B01E3E64234B81DDBB9442857AC36F8107283F53DC6EE173990\ -479EF5DD913A46F6CCBC3D8FCB0150FAA1C155020829A46CE3B24B4D91DF564058399EFA183D8B\ -0D9FC82B9BD1AD3A2BFDCACE47011E8B0B2C078CAF0BD1F58FBDFF27E6734BFB5ACB3E51A233D4\ -135BDEE26DC929B77F4A3CE2B62E6E95ABDC5D24EC56EA3E4524ED2B79AE43BCD61B7A0ED5DBB2\ -BE870F55D49276AB9B6868F28FE7A5127402DA1A153D69D9693AC5FA3894D8830D74E702FF0E52\ -4BDE87FEDFAD40D14995A7A94C881231B08C39E3BE535258C823A4F12B7F56797891458891B82B\ -6A8BB28932B942367FDAC0ACEED6854680CAB35EA9D0F9CC7143400BF1BDB654B84A9552925D99\ -623B5120F7A9A82E83D1A0668A5D1DD8D68F4B5DE34D4BBD34D4C0A84AEE897EE103CA6EE88356\ -5CBD2B0415CC668FCEF49DEA550EB569C31E4B565DD0E0AAC73E4C48460CFAA969F6D794828BC8\ -193AA0F30A08212FE5CBC05C89DFA5AC478A016921ECB0B963340276C2BF14A836C8CEC999AFC3\ -E0FC175867BF0BA0AA09617D5C38388B86E26611312368ABF78089A345B022E7E32B4E3156173D\ -10750D401B6C1D907CD127FC9734F64DABC1457C3AFFCF2F41D839AAF165D32BE40D8540C581FE\ -A39CF02779CFABF9C269B21A44F085AA077308D0BA7B398E727C1ED023F8F9B2571D0A0BAEF408\ -235F1FE5BD219F3B015AE66D3299BF1434012A60E004EEC076939D014DDAC568F374707F75538C\ -D717F232B9BF88112FE2DDF18CD0C25C0332E46426D4B5C119A805329BF1EAD2837B4984264060\ -4E4A11F21090007210B3DB6E40195ED9BD17D2B774AF08822CE3115E08FC5EE9A9CCDABA8DB673\ -ECAC0EB64CD155B6983FE4AC29C2C5EA52CAE6654FDF8FCA117B547865E13941C5672940FD26C7\ -2E44F5E84BF12D4774670FE3E7035F6D50E58FDB639B0783EBA8636B6398F3C7DBFD1DC70E793A\ -2E83C044F479C84A854CA26BB604064995A0DC9206D619D84F2EE6CF7B929FBB39B3C5AAD3E7C1\ -ED66EB66E93233A52D902FDFD603610B30F3C2E100DA258765CBEB21F698F9637E262D0142887C\ -E83227793AD5820C1B11F9D8D5C9A5E9AFFB91CEBF5E50223978D84AC944D3EB71F9F8F2BAEEFF\ -C8C1983C43998AAC89CC318BE364C3283632AC1A5E2712AD65B2E90E74570C93DA67B17A945C41\ -CC8829A11FF472471DEFD598A38A260EA7DD492A938C1E7457AC452AD7048A5731C89AC6444E9E\ -64DC461EE2138FFDB95E954BF30D2291161B68FB52FC1F:\ -61B399FB5C54FAD93B8082BA8F430F2183A77DFE3832947A0723E24751B51C75 - -CC75458EDA82E7DA1DB1D8C48050DA95D2DDB8B775C56628D177CB6F28F5F871B0FDD75E39708B\ -774B9085151647FF25E1F0EAA4E2436693272EDAB0B2BAB5AD1B941D70969BE27AD7A11F5ECD79\ -535EEFFE45FD5E27D5558CA160336203A2D1313001BC8D964481258249FF971EF4F2175F19911F\ -4E68E20944C98C1DC5A68AA47DC67338FD3C8E706225BD68A51D7A424C844B38831D52D12C64BF\ -A254A7117DCA1D9A120B5A189E2B5575B2FE98D8066229DD4E2EF4177223993A789876DA71CF19\ -F083F07C9F0387F2F82FBE907030E7841AB2118EC834457F96DB059BD4CBB838AFA0E290406893\ -EF7AB07F94A5D741AD811B0CB67D4B51D360090F7A8AF937D29EDB1A7FD40C2DAEF57EC2CD4BBA\ -6AFF1E00B115BFB4D2F1DF4C70F6DF280415F1A0A90C63980AD1D9BED38C659D6FDE472D7A58C1\ -1F85F51DB3D63E278B33D1EE0C11275027B0C79434FFD766DB5AD2D622CFB40836A2BB5125C599\ -1FD19A9BF2B90538C79BB9800AD3D439135BEEC5C8444A9FBF4277D595C802490373BA05225093\ -1D3434C95B1FD268087621D4CA631700172101F1436E76BB8AD04A47EA6CB18C526352F1B4D9C3\ -E1B1C94D4C7C509532CAEC430BD31C12B7EB0BCDB1EB34C87F2D94873DAAF4BC88E6A9E76AF943\ -2A7D3CC1C823C3BE53B7673DB19E1258AC4615B50301B3D4D035DEDE43A87B7EDDB7633C52DA4F\ -E28B356A1494B139B440B8764A404F439CFDCB7D5C2FDD5EF4B997C65733C37AEB04B17305E8BB\ -66AD986036C067F53A3C518A92EEB7237F291FB3DB0F9AFF002225DF7D678124D43D2AF2657E6F\ -C9752D4FC23A2B570804E094A9126AA427D690AE6B5E2FCCE5553B70C6EDEAEADC230560DCC63D\ -E3AEB312922AFFC9AF8104A3475A19F7D11F52B4BCD0EDCDFFC7F1329836D859E23C8D8150EC77\ -F5995403B4E8049F39F6E755082140586C690B0DBB154B606E18B6CD57738C81C5855F06DE1896\ -031AD801D354F672803EBCCFF032EAC565743261433DB2226AC0E577B88A5C5DF0E6C618756409\ -FA394B4CDB92F0BCEF00DF610A649E3D5965E960B76DC2AC3350E05241DD98A6D3DA6485B133DE\ -91B0647C225EBDDBFD46CE214B2C16BC7F715B1387807EC2D9D589C7EA15208784E1D75F0B97D6\ -4AA6A32BF2BBC50977B10B3C06D9F1695DB9B424C9F9BC15B363BB5E1859E203ADDABEB9CB5375\ -3B1C546E5911ABBEB367AD4AE6846583A5D18AC6AEDD99987BBF7763278728447AAA34A1C01157\ -2DF0460CC1E95D184DBE871DD7EA76547BAAADCBCB0BBB9B548480895ECD2AB81BDCEC1B412B02\ -CC98F6501C5C68C509C26BF0FD8365AD8EEBF5C14BB36B4E8855CFEC2D324E27BD78A4EE9AAB20\ -088CA08BF8322C7F65E509744A729AA1ED5FE27E76E95C741FD3874C0AD86F647A90BB7E7A9885\ -784BE46D6C4B2294148024B853FFB33B313CC069D9258FFA:\ -1647976017C0CCEB3204A02B3578B65C2785CF95F141063637B3689135B01D71 - -D2254E881D09E77C39BDD2BE668A83D6684172FC7F3A2E5602DF649F07756BC693BFD856F9D870\ -403954D3EDD0E48F8D071DF89FEC540A826AB52836CE9C39527452014BCDF128D53B590DA9B53F\ -39552AB49FF59EB60823ECA6BD51E0733CF0CDF4E9A0D4379000ACC56A27F0E0B9697590036776\ -0FCB86A88F86937AB2E04F2DE22B6A485776E548757C76BECF786C80C68A209F173AA1D5782AE5\ -F1DE25DD9DBC314A2DFF9A8CF318D41793A45AEE857ED30012407D8362FFEF338E04000E21546E\ -040BF8AE3643701B25B3A66A107B57B1529CCB3C88B8B781E68D578617F04261A1B467AE2D74D4\ -9A8A118F3E74826A5F2F3CE930EB3A96890CE4991FCD09CC331EDA16F60C8407EC5C9A91CD938F\ -55023445C113AF011516ACB603E93BD1C6B8977543C92C93811749978F977CEDA06A58B48F76F8\ -EE5FAEF76FA48F695A33725B45118E52106D581BA370D758B742861A87D86258623EAA359AF117\ -D028A923EFEA8194DF661409CFB75547590CEB3534A0FCED6E249792154727AB2024D3E9C7B379\ -97D811DB49761987C4E4B45C7B42DA3C1AE564D7A93ACA823ADD426374FDB3B5EFFFB5DACE925B\ -8908C7DBB125682B066C069C28CB8BCFC4888D78F9E3A001A00D8F83E1C65F596523905D142B86\ -9057301ECED09B0BDCF78FC734FD99A32D5605635806D4210637D21E617490D9FD43EECA5C0F1C\ -274A0B512490B42FE41113B4B24F8193D3DA1622F1A5D7CD43390367DFE2D80901FBBDE82CFCDE\ -4571B066D228A166FA8A873A5593E13942508EBBDE1624DC2D5E96A5B45853C54BC9D90D853D1C\ -2CE0D89C7B1F54B205712919F3053A8F8730F4D1D7749774607795DF5508D947521DB651D49700\ -A57EF2F1945AE6724AF0F81EE02F86D886702822DC4EFD421077F526803746E1782F680842BDCB\ -6F9C34D13C02AD04FC3E2C2510CA3955FD4202F40AC756EC07E6AC4EE19738BBDDB47EFD523B25\ -C1C524FFCF237800175DCAD9FBAD0141C7155BDAE41D756A4485B5BBCABC265EC4410EB8D12BC9\ -39EBE8E867843AE133D602760F7CD513AD11F94B9D85524C87135E6FCB9B402F31A32C202B8F61\ -6A4A8DB809881841C023A048A0336C58FF0176EE96B0BB64B148EB622D50CE34BCC89753AC1AA7\ -E9040FBDF789860C4C9D5AA74DB17B824CB7D13BDDBED24A6C80A118F05ED520A36CEFF13ADB15\ -5AEC3F97DA79B6C248C3375130ABE3A8FD0514F1D8624297898F3BF92B92EF363EDF7FF0D00E89\ -022EECE47A182BEB7915B98050CCE278EBEAAC31E4F721294D994FCA38A9401E8584EF5670CA70\ -6FB266F31034A36545C7C3586BDB47F9A2AEFAB724826432272F1F97B3B282E3F749089DF2E6D2\ -A6580B71BF5DF7A01F84396200B1764B09350220EF99B0BB244A044F486D2E8006F710AFCCE0AD\ -03F646C8B1A6711273D1D1A07D61D97A4A92AD6EADEC71BADE:\ -AB79BCD11952F3008FE2983D748A2C3E537BF3C7CD4F4378CB6FDCD3E607A848 - -7EC32975F47F4F8DC2E7DC7A68F02771AAF5DF6A31AEB5E6E1EC58890C4AD5F8F19C4D2FEEA12E\ -169A73281A19F36A02EFFEC4BA14E9DDD877E7F911C0D3B77FC9FB24DD9919AB4B79DF64CACA98\ -DA52E91018F628399E1A2C043673D62F8D92758C4C903AC7DBAF65E8AF151ADDB6E796335F8A58\ -8AB7034ED3FD8AE9F034C3824B1310AAC10676F41017C04642582B1A9F7EAEC9DBAAEABAA6ABEB\ -B5E15EB8AB6C3AF58D848177DA5B512466839F196B894A1A7E7C62F8012D11A42EDCF544D3CAA5\ -8C251E0036EA602A4CEEB0EA33B6D8970668C75F4BFBA6835E6740D83A4A2D740E2841363ABF07\ -D7C74811E2D171DFDE54EFD7CE74E16AAED0144B08FBC244AAA7846637662FA298C153C99985F7\ -8964364619D7C4345B84CDE705F06061D2D63DE01C2D65713AA5FE447D4FF86F00AD983F6F9B7D\ -E54E6C770B9AA69685337E73BF6B4327C96F23B94930D7C75F8C242F64BA426F900DFFC8F8EF02\ -53690A4AFFC345C070D1B1046EF55F7804AE74C74696FED88046DC61B215B8079752E804445C29\ -D6D3A8EDCD7F2B506E9890355B38D3662098EEBCEEB0791F1D26D6BEAC8BD40EA3E318210405F0\ -0A6D3E17D7A501190B355588DCAC102C6C052EF33DC33BA9068B71A9B6A1BC289E3E108B1D023E\ -978E8BFF7BFE7F88D73E4DDF6D2C2A18FD027DA76782F1812F16BA73B3D534E5EDE512CDFA71ED\ -E2CAFAA11356C37D11BF4A066E825444D7EC7612B4240C21865AA29E19D02BE980CC85AA4ADE40\ -3B5C09ACD10701CD3AFC931B0473B351D27EADDC920791BC66A1203F666B3AE8FEB1565E69DE3E\ -547B9056DD8AFB6E2B88668A0C7E5593FA8D412007F8B3BF92C1C168D0254A5B6527ED2DACAC04\ -963D7CC93D6395346A5A3A04082BDAB11B4C0A0B72B1020CF0B048EB2BF9D8609DF27BF014E96E\ -CFE2488176FA3B93DD5068FDDBCBB9FC747B6B48DF5E989586C3D0A7E17E1B5F7EB695C0FC8D2E\ -09DF77F964F6FAFC6E5D090440AD393A2B8B5CB39CEE1196F08FCEC7BB7ECF5410FEC126311F1D\ -09DF4A9119C7B09115C57250FB78D718139CE8A8C37A91A17B4DFA87B614E318894E2F7598402A\ -FE826F6CB2BCCAB72A65565C64BBDDEEDF12337D7CDF0EEA143B40BF033C541672790EDD71DF21\ -FF50AF0729498390AA5923C6E1D295A3F8D41EDC60C81956800EAB6B115A9A99C30C17AC4CC800\ -64420101410E76DE2D74E7C5B3F3BC780BA34C4D289A23587624C6E31B3EFDF9C292F1F080E3B6\ -42C65AABA102FFC85BAE63CAA050F41EE17050D300BA5D0B952860EE5BD3ACF1163BDE54C6AFE3\ -D58772FBD2F3FDA85360F462071F2717CE2AECC75F311D2AC56264FD71014F20B49E2CBF17277E\ -E857FF6AC531C006F1A6DAA6C82A15B2140959328A1E9D2A40DD03A02B850069040902A9E2C3B7\ -A9C8B13845C8786137B9EBF3AB06D6130682780248F10BE7C280:\ -FFA92041D1819A20B97BE2ED14D6D9C95FF0A4CC4104CFEABD575058D8B7BA5E - -F2592D6041113B82E0391FF3D24189FDC98F210B8D9C9C348B45B9DBBA0C0369E6175CCA2C2C55\ -067299C1EC634478F3977A6039662F83D19E8DE9085D8E2B45F350C536CDFA12394D77026BD45C\ -41DCA426720C5BE90C85F012FCFD04F06A4365587732090E6F6C52CC141B8652E92139106993D4\ -5BA95DB0BE841AC7C5747BE9B2443E8C646A3F8902CB1785AB56D8D4AC65BFE839A8E7AE57F845\ -0ADA0C8610EB3651DCEAAA11C17EE362C727DF460E89087AAFFA9A3D100EED9CD76331DDD3DF73\ -CA89B98CC7A4108B51C465735D902F5FAFFA8A4AE6816CDD628E59DCE1FEA96DAF017816651390\ -6FF735948F234EED61BF8F462E8ACDAC526BE26FB27D8F2EADD5E7F3F5C526A90CF2ED04C3F192\ -C5B800DDE45F9B63B11B6E64D4CCF2894ABD6F3353B8651BC3687995F044323525303422918AD5\ -552E0DAA2B33CB0CFB57F5817F85E140C7AB1CC1FC8084A0E03FF8BA980FE0245F55354EFBD28E\ -7EF646600CEDD1788CBE5A80EB0106BA7C7FA86D5E6751D9143E23641937276654ED1DAFC014D7\ -D0CD7DC71EAE3310D6656C41B92A9F6668932631C66CF7B70A9FD8295E888FE1780305158319F7\ -B78635BB355A54A930BC15A0626F2F85817D442D105CEC47A721276B37E4B82C17AE043EE4E4BE\ -B40CF78B72CDBF10253CDD0350673C7B91AFEC2B4EA18EF4E5E2B5231E95242EBD724FC6E7CD34\ -C3866D8F0C90065B821FD324DC2A5AB68220C6E84A6A99B2804D2D34D69C69AB0B8E5387EA38D2\ -9790FB5BD56123EC22A554B4F1D5FD3BE0A94956C70E39896D0745AB0918CA91045C128087A8F5\ -DFA7CA84DF416F3616276BFAB9B8AE44C5CE25B9F85F160971189134327017F776BED33130D33F\ -FCE5622D8A6144EB4EF50011E895DF9F068716C810C27F94815421B8247802896106F647FFF5DE\ -7F64AE9E26411C76F7FE75ED8413E9DCC95E8804E93E9C388235610C41C7D627210FCD66E5306F\ -C11F9A9DFE688379AF64EE7AE958948A7DA7013B78AF8B01EEB4C2A6EB7EE8E6FFB178F5AF8A00\ -0E31B5ABF3E44BD7E45F5E218DF8FC14A19EDFD7E0DAFC455C7082F77D6176158704036A14061B\ -9A9D7D0647C7B16E20A8566A576025A7A7E9DA3182A9F6723CBE34E68388B7D56B7E902C584758\ -F5D07FFDB5619C82A035F269E16F255B746800D4B1A3B9FF83BEE4A59C74A69EDB9667F4EC272B\ -DEAA6BADF993402CF0D23B0D07216B9348110E680F92FF7230916D8357C7D79757BD337BF60925\ -CF8611D74FD3164E2648AF0CB2C002D18CAF2092C576CA4C95E62016C6119E7704F3A5B5B28B19\ -854C1B0A4BB7762496DC6220AE0A6F44C56CCF1B9C0E323BD233F31307642E206D0CD34D2DD8AA\ -980089034B81E0285910F141A3F29B40CB9F498A5646DF2258755B1654CBC8D6B80F3F0589EE4F\ -3330EA89CC0E6AD4A3D03162C82C5061404916E41C8C1EE316448B:\ -83E01C097F00DD5947FD07BE085E895903E7C71CFE764B6CEB89082B8D6E3374 - -B1CDF8A2B282E91E1AE01820301C5F1DD5D0EBB570E138EB11FAA542A2B86DB01B4285F6BECA7A\ -85E2AD2D4B5753924B754E7EAB1DB2E0BEDA35E1B20377A54C8348C69AF9166646D0B1A2D8B1BE\ -0218A7259E920897260DFE80A53974A2E5D3B1CC45FCFC101A24F251868CC722FFA1B3283FB0DA\ -C1EBB74E6771A99B8CE08C86F28C745EAD0BB77A38BE99EED08354FF0B90D13779A43BF8499EC5\ -323F3ABECA3CFD7328D634F08E16D9FACCBCAAAF7F5A3ED47A4543983F3791CD0FC9562FC6516D\ -464C7936A7936A3BD8341C33332A724C1E89BC0A8CF968FCA37C70701675E6716AA77936E5B688\ -E09C7448F6CEBBA4E91792AB528BE434A90C3A984AB7AD43A82622EB7E7845251A9D93DB7E2779\ -73E8372EBF75AB4ADAD050C4CF43C57DBE7460D688D8205DA51B932DF163D800C0D687989990A9\ -946166B2C6A8F89FAC0D42FF69A0BAE0199189F2D8098D14334F4A99DCCACAF0182932FBF371ED\ -A4B197155AD1AC156370FB1B292949668A58AE03CD79215D8F1CCBB356ECC40D3669C5489F22C0\ -E9716BEC20DC83722BE2259DFB6640D6827756065E041ED0448C07E971F88BA783C41CDF68F4F9\ -5D7B5EE8630054BE9F1664D2E3A3EF027E59A0AC254E9E87A6DFC124C6A5E4798CD4504C496C19\ -C06B76B80AD8A2C66D96EEDD2104B83BB76904BDAE883F0EADE666C052D6AF802397579166ED76\ -2D6F4264747F655B9CDD88BA3595FA9580121B27E2AEACBDA2C95C6861181DBF457054381A30F6\ -FF7E8E62626B78F66B70BBDBA0F0B91892DFCCF1AB7813239A2B7EF6AF03407E0953D1116E1ED8\ -BAD1808BE008524A3C25244A5937528364DD85F055D0881B487C3CFE6272ABB894EEC92CE3FFE7\ -C34A60D6B1C23B2BF7AA3391B9090539D3EB5D7C51D85BD1A8E4F834F1C31B74BB45B6AAF31AA9\ -13DE1FBB5E65C2C7B731BDC491F270B884FBE9326CD3B6C0B1E2DDC4995E3ABA7447E457D724E8\ -999D54E881D4B79A992EA0BF6B8F60B53EA8ACD8DCDF9BB8238867A3A1BB90AC2B2D521591AB61\ -6E453D9E3CDBAC503AF94031D7CFD2858DE20E389B40EF0B677704BF95468ADA429E48984F7A49\ -74D534A3ADCE84EBFEE91263CC87317F9C465DA5E4EFCF0034A15278C6862168356B2BA5BC125E\ -4066154814295CD7957046E76FAACD30FABA296E1A78F7FF658669991C973FE25D4C51F8D1150C\ -8B3D5FE0B19C5C7A29C08445992B46ACF06008221B3FED8DABFA26B064D4DC92EBC1135E77905C\ -148FB5EEDE88A5A7D117ADC5406854774008ED44AE9CEB16EA398BDAE1E1BFFD6D7CD04CC2B3FB\ -AE1CCADEC9F6A58CE2FA4029434454A17081FCCF3323BBA91D26EC4C3C09DF34D6A02C6475B9B0\ -E9E31D7032441D89B2BD963A63CEE6068F965D94555B544648855BEFACE42CD49E302C1B6C43D2\ -20B1C8F677F8ACF89DABE4C265F55BC13BCF71F61CBCC2801259BF7E:\ -1331D84FDFB3161A753E6BE1C68BF78E2D8ECCB1281AEF8C1F12916352400452 - -D0CC18AC8DEFDC7089C8F8DB0298A33BF79007BA72BB0E2C57E7FEC1CC27B8982BFC06DF3F7FD0\ -9F0D33F921FD4D7522173B56AB09C48D71F846BF4546B44E219CA1257633B17C50B23EE8D20C3D\ -02360D5C53F4A32AECBB40F821D06A18903DCFCE752CCB356228802EF85165C61C6A78B5A7C6FD\ -7FBB8A3B9B9B959B7CAEC308B027629F926EEB2970032CBC906F2EE71B0063D7CF184887138B8A\ -F53D8002D26A976837186CC35CD07A31F3121C5815FC18F5CA559E3A5B42D32D8889DD2BBCD931\ -790105EE9174D72CA975E310CC3C7EAD6EFBA9B6E59B45ED1AE587032721F126C0CA38A7DA0667\ -961AA98D1C161177B322A79E5C14DE1C74495357906A8D72C7D418956C83D09176143D797B446C\ -DBF864EEA1A1BB17322347E3326F8493DB05F57AE72A86129F019B44DA6854914FFF3533A58A4C\ -D359DA953CCE3E8A9EEE35FE94D7E0DD3F9CF24762B5893B648C9EC1E12FFF96CB76C91A20D01A\ -70A5CCB2903C444AE6C9E99521F0D2283CC458363F6A289FE7503ED53800E07545C04D27B6DA4A\ -7B400C6F3F0506C46CEBE5D0B2EA251A2B415FA70A6F57821D6948790B869DE010D533B6467270\ -E246FF80B75707D2E3710411ED327C35E8BF666EFCDDA33F4317C78AC8B09BF60C3FAB9408B097\ -356DC4383D2E2F1332764DA26E5256098372F2192689AE9CA20072DD1D04F84ACF52540EEAABC4\ -26E0477B78A1CFBB5B0254B9A9AD983F5AB84DCAAC930CB0A69006518927B90F19BE83780AAE58\ -4CAC65626B450775050C82F31E148BC94F8D6437F42333E73F83C7F48D4B6A7DB06202A754D636\ -7CD29C75C91ACAD7B0BEA07BA03B9F7AB7CF7B9D4C573125AE50D41C0F5A11E23DC1C09AD02A7D\ -7408EA411F43F1CBB7B147D1FDB761FE097887461A1AD241032B52E2A394268AA334C033DF5E27\ -23327EACAF1C01541746327212B8BCEB2790EA1B80DB34C3449B62043355F9E1FB82EBE9A6E3E8\ -819B3458941F9092F713619ACDC961F3D88BA4A28D63601612927AC1701210DB67736FB565F462\ -9B55F542DC1A124B2E57D89DDC4E1FFBB32BF9AE517C9655D57101689D925057BD83B66E03D116\ -1A3CCF6575909D94D6F8C1102067ECC4314B7C2D1B00A39A6DA544A15306F348BCAE7B7FAEFA53\ -E843305F73155C2F1C0BD3B84C935C2AF2F7463AA9EC10CFEF72669EA30AD2D8ABAEBFD8DF992B\ -0792C120E302F86E4C42629BE2F866382CB28E1C5F3E829D2562CFD1476FA8E4A38471BCD7C46D\ -DE3BB0DD0CB87B0A583E5F560374B7E85B5B6BA780EB872839B7BD84B4DB4979F5F579581DD6EE\ -126CD5D426C74E9AAC605B6D147EAE0DAFF0CD5F30C465D1801C2FD776655E0C7DEB8A8C39933D\ -7E441B90CE308CE40A6977F6F1DF6C7BE079F6641F3042C973197CD98E374021CC57245C25A34A\ -3004D7C26127118C035019C87A56BDA4FC3407005594976864D161B39B:\ -8874AAE5A4315343B396F469732C783B277FA0BE98C454056EF36E203DB18161 - -7D3EFC597588B87152A6010670F36C8A900D6C217126F56D5903FD7ECFB23B5F06947272BBA7A2\ -E3C4084D2B49F82A2996F8AA26A1C8EC56DCC994101DEF03B15BD48B56DAB2A7DE37FA8FABC475\ -659B2E465FAAE217CFFB75513D40141DAF882B98AA009E1B98B360C74E3749535A553E829B595F\ -E14C0287B068C309DBD7D81F7C2A415E8107F3A9376EF901D3B8869D5FF5553567AA57992DEDB7\ -553E582E70BD2F62A22AC87A965D74FEDEF061A891A54D58D8E9046A4D6C7C6D4A0E78219C5E26\ -F93F9DA39E1F7F7619E931320C6AE0598FDEC957E8C2B055D428C822FDCA8C8EB6788BD957A2E9\ -87363C38DD83AB4E04B5EFCE9A69A09C14BDEBB72096EECF49E26DEA6CD0B3E8F8B347C1E217FE\ -9EBB2FD01C4345285A29DCEDCD0F5DC4C9DBC0CBC8A27AED672B20E085C3DCD5EE6BBF9E445A45\ -F9A1A247600AAE5B57BECF1539FE4C87D5929DBBFA1D6E5DEDF4FC358F49EE11D4ED73653042EE\ -D46B384B23307E01923F2E61D72A92B0BA66CEF763CD173C92730495359B3C939851884EFF82C8\ -1004217D3F27784C65C42A2040D72A8715E02FC3B33B596346DADAA94803244746079678A8B376\ -51FD1B39A1B677B69018CDBB656652249F91C139070C99BA849362B177054C28A55B385C4CF338\ -B13B232DB877930C22EB3F51CE070C4314CB679D4583E38931802E105FEA524BB2A2877ED178E0\ -4536C2F9679AE7C564A3E8A3EAC08E6F8B15EFCEA58942B5690DB34B507D7B111CEB47E8BA0875\ -2DE21A41F47147B7D507A3A1DF5E0F9B0DB36A7D05D84869745C4230680241E294D689653119A2\ -2F2FC5C0C9E98697A92E3513A6430908360FB0EE43A2F9718773DF7CBCBDD54E420A7193B95EB7\ -881C98CE177556BE37CEC861D56A11F77C656200EA7605AD5AF3FEB065EB8AB88E0A38034880F3\ -A2660784A701391E71A092B2DBDE145F6FAB54CFC39E3E79C3B9E54FB31EBD0AE42E0FBC9FB761\ -A3456557087C9BE253D179C6D08B90DF9F871BD29B125DD2D22F7FA4A104559699B1AB1A906C8D\ -56AE853A31607EA1EACB0B1D41F1D971C5ACFA4705F61D37CD1D808F8B0DECCCA66EF01AACE0B6\ -1974F49504A4FE7AF474CC338DB516302484B1CBEE0C8DF5143C42628AC09388C8E822775829B9\ -F5B3FB2F72448A5DE7265885A3B9DB6FCC0349B3863D01DD377BD60EFF49FAAF3C508576E34FC6\ -1A5E0F72494E45942A43FA424AF438F687DF4747632DCA34294813F6EA10009510005AA7A1FD60\ -12E94DB7CA439EC242F5C5FEEFE374EB967670D2D019589B3DCB4B41290AE70F339CDF7EEDCC71\ -927973AE9E25D8BDC0D74DC9C9E1AB8F2C648808A78FC88607C3D1BF59A5F1047F8F7419B18445\ -8742C16F7641DF79896B4BE4ECDF52BE5BB831530528D8FA0218ACC94357DF588DD027CF1C8E90\ -61DEB12D5FAF24CC59FCF6AC5A04D675AB809B88895C862BC3CBA615BC1C:\ -555F6602A47B634BEA410A9A92367748203B9FB16ECC130503F69616B66F011E - -42F3B684726E0A9E4FF5470A725DB94AB290A477DC9ADE1E3D42C4D68A3597D0E60875D1700269\ -1F5B62365CA19D4FAE96AB779E86D89AB13D46A3E90FF99DF8ADEE749BDC43EF6514241C57F32F\ -6FD153E5EC5A8854A18342639A8C0EDE6EDC6D4F50953440B939ACC3476120AFF3FDAF71663FB6\ -BE71563788668A87A106DC50ABE0158DFA0B173DDF032B44059B59E29BF438F3BCD47E4CAC0872\ -3B364BE9CDAA4AE88E54C6E2073C61F6397AFF910DF07DE05AACFEA0DC2A82C0F43D79EFC02355\ -735F3588FF13DB6D2FA5BB8D3E114B631212C560049ED9D31B890538E670B81C2E7E87D141539E\ -278A46A1E673DCB7410EB6F84CFD046665EE86FC8B256315B97262E5D90935F21E3DD17AF226A3\ -B3E2F035C64A1EEA1EE8A31E5930389A6057A1CEFB2E469C5692CAFBE39CEBF111C581A05A1AC9\ -30D3B9CFF0600FC1B96F98FD302CD691BDC5A2A24E003E67DC36D148F275E771CC2C3D9C2107A2\ -1095B4DB6AEDFF04D5AB06A2A4DEA65F4DBEC42A3843F67748DE61F00FCE264F38B28B9018FE80\ -C34788DC79674FAFB67CD49E7590159884967AC1917E6E3F27AB231BEDE67170EE458861F14843\ -6291FB892B3795F539FBBBF7115445CD8F08E2E383C85ACCD376B26507009F741D198AD4BC5CBF\ -CA3FF5D56E9202F5494B521B08799C890F3A6E6D6348817BDFD3BCCED8119D1A64EF2D02265A6F\ -C1B95BADCC295B8304804C30EBED369EF1CD253EC0025D15203F129D47394C1452DDF966408C73\ -88EB0AB7974A23D7291231F7D0C07CE2F8A66F51401EC8523F4F178B7C7473C50C67E7ABF06897\ -3D453A12C82210E922746CEFD08CA5664687D762774524B5725128CF8F29FE3C339793A1E1A0F7\ -B9BA698714AA282A4E298EC80E1550D6003B9309577940002A91AD200CE646A649784B17049758\ -473F48A9A5647CE099E65002B1B76EC05D3C81350088C7E4C043E542F2E883577AEAE24EA671F0\ -718C5A35758D07B71CAD44B7953E18A746ED7073AD9044F6AF4245424A792E09453B363ADD4226\ -F7FFD6E470D223AB12F65A9C917F3282E5D64A83DF20F22843BC9652C9C89EA22F74CC9BBB0097\ -61BBFC63FF7796C92E907537EEEB082711FAD82820FCFDCEB964B863259D049298B565112E4784\ -5595CA483E821F996512B3AB83A613A8E2F5296021302AA068CC59C8093BFAB264886C1060229F\ -E043B32E85EA44E15A81E6FC5DE4F05C91B714783D948F3E90D3B801F503F839319696FF956680\ -3FA407FB32FB6EABD2AEF94C76CA5D7D20FECE71E9E6AEDD6436FA194FC61B39495AB75EA40287\ -5686284F4D03C6DF78B95831D622859FA67B12EBC2DD1FFD5C40AE485AA971A87ADFED61D19AF2\ -F9671B8464E1F56733E3C1B98F4F70FC3CBB4E549B3437B1604163075B24D7208D4BFB11C66862\ -0CF8A291B9422AD7CE1551A65D82A2DCB00475552852D4D7C06831FD51B802:\ -D0D1561464EC8C59AE1313C89CAA89CDC2A7A0359C84B2516E873F5B19229C66 - -780DEDF7FC6C135550F524F4D84B33B769F58E7FFECE6CB25F497A87D6E5FC912F4E8A60742920\ -8CCE5A4B6657AA2830DFC8C1E9492DE204B2ACB9B42DB884A6F194FFD517DCAA205647B27A0E2C\ -BCEFB357A55F3F0D35CDC83956CDA8A9D021D694FB178C44FBD9B4003D11BAE011FB4131635A27\ -FD26C75B0523EEE2ECE6D8AFB6C76280E0A3F2C1B0531539DC020698F7466F959D6CB6BD1B0F84\ -B17906120D40E6D8DB675873FCA7EDBC1409F0EB5A759767F9F5CC01FE006586EAC27A4D4115E2\ -FF92587DE3F2F6C09222738DD99945348B8B9F6427848DF4D31EAE22FFC4BBE21ACC896CD903C3\ -CC0DF9A49B9576465AA0D8FC4F40468B41481A5AB0FA47CE1E85BF7F9B418E90DABCE9B655D183\ -B06044C92CB050EA223D2F73778BBC1B90945EEBBBB7C7238A78BCAC9A0DF94CC2FC667E110936\ -DE714855F3AAAA3D60615134868BE0715C54F39D26E9A32019684299A71358125174C6A33385AF\ -5283801FCCE195913E56D7BF2F806633DFBF11674E970FEE95B53911D46045DA1F8FAA841ED16F\ -E850949CD69A13A3DEF631337958203B39D3C1C748F96AD7E0E8F24D23AACB23624A1981D845BF\ -89F56AF58FABA2E9E6513AF5DED200C62092EA5CEDB5330B0229B4667DDDFDCC635E381701DDBD\ -55480E935460D18E94C78C2B1D1D866801E203850B8833A2E0AE32E43FBB28AD255A3D31296A34\ -8DDDB983EECC0B0D84958D1B0D95EFC39EA075AAF25595F4FA794A0889EBFCA1E57E92E7C2180B\ -DF90946D6B2A8607DA10FCCA868F6E24AAACDBD3850B44C8D8D7DCA15499C6C33A7741BB5203B3\ -9D001C32177F7C060EE5B43AB4BA9F8A53AFF79E55A532F78832446216E5484519D87395A5C0F9\ -AAB59884F8163AB732F161CFA23307AA2646C3D4C9D129C2A9173E427741B4B7B23F8139354646\ -778B10F97781953C2473FC277D3F0DE097ED9359E83A33AB01DA298741CF9EAD9CD297C0A39AB9\ -BE72D5621A06D990FB175E7E10D460245AAC744965CC2CB520B93FCB02E25DEAEBA92E9EDD0AEA\ -6DD8264D1609F3AD1990627A4E33A73257723F2405A393F1FDE2EF7935F9A41506B437DD9D2813\ -752301AE513502281CFC635844D3F13F532F3DAF403E8AA70DF3CFF67520B00EDD0D0E53A78827\ -043511256A6464CF6E3FFFDEF8C0522FF17915189E4D6377B9CFD3BEB52CE73F4A63CF262AA071\ -6C2EB5F3D9FB5E5E39D072E55DB768498C80BBA3D11E1ECBB89ADFD7EBF73030AE102BD7D5D95C\ -B4599706A0A9348EF65D59FB0FB15143C0896EF64946BDE0E5AB7205F1AA5030CD960CB4F21081\ -E3A0AA1DF10CB6DF811B9E70E3F86581092928A25EF64929DDE63AEF555F4DF0E951AE6E3C41F5\ -C1B1E962E1DFBC1F30458B7574F35A3346103C62461384354DC9B2F98497D1C4987D3CD45D84E6\ -B392DF9E0A2AA8559EB4F597DD759E8323CAF7CAD0D41A69163871648927D6FC:\ -37494F0A17C7164E023F6409B4AE8248D25391910AA24BE3F116D4A44CCC02B4 - -600BB1C53869CD6912501049B9A53E112B5E6694F39504B56C965C915DC20EF170CF0F1C9E638D\ -56BE11694156CFEA74E2BC7C14AEB360A984E29067A36D011EB1A3541B97009C5642E64916C357\ -7B4BA5C87AA36ADF41D712E22E94BD8EED81629BD548AA69624155A131654CFDDAA4D758341EC8\ -F8021B4239A1BBD9DD7AE777D903F0AE8CD332BEA85DED4A66B8140D1B694EC08E238417E00C5B\ -696008E5652C9884347AEBA3C28B58AB8B955C2849234A431C71B0C3A58BB2619BF2ACA0FFFCC1\ -710673C3EE0FEEE5E091ECCA5833F4F37E8509595BA2BF1BF7437988BE4F63C7E613FAB270149E\ -8B37FAEF45CB23E4106E6502D97135A5B7B36A7563BBDB18D4C37DF72EEE79CC4758D08ED7E0F8\ -24A3CF4C3BF116F4D7D7D60EA0A819E2FCF832E7919BEDE619C64228F9A32C885FE92A7600FCA4\ -B0C74C2BDB2B18A210A2CBEC520960EB5BD53EB6A53E01C4D4B16EC421449360841294CCA5BBB0\ -424CB8A6F6A87F26FA5A75E04BA9646D80574DB61A2D8C38534E9CEC4B85D36A105B3D3F9E2A0D\ -1C935FF8EF962F3EDB09FBD6F626C42E3EA08FC8A24122FEB53182B45098BC4644F64BDA83E2DC\ -0E6886167F03852A5783497FED6C5C8E41FEB1B0BE701139458529ECEE21F60C643CCC18ED07F6\ -95E54A3341128E1CA3A6C171DE7A2E1C50BB2C31CB0DCF5584B36CBB41B40C41E5F3719E7472AA\ -3D241FA27F212FACCD1D720B6F1D1DF4477D7A473C8347F73026E32BE78153BB975E8A61F888CF\ -60DB98888FFB5BAFED7EE92E3218747D83E5A248ABB756ACA331003C9BF27ADC5E273626060C34\ -C1E8E76306C9C7A6E4CAAE08BBDE5B1CFDB5007C10250862A4F2F5B8B58A7F8112EED4D0850CB5\ -BB2F9921C49776925D2B74F0E83ABD85E5BE986BE661C29266094CE3959232CEC6D9EBA553AF9E\ -1B70A55BD4C720D95366133576A11EEE942DAB0722538A7CE32F17B8EC2629F69483C90F3A7417\ -63CF953681E441D5E567341130A5EC5B8F36AC35725E23A6979907AC337D03FDF6AC75EF4856EA\ -D4E18738A26667196F6CD15488291F948539C8F8F018387528EC6B4963F0A3E2AFD1F4F56F1253\ -DE53F314CE4572CD6814B7E2B03EC0D88C1CD737952DAC1D85F8761E2FE3DDE9929C859B9AF957\ -FC8F78C5878243865983CB3E3CD76AD1038DCC5AD04C754FB649851A50DE89D76FFA4537BBEBA0\ -82017E5840D20F2FEECF4C1DD9B409EE4C9CEC91ACA81115BF90CF4784C998FA3A1FF18347520F\ -307E52D67C596742B677B6CCFEA597D787B63708181C765EE28328667516AB7B75F3A655810088\ -6E923F2B94D730C51A05874D9B944B458C95DA87E071D753EBADB54D0876CF387A70684ECAFCB7\ -0BE1FF16618F0DA96DB5070215B7BBCDB4AADCB7BA825538B3FDDE5D55C0BC91EF7E52072E62DD\ -1E3CD2764BAD4DB94F9C:\ -8E58A67D528725BBD8AB846914F9A31961C90BA68765F872F785FF59C4EF0D2B - -AAF2F5BD8D412040B7B7F0C638AB081C9B4F9EB542CDFDB53C0D156BEEDC811A9F9838CE32D42A\ -DB83BB1B5B83EFF374B4FC8D64FE26FC94BCA43E812079AD8C33923355C634004E10449309E9C9\ -0564887BD27A5CD0839F159CD56087913D05D48E6ED6B80350B09B3A8FF426B777FD8FCDC72C22\ -ED7308C448E6D4A28B3F0A1BC23C300E228E4C3530C98F507106D5D526253C7D49FBD5D84D20C6\ -67E346224E2F890C947F56AB6538B3AE6B297EA1AB5F33CD43A8C1654C1DFE7AACF7E7DD733C09\ -68DFF6718CBCB537FE742C68B220F243A750FB66419DB03F48AFBCCD68798CA4A24C2E49BCF380\ -004EF6B685E528F3C2FE79CD3DBB9CF88D7DE09557D10459823B5BA08F31865B5A055CB5FA58AF\ -3D849A4CEA6F7C23C9BAB07EE0F4B330FEE01BB3AC55FB5882895DD1DB086CA37064BD8558DAFD\ -B26F34ADC8A560A9B9E845BD3D18DF8C528261069332D0384C04A09CDC9AB9B631D88B06133E65\ -F1A8FDF4E5088BF2BE5C970FFC80DEA689EA3B67EABC5C097880594A0406F21963D9C2F3FB52BF\ -621019BD1F69CAAD6205E44B5D414B73AF9671088D6DAFD728351AB9F6D9C255D9700222ABEF98\ -14DE1571384DDDDD7362BDF06F3E5EA35FD56E0DA288DBC8C80CD585024F3BED4912E6D5CABAD2\ -0250A51F3FD1A25457ED07B3F652FDF0CD8F6DA583DFE780C6B5D92333DFEE4DFB22A3B4DDB141\ -BC385B0852D9B92198A8F2DA49BA0F119CF183E40EDD764B418AD5A880DE5FCCBAABE0785C8E13\ -4E03204BBE0F991A8B54A44633AF79D434BBFA0FAFDD1FAFE1071964169C712D51619C8E9EE8CA\ -DF9E54D7E61BBAB8548D9D2C53CA22A4938F8AA8EC5FDB5401276A081D7C0906556CE98AEABB5D\ -5989BD97C689BA83D2B2197298E155A0FCCA5A42355FBB6BA619783E6A1E343ADE8741349E315F\ -1BE78D1E3969F0FA6DC147C0880DAA7F066B18615F1F88307C515BC82CBE38A1967157D4592F63\ -C738C861D92348AEE550727735F0B04006CEAE3E083629855FF75332A9BDA43D2827AE97BCED1A\ -3E015AE79425237069D6F630A247B9E906D5352AC4BC486558572E876EFFC1BFBA7CF90A6C17AC\ -6AADA8B3C7D0374DEEF1D8D0CC8E4C2A7D86ABC5B6E0EF7D047AB30A6D801C91B3A84799202923\ -A7B6B1966884C50F9A2FE3A047AB588B86C70128B0A1D263751DF699C2D152A1F8B70EE6AFBA6F\ -F9EA240C4D6047EED74EA06FB885AD468E6C9D5ED4444FB1EB4987F966CC1EE51DBFC269CCFB81\ -47162965113DF7696A9FE1911E569A5E221F0B915EEB34E689F0FEA7655A179D9506E0787C205F\ -BD11CA9802E5A4D4B3F8E9D270BE51E75718BB17BF3099C8F68637059009757EAFC48010A66E1B\ -A572D774628B4C35E06F0ED0DF055F27C054B4A556B1ABEEB076D5D502390E1C31E28555BE7F6A\ -6ED4B49FD7CAB793E4BC:\ -B97C3815ABA1958CB4A6F64B3DDA017236224597101DD822F24A6A594F255973 - [GOST-34.11] # Using the CryptoPro sboxes. Generated by OpenSSL's GOST code diff --git a/configure.py b/configure.py index 1a6eb1e7f..ffaa525fb 100755 --- a/configure.py +++ b/configure.py @@ -40,10 +40,12 @@ class BuildConfigurationInformation(object): """ version_major = 1 version_minor = 9 - version_patch = 8 - version_so_patch = 8 + version_patch = 9 + version_so_patch = 9 version_suffix = '-dev' + version_datestamp = '0' + version_string = '%d.%d.%d%s' % ( version_major, version_minor, version_patch, version_suffix) soversion_string = '%d.%d.%d%s' % ( @@ -160,17 +162,17 @@ def process_command_line(args): target_group.add_option('--enable-isa', metavar='ISALIST', dest='enable_isa_extns', action='append', default=[], - help='enable ISA extensions') + help=SUPPRESS_HELP) target_group.add_option('--disable-isa', metavar='ISALIST', dest='disable_isa_extns', action='append', default=[], help=SUPPRESS_HELP) - for isa_extn in ['sse2', 'ssse3', 'altivec', 'aes_ni']: + for isa_extn in ['sse2', 'ssse3', 'altivec', 'aes-ni']: target_group.add_option('--enable-%s' % (isa_extn), action='callback', - help=SUPPRESS_HELP, + help='Enable use of %s' % (isa_extn), callback=optparse_append_const, callback_kwargs = { 'dest': 'enable_isa_extns', @@ -208,10 +210,15 @@ def process_command_line(args): build_group.add_option('--disable-debug', dest='debug_build', action='store_false', help=SUPPRESS_HELP) - build_group.add_option('--use-boost-python', dest='boost_python', + build_group.add_option('--with-boost-python', dest='boost_python', default=False, action='store_true', help='enable Boost.Python wrapper') + build_group.add_option('--without-boost-python', + dest='boost_python', + action='store_false', + help=SUPPRESS_HELP) + build_group.add_option('--gen-amalgamation', dest='gen_amalgamation', default=False, action='store_true', help='generate amalgamation files') @@ -325,11 +332,11 @@ def process_command_line(args): isa_dependencies = { 'ssse3': 'sse2', - 'aes_ni': 'sse2' + 'aes-ni': 'sse2' } if 'sse2' in options.disable_isa_extns: - sse2_deps = ['ssse3', 'aes_ni'] + sse2_deps = ['ssse3', 'aes-ni'] for isa in sse2_deps: if not enabled_or_disabled_isa(isa): @@ -576,13 +583,14 @@ class ArchInfo(object): Return CPU-specific defines for build.h """ def defines(self, options): - macros = ['TARGET_ARCH_IS_%s' % (self.basename.upper())] - - def form_cpu_macro(cpu_name): + def form_macro(cpu_name): return cpu_name.upper().replace('.', '').replace('-', '_') + macros = ['TARGET_ARCH_IS_%s' % + (form_macro(self.basename.upper()))] + if self.basename != options.cpu: - macros.append('TARGET_CPU_IS_%s' % (form_cpu_macro(options.cpu))) + macros.append('TARGET_CPU_IS_%s' % (form_macro(options.cpu))) enabled_isas = set(flatten( [self.isa_extensions_in(options.cpu), @@ -593,7 +601,7 @@ class ArchInfo(object): isa_extensions = sorted(enabled_isas - disabled_isas) for isa in isa_extensions: - macros.append('TARGET_CPU_HAS_%s' % (isa.upper())) + macros.append('TARGET_CPU_HAS_%s' % form_macro(isa)) endian = options.with_endian or self.endian @@ -899,6 +907,9 @@ def create_template_vars(build_config, options, modules, cc, arch, osinfo): 'version_minor': build_config.version_minor, 'version_patch': build_config.version_patch, 'version': build_config.version_string, + + 'version_datestamp': build_config.version_datestamp, + 'so_version': build_config.soversion_string, 'timestamp': build_config.timestamp(), diff --git a/doc/api.tex b/doc/api.tex index dc920d07b..27bed084e 100644 --- a/doc/api.tex +++ b/doc/api.tex @@ -10,9 +10,9 @@ \setlength{\oddsidemargin}{0in} \setlength{\evensidemargin}{0in} -\title{\textbf{Botan API Reference}} +\title{\textbf{Botan Reference Manual}} \author{} -\date{2010/02/05} +\date{2010/06/14} \newcommand{\filename}[1]{\texttt{#1}} \newcommand{\manpage}[2]{\texttt{#1}(#2)} @@ -39,6 +39,7 @@ \parskip=5pt \pagebreak + \section{Introduction} Botan is a C++ library that attempts to provide the most common @@ -51,100 +52,58 @@ minimal fuss, but Botan also supports a modules system. This system exposes system dependent code to the library through portable interfaces, extending the set of services available to users. +\subsection{Recommended Reading} + +It's a very good idea if you have some knowledge of cryptography prior +to trying to use this stuff. You really should read at least one and +ideally all of these books before seriously using the library. + +\setlength{\parskip}{5pt} + +\noindent +\textit{Cryptography Engineering}, Niels Ferguson, Bruce Schneier, and +Tadayoshi Kohno; Wiley + +\noindent +\textit{Security Engineering -- A Guide to Building Dependable + Distributed Systems}, Ross Anderson; Wiley + +\noindent +\textit{Handbook of Applied Cryptography}, Alfred J. Menezes, +Paul C. Van Oorschot, and Scott A. Vanstone; CRC Press (available +online at \url{http://www.cacr.math.uwaterloo.ca/hac/}) + \subsection{Targets} Botan's primary targets (system-wise) are 32 and 64-bit CPUs, with a -flat memory address space of at least 32 bits. Generally, given the -choice between optimizing for 32-bit systems and 64-bit systems, Botan -is written to prefer 64-bit, simply on the theory that where -performance is a real concern, modern 64-bit processors are the -obvious choice. However in most cases this is not an issue, as many -algorithms are specified in terms of 32-bit operations precisely to -target commodity processors. +flat memory address space of at least 32 bits. Given the choice +between optimizing for 32-bit systems and 64-bit systems, Botan is +written to prefer 64-bit, on the theory that where performance is a +real concern, modern 64-bit processors are the obvious choice. Smaller handhelds, set-top boxes, and the bigger smart phones and smart -cards, are also capable of using Botan. However, Botan uses a fairly +cards, are also capable of using Botan. However, Botan uses a large amount of code space (up to several megabytes, depending upon the compiler and options used), which could be prohibitive in some -systems. Usage of RAM is fairly modest, usually under 64K. +systems. Usage of RAM is modest, usually under 64K. Botan's design makes it quite easy to remove unused algorithms in such a way that applications do not need to be recompiled to work, even -applications that use the algorithms in question. They can simply ask -Botan if the algorithm exists, and if Botan says yes, ask the library -to give them such an object for that algorithm. - -\subsection{Why Botan?} +applications that use the algorithms in question. They can ask Botan +if the algorithm exists, and if Botan says yes, ask the library to +give them such an object for that algorithm. -Botan may be the perfect choice for your application. Or it might be a -terribly bad idea. This section will make clear what Botan is -and is not. - -First, let's cover the major strengths: - -\begin{list}{$\cdot$} - \item Support is (usually) quickly available on the project mailing lists. - Commercial support licenses are available for those that desire them. - - \item - \item Is written in a (fairly) clean object-oriented style, and the usual - API works in terms of reasonably high-level abstractions. - - \item Supports a huge variety of algorithms, including most of the major - public key algorithms and standards (such as IEEE 1363, PKCS, and - X.509v3). - - \item Supports a name-based lookup scheme, so you can get a hold of any - algorithm on the fly. - - \item You can easily extend much of the system at application compile time or - at run time. - - \item Works well with a wide variety of compilers, operating systems, and - CPUs, and more all the time. - - \item Is the only open source crypto library (that I know of) that has - support for memory allocation techniques that prevent an attacker from - reading swap in an attempt to gain access to keys or other secrets. In - fact several different such methods are supported, depending on the - system (two methods for Unix, another for Windows). - - \item Has (optional) support for Zlib and Bzip2 compression/decompression - integrated completely into the system -- it only takes a line or two of - code to add compression to your application. -\end{list} - -\noindent -And the major downsides and deficiencies are: - -\begin{list}{$\cdot$} - \item It's written in C++. If your application isn't, Botan is probably - going to be more pain than it's worth. - \item - - \item Botan doesn't directly support higher-level protocols and - formats like SSL or OpenPGP. SSH support is available from a - third-party, and there is an alpha-level SSL/TLS library - currently available. - - \item Doesn't currently support any very high level 'envelope' style - processing - support for this will probably be added once support for - CMS is available, so code using the high level interface will produce - data readable by many other libraries. -\end{list} - -\pagebreak \section{Getting Started} \subsection{Basic Conventions} With a very small number of exceptions, declarations in the library are contained within the namespace \namespace{Botan}. Botan declares -several typedef'ed types to help buffer it against changes in machine -architecture. These types are used extensively in the interface, -thus it would be often be convenient to use them without the -\namespace{Botan} prefix. You can do so by \keyword{using} the -namespace \namespace{Botan::types} (this way you can use the type +several \keyword{typedef}'ed types to help buffer it against changes +in machine architecture. These types are used extensively in the +interface, thus it would be often be convenient to use them without +the \namespace{Botan} prefix. You can do so by \keyword{using} the +namespace \namespace{Botan\_types} (this way you can use the type names without the namespace prefix, but the remainder of the library stays out of the global namespace). The included types are \type{byte} and \type{u32bit}, which are unsigned integer types. @@ -156,22 +115,21 @@ should be used with the \filename{botan/} prefix in your actual code. \subsection{Initializing the Library} -There is a set of core services that the library needs access to -while it is performing requests. To ensure these are set up, you must -create a \type{LibraryInitializer} object (usually called 'init' in -Botan example code; 'botan\_library' or 'botan\_init' may make more -sense in real applications) prior to making any calls to Botan. This -object's lifetime must exceed that of all other Botan objects your -application creates; for this reason the best place to create the +There is a set of core services that the library needs access to while +it is performing requests. To ensure these are set up, you must create +a \type{LibraryInitializer} object (usually called 'init' in Botan +example code; 'botan\_library' or 'botan\_init' may make more sense in +real applications) prior to making any calls to Botan. This object's +lifetime must exceed that of all other Botan objects your application +creates; for this reason the best place to create the \type{LibraryInitializer} is at the start of your \function{main} function, since this guarantees that it will be created first and destroyed last (via standard C++ RAII rules). The initializer does things like setting up the memory allocation system and algorithm lookup tables, finding out if there is a high resolution timer available to use, and similar such matters. With no arguments, the -library is initialized with various default settings. So most of the -time (unless you are writing threaded code; see below), all you need -is: +library is initialized with various default settings. So (unless you +are writing threaded code; see below), all you need is: \texttt{Botan::LibraryInitializer init;} @@ -179,16 +137,17 @@ at the start of your \texttt{main}. The constructor takes an optional string that specifies arguments. Currently the only possible argument is ``thread\_safe'', which must -have an Boolean argument (for instance ``thread\_safe=false'' or +have an boolean argument (for instance ``thread\_safe=false'' or ``thread\_safe=true''). If ``thread\_safe'' is specified as true the library will attempt to register a mutex type to properly guard access to shared resources. However these locks do not protect individual -Botan objects: explicit locking must be used in this case. +Botan objects: explicit locking must be used if you wish to share a +single object between threads. -If you do not create a \type{LibraryInitializer} object, pretty much -any Botan operation will fail, because it will be unable to do basic -things like allocate memory or get random bits. Note too, that you -should be careful to only create one such object. +If you do not create a \type{LibraryInitializer} object, all library +operations will fail, because it will be unable to do basic things +like allocate memory or get random bits. You should never create more +than one \type{LibraryInitializer}. It is not strictly necessary to create a \type{LibraryInitializer}; the actual code performing the initialization and shutdown are in @@ -217,15 +176,15 @@ objects will be created. The same rule applies for making sure the destructors of all your Botan objects are called before the \type{LibraryInitializer} is destroyed. This implies you can't have static variables that are Botan -objects inside functions or classes (since in most C++ runtimes, these -objects will be destroyed after main has returned). This is inelegant, -but seems to not cause many problems in practice. +objects inside functions or classes; in many C++ runtimes, these +objects will be destroyed after main has returned. -Botan's memory object classes (\type{MemoryVector}, -\type{SecureVector}, \type{SecureBuffer}) are extremely primitive, and -do not (currently) meet the requirements for an STL container -object. After Botan starts adopting C++0x features, they will be -replaced by typedefs of \type{std::vector} with a custom allocator. +Botan's memory object classes (\type{MemoryRegion}, +\type{MemoryVector}, \type{SecureVector}) are extremely primitive, and +meant only for secure storage of potentially sensitive data like +keys. They do not meet the requirements for an STL container object +and you should not try to use them with STL algorithms. For a +general-purpose container, use \type{std::vector}. Use a \function{try}/\function{catch} block inside your \function{main} function, and catch any \type{std::exception} throws @@ -239,15 +198,14 @@ wondering what went wrong. \subsection{Information Flow: Pipes and Filters} Many common uses of cryptography involve processing one or more -streams of data (be it from sockets, files, or a hardware device). -Botan provides services that make setting up data flows through -various operations, such as compression, encryption, and base64 -encoding. Each of these operations is implemented in what are called -\emph{filters} in Botan. A set of filters are created and placed into -a \emph{pipe}, and information ``flows'' through the pipe until it -reaches the end, where the output is collected for retrieval. If -you're familiar with the Unix shell environment, this design will -sound quite familiar. +streams of data. Botan provides services that make setting up data +flows through various operations, such as compression, encryption, and +base64 encoding. Each of these operations is implemented in what are +called \emph{filters} in Botan. A set of filters are created and +placed into a \emph{pipe}, and information ``flows'' through the pipe +until it reaches the end, where the output is collected for +retrieval. If you're familiar with the Unix shell environment, this +design will sound quite familiar. Here is an example that uses a pipe to base64 encode some strings: @@ -287,15 +245,15 @@ used in the \type{Pipe} between each message, by adding or removing \type{Filter}s; functions that let you do this are documented in the Pipe API section. -Most operations in Botan have a corresponding filter for use in Pipe. -Here's code that encrypts a string with AES-128 in CBC mode: +Botan has about 40 filters that perform different operations on data. +Here's code that uses one of them to encrypt a string with AES: \begin{verbatim} AutoSeeded_RNG rng, SymmetricKey key(rng, 16); // a random 128-bit key InitializationVector iv(rng, 16); // a random 128-bit IV - // Notice the algorithm we want is specified by a string + // The algorithm we want is specified by a string Pipe pipe(get_cipher(``AES-128/CBC'', key, iv, ENCRYPTION)); pipe.process_msg(``secrets''); @@ -378,7 +336,7 @@ Here's an example using two computational filters: \subsection{Fork} -It is fairly common that you might receive some data and want to +It is common that you might receive some data and want to perform more than one operation on it (\ie, encrypt it with Serpent and calculate the SHA-256 hash of the plaintext at the same time). That's where \type{Fork} comes in. \type{Fork} is a filter that @@ -522,12 +480,11 @@ use; that is, either before calling \function{start\_msg}, or after \function{end\_msg} has been called (and no new calls to \function{start\_msg} have been made yet). -The function \function{reset}() simply removes all the \type{Filter}s -that the \type{Pipe} is currently using~--~it is reset to an -initialize, ``empty'' state. Any data that is being retained by the -\type{Pipe} is retained after a \function{reset}(), and -\function{reset}() does not affect the message numbers (discussed -later). +The function \function{reset}() removes all the \type{Filter}s that +the \type{Pipe} is currently using~--~it is reset to an initialize, +``empty'' state. Any data that is being retained by the \type{Pipe} +is retained after a \function{reset}(), and \function{reset}() does +not affect the message numbers (discussed later). Calling \function{prepend} and \function{append} will either prepend or append the passed \type{Filter} object to the list of @@ -620,7 +577,7 @@ using the output operator. Here is some code that takes one or more filenames in \arg{argv} and calculates the result of several hash functions for each file. The complete program can be found as \filename{hasher.cpp} in the Botan distribution. For -brevity, most error checking has been removed. +brevity, error checking has been removed. \begin{verbatim} string name[3] = { "MD5", "SHA-1", "RIPEMD-160" }; @@ -659,7 +616,7 @@ are documented elsewhere. \subsubsection{Keyed Filters} A few sections ago, it was mentioned that \type{Pipe} can process multiple -messages, treating each of them exactly the same. Well, that was a bit of a +messages, treating each of them the same. Well, that was a bit of a lie. There are some algorithms (in particular, block ciphers not in ECB mode, and all stream ciphers) that change their state as data is put through them. @@ -721,11 +678,11 @@ And remember: if you're resetting both values, reset the key \emph{first}. \subsubsection{Cipher Filters} -Getting a hold of a \type{Filter} implementing a cipher is very easy. Simply -make sure you're including the header \filename{lookup.h}, and call -\function{get\_cipher}. Generally you will pass the return value directly into -a \type{Pipe}. There are actually a couple different functions, which do pretty -much the same thing: +Getting a hold of a \type{Filter} implementing a cipher is very +easy. Make sure you're including the header \filename{lookup.h}, and +then call \function{get\_cipher}. You will pass the return value +directly into a \type{Pipe}. There are a couple different functions +which do varying levels of initialization: \function{get\_cipher}(\type{std::string} \arg{cipher\_spec}, \type{SymmetricKey} \arg{key}, @@ -736,48 +693,48 @@ much the same thing: \type{SymmetricKey} \arg{key}, \type{Cipher\_Dir} \arg{dir}); -The version that doesn't take an IV is useful for things that don't use them, -like block ciphers in ECB mode, or most stream ciphers. If you specify a -\arg{cipher\_spec} that does want a IV, and you use the version that doesn't -take one, an exception will be thrown. The \arg{dir} argument can be either -\type{ENCRYPTION} or \type{DECRYPTION}. In a few cases, like most (but not all) -stream ciphers, these are equivalent, but even then it provides a way of -showing the ``intent'' of the operation to readers of your code. +The version that doesn't take an IV is useful for things that don't +use them, like block ciphers in ECB mode, or most stream ciphers. If +you specify a \arg{cipher\_spec} that does want a IV, and you use the +version that doesn't take one, an exception will be thrown. The +\arg{dir} argument can be either \type{ENCRYPTION} or +\type{DECRYPTION}. The \arg{cipher\_spec} is a string that specifies what cipher is to be used. The general syntax for \arg{cipher\_spec} is ``STREAM\_CIPHER'', -``BLOCK\_CIPHER/MODE'', or ``BLOCK\_CIPHER/MODE/PADDING''. In the case of -stream ciphers, no mode is necessary, so just the name is sufficient. A block -cipher requires a mode of some sort, which can be ``ECB'', ``CBC'', ``CFB(n)'', -``OFB'', ``CTR-BE'', or ``EAX(n)''. The argument to CFB mode is how many bits -of feedback should be used. If you just use ``CFB'' with no argument, it will -default to using a feedback equal to the block size of the cipher. EAX mode -also takes an optional bit argument, which tells EAX how large a tag size to -use~--~generally this is the size of the block size of the cipher, which is the -default if you don't specify any argument. +``BLOCK\_CIPHER/MODE'', or ``BLOCK\_CIPHER/MODE/PADDING''. In the case +of stream ciphers, no mode is necessary, so just the name is +sufficient. A block cipher requires a mode of some sort, which can be +``ECB'', ``CBC'', ``CFB(n)'', ``OFB'', ``CTR-BE'', or ``EAX(n)''. The +argument to CFB mode is how many bits of feedback should be used. If +you just use ``CFB'' with no argument, it will default to using a +feedback equal to the block size of the cipher. EAX mode also takes an +optional bit argument, which tells EAX how large a tag size to +use~--~generally this is the size of the block size of the cipher, +which is the default if you don't specify any argument. In the case of the ECB and CBC modes, a padding method can also be -specified. If it is not supplied, ECB defaults to not padding, and CBC defaults -to using PKCS \#5/\#7 compatible padding. The padding methods currently -available are ``NoPadding'', ``PKCS7'', ``OneAndZeros'', and ``CTS''. CTS -padding is currently only available for CBC mode, but the others can also be -used in ECB mode. - -Some example \arg{cipher\_spec} arguments are: ``DES/CFB(32)'', -``TripleDES/OFB'', ``Blowfish/CBC/CTS'', ``SAFER-SK(10)/CBC/OneAndZeros'', -``AES/EAX'', ``ARC4'' - -``CTR-BE'' refers to counter mode where the counter is incremented as if it -were a big-endian encoded integer. This is compatible with most other -implementations, but it is possible some will use the incompatible little -endian convention. This version would be denoted as ``CTR-LE'' if it were -supported. - -``EAX'' is a new cipher mode designed by Wagner, Rogaway, and Bellare. It is an -authenticated cipher mode (that is, no separate authentication is needed), has -provable security, and is free from patent entanglements. It runs about half as -fast as most of the other cipher modes (like CBC, OFB, or CTR), which is not -bad considering you don't need to use an authentication code. +specified. If it is not supplied, ECB defaults to not padding, and CBC +defaults to using PKCS \#5/\#7 compatible padding. The padding methods +currently available are ``NoPadding'', ``PKCS7'', ``OneAndZeros'', and +``CTS''. CTS padding is currently only available for CBC mode, but the +others can also be used in ECB mode. + +Some example \arg{cipher\_spec} arguments are: ``AES-128/CBC'', +``Blowfish/CTR-BE'', ``Serpent/XTS'', and ``AES-256/EAX''. + +``CTR-BE'' refers to counter mode where the counter is incremented as +if it were a big-endian encoded integer. This is compatible with most +other implementations, but it is possible some will use the +incompatible little endian convention. This version would be denoted +as ``CTR-LE'' if it were supported. + +``EAX'' is a new cipher mode designed by Wagner, Rogaway, and +Bellare. It is an authenticated cipher mode (that is, no separate +authentication is needed), has provable security, and is free from +patent entanglements. It runs about half as fast as most of the other +cipher modes (like CBC, OFB, or CTR), which is not bad considering you +don't need to use an authentication code. \subsubsection{Hashes and MACs} @@ -807,7 +764,7 @@ Examples of names for \function{Hash\_Filter} are ``SHA-1'' and ``Whirlpool''. \type{u32bit} \arg{outlength}): The constructor for a \type{MAC\_Filter} takes a key, used in calculating the -MAC, and a length parameter, which has semantics exactly the same as the one +MAC, and a length parameter, which has semantics the same as the one passed to \type{Hash\_Filter}s constructor. Examples for \arg{mac} are ``HMAC(SHA-1)'', ``CMAC(AES-128)'', and the @@ -822,25 +779,27 @@ There are four classes in this category, \type{PK\_Encryptor\_Filter}, appropriate type (\type{PK\_Encryptor}, \type{PK\_Decryptor}, etc) that is deleted by the destructor. These classes are found in \filename{pk\_filts.h}. -Three of these, for encryption, decryption, and signing are pretty much -identical conceptually. Each of them buffers its input until the end of the -message is marked with a call to the \function{end\_msg} function. Then they -encrypt, decrypt, or sign their input and send the output (the ciphertext, the -plaintext, or the signature) into the next filter. - -Signature verification works a little differently, because it needs to know -what the signature is in order to check it. You can either pass this in along -with the constructor, or call the function \function{set\_signature} -- with -this second method, you need to keep a pointer to the filter around so you can -send it this command. In either case, after \function{end\_msg} is called, it -will try to verify the signature (if the signature has not been set by either -method, an exception will be thrown here). It will then send a single byte onto -the next filter -- a 1 or a 0, which specifies whether the signature verified -or not (respectively). - -For more information about PK algorithms (including creating the appropriate -objects to pass to the constructors), read the section ``Public Key -Cryptography'' in this manual. +Three of these, for encryption, decryption, and signing are much the +same in terms of dataflow - ach of them buffers its input until the +end of the message is marked with a call to the \function{end\_msg} +function. Then they encrypt, decrypt, or sign the entire input as a +single blob and send the output (the ciphertext, the plaintext, or the +signature) into the next filter. + +Signature verification works a little differently, because it needs to +know what the signature is in order to check it. You can either pass +this in along with the constructor, or call the function +\function{set\_signature} -- with this second method, you need to keep +a pointer to the filter around so you can send it this command. In +either case, after \function{end\_msg} is called, it will try to +verify the signature (if the signature has not been set by either +method, an exception will be thrown here). It will then send a single +byte onto the next filter -- a 1 or a 0, which specifies whether the +signature verified or not (respectively). + +For more information about PK algorithms (including creating the +appropriate objects to pass to the constructors), read the section +``Public Key Cryptography'' in this manual. \subsubsection{Encoders} @@ -851,7 +810,7 @@ base64 formats. Not surprisingly, you can use \type{Hex\_Decoder} and \type{Base64\_Decoder} to convert it back into its original form. Both of the encoders can take a few options about how the data should be -formatted (all of which have defaults). The first is a \type{bool} which simply +formatted (all of which have defaults). The first is a \type{bool} which says if the encoder should insert line breaks. This defaults to false. Line breaks don't matter either way to the decoder, but it makes the output a bit more appealing to the human eye, and a few transport mechanisms @@ -859,7 +818,7 @@ output a bit more appealing to the human eye, and a few transport mechanisms The second encoder option is an integer specifying how long such lines will be (obviously this will be ignored if line-breaking isn't being used). The default -tends to be in the range of 60-80 characters, but is not specified exactly. If +tends to be in the range of 60-80 characters, but is not specified. If you want a specific value, set it. Otherwise the default should be fine. Lastly, \type{Hex\_Encoder} takes an argument of type \type{Case}, which can be @@ -868,15 +827,17 @@ specifies what case the characters A-F should be output as. The base64 encoder has no such option, because it uses both upper and lower case letters for its output. -The decoders both take a single option, which tells it how the object should -behave in the case of invalid input. The enum (called \type{Decoder\_Checking}) -can take on any of three values: \type{NONE}, \type{IGNORE\_WS}, and -\type{FULL\_CHECK}. With \type{NONE} (the default, for compatibility with -previous releases), invalid input (for example, a ``z'' character in supposedly -hex input) will simply be ignored. With \type{IGNORE\_WS}, whitespace will be -ignored by the decoder, but receiving other non-valid data will raise an -exception. Finally, \type{FULL\_CHECK} will raise an exception for \emph{any} -characters not in the encoded character set, including whitespace. +The decoders both take a single option, which tells it how the object +should behave in the case of invalid input. The enum (called +\type{Decoder\_Checking}) can take on any of three values: +\type{NONE}, \type{IGNORE\_WS}, and \type{FULL\_CHECK}. With +\type{NONE} (the default, for compatibility with previous releases), +invalid input (for example, a ``z'' character in supposedly hex input) +will be ignored. With \type{IGNORE\_WS}, whitespace will be ignored by +the decoder, but receiving other non-valid data will raise an +exception. Finally, \type{FULL\_CHECK} will raise an exception for +\emph{any} characters not in the encoded character set, including +whitespace. You can find the declarations for these types in \filename{hex.h} and \filename{base64.h}. @@ -885,8 +846,8 @@ You can find the declarations for these types in \filename{hex.h} and The system of filters and pipes was designed in an attempt to make it as simple as possible to write new \type{Filter} objects. There are -essentially four functions that need to be implemented by an object -deriving from \type{Filter}: +four functions that need to be implemented by an object deriving from +\type{Filter}: \noindent \type{void} \function{write}(\type{byte} \arg{input}[], \type{u32bit} @@ -916,27 +877,17 @@ Zlib compression module). \noindent \type{void} \function{end\_msg()}: -Implementing the \function{end\_msg} function is optional. It is called when it -has been requested that filters finish up their computations. Note that they -must \emph{not} deallocate their resources; this should be done by their -destructor. They should simply finish up with whatever computation they have -been working on (for example, a compressing filter would flush the compressor -and \function{send} the final block), and empty any buffers in preparation for -processing a fresh new set of input. It is essentially the inverse of -\function{start\_msg}. - -Additionally, if necessary, filters can define a constructor that takes any -needed arguments, and a destructor to deal with deallocating memory, closing -files, etc. +Implementing the \function{end\_msg} function is optional. It is +called when it has been requested that filters finish up their +computations. The filter should finish up with whatever computation it +is working on (for example, a compressing filter would flush the +compressor and \function{send} the final block), and empty any buffers +in preparation for processing a fresh new set of input. -There is also a \type{BufferingFilter} class (in \filename{buf\_filt.h}) that -will take a message and split it up into an initial block that can be of any -size (including zero), a sequence of fixed sized blocks of any non-zero size, -and last (possibly zero-sized) final block. This might make a useful base class -for your filters, depending on what you have in mind. +Additionally, if necessary, filters can define a constructor that +takes any needed arguments, and a destructor to deal with deallocating +memory, closing files, etc. - -\pagebreak \section{Public Key Cryptography} Let's create a 1024-bit RSA private key, encode the public key as a @@ -955,7 +906,7 @@ std::string alice_pem = X509::PEM_encode(priv_rsa); // send alice_pem to Bob, who does // Bob -std::auto_ptr<X509_PublicKey> alice(load_key(alice_pem)); +std::auto_ptr<Public_Key> alice(load_key(alice_pem)); RSA_PublicKey* alice_rsa = dynamic_cast<RSA_PublicKey>(alice); if(alice_rsa) @@ -971,21 +922,27 @@ The library has interfaces for encryption, signatures, etc that do not require knowing the exact algorithm in use (for example RSA and Rabin-Williams signatures are handled by the exact same code path). -One place where we \emph{do} need to know exactly what kind of algorithm is in -use is when we are creating a key (\emph{But}: read the section ``Importing and -Exporting PK Keys'', later in this manual). - -There are (currently) two kinds of public key algorithms in Botan: ones based -on integer factorization (RSA and Rabin-Williams), and ones based on the -discrete logarithm problem (DSA, Diffie-Hellman, Nyberg-Rueppel, and -ElGamal). Since discrete logarithm parameters (primes and generators) can be -shared among many keys, there is the notion of these being a combined type -(called \type{DL\_Group}). +One place where we \emph{do} need to know exactly what kind of +algorithm is in use is when we are creating a key (\emph{But}: read +the section ``Importing and Exporting PK Keys'', later in this +manual). + +There are currently three kinds of public key algorithms in Botan: +ones based on integer factorization (RSA and Rabin-Williams), ones +based on the discrete logarithm problem in the integers modulo a prime +(DSA, Diffie-Hellman, Nyberg-Rueppel, and ElGamal), and ones based on +the discrete logarithm problem in an elliptic curve (ECDSA, ECDH, GOST +34.10). The systems based on discrete logarithms (in either regular +integers or elliptic curves) use a group (a mathematical term), which +can be shared among many keys. An elliptic curve group is represented +by the class \type{EC\_Domain\_Params}, while a modulo-prime group is +represented by a \type{DL\_Group}. There are two ways to create a DL private key (such as -\type{DSA\_PrivateKey}). One is to pass in just a \type{DL\_Group} object -- a -new key will automatically be generated. The other involves passing in a group -to use, along with both the public and private values (private value first). +\type{DSA\_PrivateKey}). One is to pass in just a \type{DL\_Group} +object -- a new key will automatically be generated. The other +involves passing in a group to use, along with both the public and +private values (private value first). Since in integer factorization algorithms, the modulus used isn't shared by other keys, we don't use this notion. You can create a new key by passing in a @@ -1026,7 +983,7 @@ prime. It does not have anything to do with the validity of the key for any particular use, nor does it have anything to do with certificates that link a key (which, after all, is just some numbers) with a user or other entity. If \function{check\_key}'s argument is \type{true}, then it does ``strong'' -checking, which includes fairly expensive operations like primality checking. +checking, which includes expensive operations like primality checking. Keys are always checked when they are loaded or generated, so typically there is no reason to use this function directly. However, you can disable or reduce @@ -1037,51 +994,42 @@ configuration subsystem for details). \subsection{Getting a PK algorithm object} The key types, like \type{RSA\_PrivateKey}, do not implement any kind -of padding or encoding (which is generally necessary for security). To -get an object like this, the easiest thing to do is call the functions -found in \filename{look\_pk.h}. Generally these take a key, followed -by a string that specified what hashing and encoding method(s) to -use. Examples of such strings are ``EME1(SHA-256)'' for OAEP -encryption and ``EMSA4(SHA-256)'' for PSS signatures (where the -message is hashed using SHA-256). - -Here are some basic examples (using an RSA key) to give you a feel for the -possibilities. These examples assume \type{rsakey} is an -\type{RSA\_PrivateKey}, since otherwise we would not be able to create a -decryption or signature object with it (you can create encryption or signature -verification objects with public keys, naturally). Remember to delete these -objects when you're done with them. +of padding or encoding (which is necessary for security). To get an +object that knows how to do padding, use the wrapper classes included +in \filename{pubkey.h}. These take a key, along with a string that +specifies what hashing and encoding method(s) to use. Examples of such +strings are ``EME1(SHA-256)'' for OAEP encryption and +``EMSA4(SHA-256)'' for PSS signatures (where the message is hashed +using SHA-256). + +Here are some basic examples (using an RSA key) to give you a feel for +the possibilities. These examples assume \type{rsakey} is an +\type{RSA\_PrivateKey}, since otherwise we would not be able to create +a decryption or signature object with it (you can create encryption or +signature verification objects with public keys, naturally). \begin{verbatim} // PKCS #1 v2.0 / IEEE 1363 compatible encryption - PK_Encryptor* rsa_enc1 = get_pk_encryptor(rsakey, "EME1(RIPEMD-160)"); + PK_Encryptor_EME rsa_enc_pkcs1_v2(rsakey, "EME1(SHA-1)"); // PKCS #1 v1.5 compatible encryption - PK_Encryptor* rsa_enc2 = get_pk_encryptor(rsakey, "PKCS1v15"); - - // Raw encryption: no padding, input is directly encrypted by the key - // Don't use this unless you know what you're doing - PK_Encryptor* rsa_enc3 = get_pk_encryptor(rsakey, "Raw"); + PK_Encryptor_EME rsa_enc_pkcs1_v15(rsakey, "PKCS1v15") - // This object can decrypt things encrypted by rsa_enc1 - PK_Decryptor* rsa_dec1 = get_pk_decryptor(rsakey, "EME1(RIPEMD-160)"); + // This object can decrypt things encrypted by rsa_ + PK_Decryptor_EME rsa_dec_pkcs1_v2(rsakey, "EME1(SHA-1)"); // PKCS #1 v1.5 compatible signatures - PK_Signer* rsa_sig = get_pk_signer(rsakey, "EMSA3(MD5)"); - PK_Verifier* rsa_verify = get_pk_verifier(rsakey, "EMSA3(MD5)"); + PK_Signer rsa_sign_pkcs1_v15(rsakey, "EMSA3(MD5)"); + PK_Verifier rsa_verify_pkcs1_v15(rsakey, "EMSA3(MD5)"); // PKCS #1 v2.1 compatible signatures - PK_Signer* rsa_sig2 = get_pk_signer(rsakey, "EMSA4(SHA-1)"); - PK_Verifier* rsa_verify2 = get_pk_verifier(rsakey, "EMSA4(SHA-1)"); - - // Hash input with SHA-1, but don't pad the input in any way; usually - // used with DSA/NR, not RSA - PK_Signer* rsa_sig = get_pk_signer(rsakey, "EMSA1(SHA-1)"); + PK_Signer rsa_sign_pkcs1_v2(rsakey, "EMSA4(SHA-1)"); + PK_Verifier rsa_verify_pkcs1_v2(rsakey, "EMSA4(SHA-1)"); \end{verbatim} \subsection{Encryption} -The \type{PK\_Encryptor} and \type{PK\_Decryptor} classes are the interface for -encryption and decryption, respectively. +The \type{PK\_Encryptor} and \type{PK\_Decryptor} classes are the +interface for encryption and decryption, respectively. Calling \function{encrypt} with a \type{byte} array, a length parameter, and an RNG object will return the input encrypted with @@ -1092,16 +1040,14 @@ via a \type{SecureVector<byte>}. If you attempt an operation with a larger size than the key can support (this limit varies based on the algorithm, the key size, and -the padding method used (if any)), an exception will be -thrown. Alternately, you can call \function{maximum\_input\_size}, -that will return the maximum size you can safely encrypt. In fact, -you can often encrypt an object that is one byte longer, but only if -enough of the high bits of the leading byte are set to zero. Since -this is pretty dicey, it's best to stick with the advertised maximum. +the padding method used (if any)), an exception will be thrown. You +can call \function{maximum\_input\_size} to find out the maximum size +input (in bytes) that you can safely use with any particular key. -Available public key encryption algorithms in Botan are RSA and ElGamal. The -encoding methods are EME1, denoted by ``EME1(HASHNAME)'', PKCS \#1 v1.5, -called ``PKCS1v15'' or ``EME-PKCS1-v1\_5'', and raw encoding (``Raw''). +Available public key encryption algorithms in Botan are RSA and +ElGamal. The encoding methods are EME1, denoted by ``EME1(HASHNAME)'', +PKCS \#1 v1.5, called ``PKCS1v15'' or ``EME-PKCS1-v1\_5'', and raw +encoding (``Raw''). For compatibility reasons, PKCS \#1 v1.5 is recommend for use with ElGamal (most other implementations of ElGamal do not support any @@ -1137,58 +1083,64 @@ the message, the second being the (supposed) signature. It returns true if the signature is valid and false otherwise. Available public key signature algorithms in Botan are RSA, DSA, -Nyberg-Rueppel, and Rabin-Williams. Signature encoding methods include EMSA1, -EMSA2, EMSA3, EMSA4, and Raw. All of them, except Raw, take a parameter naming -a message digest function to hash the message with. Raw actually signs the -input directly; if the message is too big, the signing operation will fail. Raw -is not useful except in very specialized applications. - -There are various interactions that make certain encoding schemes and signing -algorithms more or less useful. - -EMSA2 is the usual method for encoding Rabin-William signatures, so for -compatibility with other implementations you may have to use that. EMSA4 (also -called PSS), also works with Rabin-Williams. EMSA1 and EMSA3 do \emph{not} work -with Rabin-Williams. - -RSA can be used with any of the available encoding methods. EMSA4 is by far the -most secure, but is not (as of now) widely implemented. EMSA3 (also called -``EMSA-PKCS1-v1\_5'') is commonly used with RSA (for example in SSL). EMSA1 -signs the message digest directly, without any extra padding or encoding. This -may be useful, but is not as secure as either EMSA3 or EMSA4. EMSA2 may be used -but is not recommended. - -For DSA and Nyberg-Rueppel, you should use EMSA1. None of the other encoding -methods are particularly useful for these algorithms. +ECDSA, GOST-34.11, Nyberg-Rueppel, and Rabin-Williams. Signature +encoding methods include EMSA1, EMSA2, EMSA3, EMSA4, and Raw. All of +them, except Raw, take a parameter naming a message digest function to +hash the message with. The Raw encoding signs the input directly; if +the message is too big, the signing operation will fail. Raw is not +useful except in very specialized applications. + +There are various interactions that make certain encoding schemes and +signing algorithms more or less useful. + +EMSA2 is the usual method for encoding Rabin-William signatures, so +for compatibility with other implementations you may have to use +that. EMSA4 (also called PSS), also works with Rabin-Williams. EMSA1 +and EMSA3 do \emph{not} work with Rabin-Williams. + +RSA can be used with any of the available encoding methods. EMSA4 is +by far the most secure, but is not (as of now) widely +implemented. EMSA3 (also called ``EMSA-PKCS1-v1\_5'') is commonly used +with RSA (for example in SSL). EMSA1 signs the message digest +directly, without any extra padding or encoding. This may be useful, +but is not as secure as either EMSA3 or EMSA4. EMSA2 may be used but +is not recommended. + +For DSA, ECDSA, GOST-34.11, and Nyberg-Rueppel, you should use +EMSA1. None of the other encoding methods are particularly useful for +these algorithms. \subsection{Key Agreement} -You can get a hold of a \type{PK\_Key\_Agreement\_Scheme} object by calling -\function{get\_pk\_kas} with a key that is of a type that supports key -agreement (such as a Diffie-Hellman key stored in a \type{DH\_PrivateKey} -object), and the name of a key derivation function. This can be ``Raw'', -meaning the output of the primitive itself is returned as the key, or -``KDF1(hash)'' or ``KDF2(hash)'' where ``hash'' is any string you happen to -like (hopefully you like strings like ``SHA-256'' or ``RIPEMD-160''), or -``X9.42-PRF(keywrap)'', which uses the PRF specified in ANSI X9.42. It takes -the name or OID of the key wrap algorithm that will be used to encrypt a -content encryption key. - -How key agreement generally works is that you trade public values with some -other party, and then each of you runs a computation with the other's value and -your key (this should return the same result to both parties). This computation -can be called by using \function{derive\_key} with either a byte array/length -pair, or a \type{SecureVector<byte>} than holds the public value of the other -party. The last argument to either call is a number that specifies how long a -key you want. - -Depending on the key derivation function you're using, you many not -\emph{actually} get back a key of that size. In particular, ``Raw'' will return -a number about the size of the Diffie-Hellman modulus, and KDF1 can only return -a key that is the same size as the output of the hash. KDF2, on the other -hand, will always give you a key exactly as long as you request, regardless of -the underlying hash used with it. The key returned is a \type{SymmetricKey}, -ready to pass to a block cipher, MAC, or other symmetric algorithm. +You can get a hold of a \type{PK\_Key\_Agreement\_Scheme} object by +calling \function{get\_pk\_kas} with a key that is of a type that +supports key agreement (such as a Diffie-Hellman key stored in a +\type{DH\_PrivateKey} object), and the name of a key derivation +function. This can be ``Raw'', meaning the output of the primitive +itself is returned as the key, or ``KDF1(hash)'' or ``KDF2(hash)'' +where ``hash'' is any string you happen to like (hopefully you like +strings like ``SHA-256'' or ``RIPEMD-160''), or +``X9.42-PRF(keywrap)'', which uses the PRF specified in ANSI X9.42. It +takes the name or OID of the key wrap algorithm that will be used to +encrypt a content encryption key. + +How key agreement works is that you trade public values with some +other party, and then each of you runs a computation with the other's +value and your key (this should return the same result to both +parties). This computation can be called by using +\function{derive\_key} with either a byte array/length pair, or a +\type{SecureVector<byte>} than holds the public value of the other +party. The last argument to either call is a number that specifies how +long a key you want. + +Depending on the KDF you're using, you \emph{might not} get back a key +of the size you requested. In particular ``Raw'' will return a number +about the size of the Diffie-Hellman modulus, and KDF1 can only return +a key that is the same size as the output of the hash. KDF2, on the +other hand, will always give you a key exactly as long as you request, +regardless of the underlying hash used with it. The key returned is a +\type{SymmetricKey}, ready to pass to a block cipher, MAC, or other +symmetric algorithm. The public value that should be used can be obtained by calling \function{public\_data}, which exists for any key that is associated with a @@ -1225,58 +1177,50 @@ The interfaces for doing either of these are quite similar. Let's look at the X.509 stuff first: \begin{verbatim} namespace X509 { - void encode(const X509_PublicKey& key, Pipe& out, X509_Encoding enc = PEM); - std::string PEM_encode(const X509_PublicKey& out); + MemoryVector<byte> BER_encode(const Public_Key& key); + std::string PEM_encode(const Public_Key& out); - X509_PublicKey* load_key(DataSource& in); - X509_PublicKey* load_key(const std::string& file); - X509_PublicKey* load_key(const SecureVector<byte>& buffer); + Public_Key* load_key(DataSource& in); + Public_Key* load_key(const SecureVector<byte>& buffer); } \end{verbatim} -Basically, \function{X509::encode} will take an \type{X509\_PublicKey} -(as of now, that's any RSA, DSA, or Diffie-Hellman key) and encodes it -using \arg{enc}, which can be either \type{PEM} or -\type{RAW\_BER}. Using \type{PEM} is \emph{highly} recommended for -many reasons, including compatibility with other software, for -transmission over 8-bit unclean channels, because it can be identified -by a human without special tools, and because it sometimes allows more -sane behavior of tools that process the data. It will place the -encoding into \arg{out}. Remember that if you have just created the -\type{Pipe} that you are passing to \function{X509::encode}, you need -to call \function{start\_msg} first. Particularly with public keys, -about 99\% of the time you just want to PEM encode the key and then -write it to a file or something. In this case, it's probably easier to -use \function{X509::PEM\_encode}. This function will simply return the -PEM encoding of the key as a \type{std::string}. - -For loading a public key, the preferred method is one of the variants -of \function{load\_key}. This function will return a newly allocated -key based on the data from whatever source it is using (assuming, of +The function \function{X509::BER\_encode} will take any +\type{Public\_Key} and return a standard binary structure representing +the key which can be read by many other crypto libraries. + +The function \function{X509::PEM\_encode} does the same, but +additionally formats it into a text format with headers and base64 +encoding. Using PEM is \emph{highly} recommended for many reasons, +including compatibility with other software, for transmission over +8-bit unclean channels, because it can be identified by a human +without special tools, and because it sometimes allows more sane +behavior of tools that process the data. + +For loading a public key, use one of the variants of +\function{load\_key}. This function will return a newly allocated key +based on the data from whatever source it is using (assuming, of course, the source is in fact storing a representation of a public key). The encoding used (PEM or BER) need not be specified; the format will be detected automatically. The key is allocated with \function{new}, and should be released with \function{delete} when you -are done with it. The first takes a generic \type{DataSource} that -you have to allocate~--~the others are simple wrapper functions that -take either a filename or a memory buffer. +are done with it. The first takes a generic \type{DataSource} that you +have to create~--~the others are simple wrapper functions that take +either a filename or a memory buffer. -So what can you do with the return value of \function{load\_key}? On -its own, a \type{X509\_PublicKey} isn't particularly useful; you can't -encrypt messages or verify signatures, or much else. But, using -\function{dynamic\_cast}, you can figure out what kind of operations -the key supports. Then, you can cast the key to the appropriate type -and pass it to a higher-level class. For example: +Here's an example of loading a public key and then encrypting with it: \begin{verbatim} /* Might be RSA, might be ElGamal, might be ... */ - X509_PublicKey* key = X509::load_key("pubkey.asc"); - /* You MUST use dynamic_cast to convert, because of virtual bases */ - PK_Encrypting_Key* enc_key = dynamic_cast<PK_Encrypting_Key*>(key); - if(!enc_key) - throw Some_Exception(); - PK_Encryptor* enc = get_pk_encryptor(*enc_key, "EME1(SHA-256)"); - SecureVector<byte> cipher = enc->encrypt(some_message, size_of_message); + Public_Key* key = X509::load_key("pubkey.asc"); + + /* This might throw an exception if the key doesn't support any + encryption operations + */ + + PK_Encryptor_EME encryptor(*key, "EME1(SHA-1)"); + + SecureVector<byte> ciphertext = encryptor.encrypt(msg, size_of_msg); \end{verbatim} \subsubsection{Private Keys} @@ -1287,115 +1231,95 @@ functions: \begin{verbatim} namespace PKCS8 { - void encode(const PKCS8_PrivateKey& key, Pipe& to, X509_Encoding enc = PEM); - - std::string PEM_encode(const PKCS8_PrivateKey& key); + SecureVector<byte> BER_encode(const Private_Key& key); + std::string PEM_encode(const Private_Key& key); } \end{verbatim} -These functions are basically the same as the X.509 functions described -previously. The only difference is that they take a \type{PKCS8\_PrivateKey} -type (which, again, can be either RSA, DSA, or Diffie-Hellman, but this time -the key must be a private key). In most situations, using these is a bad idea, -because anyone can come along and grab the private key without having to know -any passwords or other secrets. Unless you have very particular security -requirements, always use the versions that encrypt the key based on a -passphrase. For importing, the same functions can be used for encrypted and -unencrypted keys. - -The other way to export a PKCS \#8 key is to first encode it in the same manner -as done above, then encrypt it (using a passphrase and the techniques of PKCS -\#5), and store the whole thing into another structure. This method is -definitely preferred, since otherwise the private key is unprotected. The -following functions support this technique: +These functions are similiar to the X.509 functions described +previously. The only difference is that they take a +\type{Private\_Key} object instead. In most situations, using these is +a bad idea, because anyone can come along and grab the private key +without having to know any passwords or other secrets. Unless you have +very particular security requirements, always use the versions that +encrypt the key based on a passphrase. For importing, the same +functions can be used for encrypted and unencrypted keys. + +The other way to export a PKCS \#8 key is to first encode it in the +same manner as done above, then encrypt it using a passphrase, and +store the whole thing into another structure. This method is +definitely preferred, since otherwise the private key is +unprotected. The algorithms and structures used here are standardized +by PKCS \#5 and PKCS \#8, and can be read by many other crypto +libraries. \begin{verbatim} namespace PKCS8 { - void encrypt_key(const PKCS8_PrivateKey& key, Pipe& out, - std::string passphrase, std::string pbe = "", - X509_Encoding enc = PEM); - - std::string PEM_encode(const PKCS8_PrivateKey& key, std::string passphrase, - std::string pbe = ""); + SecureVector<byte> BER_encode(const Private_Key& key, + RandomNumberGenerator& rng, + const std::string& pass, + const std::string& pbe_algo = ""); + + std::string PEM_encode(const Private_Key& key, + RandomNumberGenerator& rng, + const std::string& pass, + const std::string& pbe_algo = ""); } \end{verbatim} -To export an encrypted private key, call \function{PKCS8::encrypt\_key}. The -\arg{key}, \arg{out}, and \arg{enc} arguments are similar in usage to the ones -for \function{PKCS8::encode}. As you might notice, there are two new arguments -for \function{PKCS8::encrypt\_key}, however. The first is a passphrase (which -you presumably got from a user somehow). This will be used to encrypt the key. -The second new argument is \arg{pbe}; this specifies a particular password -based encryption (or PBE) algorithm. - -The \function{PEM\_encode} version shown here is similar to the one that -doesn't take a passphrase. Essentially it encrypts the key (using the default -PBE algorithm), and then returns a C++ string with the PEM encoding of the key. - -If \arg{pbe} is blank, then the default algorithm (controlled by the -``base/default\_pbe'' option) will be used. As shipped, this default is -``PBE-PKCS5v20(SHA-1,TripleDES/CBC)'' . This is among the more secure options -of PKCS \#5, and is widely supported among implementations of PKCS \#5 v2.0. It -offers 168 bits of security against attacks, which should be more that -sufficient. If you need compatibility with systems that only support PKCS \#5 -v1.5, pass ``PBE-PKCS5v15(MD5,DES/CBC)'' as \arg{pbe}. However, be warned that -this PBE algorithm only has 56 bits of security against brute force attacks. As -of 1.4.5, all three keylengths of AES are also available as options, which can -be used with by specifying a PBE algorithm of -``PBE-PKCS5v20(SHA-1,AES-256/CBC)'' (or ``AES-128'' or ``AES-192''). Support -for AES is slightly non-standard, and some applications or libraries might not -handle it. It is known that OpenSSL (0.9.7 and later) do handle AES for private -key encryption. - -There may be some strange programs out there that support the v2.0 extensions -to PBES1 but not PBES2; if you need to inter-operate with a program like that, -use ``PBE-PKCS5v15(MD5,RC2/CBC)''. For example, OpenSSL supports this format -(though since it also supports the v2.0 schemes, there is no reason not to just -use TripleDES or AES). This scheme uses a 64-bit key that, while -significantly better than a 56-bit key, is a bit too small for comfort. - -Last but not least, there are some functions that are basically identical to -\function{X509::load\_key} that will load, and possibly decrypt, a PKCS \#8 -private key: +There are three new arguments needed here to support the encryption +process in addition to the private key itself. The first is a +\type{RandomNumberGenerator}, which is needed for various purposes +internally. The \arg{pass} argument is the passphrase that will be +used to encrypt the key. Both of these are required. The final +(optional) argument is \arg{pbe}; this specifies a particular password +based encryption (or PBE) algorithm. If you don't specify a PBE, +a compiled in default will be used; this should be fine. + +Last but not least, there are some functions that will load (and +decrypt, if necessary) a PKCS \#8 private key: \begin{verbatim} namespace PKCS8 { - PKCS8_PrivateKey* load_key(DataSource& in, - RandomNumberGenerator& rng, - const User_Interface& ui); - PKCS8_PrivateKey* load_key(DataSource& in, - RandomNumberGenerator& rng, - std::string passphrase = ""); - - PKCS8_PrivateKey* load_key(const std::string& filename, - RandomNumberGenerator& rng, - const User_Interface& ui); - PKCS8_PrivateKey* load_key(const std::string& filename, - RandomNumberGenerator& rng, - const std::string& passphrase = ""); + Private_Key* load_key(DataSource& in, + RandomNumberGenerator& rng, + const User_Interface& ui); + + Private_Key* load_key(DataSource& in, + RandomNumberGenerator& rng, + std::string passphrase = ""); + + Private_Key* load_key(const std::string& filename, + RandomNumberGenerator& rng, + const User_Interface& ui); + + Private_Key* load_key(const std::string& filename, + RandomNumberGenerator& rng, + const std::string& passphrase = ""); } \end{verbatim} -The versions that take \type{std::string} \arg{passphrase}s are primarily for -compatibility, but they are useful in limited circumstances. The -\type{User\_Interface} versions are how \function{load\_key} is actually -implemented, and provides for much more flexibility. Essentially, if the -passphrase given to the function is not correct, then an exception is thrown -and that is that. However, if you pass in an UI object instead, then the UI -object can keep asking the user for the passphrase until they get it right (or -until they cancel the action, though the UI interface). A -\type{User\_Interface} has very little to do with talking to users; it's just a -way to glue together Botan and whatever user interface you happen to be -using. You can think of it as a user interface interface. The default -\type{User\_Interface} is actually very dumb, and effectively acts just like -the versions taking the \type{std::string}. +The versions that take \type{std::string} \arg{passphrase}s are +primarily for compatibility, but they are useful in limited +circumstances. The \type{User\_Interface} versions are how +\function{load\_key} is implemented, and provides for much more +flexibility. If the passphrase passed in is not correct, then an +exception is thrown and that is that. However, if you pass in an UI +object, then the UI object can keep asking the user for the passphrase +until they get it right (or until they cancel the action, though the +UI interface). A \type{User\_Interface} has very little to do with +talking to users; it's just a way to glue together Botan and whatever +user interface you happen to be using. You can think of it as a user +interface interface. The default \type{User\_Interface} is rather +dumb, and acts rather like the versions taking the \type{std::string}; +it tries the passphrase passed in first, and then it cancels. All versions need access to a \type{RandomNumberGenerator} in order to perform probabilistic tests on the loaded key material. -After loading a key, you can use \function{dynamic\_cast} to find out what -operations it supports, and use it appropriately. Remember to \function{delete} -it once you are done with it. +After loading a key, you can use \function{dynamic\_cast} to find out +what operations it supports, and use it appropriately. Remember to +\function{delete} the object once you are done with it. \subsubsection{Limitations} @@ -1413,13 +1337,12 @@ assign them an OID by putting a line in a Botan configuration file, calling it is possible that a future version will use a format that is different from the current one (\ie, a newly standardized format). -\pagebreak \section{Certificate Handling} -A certificate is essentially a binding between some identifying information of -a person or other entity (called a \emph{subject}) and a public key. This -binding is asserted by a signature on the certificate, which is placed there by -some authority (the \emph{issuer}) that at least claims that it knows the +A certificate is a binding between some identifying information +(called a \emph{subject}) and a public key. This binding is asserted +by a signature on the certificate, which is placed there by some +authority (the \emph{issuer}) that at least claims that it knows the subject named in the certificate really ``owns'' the private key corresponding to the public key in the certificate. @@ -1427,67 +1350,75 @@ The major certificate format in use today is X.509v3, designed by ISO and further hacked on by dozens (hundreds?) of other organizations. When working with certificates, the main class to remember is -\type{X509\_Certificate}. You can read an object of this type, but you can't -create one on the fly; a CA object is necessary for actually making a new -certificate. So for the most part, you only have to worry about reading them -in, verifying the signatures, and getting the bits of data in them (most -commonly the public key, and the information about the user of that key). An -X.509v3 certificate can contain a literally infinite number of items related to -all kinds of things. Botan doesn't support a lot of them, simply because nobody -uses them and they're an impossible mess to work with. This section only -documents the most commonly used ones of the ones that are supported; for the -rest, read \filename{x509cert.h} and \filename{asn1\_obj.h} (which has the +\type{X509\_Certificate}. You can read an object of this type, but you +can't create one on the fly; a CA object is necessary for making a new +certificate. So for the most part, you only have to worry about +reading them in, verifying the signatures, and getting the bits of +data in them (most commonly the public key, and the information about +the user of that key). An X.509v3 certificate can contain a literally +infinite number of items related to all kinds of things. Botan doesn't +support a lot of them, because nobody uses them and they're an +impossible mess to work with. This section only documents the most +commonly used ones of the ones that are supported; for the rest, read +\filename{x509cert.h} and \filename{asn1\_obj.h} (which has the definitions of various common ASN.1 constructs used in X.509). \subsection{So what's in an X.509 certificate?} -Obviously, you want to be able to get the public key. This is achieved by -calling the member function \function{subject\_public\_key}, which will return -a \type{X509\_PublicKey*}. As to what to do with this, read about -\function{load\_key} in the section ``Importing and Exporting PK Keys''. In the -general case, this could be any kind of public key, though 99\% of the time it -will be an RSA key. However, Diffie-Hellman and DSA keys are also supported, so -be careful about how you treat this. It is also a wise idea to examine the -value returned by \function{constraints}, to see what uses the public key is -approved for. - -The second major piece of information you'll want is the name/email/etc of the -person to whom this certificate is assigned. Here is where things get a little -nasty. X.509v3 has two (well, mostly just two $\ldots$) different places where -you can stick information about the user: the \emph{subject} field, and in an -extension called \emph{subjectAlternativeName}. The \emph{subject} field is -supposed to only included the following information: country, organization -(possibly), an organizational sub-unit name (possibly), and a so-called common -name. The common name is usually the name of the person, or it could be a title -associated with a position of some sort in the organization. It may also -include fields for state/province and locality. What exactly a locality is, -nobody knows, but it's usually given as a city name. - -Botan doesn't currently support any of the Unicode variants used in ASN.1 -(UTF-8, UCS-2, and UCS-4), any of which could be used for the fields in the -DN. This could be problematic, particularly in Asia and other areas where -non-ASCII characters are needed for most names. The UTF-8 and UCS-2 string -types \emph{are} accepted (in fact, UTF-8 is used when encoding much of the -time), but if any of the characters included in the string are not in ISO -8859-1 (\ie 0 \ldots 255), an exception will get thrown. Currently the -\type{ASN1\_String} type holds its data as ISO 8859-1 internally (regardless -of local character set); this would have to be changed to hold UCS-2 or UCS-4 -in order to support Unicode (also, many interfaces in the X.509 code would have -to accept or return a \type{std::wstring} instead of a \type{std::string}). - -Like the distinguished names, subject alternative names can contain a lot of -things that Botan will flat out ignore (most of which you would never actually -want to use). However, there are three very useful pieces of information that -this extension might hold: an email address (``[email protected]''), a DNS name -(``somehost.site2.com''), or a URI (``http://www.site3.com''). - -So, how to get the information? Simply call \function{subject\_info} with the +Obviously, you want to be able to get the public key. This is achieved +by calling the member function \function{subject\_public\_key}, which +will return a \type{Public\_Key*}. As to what to do with this, read +about \function{load\_key} in the section ``Importing and Exporting PK +Keys''. In the general case, this could be any kind of public key, +though 99\% of the time it will be an RSA key. However, Diffie-Hellman +and DSA keys are also supported, so be careful about how you treat +this. It is also a wise idea to examine the value returned by +\function{constraints}, to see what uses the public key is approved +for. + +The second major piece of information you'll want is the +name/email/etc of the person to whom this certificate is +assigned. Here is where things get a little nasty. X.509v3 has two +(well, mostly just two $\ldots$) different places where you can stick +information about the user: the \emph{subject} field, and in an +extension called \emph{subjectAlternativeName}. The \emph{subject} +field is supposed to only included the following information: country, +organization, an organizational sub-unit name, and a so-called common +name. The common name is usually the name of the person, or it could +be a title associated with a position of some sort in the +organization. It may also include fields for state/province and +locality. What a locality is, nobody knows, but it's usually given as +a city name. + +Botan doesn't currently support any of the Unicode variants used in +ASN.1 (UTF-8, UCS-2, and UCS-4), any of which could be used for the +fields in the DN. This could be problematic, particularly in Asia and +other areas where non-ASCII characters are needed for most names. The +UTF-8 and UCS-2 string types \emph{are} accepted (in fact, UTF-8 is +used when encoding much of the time), but if any of the characters +included in the string are not in ISO 8859-1 (\ie 0 \ldots 255), an +exception will get thrown. Currently the \type{ASN1\_String} type +holds its data as ISO 8859-1 internally (regardless of local character +set); this would have to be changed to hold UCS-2 or UCS-4 in order to +support Unicode (also, many interfaces in the X.509 code would have to +accept or return a \type{std::wstring} instead of a +\type{std::string}). + +Like the distinguished names, subject alternative names can contain a +lot of things that Botan will flat out ignore (most of which you would +likely never want to use). However, there are three very useful pieces +of information that this extension might hold: an email address +(``[email protected]''), a DNS name (``somehost.site2.com''), or a URI +(``http://www.site3.com''). + +So, how to get the information? Call \function{subject\_info} with the name of the piece of information you want, and it will return a -\type{std::string} that is either empty (signifying that the certificate -doesn't have this information), or has the information requested. There are -several names for each possible item, but the most easily readable ones are: -``Name'', ``Country'', ``Organization'', ``Organizational Unit'', ``Locality'', -``State'', ``RFC822'', ``URI'', and ``DNS''. These values are returned as a +\type{std::string} that is either empty (signifying that the +certificate doesn't have this information), or has the information +requested. There are several names for each possible item, but the +most easily readable ones are: ``Name'', ``Country'', +``Organization'', ``Organizational Unit'', ``Locality'', ``State'', +``RFC822'', ``URI'', and ``DNS''. These values are returned as a \type{std::string}. You can also get information about the issuer of the certificate in the same @@ -1495,10 +1426,10 @@ way, using \function{issuer\_info}. \subsubsection{X.509v3 Extensions} -X.509v3 specifies a large number of possible extensions. Botan supports some, -but by no means all of them. This section lists which ones are supported, and -notes areas where there may be problems with the handling. You have to be -pretty familiar with X.509 in order to understand what this is talking about. +X.509v3 specifies a large number of possible extensions. Botan +supports some, but by no means all of them. This section lists which +ones are supported, and notes areas where there may be problems with +the handling. \begin{list}{$\cdot$} \item Key Usage and Extended Key Usage: No problems known. @@ -1529,16 +1460,17 @@ pretty familiar with X.509 in order to understand what this is talking about. \subsubsection{Revocation Lists} -It will occasionally happen that a certificate must be revoked before its -expiration date. Examples of this happening include the private key being -compromised, or the user to which it has been assigned leaving an -organization. Certificate revocation lists are an answer to this problem -(though online certificate validation techniques are starting to become -somewhat more popular). Essentially, every once in a while the CA will release -a CRL, listing all certificates that have been revoked. Also included is -various pieces of information like what time a particular certificate was -revoked, and for what reason. In most systems, it is wise to support some form -of certificate revocation, and CRLs handle this fairly easily. +It will occasionally happen that a certificate must be revoked before +its expiration date. Examples of this happening include the private +key being compromised, or the user to which it has been assigned +leaving an organization. Certificate revocation lists are an answer to +this problem (though online certificate validation techniques are +starting to become somewhat more popular). Every once in a while the +CA will release a new CRL, listing all certificates that have been +revoked. Also included is various pieces of information like what time +a particular certificate was revoked, and for what reason. In most +systems, it is wise to support some form of certificate revocation, +and CRLs handle this easily. For most users, processing a CRL is quite easy. All you have to do is call the constructor, which will take a filename (or a \type{DataSource\&}). The CRLs @@ -1575,10 +1507,10 @@ we hit the top of the certificate tree somewhere. It would be a might huge pain to have to handle all of that manually in every application, so there is something that does it for you: \type{X509\_Store}. -This is a pretty easy thing to use. The basic operations are: put certificates -and CRLs into it, search for certificates, and attempt to verify -certificates. That's about it. In the future, there will be support for online -retrieval of certificates and CRLs (\eg with the HTTP cert-store interface +The basic operations are: put certificates and CRLs into it, search +for certificates, and attempt to verify certificates. That's about +it. In the future, there will be support for online retrieval of +certificates and CRLs (\eg with the HTTP cert-store interface currently under consideration by PKIX). \subsubsection{Adding Certificates} @@ -1652,18 +1584,18 @@ effective than the name, since email addresses are rarely shared. \subsubsection{Certificate Stores} -An object of type \type{Certificate\_Store} is a generalized interface to an -external source for certificates (and CRLs). Examples of such a store would be -one that looked up the certificates in a SQL database, or by contacting a CGI -script running on a HTTP server. There are currently three mechanisms for -looking up a certificate, and one for retrieving CRLs. By default, most of -these mechanisms will simply return an empty \type{std::vector} of -\type{X509\_Certificate}. This storage mechanism is \emph{only} queried when -doing certificate validation: it allows you to distribute only the root key -with an application, and let some online method handle getting all the other -certificates that are needed to validate an end entity certificate. In -particular, the search routines will not attempt to access the external -database. +An object of type \type{Certificate\_Store} is a generalized interface +to an external source for certificates (and CRLs). Examples of such a +store would be one that looked up the certificates in a SQL database, +or by contacting a CGI script running on a HTTP server. There are +currently three mechanisms for looking up a certificate, and one for +retrieving CRLs. By default, most of these mechanisms will return an +empty \type{std::vector} of \type{X509\_Certificate}. This storage +mechanism is \emph{only} queried when doing certificate validation: it +allows you to distribute only the root key with an application, and +let some online method handle getting all the other certificates that +are needed to validate an end entity certificate. In particular, the +search routines will not attempt to access the external database. The three certificate lookup methods are \function{by\_SKID} (Subject Key Identifier), \function{by\_name} (the CommonName DN entry), and @@ -1675,17 +1607,18 @@ implement \function{by\_name} or \function{by\_email}, but \function{by\_SKID} is mandatory to implement, and, currently, is the only version that is used by \type{X509\_Store}. -Finally, there is a method for finding CRLs, called \function{get\_crls\_for}, -that takes an \type{X509\_Certificate} object, and returns a -\type{std::vector} of \type{X509\_CRL}. While generally there will be only one -CRL, the use of the vector makes it easy to return no CRLs (\eg, if the -certificate store doesn't support retrieving them), or return multiple ones -(for example, if the certificate store can't determine precisely which key was -used to sign the certificate). Implementing the function is optional, and by +Finally, there is a method for finding CRLs, called +\function{get\_crls\_for}, that takes an \type{X509\_Certificate} +object, and returns a \type{std::vector} of \type{X509\_CRL}. While +normally there will be only one CRL, the use of the vector makes it +easy to return no CRLs (\eg, if the certificate store doesn't support +retrieving them), or return multiple ones (for example, if the +certificate store can't determine precisely which key was used to sign +the certificate). Implementing the function is optional, and by default will return no CRLs. If it is available, it will be used by \type{X509\_CRL}. -As for actually using such a store, you have to tell \type{X509\_Store} about +As for using such a store, you have to tell \type{X509\_Store} about it, by calling the \type{X509\_Store} member function \function{add\_new\_certstore}(\type{Certificate\_Store}* \arg{new\_store}) @@ -1702,41 +1635,46 @@ certificate: \function{validate\_cert}(\type{const X509\_Certificate\&} \arg{cert}, \type{Cert\_Usage} \arg{usage} = \type{ANY}) -To sum things up simply, it returns \type{VERIFIED} if the certificate can -safely be considered valid for the usage(s) described by \arg{usage}, and an -error code if it is not. Naturally, things are a bit more complicated than -that. The enum \type{Cert\_Usage} is defined inside the \type{X509\_Store} -class, it (currently) can take on any of the values \type{ANY} (any usage is -OK), \type{TLS\_SERVER} (for SSL/TLS server authentication), \type{TLS\_CLIENT} -(for SSL/TLS client authentication), \type{CODE\_SIGNING}, -\type{EMAIL\_PROTECTION} (email encryption, usually this means S/MIME), -\type{TIME\_STAMPING} (in theory any time stamp application, usually IETF -PKIX's Time Stamp Protocol), or \type{CRL\_SIGNING}. Note that Microsoft's code -signing system, certainly the most widely used, uses a completely different -(and basically undocumented) method for marking certificates for code signing. - -First, how does it know if a certificate is valid? Basically, a certificate is -valid if both of the following hold: a) the signature in the certificate can be -verified using the public key in the issuer's certificate, and b) the issuer's -certificate is a valid CA certificate. Note that this definition is -recursive. We get out of this by ``bottoming out'' when we reach a certificate -that we consider trusted. In general this will either be a commercial root CA, -or an organization or application specific CA. - -There are actually a few other restrictions (validity periods, key usage -restrictions, etc), but the above summarizes the major points of the validation -algorithm. In theory, Botan implements the certificate path validation -algorithm given in RFC 2459, but in practice it does not (yet), because we -don't support the X.509v3 policy or name constraint extensions. - -Possible values for \arg{usage} are \type{TLS\_SERVER}, \type{TLS\_CLIENT}, -\type{CODE\_SIGNING}, \type{EMAIL\_PROTECTION}, \type{CRL\_SIGNING}, and -\type{TIME\_STAMPING}, and \type{ANY}. The default \type{ANY} does not mean -valid for any use, it means ``is valid for some usage''. This is generally -fine, and in fact requiring that a random certificate support a particular -usage will likely result in a lot of failures, unless your application is very -careful to always issue certificates with the proper extensions, and you never -use certificates generated by other apps. +This function will return \type{VERIFIED} if the certificate can +safely be considered valid for the usage(s) described by \arg{usage}, +and an error code if it is not. Naturally, things are a bit more +complicated than that. The enum \type{Cert\_Usage} is defined inside +the \type{X509\_Store} class, it (currently) can take on any of the +values \type{ANY} (any usage is OK), \type{TLS\_SERVER} (for SSL/TLS +server authentication), \type{TLS\_CLIENT} (for SSL/TLS client +authentication), \type{CODE\_SIGNING}, \type{EMAIL\_PROTECTION} (email +encryption, usually this means S/MIME), \type{TIME\_STAMPING} (in +theory any time stamp application, usually IETF PKIX's Time Stamp +Protocol), or \type{CRL\_SIGNING}. Note that Microsoft's code signing +system, certainly the most widely used, uses a completely different +(and mostly undocumented) method for marking certificates for code +signing. + +First, how does it know if a certificate is valid? A certificate is +valid if both of the following hold: a) the signature in the +certificate can be verified using the public key in the issuer's +certificate, and b) the issuer's certificate is a valid CA +certificate. Note that this definition is recursive. We get out of +this by ``bottoming out'' when we reach a certificate that we consider +trusted. In general this will either be a commercial root CA, or an +organization or application specific CA. + +There are a few other restrictions (validity periods, key usage +restrictions, etc), but the above summarizes the major points of the +validation algorithm. In theory, Botan implements the certificate path +validation algorithm given in RFC 2459, but in practice it does not +(yet), because we don't support the X.509v3 policy or name constraint +extensions. + +Possible values for \arg{usage} are \type{TLS\_SERVER}, +\type{TLS\_CLIENT}, \type{CODE\_SIGNING}, \type{EMAIL\_PROTECTION}, +\type{CRL\_SIGNING}, and \type{TIME\_STAMPING}, and \type{ANY}. The +default \type{ANY} does not mean valid for any use, it means ``is +valid for some usage''. This is usually what you want; requiring that +a random certificate support a particular usage will likely result in +a lot of failures, unless your application is very careful to always +issue certificates with the proper extensions, and you never use +certificates generated by other apps. Return values for \function{validate\_cert} (and \function{add\_crl}) include: @@ -1777,26 +1715,28 @@ Return values for \function{validate\_cert} (and \function{add\_crl}) include: \subsection{Certificate Authorities} -Setting up a CA for X.509 certificates is actually probably the easiest thing -to do related to X.509. A CA is represented by the type \type{X509\_CA}, which -can be found in \filename{x509\_ca.h}. A CA always needs its own certificate, -which can either be a self-signed certificate (see below on how to create one) -or one issued by another CA (see the section on PKCS \#10 requests). Creating -a CA object is done by the following constructor: +Setting up a CA for X.509 certificates is perhaps the easiest thing to +do related to X.509. A CA is represented by the type \type{X509\_CA}, +which can be found in \filename{x509\_ca.h}. A CA always needs its own +certificate, which can either be a self-signed certificate (see below +on how to create one) or one issued by another CA (see the section on +PKCS \#10 requests). Creating a CA object is done by the following +constructor: \begin{verbatim} - X509_CA(const X509_Certificate& cert, const PKCS8_PrivateKey& key); + X509_CA(const X509_Certificate& cert, const Private_Key& key); \end{verbatim} The private key is the private key corresponding to the public key in the CA's certificate. -Generally, requests for new certificates are supplied to a CA in the form on -PKCS \#10 certificate requests (called a \type{PKCS10\_Request} object in +Requests for new certificates are supplied to a CA in the form on PKCS +\#10 certificate requests (called a \type{PKCS10\_Request} object in Botan). These are decoded in a similar manner to -certificates/CRLs/etc. Generally, a request is vetted by humans (who somehow -verify that the name in the request corresponds to the name of the person who -requested it), and then signed by a CA key, generating a new certificate. +certificates/CRLs/etc. A request is vetted by humans (who somehow +verify that the name in the request corresponds to the name of the +entity who requested it), and then signed by a CA key, generating a +new certificate. \begin{verbatim} X509_Certificate sign_request(const PKCS10_Request&) const; @@ -1810,16 +1750,15 @@ validate any certificate if the appropriate CRLs are not available (though hardly any systems are that strict). In any case, a CA should have a valid CRL available at all times. -Of course, you might be wondering what to do if no certificates have been -revoked. In fact, CRLs can be issued without any actually revoked certificates -- the list of certs will simply be empty. To generate a new, empty CRL, just -call \type{X509\_CRL} -\function{X509\_CA::new\_crl}(\type{u32bit}~\arg{seconds}~=~0)~--~it will -create a new, empty, CRL. If \arg{seconds} is the default 0, then the normal -default CRL next update time (the value of the ``x509/crl/next\_update'') will -be used. If not, then \arg{seconds} specifies how long (in seconds) it will be -until the CRL's next update time (after this time, most clients will reject the -CRL as too old). +Of course, you might be wondering what to do if no certificates have +been revoked. Never fear; empty CRLs, which revoke nothing at all, can +be issued. To generate a new, empty CRL, just call \type{X509\_CRL} +\function{X509\_CA::new\_crl}(\type{u32bit}~\arg{seconds}~=~0)~--~it +will create a new, empty, CRL. If \arg{seconds} is the default 0, then +the normal default CRL next update time (the value of the +``x509/crl/next\_update'') will be used. If not, then \arg{seconds} +specifies how long (in seconds) it will be until the CRL's next update +time (after this time, most clients will reject the CRL as too old). On the other hand, you may have issued a CRL before. In that case, you will want to issue a new CRL that contains all previously revoked @@ -1849,14 +1788,14 @@ case. \subsubsection{Self-Signed Certificates} -Generating a new self-signed certificate can often be useful, for example when -setting up a new root CA, or for use in email applications. In this case, -the solution is summed up simply as: +Generating a new self-signed certificate can often be useful, for +example when setting up a new root CA, or for use in email +applications. The library provides a utility function for this: \begin{verbatim} namespace X509 { X509_Certificate create_self_signed_cert(const X509_Cert_Options& opts, - const PKCS8_PrivateKey& key); + const Private_Key& key); } \end{verbatim} @@ -1875,7 +1814,7 @@ certificate requests. \begin{verbatim} namespace X509 { PKCS10_Request create_cert_req(const X509_Cert_Options&, - const PKCS8_PrivateKey&); + const Private_Key&); } \end{verbatim} @@ -1887,11 +1826,12 @@ minted X.509 certificate. There is an example of using this function in the \subsubsection{Certificate Options} -So what is this \type{X509\_Cert\_Options} thing we've been passing around? -Basically, it's a bunch of information that will end up being stored into the -certificate. This information comes in 3 major flavors: information about the -subject (CA or end-user), the validity period of the certificate, and -restrictions on the usage of the certificate. +What is this \type{X509\_Cert\_Options} thing we've been passing +around? It's a class representing a bunch of information that will end +up being stored into the certificate. This information comes in 3 +major flavors: information about the subject (CA or end-user), the +validity period of the certificate, and restrictions on the usage of +the certificate. First and foremost is a number of \type{std::string} members, which contains various bits of information about the user: \arg{common\_name}, @@ -1922,17 +1862,19 @@ to use is to create (or request) a CA certificate, which can be done by calling the member function \function{CA\_key}. This should only be used when needed. Other constraints can be set by calling the member functions -\function{add\_constraints} and \function{add\_ex\_constraints}. The first -takes a \type{Key\_Constraints} value, and replaces any previously set -value. If no value is set, then the certificate key is marked as being valid -for any usage. You can set it to any of the following (for more than one -usage, OR them together): \type{DIGITAL\_SIGNATURE}, \type{NON\_REPUDIATION}, -\type{KEY\_ENCIPHERMENT}, \type{DATA\_ENCIPHERMENT}, \type{KEY\_AGREEMENT}, -\type{KEY\_CERT\_SIGN}, \type{CRL\_SIGN}, \type{ENCIPHER\_ONLY}, -\type{DECIPHER\_ONLY}. Many of these have quite special semantics, so you -should either consult the appropriate standards document (such as RFC 3280), or -simply not call \function{add\_constraints}, in which case the appropriate -values will be chosen for you. +\function{add\_constraints} and \function{add\_ex\_constraints}. The +first takes a \type{Key\_Constraints} value, and replaces any +previously set value. If no value is set, then the certificate key is +marked as being valid for any usage. You can set it to any of the +following (for more than one usage, OR them together): +\type{DIGITAL\_SIGNATURE}, \type{NON\_REPUDIATION}, +\type{KEY\_ENCIPHERMENT}, \type{DATA\_ENCIPHERMENT}, +\type{KEY\_AGREEMENT}, \type{KEY\_CERT\_SIGN}, \type{CRL\_SIGN}, +\type{ENCIPHER\_ONLY}, \type{DECIPHER\_ONLY}. Many of these have quite +special semantics, so you should either consult the appropriate +standards document (such as RFC 3280), or just not call +\function{add\_constraints}, in which case the appropriate values will +be chosen for you. The second function, \function{add\_ex\_constraints}, allows you to specify an OID that has some meaning with regards to restricting the key to particular @@ -1946,7 +1888,6 @@ for use with S/MIME), ``PKIX.IPsecUser'', ``PKIX.IPsecTunnel'', \function{add\_ex\_constraints} any number of times~--~each new OID will be added to the list to include in the certificate. -\pagebreak \section{The Low-Level Interface} Botan has two different interfaces. The one documented in this section is meant @@ -1972,9 +1913,10 @@ algorithm objects using the functions in \filename{lookup.h}. \noindent \type{void} \function{clear}(): -Clear out the algorithm's internal state. A block cipher object will ``forget'' -its key, a hash function will ``forget'' any data put into it, etc. Basically, -the object will look exactly as it did when you initially allocated it. +Clear out the algorithm's internal state. A block cipher object will +``forget'' its key, a hash function will ``forget'' any data put into +it, etc. The object will look and behave as it did when you initially +allocated it. \noindent \function{clone}(): @@ -1991,9 +1933,10 @@ operator. \subsection{Keys and IVs} -Both symmetric keys and initialization values can simply be considered byte (or -octet) strings. These are represented by the classes \type{SymmetricKey} and -\type{InitializationVector}, which are subclasses of \type{OctetString}. +Both symmetric keys and initialization values can be considered byte +(or octet) strings. These are represented by the classes +\type{SymmetricKey} and \type{InitializationVector}, which are +subclasses of \type{OctetString}. Since often it's hard to distinguish between a key and IV, many things (such as key derivation mechanisms) return \type{OctetString} instead of @@ -2014,14 +1957,20 @@ and stored. Whitespace is ignored. \function{OctetString}(\type{const byte} \arg{input}[], \type{u32bit} \arg{length}): -This constructor simply copies its input. +This constructor copies its input. \subsection{Symmetrically Keyed Algorithms} -Block ciphers, stream ciphers, and MACs all handle keys in pretty much the same -way. To make this similarity explicit, all algorithms of those types are -derived from the \type{SymmetricAlgorithm} base class. This type has three -functions: +Block ciphers, stream ciphers, and MACs are all keyed operations; to +be useful, they have to be set to use a particular key, which is a +randomly chosen string of bits of a specified length. The length +required by any particular algorithm may vary, depending on both the +algorithm specification and the implementation. You can query any +botan object to find out what key length(s) it supports. + +To make this similarity in terms of keying explicit, all algorithms of +those types are derived from the \type{SymmetricAlgorithm} base +class. This type has three functions: \noindent \type{void} \function{set\_key}(\type{const byte} \arg{key}[], \type{u32bit} @@ -2038,13 +1987,13 @@ Most algorithms only accept keys of certain lengths. If you attempt to call This function returns true if a key of the given length will be accepted by the cipher. -There are also three constant data members of every \type{SymmetricAlgorithm} -object, which specify exactly what limits there are on keys which that object -can accept: +There are also three constant data members of every +\type{SymmetricAlgorithm} object, which specify what limits there are +on keys which that object can accept: -MAXIMUM\_KEYLENGTH: The maximum length of a key. Usually, this is at most 32 -(256 bits), even if the algorithm actually supports more. In a few rare cases -larger keys will be supported. +MAXIMUM\_KEYLENGTH: The maximum length of a key. Usually, this is at +most 32 (256 bits), even if the algorithm supports more. In a few rare +cases larger keys will be supported. MINIMUM\_KEYLENGTH: The minimum length of a key. This is at least 1. @@ -2150,29 +2099,30 @@ shown in the second prototype. It will return the hash/mac value in a memory buffer, which will have size OUTPUT\_LENGTH. There is also a pair of functions called \function{process}. They are -essentially a combination of a single \function{update}, and \function{final}. -Both versions return the final value, rather than placing it an array. Calling -\function{process} with a single byte value isn't available, mostly because it -would rarely be useful. - -A MAC can be viewed (in most cases) as simply a keyed hash function, so classes -that are derived from \type{MessageAuthenticationCode} have \function{update} -and \function{final} classes just like a \type{HashFunction} (and like a -\type{HashFunction}, after \function{final} is called, it can be used to make a -new MAC right away; the key is kept around). +a combination of a single \function{update}, and \function{final}. +Both versions return the final value, rather than placing it an +array. Calling \function{process} with a single byte value isn't +available, mostly because it would rarely be useful. + +A MAC can be viewed (in most cases) as a keyed hash function, so +classes that are derived from \type{MessageAuthenticationCode} have +\function{update} and \function{final} classes just like a +\type{HashFunction} (and like a \type{HashFunction}, after +\function{final} is called, it can be used to make a new MAC right +away; the key is kept around). A MAC has the \type{SymmetricAlgorithm} interface in addition to the \type{BufferedComputation} interface. -\pagebreak \section{Random Number Generators} -The random number generators provided in Botan are meant for creating keys, -IVs, padding, nonces, and anything else that requires 'random' data. It is -important to remember that the output of these classes will vary, even if they -are supplied with exactly the same seed (\ie, two \type{Randpool} objects with -similar initial states will not produce the same output, because the value of -high resolution timers is added to the state at various points). +The random number generators provided in Botan are meant for creating +keys, IVs, padding, nonces, and anything else that requires 'random' +data. It is important to remember that the output of these classes +will vary, even if they are supplied with ethe same seed (\ie, two +\type{Randpool} objects with similar initial states will not produce +the same output, because the value of high resolution timers is added +to the state at various points). To ensure good quality output, a PRNG needs to be seeded with truly random data (such as that produced by a hardware RNG). Typically, you will use an @@ -2240,10 +2190,10 @@ been checked against official X9.31 test vectors. Internally, the PRNG holds a pointer to another PRNG (typically Randpool). This internal PRNG generates the key and seed used by the X9.31 algorithm, as well as the date/time vectors. Each time an X9.31 -PRNG object receives entropy, it simply passes it along to the PRNG it -is holding, and then pulls out some random bits to generate a new key -and seed. This PRNG considers itself seeded as soon as the internal -PRNG is seeded. +PRNG object receives entropy, it passes it along to the PRNG it is +holding, and then pulls out some random bits to generate a new key and +seed. This PRNG considers itself seeded as soon as the internal PRNG +is seeded. As of version 1.4.7, the X9.31 PRNG is by default used for all random number generation. @@ -2256,51 +2206,49 @@ you should use an \type{EntropySource} is to pass it to a PRNG that will extract entropy from it -- never use the output directly for any kind of key or nonce generation! -\type{EntropySource} has a pair of functions for getting entropy from some -external source, called \function{fast\_poll} and \function{slow\_poll}. These -pass a buffer of bytes to be written; the functions then return how many bytes -of entropy were actually gathered. \type{EntropySource}s are usually used to -seed the global PRNG using the functions found in the \namespace{Global\_RNG} +\type{EntropySource} has a pair of functions for getting entropy from +some external source, called \function{fast\_poll} and +\function{slow\_poll}. These pass a buffer of bytes to be written; the +functions then return how many bytes of entropy were +gathered. \type{EntropySource}s are usually used to seed the global +PRNG using the functions found in the \namespace{Global\_RNG} namespace. Note for writers of \type{EntropySource}s: it isn't necessary to use any kind of cryptographic hash on your output. The data produced by an EntropySource is only used by an application after it has been hashed by the \type{RandomNumberGenerator} that asked for the entropy, thus any hashing -you do will be wasteful of both CPU cycles and possibly entropy. +you do will be wasteful of both CPU cycles and entropy. -\pagebreak \section{User Interfaces} -Botan has recently changed some infrastructure to better accommodate more -complex user interfaces, in particular ones that are based on event -loops. Primary among these was the fact that when doing something like loading -a PKCS \#8 encoded private key, a passphrase might be needed, but then again it -might not (a PKCS \#8 key doesn't have to be encrypted). Asking for a -passphrase to decrypt an unencrypted key is rather pointless. Not only that, -but the way to handle the user typing the wrong passphrase was complicated, +Botan has recently changed some infrastructure to better accommodate +more complex user interfaces, in particular ones that are based on +event loops. Primary among these was the fact that when doing +something like loading a PKCS \#8 encoded private key, a passphrase +might be needed, but then again it might not (a PKCS \#8 key doesn't +have to be encrypted). Asking for a passphrase to decrypt an +unencrypted key is rather pointless. Not only that, but the way to +handle the user typing the wrong passphrase was complicated, undocumented, and inefficient. -So now Botan has an object called \type{UI}, which provides a simple interface -for the aspects of user interaction the library has to be concerned -with. Currently, this means getting a passphrase from the user, and that's it -(\type{UI} will probably be extended in the future to support other operations -as they are needed). The base \type{UI} class is very stupid, because the -library can't directly assume anything about the environment that it's running -under (for example, if there will be someone sitting at the terminal, if the -application is even \emph{attached} to a terminal, and so on). But since you -can subclass \type{UI} to use whatever method happens to be appropriate for -your application, this isn't a big deal. - -There is (currently) a single function that can be overridden by subclasses of -\type{UI} (the \type{std::string} arguments are actually \type{const -std::string\&}, but shown as simply \type{std::string} to keep the line from -wrapping): +So now Botan has an object called \type{UI}, which provides a simple +interface for the aspects of user interaction the library has to be +concerned with. Currently, this means getting a passphrase from the +user, and that's it (\type{UI} will probably be extended in the future +to support other operations as they are needed). The base \type{UI} +class is very stupid, because the library can't directly assume +anything about the environment that it's running under (for example, +if there will be someone sitting at the terminal, if the application +is even \emph{attached} to a terminal, and so on). But since you can +subclass \type{UI} to use whatever method happens to be appropriate +for your application, this isn't a big deal. -\noindent -\type{std::string} \function{get\_passphrase}(\type{std::string} \arg{what}, - \type{std::string} \arg{source}, - \type{UI\_Result\&} \arg{result}) const; +\begin{verbatim} + std::string get_passphrase(const std::string& what, + const std::string& source, + UI_Result& result) const; +\end{verbatim} The \arg{what} argument specifies what the passphrase is needed for (for example, PKCS \#8 key loading passes \arg{what} as ``PKCS \#8 private @@ -2330,7 +2278,6 @@ application. If you write a \type{UI} object for another windowing system in general (ideally under a permissive license such as public domain or MIT/BSD), feel free to send in a copy. -\pagebreak \section{Botan's Modules} Botan comes with a variety of modules that can be compiled into the system. @@ -2340,10 +2287,10 @@ defined. \subsection{Pipe I/O for Unix File Descriptors} -This is a fairly minor feature, but it comes in handy sometimes. In all +This is a minor feature, but it comes in handy sometimes. In all installations of the library, Botan's \type{Pipe} object overloads the -\keyword{<<} and \keyword{>>} operators for C++ iostream objects, which is -usually more than sufficient for doing I/O. +\keyword{<<} and \keyword{>>} operators for C++ iostream objects, +which is usually more than sufficient for doing I/O. However, there are cases where the iostream hierarchy does not map well to local 'file types', so there is also the ability to do I/O directly with Unix @@ -2357,13 +2304,13 @@ check out the \filename{hash\_fd} example, included in the Botan distribution. \subsection{Entropy Sources} -All of these are used by the \function{Global\_RNG::seed} function if they are -available. Since this function is called by the \type{LibraryInitializer} class -when it is created, it is fairly rare that you will need to deal with any of -these classes directly. Even in the case of a long-running server that needs to -renew its entropy poll, it is easier to simply call -\function{Global\_RNG::seed} (see the section entitled ``The Global PRNG'' for -more details). +All of these are used by the \function{Global\_RNG::seed} function if +they are available. Since this function is called by the +\type{LibraryInitializer} class when it is created, it is rare +that you will need to deal with any of these classes directly. Even in +the case of a long-running server that needs to renew its entropy +poll, it is easier to call \function{Global\_RNG::seed} (see the +section entitled ``The Global PRNG'' for more details). \noindent \type{EGD\_EntropySource}: Query an EGD socket. If the macro @@ -2392,14 +2339,14 @@ of bits are read in order to get that 16 bits). It is declared in use this as a last resort. I don't really trust it, and neither should you. \noindent -\type{Win32\_CAPI\_EntropySource}: This routines gathers entropy from a Win32 -CAPI module. It takes an optional \type{std::string} that will specify what -type of CAPI provider to use. Generally the CAPI RNG is always the same -software-based PRNG, but there are a few that may use a hardware RNG. By -default it will use the first provider listed in the option -``rng/ms\_capi\_prov\_type'' that is available on the machine (currently the -providers ``RSA\_FULL'', ``INTEL\_SEC'', ``FORTEZZA'', and ``RNG'' are -recognized). +\type{Win32\_CAPI\_EntropySource}: This routines gathers entropy from +a Win32 CAPI module. It takes an optional \type{std::string} that will +specify what type of CAPI provider to use. The CAPI RNG is usually a +default software-based PRNG, but there are a few providers that may +use a hardware RNG. By default it will use the first provider listed +in the option ``rng/ms\_capi\_prov\_type'' that is available on the +machine (currently the providers ``RSA\_FULL'', ``INTEL\_SEC'', +``FORTEZZA'', and ``RNG'' are recognized). \noindent \type{BeOS\_EntropySource}: Query system statistics using various BeOS-specific @@ -2443,11 +2390,12 @@ The Bzip2 module was contributed by Peter J. Jones. \subsubsection{Zlib} -Zlib compression works pretty much like Bzip2 compression. The only differences -in this case are that the macro is \macro{BOTAN\_EXT\_COMPRESSOR\_ZLIB}, the -header you need to include is called \filename{botan/zlib.h} (remember that you -shouldn't just \verb|#include <zlib.h>|, or you'll get the regular zlib API, -which is not what you want). The Botan classes for Zlib +Zlib compression works much like Bzip2 compression. The only +differences in this case are that the macro is +\macro{BOTAN\_EXT\_COMPRESSOR\_ZLIB}, the header you need to include +is called \filename{botan/zlib.h} (remember that you shouldn't just +\verb|#include <zlib.h>|, or you'll get the regular zlib API, which is +not what you want). The Botan classes for Zlib compression/decompression are called \type{Zlib\_Compression} and \type{Zlib\_Decompression}. @@ -2485,7 +2433,7 @@ RFC 1950. \subsubsection{Data Sources} A \type{DataSource} is a simple abstraction for a thing that stores bytes. This -type is used fairly heavily in the areas of the API related to ASN.1 +type is used heavily in the areas of the API related to ASN.1 encoding/decoding. The following types are \type{DataSource}s: \type{Pipe}, \type{SecureQueue}, and a couple of special purpose ones: \type{DataSource\_Memory} and \type{DataSource\_Stream}. @@ -2504,13 +2452,13 @@ up a file with that name and read from it. \subsubsection{Data Sinks} -A \type{DataSink} (in \filename{data\_snk.h}) is a \type{Filter} that takes -arbitrary amounts of input, and produces no output. Generally, this means it's -doing something with the data outside the realm of what -\type{Filter}/\type{Pipe} can handle, for example, writing it to a file (which -is what the \type{DataSink\_Stream} does). There is no need for -\type{DataSink}s that write to a \type{std::string} or memory buffer, because -\type{Pipe} can handle that by itself. +A \type{DataSink} (in \filename{data\_snk.h}) is a \type{Filter} that +takes arbitrary amounts of input, and produces no output. This means +it's doing something with the data outside the realm of what +\type{Filter}/\type{Pipe} can handle, for example, writing it to a +file (which is what the \type{DataSink\_Stream} does). There is no +need for \type{DataSink}s that write to a \type{std::string} or memory +buffer, because \type{Pipe} can handle that by itself. Here's a quick example of using a \type{DataSink}, which encrypts \filename{in.txt} and sends the output to \filename{out.txt}. There is @@ -2525,93 +2473,8 @@ implicit. \end{verbatim} A real advantage of this is that even if ``in.txt'' is large, only as -much memory is needed for internal I/O buffers will actually be used. - -\subsection{Writing Modules} - -It's a lot simpler to write modules for Botan that it is to write code -in the core library, for several reasons. First, a module can rely on -external libraries and services beyond the base ISO C++ libraries, and -also machine dependent features. Also, the code can be added at -configuration time on the user's end with very little effort (\ie the -code can be distributed separately, and included by the user without -needing to patch any existing source files). - -Each module lives in a subdirectory of the \filename{modules} -directory, which exists at the top-level of the Botan source tree. The -``short name'' of the module is the same as the name of this -directory. The only required file in this directory is -\filename{info.txt}, which contains directives that specify what a -particular module does, what systems it runs on, and so on. Comments -in \filename{info.txt} start with a \verb|#| character and continue -to end of line. - -Recognized directives include: - -\newcommand{\directive}[2]{ - \vskip 4pt - \noindent - \texttt{#1}: #2 -} - -\directive{realname <name>}{Specify that the 'real world' name of this module - is \texttt{<name>}.} - -\directive{note <note>}{Add a note that will be seen by the end-user at -configure time if the module is included into the library.} - -\directive{require\_version <version>}{Require at configure time that -the version of Botan in use be at least \texttt{<version>}.} - -\directive{define <macro>[,<macro>[,...]]}{Cause the macro - \macro{BOTAN\_EXT\_<macro>} (for each instance of \macro{<macro>} - in the directive) to be defined in \filename{build.h}. This should - only be used if the module creates user-visible changes. There is a - set of conventions that should be followed in deciding what to call - this macro (where xxx denotes some descriptive and distinguishing - characteristic of the thing implemented, such as - \macro{ALLOC\_MLOCK} or \macro{MUTEX\_PTHREAD}): - -\begin{itemize} -\item Allocator: \macro{ALLOC\_xxx} -\item Compressors: \macro{COMPRESSOR\_xxx} -\item EntropySource: \macro{ENTROPY\_SRC\_xxx} -\item Engines: \macro{ENGINE\_xxx} -\item Mutex: \macro{MUTEX\_xxx} -\item Timer: \macro{TIMER\_xxx} -\end{itemize} -} - -\directive{<libs> / </libs>}{This specifies any extra libraries to be -linked in. It is a mapping from OS to library name, for example -\texttt{linux -> rt}, which means that on Linux librt should be linked -in. You can also use ``all'' to force the library to be linked in on -all systems.} - -\directive{<add> / </add>}{Tell the configuration script to add the - files named between these two tags into the source tree. All these - files must exist in the current module directory.} - -\directive{<ignore> / </ignore>}{Tell the configuration script to - ignore the files named in the main source tree. This is useful, for - example, when replacing a C++ implementation with a pure assembly - version.} - -\directive{<replace> / </replace>}{Tell the configuration script to - ignore the file given in the main source tree, and instead use the - one in the module's directory.} - -Additionally, the module file can contain blocks, delimited by the -following pairs: +much memory is needed for internal I/O buffers will be used. -\texttt{<os> / </os>}, \texttt{<arch> / </arch>}, \texttt{<cc> / </cc>} - -\noindent -For example, putting ``alpha'' and ``ia64'' in a \texttt{<arch>} block will -make the configuration script only allow the module to be compiled on those -architectures. Not having a block means any value is acceptable. - -\pagebreak \section{Miscellaneous} This section has documentation for anything that just didn't fit into any of @@ -2621,7 +2484,7 @@ degree of applicability. \subsection{S2K Algorithms} -There are various procedures (usually fairly ad-hoc) for turning a +There are various procedures (usually ad-hoc) for turning a passphrase into a (mostly) arbitrary length key for a symmetric cipher. A general interface for such algorithms is presented in \filename{s2k.h}. The main function is \function{derive\_key}, which @@ -2807,22 +2670,18 @@ application \texttt{setuid} \texttt{root}, and then drop privileges immediately after creating your \type{LibraryInitializer}. If you end up using more than what's been allocated, some of your sensitive data might end up being swappable, but that beats running as \texttt{root} -all the time. BTW, I would note that, at least on Linux, you can use a -kernel module to give your process extra privileges (such as the -ability to call \function{mlock}) without being root. For example, -check out my Capability Override LSM -(\url{http://www.randombit.net/projects/cap\_over/}), which makes this -pretty easy to do. - -These classes should also be used within your own code for storing sensitive -data. They are only meant for primitive data types (int, long, etc): if you -want a container of higher level Botan objects, you can just use a -\verb|std::vector|, since these objects know how to clear themselves when they -are destroyed. You cannot, however, have a \verb|std::vector| (or any other -container) of \type{Pipe}s or \type{Filter}s, because these types have pointers -to other \type{Filter}s, and implementing copy constructors for these types -would be both hard and quite expensive (vectors of pointers to such objects is -fine, though). +all the time. + +These classes should also be used within your own code for storing +sensitive data. They are only meant for primitive data types (int, +long, etc): if you want a container of higher level Botan objects, you +can just use a \verb|std::vector|, since these objects know how to +clear themselves when they are destroyed. You cannot, however, have a +\verb|std::vector| (or any other container) of \type{Pipe}s or +\type{Filter}s, because these types have pointers to other +\type{Filter}s, and implementing copy constructors for these types +would be both hard and quite expensive (vectors of pointers to such +objects is fine, though). These types are not described in any great detail: for more information, consult the definitive sources~--~the header files \filename{secmem.h} and @@ -2842,15 +2701,17 @@ and \function{size}. \subsection{Allocators} -The containers described above get their memory from allocators. As a user of -the library, you can add new allocator methods at run time for containers, -including the ones used internally by the library, to use. The interface to -this is in \filename{allocate.h}. Basically how it works is that code needing -an allocator uses \function{get\_allocator}, which returns a pointer to an -allocator. This pointer should not be freed: the caller does not own the -allocator (it is shared among multiple users, and locks itself as needed). It -is possible to call \function{get\_allocator} with a specific name to request a -particular type of allocator, otherwise, a default allocator type is returned. +The containers described above get their memory from allocators. As a +user of the library, you can add new allocator methods at run time for +containers, including the ones used internally by the library, to +use. The interface to this is in \filename{allocate.h}. Code needing +to allocate or deallocate memory calls \function{get\_allocator}, +which returns a pointer to an allocator object. This pointer should +not be freed: the caller does not own the allocator (it is shared +among multiple allocatore users, and uses a mutex to serialize access +internally if necessary). It is possible to call +\function{get\_allocator} with a specific name to request a particular +type of allocator, otherwise, a default allocator type is returned. At start time, the only allocator known is a \type{Default\_Allocator}, which just allocates memory using \function{malloc}, and \function{memset}s it to 0 @@ -2885,7 +2746,7 @@ the best way to learn is to look at the headers. Probably the most important are the encoding/decoding functions, which transform the normal representation of a \type{BigInt} into some other form, -such as a decimal string. The most useful of these functions are +such as a decimal string. \type{SecureVector<byte>} \function{BigInt::encode}(\type{BigInt}, \type{Encoding}) @@ -2922,7 +2783,7 @@ BigInt. There are several other \type{BigInt} constructors, which I would seriously recommend you avoid, as they are only intended for use internally by the library, and may arbitrarily change, or be removed, in a future release. -An essentially random sampling of \type{BigInt} related functions: +An random sampling of \type{BigInt} related functions: \type{u32bit} \function{BigInt::bytes}(): Return the size of this \type{BigInt} in bytes. @@ -2942,9 +2803,9 @@ primality test with fixed bases. For higher assurance, use \subsubsection{Efficiency Hints} If you can, always use expressions of the form \verb|a += b| over -\verb|a = a + b|. The difference can be \emph{very} substantial, because the -first form prevents at least one needless memory allocation, and possibly as -many as three. +\verb|a = a + b|. The difference can be \emph{very} substantial, +because the first form prevents at least one needless memory +allocation, and possibly as many as three. If you're doing repeated modular exponentiations with the same modulus, create a \type{BarrettReducer} ahead of time. If the exponent or base is a constant, @@ -2954,31 +2815,31 @@ the normal high-level interfaces, of course. Never use the low-level MPI functions (those that begin with \texttt{bigint\_}). These are completely internal to the library, and may make arbitrarily strange and undocumented assumptions about their -inputs, and don't check to see if they are actually true, on the -assumption that only the library itself calls them, and that the -library knows what the assumptions are. The interfaces for these -functions can change completely without notice. +inputs, and don't check to see if they are true, on the assumption +that only the library itself calls them, and that the library knows +what the assumptions are. The interfaces for these functions can +change completely without notice. -\pagebreak \section{Algorithms} \subsection{Recommended Algorithms} -This section is by no means the last word on selecting which algorithms to use. -However, Botan includes a sometimes bewildering array of possible algorithms, -and unless you're familiar with the latest developments in the field, it can be -hard to know what is secure and what is not. The following attributes of the -algorithms were evaluated when making this list: security, standardization, -patent status, support by other implementations, and efficiency (in roughly -that order). +This section is by no means the last word on selecting which +algorithms to use. However, Botan includes a sometimes bewildering +array of possible algorithms, and unless you're familiar with the +latest developments in the field, it can be hard to know what is +secure and what is not. The following attributes of the algorithms +were evaluated when making this list: security, standardization, +patent status, support by other implementations, and efficiency (in +roughly that order). -It is intended as a set of simple guidelines for developers, and nothing more. -It's entirely possible that there are algorithms in Botan that will turn out to -be more secure than the ones listed, but the algorithms listed here are -(currently) thought to be safe. +It is intended as a set of simple guidelines for developers, and +nothing more. It's entirely possible that there are algorithms in +Botan that will turn out to be more secure than the ones listed, but +the algorithms listed here are (currently) thought to be safe. \begin{list}{$\cdot$} - \item Block ciphers: AES or Serpent in CBC or CTR mode + \item Block ciphers: AES or Serpent in CBC, CTR, or XTS mode \item Hash functions: SHA-256, SHA-512 @@ -2986,69 +2847,33 @@ be more secure than the ones listed, but the algorithms listed here are \item Public Key Encryption: RSA with ``EME1(SHA-256)'' - \item Public Key Signatures: RSA with EMSA4 and any recommended hash, or DSA - with ``EMSA1(SHA-256)'' + \item Public Key Signatures: RSA with EMSA4 and any recommended + hash, or DSA or ECDSA with ``EMSA1(SHA-256)'' - \item Key Agreement: Diffie-Hellman, with ``KDF2(SHA-256)'' + \item Key Agreement: Diffie-Hellman or ECDH, with ``KDF2(SHA-256)'' \end{list} -\subsection{Compliance with Standards} - -Botan is/should be at least roughly compatible with many cryptographic -standards, including the following: - -\newcommand{\standard}[2]{ - \vskip 4pt - * #1: \textbf{#2} -} - -\standard{RSA}{PKCS \#1 v2.1, ANSI X9.31} - -\standard{DSA}{ANSI X9.30, FIPS 186-2} - -\standard{Diffie-Hellman}{ANSI X9.42, PKCS \#3} - -\standard{Certificates}{ITU X.509, RFC 3280/3281 (PKIX), PKCS \#9 v2.0, -PKCS \#10} - -\standard{Private Key Formats}{PKCS \#5 v2.0, PKCS \#8} - -\standard{DES/DES-EDE}{FIPS 46-3, ANSI X3.92, ANSI X3.106} - -\standard{SHA-1}{FIPS 180-2} - -\standard{HMAC}{ANSI X9.71, FIPS 198} - -\standard{ANSI X9.19 MAC}{ANSI X9.9, ANSI X9.19} - -\vskip 8pt -\noindent -There is also support for the very general standards of \textbf{IEEE 1363-2000} -and \textbf{1363a}. Most of the contents of such are included in the standards -mentioned above, in various forms (usually with extra restrictions that 1363 -does not impose). - \subsection{Algorithms Listing} Botan includes a very sizable number of cryptographic algorithms. In nearly all cases, you never need to know the header file or type name to use them. However, you do need to know what string (or strings) are -used to identify that algorithm. Generally, these names conform to -those set out by SCAN (Standard Cryptographic Algorithm Naming), which -is a document that specifies how strings are mapped onto algorithm -objects, which is useful for a wide variety of crypto APIs (SCAN is -oriented towards Java, but Botan and several other non-Java libraries -also make at least some use of it). For full details, read the SCAN -document, which can be found at +used to identify that algorithm. These names conform to those set out +by SCAN (Standard Cryptographic Algorithm Naming), which is a document +that specifies how strings are mapped onto algorithm objects, which is +useful for a wide variety of crypto APIs (SCAN is oriented towards +Java, but Botan and several other non-Java libraries also make at +least some use of it). For full details, read the SCAN document, which +can be found at \url{http://www.users.zetnet.co.uk/hopwood/crypto/scan/} Many of these algorithms can take options (such as the number of rounds in a block cipher, the output size of a hash function, etc). These are shown in the following list; all of them default to -reasonable values (unless otherwise marked). There are -algorithm-specific limits on most of them. When you see something like -``HASH'' or ``BLOCK'', that means you should insert the name of some -algorithm of that type. There are no defaults for those options. +reasonable values. There are algorithm-specific limits on most of +them. When you see something like ``HASH'' or ``BLOCK'', that means +you should insert the name of some algorithm of that type. There are +no defaults for those options. A few very obscure algorithms are skipped; if you need one of them, you'll know it, and you can look in the appropriate header to see what @@ -3059,48 +2884,30 @@ match that in SCAN, if it's defined there). \item ROUNDS: The number of rounds in a block cipher. \item \item OUTSZ: The output size of a hash function or MAC - \item PASS: The number of passes in a hash function (more passes generally - means more security). \end{list} \vskip .05in \noindent -\textbf{Block Ciphers:} ``AES'', ``Blowfish'', ``CAST-128'', -``CAST-256'', ``DES'', ``DESX'', ``TripleDES'', ``GOST'', ``IDEA'', -``MARS'', ``MISTY1(ROUNDS)'', ``RC2'', ``RC5(ROUNDS)'', ``RC6'', -``SAFER-SK(ROUNDS)'', ``SEED'', ``Serpent'', ``Skipjack'', ``Square'', -``TEA'', ``Twofish'', ``XTEA'' +\textbf{Block Ciphers:} ``AES'' (and ``AES-128'', ``AES-192'', and +``AES-256''), ``Blowfish'', ``CAST-128'', ``CAST-256'', ``DES'', +``DESX'', ``TripleDES'', ``GOST-28147-89'', ``IDEA'', ``KASUMI'', +``MARS'', ``MISTY1(ROUNDS)'', ``Noekeon'', ``RC2'', ``RC5(ROUNDS)'', +``RC6'', ``SAFER-SK(ROUNDS)'', ``SEED'', ``Serpent'', ``Skipjack'', +``Square'', ``TEA'', ``Twofish'', ``XTEA'' \noindent -\textbf{Stream Ciphers:} ``ARC4'', ``MARK4'', ``Turing'', ``WiderWake4+1-BE'' +\textbf{Stream Ciphers:} ``ARC4'', ``MARK4'', ``Salsa20'', ``Turing'', +``WiderWake4+1-BE'' \noindent -\textbf{Hash Functions:} ``FORK-256'', ``HAS-160'', ``GOST-34.11'', +\textbf{Hash Functions:} ``HAS-160'', ``GOST-34.11'', ``MD2'', ``MD4'', ``MD5'', ``RIPEMD-128'', ``RIPEMD-160'', ``SHA-160'', ``SHA-256'', ``SHA-384'', ``SHA-512'', ``Skein-512'', -``Tiger(OUTSZ,PASS)'', ``Whirlpool'' +``Tiger(OUTSZ)'', ``Whirlpool'' \noindent \textbf{MACs:} ``HMAC(HASH)'', ``CMAC(BLOCK)'', ``X9.19-MAC'' -\subsection{Compatibility} - -Generally, cryptographic algorithms are well standardized, thus -compatibility between implementations is relatively simple (of course, not all -algorithms are supported by all implementations). But there are a few -algorithms that are poorly specified, and these should be avoided if you wish -your data to be processed in the same way by another implementation (including -future versions of Botan). - -The block cipher GOST has a particularly poor specification: there are no -standard Sboxes, and the specification does not give test vectors even for -sample boxes, which leads to issues of endian conventions, etc. - -If you wish maximum portability between different implementations of an -algorithm, it's best to stick to strongly defined and well standardized -algorithms, TripleDES, AES, HMAC, and SHA-256 all being good examples. - -\pagebreak \section{Support and Further Information} \subsection{Patents} @@ -3115,42 +2922,14 @@ not encumbered by patents. If you have any concerns about the patent status of any algorithm you are considering using in an application, please discuss it with your attorney. -\subsection{Recommended Reading} - -It's a very good idea if you have some knowledge of cryptography prior -to trying to use this stuff. You really should read one or more of -these books before seriously using the library (note that the Handbook -of Applied Cryptography is available for free online): - -\setlength{\parskip}{5pt} - -\noindent -\textit{Handbook of Applied Cryptography}, Alfred J. Menezes, -Paul C. Van Oorschot, and Scott A. Vanstone; CRC Press - -\noindent -\textit{Security Engineering -- A Guide to Building Dependable Distributed -Systems}, Ross Anderson; Wiley - -\noindent -\textit{Cryptography: Theory and Practice}, Douglas R. Stinson; CRC Press - -\noindent -\textit{Applied Cryptography, 2nd Ed.}, Bruce Schneier; Wiley - -\noindent -Once you've got the basics down, these are good things to at least take a look -at: IEEE 1363 and 1363a, SCAN, NESSIE, PKCS \#1 v2.1, the security related FIPS -documents, and the CFRG RFCs. - \subsection{Support} Questions or problems you have with Botan can be directed to the development mailing list. Joining this list is highly recommended if you're going to be using Botan, since often advance notice of upcoming changes is sent there. ``Philosophical'' bug reports, announcements of -programs using Botan, and basically anything else having to do with -Botan are also welcome. +programs using Botan, and anything else having to do with Botan are +also welcome. The lists can be found at \url{http://lists.randombit.net/mailman/listinfo/}. @@ -3167,7 +2946,7 @@ Web Site: \url{http://botan.randombit.net} \subsection{License} -Copyright \copyright 2000-2008, Jack Lloyd +Copyright \copyright 2000-2010, Jack Lloyd Licensed under the same terms as the Botan source diff --git a/doc/building.tex b/doc/building.tex index 5d9b0b171..91d3ded42 100644 --- a/doc/building.tex +++ b/doc/building.tex @@ -13,7 +13,7 @@ \title{\textbf{Botan Build Guide}} \author{Jack Lloyd \\ \texttt{[email protected]}} -\date{2009-10-09} +\date{2010-06-10} \newcommand{\filename}[1]{\texttt{#1}} \newcommand{\module}[1]{\texttt{#1}} @@ -42,13 +42,16 @@ the build system, primarily due to lack of access. Please contact the maintainer if you would like to build Botan on such a system. Botan's build is controlled by configure.py, which is a Python -script. Python 2.4 or later is required. +script. Python 2.4 or later is required (but if you want to use the +incompatible Python 3, you must first run the \texttt{2to3} script on +it). \section{For the Impatient} \begin{verbatim} $ ./configure.py [--prefix=/some/directory] $ make +$ make check $ make install \end{verbatim} @@ -63,7 +66,10 @@ spot, you might need to prefix the \texttt{configure.py} command with The first step is to run \filename{configure.py}, which is a Python script that creates various directories, config files, and a Makefile for building everything. The script requires at least Python 2.4; any -later version of Python 2.x should also work. +later version of Python 2.x should also work. If you want to use +Python 3.1, first run the program \texttt{2to3} (included in the +Python distribution) on the script; this will convert the script to +the Python 3.x dialect. The script will attempt to guess what kind of system you are trying to compile for (and will print messages telling you what it guessed). @@ -95,11 +101,15 @@ might not have. For instance to enable zlib support, add \verb|--with-zlib| to your invocation of \verb|configure.py|. You can control which algorithms and modules are built using the -options ``\verb|--enable-modules=MODS|'' and -``\verb|--disable-modules=MODS|'', for instance \\ -``\verb|--enable-modules=blowfish,md5,rsa,zlib --disable-modules=arc4,cmac|''. -Modules not listed on the command line will simply be loaded if needed -or if configured to load by default. +options \verb|--enable-modules=MODS| and +\verb|--disable-modules=MODS|, for instance +\verb|--enable-modules=blowfish,md5,rsa,zlib| and +\verb|--disable-modules=arc4,cmac|. Modules not listed on the command +line will simply be loaded if needed or if configured to load by +default. If you use \verb|--no-autoload|, only the most core modules +will be included; you can then explicitly enable things that you want +to use with enable-modules. This is useful for creating a minimal +build targetted to a specific application. The script tries to guess what kind of makefile to generate, and it almost always guesses correctly (basically, Visual C++ uses NMAKE with @@ -123,8 +133,9 @@ The basic build procedure on Unix and Unix-like systems is: $ make install \end{verbatim} -This will probably default to using GCC, depending on what can be -found within your PATH. +On Unix systems the script will default to using GCC; use +\texttt{--cc} if you want something else. For instance use +\texttt{--cc=icc} for Intel C++ and \texttt{--cc=clang} for Clang. The \verb|make install| target has a default directory in which it will install Botan (typically \verb|/usr/local|). You can override @@ -142,29 +153,31 @@ to include the directory that the Botan libraries were installed into. \subsection{MS Windows} -The situation is not much different here. We'll assume you're using Visual C++ -(for Cygwin, the Unix instructions are probably more relevant). You need to -have a copy of Python installed, and have both Python and Visual C++ in your path. +If you don't want to deal with building botan on Windows, check the +website; commonly prebuild Windows binaries with installers are +available, especially for stable versions. + +The situation is not much different here. We'll assume you're using +Visual C++ (for Cygwin, the Unix instructions are probably more +relevant). You need to have a copy of Python installed, and have both +Python and Visual C++ in your path. \begin{verbatim} > python configure.py --cc=msvc (or --cc=gcc for MinGW) [--cpu=CPU] > nmake > nmake check # optional, but recommended + > nmake install \end{verbatim} For Win95 pre OSR2, the \verb|cryptoapi_rng| module will not work, because CryptoAPI didn't exist. And all versions of NT4 lack the ToolHelp32 interface, which is how \verb|win32_stats| does its slow polls, so a version of the library built with that module will not -load under NT4. Later systems (98/ME/2000/XP) support both methods, so -this shouldn't be much of an issue. +load under NT4. Later versions of Windows support both methods, so +this shouldn't be much of an issue anymore. -Unfortunately, there currently isn't an install script usable on -Windows. Basically all you have to do is copy the newly created -\filename{libbotan.lib} to someplace where you can find it later (say, -\verb|C:\botan\|). Then copy the entire \verb|build\include\botan| -directory, which was constructed when you built the library, into the -same directory. +By default the install target will be 'C:\textbackslash botan'; you +can modify this with the \texttt{--prefix} option. When building your applications, all you have to do is tell the compiler to look for both include files and library files in @@ -208,12 +221,6 @@ perfectly fine. buffers throughout Botan. A good rule of thumb would be to use the page size of your machine. The default should be fine for most, if not all, purposes. -\macro{BOTAN\_GZIP\_OS\_CODE}: The OS code is included in the Gzip header when -compressing. The default is 255, which means 'Unknown'. You can look in RFC -1952 for the full list; the most common are Windows (0) and Unix (3). There is -also a Macintosh (7), but it probably makes more sense to use the Unix code on -OS X. - \subsection{Multiple Builds} It may be useful to run multiple builds with different @@ -239,20 +246,22 @@ enabled at build time; these include: \newcommand{\mod}[2]{\textbf{#1}: #2} \begin{list}{$\cdot$} - \item \mod{bzip2}{Enables an application to perform bzip2 compression - and decompression using the library. Available on any system that has - bzip2.} + \item \mod{bzip2}{Enables an application to perform bzip2 + compression and decompression using the library. Available on any + system that has bzip2. To enable, use option \verb|--with-bzip2|} + + \item \mod{zlib}{Enables an application to perform zlib compression + and decompression using the library. Available on any system that + has zlib. To enable, use option \verb|--with-zlib|} - \item \mod{zlib}{Enables an application to perform zlib compression and - decompression using the library. Available on any system that has - zlib.} + \item \mod{gnump}{An engine that uses GNU MP to speed up PK + operations. GNU MP 4.1 or later is required. To enable, use + option \verb|--with-gnump|} - \item \mod{gnump}{An engine that uses GNU MP to speed up PK operations. - GNU MP 4.1 or later is required.} + \item \mod{openssl}{An engine that uses OpenSSL to speed up public + key operations and some ciphers/hashes. OpenSSL 0.9.7 or later is + required.} To enable, use option \verb|--with-openssl|} - \item \mod{openssl}{An engine that uses OpenSSL to speed up public key - operations and some ciphers/hashes. OpenSSL 0.9.7 or - later is required.} \end{list} \section{Building Applications} @@ -297,11 +306,11 @@ namespaced by the major and minor versions. So it can be used, for instance, as \begin{verbatim} -$ pkg-config botan-1.8 --modversion -1.8.0 -$ pkg-config botan-1.8 --cflags +$ pkg-config botan-1.9 --modversion +1.9.8 +$ pkg-config botan-1.9 --cflags -I/usr/local/include -$ pkg-config botan-1.8 --libs +$ pkg-config botan-1.9 --libs -L/usr/local/lib -lbotan -lm -lbz2 -lpthread -lrt \end{verbatim} @@ -320,7 +329,7 @@ to set the appropriate flags in their Makefile/project file. The Python wrappers for Botan use Boost.Python, so you must have Boost installed. To build the wrappers, add the flag -\verb|--use-boost-python| +\verb|--with-boost-python| to \verb|configure.py|. This will create a second makefile, \verb|Makefile.python|, with instructions for building the Python diff --git a/doc/examples/bench.cpp b/doc/examples/bench.cpp index 7054d8563..fe6bdc839 100644 --- a/doc/examples/bench.cpp +++ b/doc/examples/bench.cpp @@ -47,7 +47,6 @@ const std::string algos[] = { "XTEA", "Adler32", "CRC32", - "FORK-256", "GOST-34.11", "HAS-160", "MD2", diff --git a/doc/examples/factor.cpp b/doc/examples/factor.cpp index c4d37c92b..58b12d9a5 100644 --- a/doc/examples/factor.cpp +++ b/doc/examples/factor.cpp @@ -1,13 +1,12 @@ /* -* (C) 2009 Jack Lloyd +* (C) 2009-2010 Jack Lloyd * * Distributed under the terms of the Botan license +* +* Factor integers using a combination of trial division by small +* primes, and Pollard's Rho algorithm */ -/* - Factor integers using a combination of trial division by small primes, - and Pollard's Rho algorithm -*/ #include <botan/botan.h> #include <botan/reducer.h> #include <botan/numthry.h> @@ -15,8 +14,7 @@ using namespace Botan; #include <algorithm> #include <iostream> -#include <memory> - +#include <iterator> namespace { @@ -142,8 +140,9 @@ int main(int argc, char* argv[]) std::sort(factors.begin(), factors.end()); std::cout << n << ": "; - for(u32bit j = 0; j != factors.size(); j++) - std::cout << factors[j] << " "; + std::copy(factors.begin(), + factors.end(), + std::ostream_iterator<BigInt>(std::cout, " ")); std::cout << "\n"; } catch(std::exception& e) diff --git a/doc/log.txt b/doc/log.txt index aeeffa9d9..69db45f0d 100644 --- a/doc/log.txt +++ b/doc/log.txt @@ -1,8 +1,16 @@ -* 1.9.8-dev, ????-??-?? +* 1.9.9-dev, ????-??-?? + - Increase default iteration counts for private key encryption + - Expand and update the Doxygen documentation + +* 1.9.8, 2010-06-14 + - Add support for wide multiplications on 64-bit Windows - Use constant time multiplication in IDEA - Avoid possible timing attack against OAEP decoding + - Removed FORK-256; rarely used and it has been broken + - Rename --use-boost-python to --with-boost-python - Skip building shared libraries on MinGW/Cygwin + - Fix creation of 512 and 768 bit DL groups using the DSA kosherizer - Fix compilation on GCC versions before 4.3 (missing cpuid.h) - Fix complilation under the Clang compiler diff --git a/doc/python/rsa.py b/doc/python/rsa.py index 09ca22314..8ca95ff8b 100755 --- a/doc/python/rsa.py +++ b/doc/python/rsa.py @@ -2,6 +2,18 @@ import botan +def make_into_c_array(ber): + output = 'static unsigned char key_data[%d] = {\n\t' % (len(ber)) + + for (idx,c) in zip(range(len(ber)), ber): + if idx != 0 and idx % 8 == 0: + output += "\n\t" + output += "0x%s, " % (c.encode('hex')) + + output += "\n};\n" + + return output + rng = botan.RandomNumberGenerator() rsa_priv = botan.RSA_PrivateKey(768, rng) @@ -10,9 +22,11 @@ print rsa_priv.to_string() print int(rsa_priv.get_N()) print int(rsa_priv.get_E()) - rsa_pub = botan.RSA_PublicKey(rsa_priv) +print make_into_c_array(rsa_pub.to_ber()) +#print make_into_c_array(rsa_priv.to_ber()) + key = rng.gen_random(20) ciphertext = rsa_pub.encrypt(key, 'EME1(SHA-1)', rng) @@ -23,7 +37,6 @@ plaintext = rsa_priv.decrypt(ciphertext, 'EME1(SHA-1)') print plaintext == key - signature = rsa_priv.sign(key, 'EMSA4(SHA-256)', rng) print rsa_pub.verify(key, signature, 'EMSA4(SHA-256)') diff --git a/readme.txt b/readme.txt index ded0d9222..7bd33bd4d 100644 --- a/readme.txt +++ b/readme.txt @@ -1,4 +1,5 @@ -Botan 1.9.8-dev, ????-??-?? +Botan 1.9.9-dev, ????-??-?? +http://botan.randombit.net/ Botan is a C++ class library for performing a wide variety of cryptographic operations. @@ -12,18 +13,18 @@ to the botan-devel mailing list: http://lists.randombit.net/mailman/listinfo/botan-devel/ In the doc directory, there should be a set of PDFs, including - -building.pdf - build instructions -api.pdf - the API reference manual -tutorial.pdf - a set of simple examples and tutorials + building.pdf - build instructions + api.pdf - the API reference manual + tutorial.pdf - a set of simple examples and tutorials A set of example programs can be found in the doc/examples directory. +You can also find Doxygen generated documentation online at + http://botan.randombit.net/doxygen -Check http://botan.randombit.net/ for announcements and new -releases. If you'll be developing code using this library, consider -joining the mailing lists to keep up to date with changes and new -releases. +Check the project website for announcements and new releases. If +you'll be developing code using this library, consider joining the +mailing lists to keep up to date with changes. As always, feel free to contact me with any questions or comments. --Jack Lloyd ([email protected]) + - Jack Lloyd ([email protected]) diff --git a/src/algo_factory/algo_cache.h b/src/algo_factory/algo_cache.h index bafea45e9..45c64628d 100644 --- a/src/algo_factory/algo_cache.h +++ b/src/algo_factory/algo_cache.h @@ -30,11 +30,19 @@ template<typename T> class Algorithm_Cache { public: + /** + * @param algo_spec names the requested algorithm + * @param pref_provider suggests a preferred provider + * @return prototype object, or NULL + */ const T* get(const std::string& algo_spec, const std::string& pref_provider); /** * Add a new algorithm implementation to the cache + * @param algo the algorithm prototype object + * @param requested_name how this name will be requested + * @param provider_name is the name of the provider of this prototype */ void add(T* algo, const std::string& requested_name, @@ -42,15 +50,23 @@ class Algorithm_Cache /** * Set the preferred provider + * @param algo_spec names the algorithm + * @param provider names the preferred provider */ void set_preferred_provider(const std::string& algo_spec, const std::string& provider); /** * Return the list of providers of this algorithm + * @param algo_name names the algorithm + * @return list of providers of this algorithm */ std::vector<std::string> providers_of(const std::string& algo_name); + /** + * Constructor + * @param m a mutex to serialize internal access + */ ~Algorithm_Cache(); private: typename std::map<std::string, std::map<std::string, T*> >::const_iterator @@ -62,7 +78,7 @@ class Algorithm_Cache std::map<std::string, std::map<std::string, T*> > algorithms; }; -/** +/* * Look for an algorithm implementation in the cache, also checking aliases * Assumes object lock is held */ @@ -84,7 +100,7 @@ Algorithm_Cache<T>::find_algorithm(const std::string& algo_spec) return algo; } -/** +/* * Look for an algorithm implementation by a particular provider */ template<typename T> @@ -132,7 +148,7 @@ const T* Algorithm_Cache<T>::get(const std::string& algo_spec, return prototype; } -/** +/* * Add an implementation to the cache */ template<typename T> @@ -155,7 +171,7 @@ void Algorithm_Cache<T>::add(T* algo, } } -/** +/* * Find the providers of this algo (if any) */ template<typename T> std::vector<std::string> @@ -180,7 +196,7 @@ Algorithm_Cache<T>::providers_of(const std::string& algo_name) return providers; } -/** +/* * Set the preferred provider for an algorithm */ template<typename T> @@ -192,7 +208,7 @@ void Algorithm_Cache<T>::set_preferred_provider(const std::string& algo_spec, pref_providers[algo_spec] = provider; } -/** +/* * Algorithm_Cache<T> Destructor */ template<typename T> diff --git a/src/algo_factory/algo_factory.cpp b/src/algo_factory/algo_factory.cpp index 5f3e752bd..2de4461cd 100644 --- a/src/algo_factory/algo_factory.cpp +++ b/src/algo_factory/algo_factory.cpp @@ -22,7 +22,7 @@ namespace Botan { namespace { -/** +/* * Template functions for the factory prototype/search algorithm */ template<typename T> @@ -84,7 +84,7 @@ const T* factory_prototype(const std::string& algo_spec, } -/** +/* * Setup caches */ Algorithm_Factory::Algorithm_Factory() @@ -95,7 +95,7 @@ Algorithm_Factory::Algorithm_Factory() mac_cache = new Algorithm_Cache<MessageAuthenticationCode>(); } -/** +/* * Delete all engines */ Algorithm_Factory::~Algorithm_Factory() @@ -114,7 +114,7 @@ void Algorithm_Factory::add_engine(Engine* engine) engines.push_back(engine); } -/** +/* * Set the preferred provider for an algorithm */ void Algorithm_Factory::set_preferred_provider(const std::string& algo_spec, @@ -130,7 +130,7 @@ void Algorithm_Factory::set_preferred_provider(const std::string& algo_spec, mac_cache->set_preferred_provider(algo_spec, provider); } -/** +/* * Get an engine out of the list */ Engine* Algorithm_Factory::get_engine_n(u32bit n) const @@ -140,7 +140,7 @@ Engine* Algorithm_Factory::get_engine_n(u32bit n) const return engines[n]; } -/** +/* * Return the possible providers of a request * Note: assumes you don't have different types by the same name */ @@ -164,7 +164,7 @@ Algorithm_Factory::providers_of(const std::string& algo_spec) return std::vector<std::string>(); } -/** +/* * Return the prototypical block cipher corresponding to this request */ const BlockCipher* @@ -175,7 +175,7 @@ Algorithm_Factory::prototype_block_cipher(const std::string& algo_spec, *this, block_cipher_cache); } -/** +/* * Return the prototypical stream cipher corresponding to this request */ const StreamCipher* @@ -186,7 +186,7 @@ Algorithm_Factory::prototype_stream_cipher(const std::string& algo_spec, *this, stream_cipher_cache); } -/** +/* * Return the prototypical object corresponding to this request (if found) */ const HashFunction* @@ -197,7 +197,7 @@ Algorithm_Factory::prototype_hash_function(const std::string& algo_spec, *this, hash_cache); } -/** +/* * Return the prototypical object corresponding to this request */ const MessageAuthenticationCode* @@ -209,7 +209,7 @@ Algorithm_Factory::prototype_mac(const std::string& algo_spec, *this, mac_cache); } -/** +/* * Return a new block cipher corresponding to this request */ BlockCipher* @@ -221,7 +221,7 @@ Algorithm_Factory::make_block_cipher(const std::string& algo_spec, throw Algorithm_Not_Found(algo_spec); } -/** +/* * Return a new stream cipher corresponding to this request */ StreamCipher* @@ -233,7 +233,7 @@ Algorithm_Factory::make_stream_cipher(const std::string& algo_spec, throw Algorithm_Not_Found(algo_spec); } -/** +/* * Return a new object corresponding to this request */ HashFunction* @@ -245,7 +245,7 @@ Algorithm_Factory::make_hash_function(const std::string& algo_spec, throw Algorithm_Not_Found(algo_spec); } -/** +/* * Return a new object corresponding to this request */ MessageAuthenticationCode* @@ -257,7 +257,7 @@ Algorithm_Factory::make_mac(const std::string& algo_spec, throw Algorithm_Not_Found(algo_spec); } -/** +/* * Add a new block cipher */ void Algorithm_Factory::add_block_cipher(BlockCipher* block_cipher, @@ -266,7 +266,7 @@ void Algorithm_Factory::add_block_cipher(BlockCipher* block_cipher, block_cipher_cache->add(block_cipher, block_cipher->name(), provider); } -/** +/* * Add a new stream cipher */ void Algorithm_Factory::add_stream_cipher(StreamCipher* stream_cipher, @@ -275,7 +275,7 @@ void Algorithm_Factory::add_stream_cipher(StreamCipher* stream_cipher, stream_cipher_cache->add(stream_cipher, stream_cipher->name(), provider); } -/** +/* * Add a new hash */ void Algorithm_Factory::add_hash_function(HashFunction* hash, @@ -284,7 +284,7 @@ void Algorithm_Factory::add_hash_function(HashFunction* hash, hash_cache->add(hash, hash->name(), provider); } -/** +/* * Add a new mac */ void Algorithm_Factory::add_mac(MessageAuthenticationCode* mac, diff --git a/src/algo_factory/algo_factory.h b/src/algo_factory/algo_factory.h index 92653ab66..881194f0c 100644 --- a/src/algo_factory/algo_factory.h +++ b/src/algo_factory/algo_factory.h @@ -1,4 +1,4 @@ -/** +/* * Algorithm Factory * (C) 2008 Jack Lloyd * @@ -154,13 +154,21 @@ class BOTAN_DLL Algorithm_Factory void add_mac(MessageAuthenticationCode* algo, const std::string& provider); - /* - * Deprecated + /** + * An iterator for the engines in this factory + * @deprecated */ class BOTAN_DLL Engine_Iterator { public: + /** + * @return next engine in the sequence + */ class Engine* next() { return af.get_engine_n(n++); } + + /** + * @param a an algorithm factory + */ Engine_Iterator(const Algorithm_Factory& a) : af(a) { n = 0; } private: const Algorithm_Factory& af; diff --git a/src/algo_factory/prov_weight.cpp b/src/algo_factory/prov_weight.cpp index 17284d024..0ca588aa9 100644 --- a/src/algo_factory/prov_weight.cpp +++ b/src/algo_factory/prov_weight.cpp @@ -1,4 +1,4 @@ -/** +/* * Default provider weights for Algorithm_Cache * (C) 2008 Jack Lloyd * diff --git a/src/alloc/alloc_mmap/mmap_mem.cpp b/src/alloc/alloc_mmap/mmap_mem.cpp index 4a7019ae7..a2059a6ea 100644 --- a/src/alloc/alloc_mmap/mmap_mem.cpp +++ b/src/alloc/alloc_mmap/mmap_mem.cpp @@ -6,6 +6,7 @@ */ #include <botan/internal/mmap_mem.h> +#include <vector> #include <cstring> #include <sys/types.h> @@ -44,29 +45,38 @@ void* MemoryMapping_Allocator::alloc_block(u32bit n) { public: int get_fd() const { return fd; } - const std::string path() const { return filepath; } TemporaryFile(const std::string& base) { - const std::string path = base + "XXXXXX"; + const std::string mkstemp_template = base + "XXXXXX"; - filepath = new char[path.length() + 1]; - std::strcpy(filepath, path.c_str()); + std::vector<char> filepath(mkstemp_template.begin(), + mkstemp_template.end()); + filepath.push_back(0); // add terminating NULL mode_t old_umask = ::umask(077); - fd = ::mkstemp(filepath); + fd = ::mkstemp(&filepath[0]); ::umask(old_umask); + + if(fd == -1) + throw MemoryMapping_Failed("Temporary file allocation failed"); + + if(::unlink(&filepath[0]) != 0) + throw MemoryMapping_Failed("Could not unlink temporary file"); } ~TemporaryFile() { - delete[] filepath; + /* + * We can safely close here, because post-mmap the file + * will continue to exist until the mmap is unmapped from + * our address space upon deallocation. + */ if(fd != -1 && ::close(fd) == -1) throw MemoryMapping_Failed("Could not close file"); } private: int fd; - char* filepath; }; TemporaryFile file("/tmp/botan_"); @@ -74,9 +84,6 @@ void* MemoryMapping_Allocator::alloc_block(u32bit n) if(file.get_fd() == -1) throw MemoryMapping_Failed("Could not create file"); - if(::unlink(file.path().c_str())) - throw MemoryMapping_Failed("Could not unlink file '" + file.path() + "'"); - if(::lseek(file.get_fd(), n-1, SEEK_SET) < 0) throw MemoryMapping_Failed("Could not seek file"); diff --git a/src/alloc/alloc_mmap/mmap_mem.h b/src/alloc/alloc_mmap/mmap_mem.h index 14caf5db1..890658ebc 100644 --- a/src/alloc/alloc_mmap/mmap_mem.h +++ b/src/alloc/alloc_mmap/mmap_mem.h @@ -12,8 +12,11 @@ namespace Botan { -/* -* Memory Mapping Allocator +/** +* Allocator that uses memory maps backed by disk. We zeroize the map +* upon deallocation. If swap occurs, the VM will swap to the shared +* file backing rather than to a swap device, which means we know where +* it is and can zap it later. */ class MemoryMapping_Allocator : public Pooling_Allocator { diff --git a/src/alloc/allocate.h b/src/alloc/allocate.h index 180f2c021..819e2542c 100644 --- a/src/alloc/allocate.h +++ b/src/alloc/allocate.h @@ -13,7 +13,7 @@ namespace Botan { -/* +/** * Allocator Interface */ class BOTAN_DLL Allocator diff --git a/src/alloc/mem_pool/mem_pool.h b/src/alloc/mem_pool/mem_pool.h index f0a564965..f2b57a73b 100644 --- a/src/alloc/mem_pool/mem_pool.h +++ b/src/alloc/mem_pool/mem_pool.h @@ -16,7 +16,7 @@ namespace Botan { -/* +/** * Pooling Allocator */ class Pooling_Allocator : public Allocator diff --git a/src/alloc/secmem.h b/src/alloc/secmem.h index b3b3fa973..39b5549a9 100644 --- a/src/alloc/secmem.h +++ b/src/alloc/secmem.h @@ -24,7 +24,7 @@ class MemoryRegion /** * Find out the size of the buffer, i.e. how many objects of type T it * contains. - * @return the size of the buffer + * @return size of the buffer */ u32bit size() const { return used; } @@ -36,37 +36,37 @@ class MemoryRegion /** * Get a pointer to the first element in the buffer. - * @return a pointer to the first element in the buffer + * @return pointer to the first element in the buffer */ operator T* () { return buf; } /** * Get a constant pointer to the first element in the buffer. - * @return a constant pointer to the first element in the buffer + * @return constant pointer to the first element in the buffer */ operator const T* () const { return buf; } /** * Get a pointer to the first element in the buffer. - * @return a pointer to the first element in the buffer + * @return pointer to the first element in the buffer */ T* begin() { return buf; } /** * Get a constant pointer to the first element in the buffer. - * @return a constant pointer to the first element in the buffer + * @return constant pointer to the first element in the buffer */ const T* begin() const { return buf; } /** * Get a pointer to the last element in the buffer. - * @return a pointer to the last element in the buffer + * @return pointer to the last element in the buffer */ T* end() { return (buf + size()); } /** * Get a constant pointer to the last element in the buffer. - * @return a constant pointer to the last element in the buffer + * @return constant pointer to the last element in the buffer */ const T* end() const { return (buf + size()); } @@ -97,8 +97,8 @@ class MemoryRegion /** * Copy the contents of another buffer into this buffer. * The former contents of *this are discarded. - * @param in the buffer to copy the contents from. - * @return a reference to *this + * @param other the buffer to copy the contents from. + * @return reference to *this */ MemoryRegion<T>& operator=(const MemoryRegion<T>& other) { if(this != &other) set(other); return (*this); } @@ -156,7 +156,7 @@ class MemoryRegion /** * Append data to the end of this buffer. - * @param data the buffer containing the data to append + * @param other the buffer containing the data to append */ void append(const MemoryRegion<T>& other) { append(other.begin(), other.size()); } @@ -299,7 +299,7 @@ class MemoryVector : public MemoryRegion<T> /** * Copy the contents of another buffer into this buffer. * @param in the buffer to copy the contents from - * @return a reference to *this + * @return reference to *this */ MemoryVector<T>& operator=(const MemoryRegion<T>& in) { if(this != &in) set(in); return (*this); } @@ -352,7 +352,7 @@ class SecureVector : public MemoryRegion<T> /** * Copy the contents of another buffer into this buffer. * @param in the buffer to copy the contents from - * @return a reference to *this + * @return reference to *this */ SecureVector<T>& operator=(const MemoryRegion<T>& in) { if(this != &in) set(in); return (*this); } diff --git a/src/alloc/system_alloc/defalloc.h b/src/alloc/system_alloc/defalloc.h index 436549540..54583d7b1 100644 --- a/src/alloc/system_alloc/defalloc.h +++ b/src/alloc/system_alloc/defalloc.h @@ -12,8 +12,8 @@ namespace Botan { -/* -* Malloc Allocator +/** +* Allocator using malloc */ class Malloc_Allocator : public Allocator { @@ -24,8 +24,8 @@ class Malloc_Allocator : public Allocator std::string type() const { return "malloc"; } }; -/* -* Locking Allocator +/** +* Allocator using malloc plus locking */ class Locking_Allocator : public Pooling_Allocator { diff --git a/src/asn1/alg_id.h b/src/asn1/alg_id.h index 4a1ad2f30..417a71b30 100644 --- a/src/asn1/alg_id.h +++ b/src/asn1/alg_id.h @@ -14,7 +14,7 @@ namespace Botan { -/* +/** * Algorithm Identifier */ class BOTAN_DLL AlgorithmIdentifier : public ASN1_Object diff --git a/src/asn1/asn1_int.h b/src/asn1/asn1_int.h index e6fb09398..3562f692b 100644 --- a/src/asn1/asn1_int.h +++ b/src/asn1/asn1_int.h @@ -13,7 +13,7 @@ namespace Botan { -/* +/** * ASN.1 Type and Class Tags */ enum ASN1_Tag { @@ -50,7 +50,7 @@ enum ASN1_Tag { DIRECTORY_STRING = 0xFF01 }; -/* +/** * Basic ASN.1 Object Interface */ class BOTAN_DLL ASN1_Object @@ -61,7 +61,7 @@ class BOTAN_DLL ASN1_Object virtual ~ASN1_Object() {} }; -/* +/** * BER Encoded Object */ class BOTAN_DLL BER_Object @@ -86,7 +86,7 @@ bool maybe_BER(DataSource&); } -/* +/** * General BER Decoding Error Exception */ struct BOTAN_DLL BER_Decoding_Error : public Decoding_Error @@ -94,7 +94,7 @@ struct BOTAN_DLL BER_Decoding_Error : public Decoding_Error BER_Decoding_Error(const std::string&); }; -/* +/** * Exception For Incorrect BER Taggings */ struct BOTAN_DLL BER_Bad_Tag : public BER_Decoding_Error diff --git a/src/asn1/asn1_obj.h b/src/asn1/asn1_obj.h index a640f712b..c0b74ea0e 100644 --- a/src/asn1/asn1_obj.h +++ b/src/asn1/asn1_obj.h @@ -18,7 +18,7 @@ namespace Botan { -/* +/** * Attribute */ class BOTAN_DLL Attribute : public ASN1_Object @@ -35,7 +35,7 @@ class BOTAN_DLL Attribute : public ASN1_Object Attribute(const std::string&, const MemoryRegion<byte>&); }; -/* +/** * X.509 Time */ class BOTAN_DLL X509_Time : public ASN1_Object @@ -62,7 +62,7 @@ class BOTAN_DLL X509_Time : public ASN1_Object ASN1_Tag tag; }; -/* +/** * Simple String */ class BOTAN_DLL ASN1_String : public ASN1_Object @@ -83,7 +83,7 @@ class BOTAN_DLL ASN1_String : public ASN1_Object ASN1_Tag tag; }; -/* +/** * Distinguished Name */ class BOTAN_DLL X509_DN : public ASN1_Object @@ -113,7 +113,7 @@ class BOTAN_DLL X509_DN : public ASN1_Object MemoryVector<byte> dn_bits; }; -/* +/** * Alternative Name */ class BOTAN_DLL AlternativeName : public ASN1_Object diff --git a/src/asn1/asn1_oid.h b/src/asn1/asn1_oid.h index e6d077bee..b3db97744 100644 --- a/src/asn1/asn1_oid.h +++ b/src/asn1/asn1_oid.h @@ -31,13 +31,13 @@ class BOTAN_DLL OID : public ASN1_Object /** * Get this OID as list (vector) of its components. - * @return a vector representing this OID + * @return vector representing this OID */ std::vector<u32bit> get_id() const { return id; } /** * Get this OID as a string - * @return a string representing this OID + * @return string representing this OID */ std::string as_string() const; @@ -55,7 +55,7 @@ class BOTAN_DLL OID : public ASN1_Object /** * Add a component to this OID. * @param new_comp the new component to add to the end of this OID - * @return a reference to *this + * @return reference to *this */ OID& operator+=(u32bit new_comp); diff --git a/src/asn1/ber_dec.h b/src/asn1/ber_dec.h index 359b2e7dd..296d11037 100644 --- a/src/asn1/ber_dec.h +++ b/src/asn1/ber_dec.h @@ -13,7 +13,7 @@ namespace Botan { -/* +/** * BER Decoding Object */ class BOTAN_DLL BER_Decoder diff --git a/src/asn1/der_enc.h b/src/asn1/der_enc.h index 23b5297e5..ae10b4bc8 100644 --- a/src/asn1/der_enc.h +++ b/src/asn1/der_enc.h @@ -13,7 +13,10 @@ namespace Botan { -/* +class BigInt; +class ASN1_Object; + +/** * General DER Encoding Object */ class BOTAN_DLL DER_Encoder @@ -33,13 +36,13 @@ class BOTAN_DLL DER_Encoder DER_Encoder& encode_null(); DER_Encoder& encode(bool); DER_Encoder& encode(u32bit); - DER_Encoder& encode(const class BigInt&); + DER_Encoder& encode(const BigInt&); DER_Encoder& encode(const MemoryRegion<byte>&, ASN1_Tag); DER_Encoder& encode(const byte[], u32bit, ASN1_Tag); DER_Encoder& encode(bool, ASN1_Tag, ASN1_Tag = CONTEXT_SPECIFIC); DER_Encoder& encode(u32bit, ASN1_Tag, ASN1_Tag = CONTEXT_SPECIFIC); - DER_Encoder& encode(const class BigInt&, ASN1_Tag, + DER_Encoder& encode(const BigInt&, ASN1_Tag, ASN1_Tag = CONTEXT_SPECIFIC); DER_Encoder& encode(const MemoryRegion<byte>&, ASN1_Tag, ASN1_Tag, ASN1_Tag = CONTEXT_SPECIFIC); @@ -62,7 +65,7 @@ class BOTAN_DLL DER_Encoder return (*this); } - DER_Encoder& encode(const class ASN1_Object&); + DER_Encoder& encode(const ASN1_Object&); DER_Encoder& encode_if(bool, DER_Encoder&); DER_Encoder& add_object(ASN1_Tag, ASN1_Tag, const byte[], u32bit); diff --git a/src/benchmark/benchmark.cpp b/src/benchmark/benchmark.cpp index 2b0ed7cb6..3ae4e1d5e 100644 --- a/src/benchmark/benchmark.cpp +++ b/src/benchmark/benchmark.cpp @@ -1,4 +1,4 @@ -/** +/* * Runtime benchmarking * (C) 2008-2009 Jack Lloyd * diff --git a/src/benchmark/benchmark.h b/src/benchmark/benchmark.h index baabc14ca..dfd2d7050 100644 --- a/src/benchmark/benchmark.h +++ b/src/benchmark/benchmark.h @@ -1,4 +1,4 @@ -/** +/* * Runtime benchmarking * (C) 2008-2009 Jack Lloyd * diff --git a/src/block/aes/aes.cpp b/src/block/aes/aes.cpp index df2674f34..bf9a4198b 100644 --- a/src/block/aes/aes.cpp +++ b/src/block/aes/aes.cpp @@ -1,4 +1,4 @@ -/** +/* * AES * (C) 1999-2009 Jack Lloyd * @@ -409,7 +409,7 @@ const u32bit TD[1024] = { } -/** +/* * AES Encryption */ void AES::encrypt_n(const byte in[], byte out[], u32bit blocks) const @@ -503,7 +503,7 @@ void AES::encrypt_n(const byte in[], byte out[], u32bit blocks) const } } -/** +/* * AES Decryption */ void AES::decrypt_n(const byte in[], byte out[], u32bit blocks) const @@ -583,7 +583,7 @@ void AES::decrypt_n(const byte in[], byte out[], u32bit blocks) const } } -/** +/* * AES Key Schedule */ void AES::key_schedule(const byte key[], u32bit length) @@ -636,7 +636,7 @@ void AES::key_schedule(const byte key[], u32bit length) DK.copy(XDK, length + 24); } -/** +/* * AES Byte Substitution */ u32bit AES::S(u32bit input) @@ -645,7 +645,7 @@ u32bit AES::S(u32bit input) SE[get_byte(2, input)], SE[get_byte(3, input)]); } -/** +/* * AES Constructor */ AES::AES(u32bit key_size) : BlockCipher(16, key_size) @@ -655,7 +655,7 @@ AES::AES(u32bit key_size) : BlockCipher(16, key_size) ROUNDS = (key_size / 4) + 6; } -/** +/* * Clear memory of sensitive data */ void AES::clear() diff --git a/src/block/aes/aes.h b/src/block/aes/aes.h index 45026f732..8770bdb35 100644 --- a/src/block/aes/aes.h +++ b/src/block/aes/aes.h @@ -1,4 +1,4 @@ -/** +/* * AES * (C) 1999-2009 Jack Lloyd * @@ -26,7 +26,12 @@ class BOTAN_DLL AES : public BlockCipher BlockCipher* clone() const { return new AES; } AES() : BlockCipher(16, 16, 32, 8) { ROUNDS = 14; } - AES(u32bit); + + /** + * AES fixed to a particular key_size (16, 24, or 32 bytes) + * @param key_size the chosen fixed key size + */ + AES(u32bit key_size); private: void key_schedule(const byte[], u32bit); static u32bit S(u32bit); diff --git a/src/block/aes_intel/aes_intel.cpp b/src/block/aes_intel/aes_intel.cpp index 3d3683d7d..211bb3b47 100644 --- a/src/block/aes_intel/aes_intel.cpp +++ b/src/block/aes_intel/aes_intel.cpp @@ -1,4 +1,4 @@ -/** +/* * AES using Intel's AES-NI instructions * (C) 2009 Jack Lloyd * @@ -100,7 +100,7 @@ __m128i aes_256_key_expansion(__m128i key, __m128i key2) B3 = _mm_aesdeclast_si128(B3, K); \ } while(0) -/** +/* * AES-128 Encryption */ void AES_128_Intel::encrypt_n(const byte in[], byte out[], u32bit blocks) const @@ -176,7 +176,7 @@ void AES_128_Intel::encrypt_n(const byte in[], byte out[], u32bit blocks) const } } -/** +/* * AES-128 Decryption */ void AES_128_Intel::decrypt_n(const byte in[], byte out[], u32bit blocks) const @@ -252,7 +252,7 @@ void AES_128_Intel::decrypt_n(const byte in[], byte out[], u32bit blocks) const } } -/** +/* * AES-128 Key Schedule */ void AES_128_Intel::key_schedule(const byte key[], u32bit) @@ -301,7 +301,7 @@ void AES_128_Intel::key_schedule(const byte key[], u32bit) _mm_storeu_si128(DK_mm + 10, K0); } -/** +/* * Clear memory of sensitive data */ void AES_128_Intel::clear() @@ -310,7 +310,7 @@ void AES_128_Intel::clear() DK.clear(); } -/** +/* * AES-192 Encryption */ void AES_192_Intel::encrypt_n(const byte in[], byte out[], u32bit blocks) const @@ -392,7 +392,7 @@ void AES_192_Intel::encrypt_n(const byte in[], byte out[], u32bit blocks) const } } -/** +/* * AES-192 Decryption */ void AES_192_Intel::decrypt_n(const byte in[], byte out[], u32bit blocks) const @@ -474,7 +474,7 @@ void AES_192_Intel::decrypt_n(const byte in[], byte out[], u32bit blocks) const } } -/** +/* * AES-192 Key Schedule */ void AES_192_Intel::key_schedule(const byte key[], u32bit) @@ -517,7 +517,7 @@ void AES_192_Intel::key_schedule(const byte key[], u32bit) _mm_storeu_si128(DK_mm + 12, EK_mm[0]); } -/** +/* * Clear memory of sensitive data */ void AES_192_Intel::clear() @@ -526,7 +526,7 @@ void AES_192_Intel::clear() DK.clear(); } -/** +/* * AES-256 Encryption */ void AES_256_Intel::encrypt_n(const byte in[], byte out[], u32bit blocks) const @@ -614,7 +614,7 @@ void AES_256_Intel::encrypt_n(const byte in[], byte out[], u32bit blocks) const } } -/** +/* * AES-256 Decryption */ void AES_256_Intel::decrypt_n(const byte in[], byte out[], u32bit blocks) const @@ -702,7 +702,7 @@ void AES_256_Intel::decrypt_n(const byte in[], byte out[], u32bit blocks) const } } -/** +/* * AES-256 Key Schedule */ void AES_256_Intel::key_schedule(const byte key[], u32bit) @@ -767,7 +767,7 @@ void AES_256_Intel::key_schedule(const byte key[], u32bit) _mm_storeu_si128(DK_mm + 14, K0); } -/** +/* * Clear memory of sensitive data */ void AES_256_Intel::clear() diff --git a/src/block/aes_intel/aes_intel.h b/src/block/aes_intel/aes_intel.h index a3ebf153b..592fb7faa 100644 --- a/src/block/aes_intel/aes_intel.h +++ b/src/block/aes_intel/aes_intel.h @@ -1,4 +1,4 @@ -/** +/* * AES using Intel's AES-NI instructions * (C) 2009 Jack Lloyd * @@ -18,7 +18,7 @@ namespace Botan { class BOTAN_DLL AES_128_Intel : public BlockCipher { public: - u32bit parallelism() const { return 8; } + u32bit parallelism() const { return 4; } void encrypt_n(const byte in[], byte out[], u32bit blocks) const; void decrypt_n(const byte in[], byte out[], u32bit blocks) const; @@ -40,7 +40,7 @@ class BOTAN_DLL AES_128_Intel : public BlockCipher class BOTAN_DLL AES_192_Intel : public BlockCipher { public: - u32bit parallelism() const { return 8; } + u32bit parallelism() const { return 4; } void encrypt_n(const byte in[], byte out[], u32bit blocks) const; void decrypt_n(const byte in[], byte out[], u32bit blocks) const; @@ -62,7 +62,7 @@ class BOTAN_DLL AES_192_Intel : public BlockCipher class BOTAN_DLL AES_256_Intel : public BlockCipher { public: - u32bit parallelism() const { return 8; } + u32bit parallelism() const { return 4; } void encrypt_n(const byte in[], byte out[], u32bit blocks) const; void decrypt_n(const byte in[], byte out[], u32bit blocks) const; diff --git a/src/block/aes_intel/info.txt b/src/block/aes_intel/info.txt index 6e67a6ed9..8bf0f07ee 100644 --- a/src/block/aes_intel/info.txt +++ b/src/block/aes_intel/info.txt @@ -2,7 +2,7 @@ define AES_INTEL load_on auto -need_isa aes_ni +need_isa aes-ni <requires> aes_isa_eng diff --git a/src/block/block_cipher.h b/src/block/block_cipher.h index 2d9198c58..c1b58996e 100644 --- a/src/block/block_cipher.h +++ b/src/block/block_cipher.h @@ -1,4 +1,4 @@ -/** +/* * Block Cipher Base Class * (C) 1999-2009 Jack Lloyd * @@ -19,14 +19,38 @@ class BOTAN_DLL BlockCipher : public SymmetricAlgorithm { public: /** + * BlockCipher constructor + * @param block_size the size of blocks this cipher processes + * @param key_min the minimum key size + * @param key_max the maximum key size + * @param key_mod the modulo restriction on the key size + */ + BlockCipher(u32bit block_size, + u32bit key_min, + u32bit key_max = 0, + u32bit key_mod = 1) : + SymmetricAlgorithm(key_min, key_max, key_mod), + BLOCK_SIZE(block_size) {} + + virtual ~BlockCipher() {} + + /** * The block size of this algorithm. */ const u32bit BLOCK_SIZE; /** - * @return the preferred parallelism of this cipher + * @return native parallelism of this cipher in blocks */ - virtual u32bit parallelism() const { return 4; } + virtual u32bit parallelism() const { return 1; } + + /** + * @return prefererred parallelism of this cipher in bytes + */ + u32bit parallel_bytes() const + { + return parallelism() * BLOCK_SIZE * BOTAN_BLOCK_CIPHER_PAR_MULT; + } /** * Encrypt a block. @@ -50,7 +74,7 @@ class BOTAN_DLL BlockCipher : public SymmetricAlgorithm /** * Encrypt a block. - * @param in The plaintext block to be encrypted as a byte array. + * @param block the plaintext block to be encrypted * Must be of length BLOCK_SIZE. Will hold the result when the function * has finished. */ @@ -58,7 +82,7 @@ class BOTAN_DLL BlockCipher : public SymmetricAlgorithm /** * Decrypt a block. - * @param in The ciphertext block to be decrypted as a byte array. + * @param block the ciphertext block to be decrypted * Must be of length BLOCK_SIZE. Will hold the result when the function * has finished. */ @@ -91,15 +115,6 @@ class BOTAN_DLL BlockCipher : public SymmetricAlgorithm * Zeroize internal state */ virtual void clear() = 0; - - BlockCipher(u32bit block_size, - u32bit key_min, - u32bit key_max = 0, - u32bit key_mod = 1) : - SymmetricAlgorithm(key_min, key_max, key_mod), - BLOCK_SIZE(block_size) {} - - virtual ~BlockCipher() {} }; } diff --git a/src/block/blowfish/blowfish.h b/src/block/blowfish/blowfish.h index 2306f0e37..a178ec488 100644 --- a/src/block/blowfish/blowfish.h +++ b/src/block/blowfish/blowfish.h @@ -12,7 +12,7 @@ namespace Botan { -/* +/** * Blowfish */ class BOTAN_DLL Blowfish : public BlockCipher diff --git a/src/block/cascade/cascade.h b/src/block/cascade/cascade.h index 98c64fb3e..abd9b015d 100644 --- a/src/block/cascade/cascade.h +++ b/src/block/cascade/cascade.h @@ -12,7 +12,7 @@ namespace Botan { -/* +/** * Block Cipher Cascade */ class BOTAN_DLL Cascade_Cipher : public BlockCipher @@ -25,6 +25,11 @@ class BOTAN_DLL Cascade_Cipher : public BlockCipher std::string name() const; BlockCipher* clone() const; + /** + * Create a cascade of two block ciphers + * @param cipher1 the first cipher + * @param cipher2 the second cipher + */ Cascade_Cipher(BlockCipher* cipher1, BlockCipher* cipher2); ~Cascade_Cipher(); diff --git a/src/block/cast/cast128.h b/src/block/cast/cast128.h index 048d2e43c..967e91938 100644 --- a/src/block/cast/cast128.h +++ b/src/block/cast/cast128.h @@ -12,7 +12,7 @@ namespace Botan { -/* +/** * CAST-128 */ class BOTAN_DLL CAST_128 : public BlockCipher diff --git a/src/block/cast/cast256.h b/src/block/cast/cast256.h index 170d94e77..c4a305671 100644 --- a/src/block/cast/cast256.h +++ b/src/block/cast/cast256.h @@ -12,7 +12,7 @@ namespace Botan { -/* +/** * CAST-256 */ class BOTAN_DLL CAST_256 : public BlockCipher diff --git a/src/block/des/des.h b/src/block/des/des.h index 32dd3daf6..1ae806850 100644 --- a/src/block/des/des.h +++ b/src/block/des/des.h @@ -12,7 +12,7 @@ namespace Botan { -/* +/** * DES */ class BOTAN_DLL DES : public BlockCipher @@ -32,7 +32,7 @@ class BOTAN_DLL DES : public BlockCipher SecureVector<u32bit, 32> round_key; }; -/* +/** * Triple DES */ class BOTAN_DLL TripleDES : public BlockCipher diff --git a/src/block/des/desx.h b/src/block/des/desx.h index 440574e9d..45a9d8479 100644 --- a/src/block/des/desx.h +++ b/src/block/des/desx.h @@ -12,7 +12,7 @@ namespace Botan { -/* +/** * DESX */ class BOTAN_DLL DESX : public BlockCipher diff --git a/src/block/gost_28147/gost_28147.h b/src/block/gost_28147/gost_28147.h index 2ccb3214d..ec23466f4 100644 --- a/src/block/gost_28147/gost_28147.h +++ b/src/block/gost_28147/gost_28147.h @@ -21,14 +21,24 @@ namespace Botan { class BOTAN_DLL GOST_28147_89_Params { public: + /** + * @param row the row + * @param col the column + * @return sbox entry at this row/column + */ byte sbox_entry(u32bit row, u32bit col) const; + /** + * @return name of this parameter set + */ std::string param_name() const { return name; } /** * Default GOST parameters are the ones given in GOST R 34.11 for * testing purposes; these sboxes are also used by Crypto++, and, - * at least according to Wikipedia, the Central Bank of Russian Federation + * at least according to Wikipedia, the Central Bank of Russian + * Federation + * @param name of the parameter set */ GOST_28147_89_Params(const std::string& name = "R3411_94_TestParam"); private: @@ -50,6 +60,9 @@ class BOTAN_DLL GOST_28147_89 : public BlockCipher std::string name() const { return "GOST-28147-89"; } BlockCipher* clone() const { return new GOST_28147_89(SBOX); } + /** + * @param params the sbox parameters to use + */ GOST_28147_89(const GOST_28147_89_Params& params); private: GOST_28147_89(const SecureVector<u32bit, 1024>& other_SBOX) : diff --git a/src/block/idea/idea.h b/src/block/idea/idea.h index 1a9644d4e..e9ccf366d 100644 --- a/src/block/idea/idea.h +++ b/src/block/idea/idea.h @@ -12,7 +12,7 @@ namespace Botan { -/* +/** * IDEA */ class BOTAN_DLL IDEA : public BlockCipher @@ -26,8 +26,10 @@ class BOTAN_DLL IDEA : public BlockCipher BlockCipher* clone() const { return new IDEA; } IDEA() : BlockCipher(8, 16) {} - protected: + private: void key_schedule(const byte[], u32bit); + + protected: // for IDEA_SSE2 SecureVector<u16bit, 52> EK, DK; }; diff --git a/src/block/idea_sse2/idea_sse2.h b/src/block/idea_sse2/idea_sse2.h index 657581d74..b00e0f400 100644 --- a/src/block/idea_sse2/idea_sse2.h +++ b/src/block/idea_sse2/idea_sse2.h @@ -12,13 +12,13 @@ namespace Botan { -/* +/** * IDEA in SSE2 */ class BOTAN_DLL IDEA_SSE2 : public IDEA { public: - u32bit parallelism() const { return 16; } + u32bit parallelism() const { return 8; } void encrypt_n(const byte in[], byte out[], u32bit blocks) const; void decrypt_n(const byte in[], byte out[], u32bit blocks) const; diff --git a/src/block/kasumi/kasumi.h b/src/block/kasumi/kasumi.h index 827989a57..fda348ef3 100644 --- a/src/block/kasumi/kasumi.h +++ b/src/block/kasumi/kasumi.h @@ -12,8 +12,8 @@ namespace Botan { -/* -* KASUMI +/** +* KASUMI, the block cipher used in 3G telephony */ class BOTAN_DLL KASUMI : public BlockCipher { diff --git a/src/block/lion/lion.h b/src/block/lion/lion.h index f24acdb72..bba4e6f30 100644 --- a/src/block/lion/lion.h +++ b/src/block/lion/lion.h @@ -14,8 +14,13 @@ namespace Botan { -/* -* Lion +/** +* Lion is a block cipher construction designed by Ross Anderson and +* Eli Biham, described in "Two Practical and Provably Secure Block +* Ciphers: BEAR and LION". It has a variable block size and is +* designed to encrypt very large blocks (up to a megabyte) + +* http://www.cl.cam.ac.uk/~rja14/Papers/bear-lion.pdf */ class BOTAN_DLL Lion : public BlockCipher { @@ -27,7 +32,15 @@ class BOTAN_DLL Lion : public BlockCipher std::string name() const; BlockCipher* clone() const; - Lion(HashFunction*, StreamCipher*, u32bit); + /** + * @param hash the hash to use internally + * @param cipher the stream cipher to use internally + * @param block_size the size of the block to use + */ + Lion(HashFunction* hash, + StreamCipher* cipher, + u32bit block_size); + ~Lion() { delete hash; delete cipher; } private: void key_schedule(const byte[], u32bit); diff --git a/src/block/lubyrack/lubyrack.h b/src/block/lubyrack/lubyrack.h index 7249cf157..a69d2302f 100644 --- a/src/block/lubyrack/lubyrack.h +++ b/src/block/lubyrack/lubyrack.h @@ -13,8 +13,8 @@ namespace Botan { -/* -* Luby-Rackoff +/** +* Luby-Rackoff block cipher construction */ class BOTAN_DLL LubyRackoff : public BlockCipher { @@ -26,6 +26,9 @@ class BOTAN_DLL LubyRackoff : public BlockCipher std::string name() const; BlockCipher* clone() const; + /** + * @param hash function to use to form the block cipher + */ LubyRackoff(HashFunction* hash); ~LubyRackoff() { delete hash; } private: diff --git a/src/block/mars/mars.h b/src/block/mars/mars.h index f2a6d0197..f455ec5ca 100644 --- a/src/block/mars/mars.h +++ b/src/block/mars/mars.h @@ -12,6 +12,9 @@ namespace Botan { +/** +* MARS, IBM's candidate for AES +*/ class BOTAN_DLL MARS : public BlockCipher { public: diff --git a/src/block/misty1/misty1.h b/src/block/misty1/misty1.h index 7b4d91def..a9bc12c7b 100644 --- a/src/block/misty1/misty1.h +++ b/src/block/misty1/misty1.h @@ -1,4 +1,4 @@ -/** +/* * MISTY1 * (C) 1999-2008 Jack Lloyd * @@ -25,7 +25,11 @@ class BOTAN_DLL MISTY1 : public BlockCipher std::string name() const { return "MISTY1"; } BlockCipher* clone() const { return new MISTY1; } - MISTY1(u32bit = 8); + /** + * @param rounds the number of rounds. Must be 8 with the current + * implementation + */ + MISTY1(u32bit rounds = 8); private: void key_schedule(const byte[], u32bit); diff --git a/src/block/noekeon/noekeon.h b/src/block/noekeon/noekeon.h index abeecbc64..018c1d1fd 100644 --- a/src/block/noekeon/noekeon.h +++ b/src/block/noekeon/noekeon.h @@ -12,7 +12,7 @@ namespace Botan { -/* +/** * Noekeon */ class BOTAN_DLL Noekeon : public BlockCipher @@ -26,9 +26,13 @@ class BOTAN_DLL Noekeon : public BlockCipher BlockCipher* clone() const { return new Noekeon; } Noekeon() : BlockCipher(16, 16) {} - protected: + private: void key_schedule(const byte[], u32bit); + protected: // for access by SIMD subclass + /** + * The Noekeon round constants + */ static const byte RC[17]; SecureVector<u32bit, 4> EK, DK; diff --git a/src/block/noekeon_simd/noekeon_simd.h b/src/block/noekeon_simd/noekeon_simd.h index 55fdfbd22..507f17e21 100644 --- a/src/block/noekeon_simd/noekeon_simd.h +++ b/src/block/noekeon_simd/noekeon_simd.h @@ -12,13 +12,13 @@ namespace Botan { -/* -* Noekeon +/** +* Noekeon implementation using SIMD operations */ class BOTAN_DLL Noekeon_SIMD : public Noekeon { public: - u32bit parallelism() const { return 8; } + u32bit parallelism() const { return 4; } void encrypt_n(const byte in[], byte out[], u32bit blocks) const; void decrypt_n(const byte in[], byte out[], u32bit blocks) const; diff --git a/src/block/rc2/rc2.h b/src/block/rc2/rc2.h index dd0295572..c16680347 100644 --- a/src/block/rc2/rc2.h +++ b/src/block/rc2/rc2.h @@ -12,7 +12,7 @@ namespace Botan { -/* +/** * RC2 */ class BOTAN_DLL RC2 : public BlockCipher @@ -21,7 +21,12 @@ class BOTAN_DLL RC2 : public BlockCipher void encrypt_n(const byte in[], byte out[], u32bit blocks) const; void decrypt_n(const byte in[], byte out[], u32bit blocks) const; - static byte EKB_code(u32bit); + /** + * Return the code of the effective key bits + * @param bits key length + * @return EKB code + */ + static byte EKB_code(u32bit bits); void clear() { K.clear(); } std::string name() const { return "RC2"; } diff --git a/src/block/rc5/rc5.h b/src/block/rc5/rc5.h index 82931c1d2..385c6b2b1 100644 --- a/src/block/rc5/rc5.h +++ b/src/block/rc5/rc5.h @@ -12,7 +12,7 @@ namespace Botan { -/* +/** * RC5 */ class BOTAN_DLL RC5 : public BlockCipher @@ -25,7 +25,11 @@ class BOTAN_DLL RC5 : public BlockCipher std::string name() const; BlockCipher* clone() const { return new RC5(ROUNDS); } - RC5(u32bit); + /** + * @param rounds the number of RC5 rounds to run. Must be between + * 8 and 32 and a multiple of 4. + */ + RC5(u32bit rounds); private: void key_schedule(const byte[], u32bit); SecureVector<u32bit> S; diff --git a/src/block/rc6/rc6.h b/src/block/rc6/rc6.h index cc1534ee2..9b2d587fa 100644 --- a/src/block/rc6/rc6.h +++ b/src/block/rc6/rc6.h @@ -12,8 +12,8 @@ namespace Botan { -/* -* RC6 +/** +* RC6, Ron Rivest's AES candidate */ class BOTAN_DLL RC6 : public BlockCipher { diff --git a/src/block/safer/safer_sk.h b/src/block/safer/safer_sk.h index 80d2dc069..c93797602 100644 --- a/src/block/safer/safer_sk.h +++ b/src/block/safer/safer_sk.h @@ -12,7 +12,7 @@ namespace Botan { -/* +/** * SAFER-SK */ class BOTAN_DLL SAFER_SK : public BlockCipher @@ -25,7 +25,11 @@ class BOTAN_DLL SAFER_SK : public BlockCipher std::string name() const; BlockCipher* clone() const; - SAFER_SK(u32bit); + /** + * @param rounds the number of rounds to use - must be between 1 + * and 13 + */ + SAFER_SK(u32bit rounds); private: void key_schedule(const byte[], u32bit); diff --git a/src/block/seed/seed.h b/src/block/seed/seed.h index e56b77dbb..0c80199ad 100644 --- a/src/block/seed/seed.h +++ b/src/block/seed/seed.h @@ -12,8 +12,8 @@ namespace Botan { -/* -* SEED +/** +* SEED, a Korean block cipher */ class BOTAN_DLL SEED : public BlockCipher { diff --git a/src/block/serpent/serpent.h b/src/block/serpent/serpent.h index 37ce10c7b..1c13d00f9 100644 --- a/src/block/serpent/serpent.h +++ b/src/block/serpent/serpent.h @@ -12,8 +12,8 @@ namespace Botan { -/* -* Serpent +/** +* Serpent, an AES finalist */ class BOTAN_DLL Serpent : public BlockCipher { @@ -26,7 +26,7 @@ class BOTAN_DLL Serpent : public BlockCipher BlockCipher* clone() const { return new Serpent; } Serpent() : BlockCipher(16, 16, 32, 8) {} protected: - void key_schedule(const byte[], u32bit); + void key_schedule(const byte key[], u32bit length); SecureVector<u32bit, 132> round_key; }; diff --git a/src/block/serpent_ia32/serp_ia32.h b/src/block/serpent_ia32/serp_ia32.h index dc6beaf13..229a2042b 100644 --- a/src/block/serpent_ia32/serp_ia32.h +++ b/src/block/serpent_ia32/serp_ia32.h @@ -12,8 +12,8 @@ namespace Botan { -/* -* Serpent +/** +* Serpent implementation in x86 assembly */ class BOTAN_DLL Serpent_IA32 : public Serpent { diff --git a/src/block/serpent_simd/serp_simd.h b/src/block/serpent_simd/serp_simd.h index dc2b08736..f0a11fc93 100644 --- a/src/block/serpent_simd/serp_simd.h +++ b/src/block/serpent_simd/serp_simd.h @@ -12,13 +12,13 @@ namespace Botan { -/* -* Serpent +/** +* Serpent implementation using SIMD */ class BOTAN_DLL Serpent_SIMD : public Serpent { public: - u32bit parallelism() const { return 8; } + u32bit parallelism() const { return 4; } void encrypt_n(const byte in[], byte out[], u32bit blocks) const; void decrypt_n(const byte in[], byte out[], u32bit blocks) const; diff --git a/src/block/skipjack/skipjack.h b/src/block/skipjack/skipjack.h index d481aee08..29978efc7 100644 --- a/src/block/skipjack/skipjack.h +++ b/src/block/skipjack/skipjack.h @@ -12,8 +12,8 @@ namespace Botan { -/* -* Skipjack +/** +* Skipjack, a NSA designed cipher used in Fortezza */ class BOTAN_DLL Skipjack : public BlockCipher { diff --git a/src/block/square/square.h b/src/block/square/square.h index 8e1f7f815..a17771f11 100644 --- a/src/block/square/square.h +++ b/src/block/square/square.h @@ -12,7 +12,7 @@ namespace Botan { -/* +/** * Square */ class BOTAN_DLL Square : public BlockCipher diff --git a/src/block/tea/tea.h b/src/block/tea/tea.h index 152c9a905..128f42080 100644 --- a/src/block/tea/tea.h +++ b/src/block/tea/tea.h @@ -12,7 +12,7 @@ namespace Botan { -/* +/** * TEA */ class BOTAN_DLL TEA : public BlockCipher diff --git a/src/block/twofish/twofish.h b/src/block/twofish/twofish.h index 7600abca8..3191dc963 100644 --- a/src/block/twofish/twofish.h +++ b/src/block/twofish/twofish.h @@ -12,8 +12,8 @@ namespace Botan { -/* -* Twofish +/** +* Twofish, an AES finalist */ class BOTAN_DLL Twofish : public BlockCipher { diff --git a/src/block/xtea/xtea.h b/src/block/xtea/xtea.h index 940992dfa..b16cdf555 100644 --- a/src/block/xtea/xtea.h +++ b/src/block/xtea/xtea.h @@ -12,7 +12,7 @@ namespace Botan { -/* +/** * XTEA */ class BOTAN_DLL XTEA : public BlockCipher diff --git a/src/block/xtea_simd/xtea_simd.h b/src/block/xtea_simd/xtea_simd.h index 04a4977ae..87eeb433b 100644 --- a/src/block/xtea_simd/xtea_simd.h +++ b/src/block/xtea_simd/xtea_simd.h @@ -12,13 +12,13 @@ namespace Botan { -/* -* XTEA (SIMD variant) +/** +* XTEA implemented using SIMD operations */ class BOTAN_DLL XTEA_SIMD : public XTEA { public: - u32bit parallelism() const { return 16; } + u32bit parallelism() const { return 8; } void encrypt_n(const byte in[], byte out[], u32bit blocks) const; void decrypt_n(const byte in[], byte out[], u32bit blocks) const; diff --git a/src/build-data/arch/amd64.txt b/src/build-data/arch/amd64.txt index b0cf546d7..6b721805e 100644 --- a/src/build-data/arch/amd64.txt +++ b/src/build-data/arch/amd64.txt @@ -29,10 +29,12 @@ opteron -> k8 amdopteron -> k8 athlon64 -> k8 barcelona -> k10 + +corei5cpum520 -> westmere </submodel_aliases> <isa_extn> sse2:all ssse3:core2,nehalem,westmere -aes_ni:westmere +aes-ni:westmere </isa_extn> diff --git a/src/build-data/botan.doxy.in b/src/build-data/botan.doxy.in index 87d6e58eb..2f76a756b 100644 --- a/src/build-data/botan.doxy.in +++ b/src/build-data/botan.doxy.in @@ -13,7 +13,7 @@ BRIEF_MEMBER_DESC = YES REPEAT_BRIEF = YES ABBREVIATE_BRIEF = ALWAYS_DETAILED_SEC = NO -INLINE_INHERITED_MEMB = NO +INLINE_INHERITED_MEMB = YES FULL_PATH_NAMES = YES STRIP_FROM_PATH = STRIP_FROM_INC_PATH = @@ -21,7 +21,6 @@ SHORT_NAMES = NO JAVADOC_AUTOBRIEF = NO QT_AUTOBRIEF = NO MULTILINE_CPP_IS_BRIEF = NO -DETAILS_AT_TOP = NO INHERIT_DOCS = YES SEPARATE_MEMBER_PAGES = NO TAB_SIZE = 8 @@ -40,7 +39,7 @@ TYPEDEF_HIDES_STRUCT = NO EXTRACT_ALL = YES EXTRACT_PRIVATE = NO EXTRACT_STATIC = NO -EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_CLASSES = NO EXTRACT_LOCAL_METHODS = NO EXTRACT_ANON_NSPACES = NO HIDE_UNDOC_MEMBERS = NO @@ -69,7 +68,7 @@ FILE_VERSION_FILTER = #--------------------------------------------------------------------------- QUIET = YES WARNINGS = YES -WARN_IF_UNDOCUMENTED = NO +WARN_IF_UNDOCUMENTED = YES WARN_IF_DOC_ERROR = YES WARN_NO_PARAMDOC = NO WARN_FORMAT = "$file:$line: $text" @@ -83,7 +82,7 @@ FILE_PATTERNS = RECURSIVE = YES EXCLUDE = EXCLUDE_SYMLINKS = NO -EXCLUDE_PATTERNS = +EXCLUDE_PATTERNS = */wrap/* EXCLUDE_SYMBOLS = EXAMPLE_PATH = EXAMPLE_PATTERNS = diff --git a/src/build-data/buildh.in b/src/build-data/buildh.in index 90d274d58..6a203234a 100644 --- a/src/build-data/buildh.in +++ b/src/build-data/buildh.in @@ -8,6 +8,8 @@ #define BOTAN_VERSION_MINOR %{version_minor} #define BOTAN_VERSION_PATCH %{version_patch} +#define BOTAN_VERSION_DATESTAMP %{version_datestamp} + #ifndef BOTAN_DLL #define BOTAN_DLL %{dll_import_flags} #endif @@ -15,6 +17,7 @@ /* Chunk sizes */ #define BOTAN_DEFAULT_BUFFER_SIZE 4096 #define BOTAN_MEM_POOL_CHUNK_SIZE 64*1024 +#define BOTAN_BLOCK_CIPHER_PAR_MULT 4 /* BigInt toggles */ #define BOTAN_MP_WORD_BITS %{mp_bits} diff --git a/src/build-data/cc/gcc.txt b/src/build-data/cc/gcc.txt index d133065a8..ebb239c86 100644 --- a/src/build-data/cc/gcc.txt +++ b/src/build-data/cc/gcc.txt @@ -10,7 +10,7 @@ add_lib_option -l lang_flags "-ansi -std=c++0x" #warning_flags "-W -Wall" -warning_flags "-Werror -Wextra -Wall -Wstrict-aliasing -Wstrict-overflow=5 -Wcast-align -Wmissing-declarations -Wno-unused-parameter -Wpointer-arith -Wcast-qual" +warning_flags "-Werror -Wextra -Wall -Wstrict-aliasing -Wstrict-overflow=5 -Wcast-align -Wmissing-declarations -Wpointer-arith -Wcast-qual" lib_opt_flags "-O3" check_opt_flags "-O2" @@ -29,7 +29,7 @@ default -> "$(CXX) -shared -fPIC -Wl,-soname,$(SONAME)" # AIX doesn't seem to have soname support (weird...) aix -> "$(CXX) -shared -fPIC" -darwin -> "$(CXX) -dynamiclib -fPIC -install_name $(SONAME)" +darwin -> "$(CXX) -dynamiclib -fPIC -install_name $(LIBDIR)/$(SONAME)" hpux -> "$(CXX) -shared -fPIC -Wl,+h,$(SONAME)" solaris -> "$(CXX) -shared -fPIC -Wl,-h,$(SONAME)" # Gotta use ld directly on BeOS, their GCC is busted diff --git a/src/build-data/cc/msvc.txt b/src/build-data/cc/msvc.txt index 273f1c5c0..24d91b3f3 100644 --- a/src/build-data/cc/msvc.txt +++ b/src/build-data/cc/msvc.txt @@ -11,7 +11,7 @@ add_lib_option "" no_debug_flags "/O2" debug_flags "/Od /Zi /DDEBUG" check_opt_flags "/O2 /D_CONSOLE" -lang_flags "/EHsc /GR" +lang_flags "/EHs /GR" warning_flags "/W3 /wd4275" shared_flags "/DBOTAN_DLL=__declspec(dllexport)" diff --git a/src/build-data/innosetup.in b/src/build-data/innosetup.in index c3e0f1ebd..0a7eeb8f6 100644 --- a/src/build-data/innosetup.in +++ b/src/build-data/innosetup.in @@ -8,12 +8,16 @@ AppPublisher=Jack Lloyd AppPublisherURL=http://botan.randombit.net/ AppVersion=%{version} -VersionInfoCopyright=Copyright (C) 1999-2009 Jack Lloyd and others +VersionInfoCopyright=Copyright (C) 1999-2010 Jack Lloyd and others VersionInfoVersion=%{version_major}.%{version_minor}.%{version_patch}.0 ; Require at least Windows 98 or 2000 MinVersion=4.1,5.0 +; Uncomment for 64 bit builds +;ArchitecturesAllowed = x64 +;ArchitecturesInstallIn64BitMode = x64 + DefaultDirName={pf}\botan DefaultGroupName=botan diff --git a/src/build-data/makefile/nmake.in b/src/build-data/makefile/nmake.in index 212825131..9928f3d4e 100644 --- a/src/build-data/makefile/nmake.in +++ b/src/build-data/makefile/nmake.in @@ -15,10 +15,6 @@ VERSION = %{version} ### Installation Settings DESTDIR = %{prefix} -LIBDIR = $(DESTDIR)\%{libdir} -HEADERDIR = $(DESTDIR)\%{includedir}\botan -DOCDIR = $(DESTDIR)\%{docdir}\botan-$(VERSION) - ### Aliases for Common Programs AR = %{ar_command} CD = @cd @@ -86,4 +82,6 @@ distclean: clean ### Install Commands install: $(LIBRARIES) - $(ECHO) "Install command not implemented" + -$(MKDIR) $(DESTDIR)\include\botan + $(INSTALL_CMD) botan.* $(DESTDIR) + $(INSTALL_CMD) build\include\botan\*.h $(DESTDIR)\include\botan diff --git a/src/cert/cvc/cvc_ado.h b/src/cert/cvc/cvc_ado.h index 230ee8b8d..65a39fd91 100644 --- a/src/cert/cvc/cvc_ado.h +++ b/src/cert/cvc/cvc_ado.h @@ -41,6 +41,7 @@ class BOTAN_DLL EAC1_1_ADO : public EAC1_1_obj<EAC1_1_ADO> * Create a signed CVC ADO request from to be signed (TBS) data * @param signer the signer used to sign the CVC ADO request * @param tbs_bits the TBS data to sign + * @param rng a random number generator */ static MemoryVector<byte> make_signed( PK_Signer& signer, diff --git a/src/cert/cvc/cvc_cert.h b/src/cert/cvc/cvc_cert.h index 12bc41a9c..69d0d824a 100644 --- a/src/cert/cvc/cvc_cert.h +++ b/src/cert/cvc/cvc_cert.h @@ -92,7 +92,8 @@ inline bool operator!=(EAC1_1_CVC const& lhs, EAC1_1_CVC const& rhs) * @param holder_auth_templ the holder authorization value byte to * appear in the CHAT of the certificate * @param ced the CED to appear in the certificate -* @param ced the CEX to appear in the certificate +* @param cex the CEX to appear in the certificate +* @param rng a random number generator */ EAC1_1_CVC BOTAN_DLL make_cvc_cert(PK_Signer& signer, const MemoryRegion<byte>& public_key, diff --git a/src/cert/cvc/cvc_gen_cert.h b/src/cert/cvc/cvc_gen_cert.h index 4f98041e3..7b125c10d 100644 --- a/src/cert/cvc/cvc_gen_cert.h +++ b/src/cert/cvc/cvc_gen_cert.h @@ -70,6 +70,7 @@ class EAC1_1_gen_CVC : public EAC1_1_obj<Derived> // CRTP continuation from EAC1 * Create a signed generalized CVC object. * @param signer the signer used to sign this object * @param tbs_bits the body the generalized CVC object to be signed + * @param rng a random number generator * @result the DER encoded signed generalized CVC object */ static MemoryVector<byte> make_signed( diff --git a/src/cert/cvc/cvc_self.h b/src/cert/cvc/cvc_self.h index fb24ecd3a..f7bf6d5d8 100644 --- a/src/cert/cvc/cvc_self.h +++ b/src/cert/cvc/cvc_self.h @@ -97,7 +97,8 @@ namespace DE_EAC { * shall be entitled to read the biometrical iris image * @param fingerpr indicates whether the entity associated with the certificate * shall be entitled to read the biometrical fingerprint image -* @param rng the rng to use +* @param cvca_validity_months length of time in months this will be valid +* @param rng a random number generator * @result the CVCA certificate created */ EAC1_1_CVC BOTAN_DLL create_cvca(Private_Key const& priv_key, @@ -146,8 +147,10 @@ EAC1_1_Req BOTAN_DLL create_cvc_req(Private_Key const& priv_key, * @param seqnr the sequence number of the certificate to be created * @param seqnr_len the number of digits the sequence number will be * encoded in -* @param domestic indicates whether to sign a domestic or a foreign certificate: -* set to true for domestic +* @param domestic indicates whether to sign a domestic or a foreign +* certificate: set to true for domestic +* @param dvca_validity_months validity period in months +* @param ca_is_validity_months validity period in months * @param rng a random number generator * @result the new certificate * diff --git a/src/cert/cvc/eac_asn_obj.h b/src/cert/cvc/eac_asn_obj.h index 3ab57d7e4..dc4f82578 100644 --- a/src/cert/cvc/eac_asn_obj.h +++ b/src/cert/cvc/eac_asn_obj.h @@ -26,13 +26,13 @@ class BOTAN_DLL EAC_Time : public ASN1_Object /** * Get a this objects value as a string. - * @return the date string + * @return date string */ std::string as_string() const; /** * Get a this objects value as a readable formatted string. - * @return the date string + * @return date string */ std::string readable_string() const; @@ -71,19 +71,19 @@ class BOTAN_DLL EAC_Time : public ASN1_Object /** * Get the year value of this objects. - * @return the year value + * @return year value */ u32bit get_year() const { return year; } /** * Get the month value of this objects. - * @return the month value + * @return month value */ u32bit get_month() const { return month; } /** * Get the day value of this objects. - * @return the day value + * @return day value */ u32bit get_day() const { return day; } @@ -170,13 +170,13 @@ class BOTAN_DLL ASN1_EAC_String: public ASN1_Object /** * Get this objects string value. - * @return the string value + * @return string value */ std::string value() const; /** * Get this objects string value. - * @return the string value in iso8859 encoding + * @return string value in iso8859 encoding */ std::string iso_8859() const; diff --git a/src/cert/cvc/eac_obj.h b/src/cert/cvc/eac_obj.h index 66752b10c..eb6db3369 100644 --- a/src/cert/cvc/eac_obj.h +++ b/src/cert/cvc/eac_obj.h @@ -13,7 +13,7 @@ namespace Botan { -/* +/** * TR03110 v1.1 EAC CV Certificate */ template<typename Derived> // CRTP is used enable the call sequence: diff --git a/src/cert/cvc/ecdsa_sig.h b/src/cert/cvc/ecdsa_sig.h index 1397a92b1..a92052470 100644 --- a/src/cert/cvc/ecdsa_sig.h +++ b/src/cert/cvc/ecdsa_sig.h @@ -15,6 +15,9 @@ namespace Botan { +/** +* Class representing an ECDSA signature +*/ class BOTAN_DLL ECDSA_Signature { public: diff --git a/src/cert/cvc/signed_obj.h b/src/cert/cvc/signed_obj.h index 0e7dd6bdb..0c0fb30af 100644 --- a/src/cert/cvc/signed_obj.h +++ b/src/cert/cvc/signed_obj.h @@ -24,7 +24,7 @@ class BOTAN_DLL EAC_Signed_Object public: /** * Get the TBS (to-be-signed) data in this object. - * @return the DER encoded TBS data of this object + * @return DER encoded TBS data of this object */ virtual SecureVector<byte> tbs_data() const = 0; @@ -32,7 +32,7 @@ class BOTAN_DLL EAC_Signed_Object * Get the signature of this object as a concatenation, i.e. if the * signature consists of multiple parts (like in the case of ECDSA) * these will be concatenated. - * @return the signature as a concatenation of its parts + * @return signature as a concatenation of its parts */ /* @@ -50,6 +50,7 @@ class BOTAN_DLL EAC_Signed_Object /** * Check the signature of this object. * @param key the public key associated with this signed object + * @param sig the signature we are checking * @return true if the signature was created by the private key * associated with this public key */ @@ -59,19 +60,20 @@ class BOTAN_DLL EAC_Signed_Object /** * Write this object DER encoded into a specified pipe. * @param pipe the pipe to write the encoded object to - * @param enc the encoding type to use + * @param encoding the encoding type to use */ - virtual void encode(Pipe&, X509_Encoding = PEM) const = 0; + virtual void encode(Pipe& pipe, + X509_Encoding encoding = PEM) const = 0; /** * BER encode this object. - * @return the result containing the BER representation of this object. + * @return result containing the BER representation of this object. */ SecureVector<byte> BER_encode() const; /** * PEM encode this object. - * @return the result containing the PEM representation of this object. + * @return result containing the PEM representation of this object. */ std::string PEM_encode() const; diff --git a/src/cert/x509/certstor.h b/src/cert/x509/certstor.h index d5004e366..2e39a7178 100644 --- a/src/cert/x509/certstor.h +++ b/src/cert/x509/certstor.h @@ -13,7 +13,7 @@ namespace Botan { -/* +/** * Certificate Store Interface */ class BOTAN_DLL Certificate_Store diff --git a/src/cert/x509/crl_ent.h b/src/cert/x509/crl_ent.h index 050356c84..ec90750db 100644 --- a/src/cert/x509/crl_ent.h +++ b/src/cert/x509/crl_ent.h @@ -23,19 +23,19 @@ class BOTAN_DLL CRL_Entry : public ASN1_Object /** * Get the serial number of the certificate associated with this entry. - * @return the certificate's serial number + * @return certificate's serial number */ MemoryVector<byte> serial_number() const { return serial; } /** * Get the revocation date of the certificate associated with this entry - * @return the certificate's revocation date + * @return certificate's revocation date */ X509_Time expire_time() const { return time; } /** * Get the entries reason code - * @return the reason code + * @return reason code */ CRL_Code reason_code() const { return reason; } @@ -49,7 +49,8 @@ class BOTAN_DLL CRL_Entry : public ASN1_Object * @param cert the certificate to revoke * @param reason the reason code to set in the entry */ - CRL_Entry(const X509_Certificate&, CRL_Code = UNSPECIFIED); + CRL_Entry(const X509_Certificate& cert, + CRL_Code reason = UNSPECIFIED); private: bool throw_on_unknown_critical; diff --git a/src/cert/x509/pkcs10.h b/src/cert/x509/pkcs10.h index 9b435de52..d1be9e0d3 100644 --- a/src/cert/x509/pkcs10.h +++ b/src/cert/x509/pkcs10.h @@ -23,38 +23,38 @@ class BOTAN_DLL PKCS10_Request : public X509_Object public: /** * Get the subject public key. - * @return the subject public key + * @return subject public key */ Public_Key* subject_public_key() const; /** * Get the raw DER encoded public key. - * @return the raw DER encoded public key + * @return raw DER encoded public key */ MemoryVector<byte> raw_public_key() const; /** * Get the subject DN. - * @return the subject DN + * @return subject DN */ X509_DN subject_dn() const; /** * Get the subject alternative name. - * @return the subject alternative name. + * @return subject alternative name. */ AlternativeName subject_alt_name() const; /** * Get the key constraints for the key associated with this * PKCS#10 object. - * @return the key constraints + * @return key constraints */ Key_Constraints constraints() const; /** * Get the extendend key constraints (if any). - * @return the extended key constraints + * @return extended key constraints */ std::vector<OID> ex_constraints() const; @@ -67,13 +67,13 @@ class BOTAN_DLL PKCS10_Request : public X509_Object /** * Return the constraint on the path length defined * in the BasicConstraints extension. - * @return the path limit + * @return path limit */ u32bit path_limit() const; /** * Get the challenge password for this request - * @return the challenge password for this request + * @return challenge password for this request */ std::string challenge_password() const; diff --git a/src/cert/x509/x509_ca.h b/src/cert/x509/x509_ca.h index b680bd0e4..7aca26d03 100644 --- a/src/cert/x509/x509_ca.h +++ b/src/cert/x509/x509_ca.h @@ -30,7 +30,7 @@ class BOTAN_DLL X509_CA * @param rng the rng to use * @param not_before the starting time for the certificate * @param not_after the expiration time for the certificate - * @return the resulting certificate + * @return resulting certificate */ X509_Certificate sign_request(const PKCS10_Request& req, RandomNumberGenerator& rng, @@ -39,7 +39,7 @@ class BOTAN_DLL X509_CA /** * Get the certificate of this CA. - * @return the CA certificate + * @return CA certificate */ X509_Certificate ca_certificate() const; @@ -48,7 +48,7 @@ class BOTAN_DLL X509_CA * @param rng the random number generator to use * @param next_update the time to set in next update in seconds * as the offset from the current time - * @return the new CRL + * @return new CRL */ X509_CRL new_crl(RandomNumberGenerator& rng, u32bit next_update = 0) const; @@ -71,6 +71,7 @@ class BOTAN_DLL X509_CA * @param signer a signing object * @param rng a random number generator * @param sig_algo the signature algorithm identifier + * @param pub_key the serialized public key * @param not_before the start time of the certificate * @param not_after the end time of the certificate * @param issuer_dn the DN of the issuer @@ -92,6 +93,7 @@ class BOTAN_DLL X509_CA * Create a new CA object. * @param ca_certificate the certificate of the CA * @param key the private key of the CA + * @param hash_fn name of a hash function to use for signing */ X509_CA(const X509_Certificate& ca_certificate, const Private_Key& key, diff --git a/src/cert/x509/x509_crl.h b/src/cert/x509/x509_crl.h index a7903e7e6..c2b3c4f5c 100644 --- a/src/cert/x509/x509_crl.h +++ b/src/cert/x509/x509_crl.h @@ -31,13 +31,13 @@ class BOTAN_DLL X509_CRL : public X509_Object /** * Get the entries of this CRL in the form of a vector. - * @return a vector containing the entries of this CRL. + * @return vector containing the entries of this CRL. */ std::vector<CRL_Entry> get_revoked() const; /** * Get the issuer DN of this CRL. - * @return the CRLs issuer DN + * @return CRLs issuer DN */ X509_DN issuer_dn() const; @@ -49,31 +49,35 @@ class BOTAN_DLL X509_CRL : public X509_Object /** * Get the serial number of this CRL. - * @return the CRLs serial number + * @return CRLs serial number */ u32bit crl_number() const; /** * Get the CRL's thisUpdate value. - * @return the CRLs thisUpdate + * @return CRLs thisUpdate */ X509_Time this_update() const; /** * Get the CRL's nextUpdate value. - * @return the CRLs nextdUpdate + * @return CRLs nextdUpdate */ X509_Time next_update() const; /** * Construct a CRL from a data source. * @param source the data source providing the DER or PEM encoded CRL. + * @param throw_on_unknown_critical should we throw an exception + * if an unknown CRL extension marked as critical is encountered. */ - X509_CRL(DataSource&, bool throw_on_unknown_critical = false); + X509_CRL(DataSource& source, bool throw_on_unknown_critical = false); /** * Construct a CRL from a file containing the DER or PEM encoded CRL. * @param filename the name of the CRL file + * @param throw_on_unknown_critical should we throw an exception + * if an unknown CRL extension marked as critical is encountered. */ X509_CRL(const std::string& filename, bool throw_on_unknown_critical = false); diff --git a/src/cert/x509/x509_ext.h b/src/cert/x509/x509_ext.h index a5bfd357f..213a077a2 100644 --- a/src/cert/x509/x509_ext.h +++ b/src/cert/x509/x509_ext.h @@ -16,18 +16,40 @@ namespace Botan { -/* +/** * X.509 Certificate Extension */ class BOTAN_DLL Certificate_Extension { public: + /** + * @return OID representing this extension + */ OID oid_of() const; + /** + * Make a copy of this extension + * @return copy of this + */ virtual Certificate_Extension* copy() const = 0; - virtual void contents_to(Data_Store&, Data_Store&) const = 0; + /* + * Add the contents of this extension into the information + * for the subject and/or issuer, as necessary. + * @param subject the subject info + * @param issuer the issuer info + */ + virtual void contents_to(Data_Store& subject, + Data_Store& issuer) const = 0; + + /* + * @return short readable name + */ virtual std::string config_id() const = 0; + + /* + * @return specific OID name + */ virtual std::string oid_name() const = 0; virtual ~Certificate_Extension() {} @@ -38,7 +60,7 @@ class BOTAN_DLL Certificate_Extension virtual void decode_inner(const MemoryRegion<byte>&) = 0; }; -/* +/** * X.509 Certificate Extension List */ class BOTAN_DLL Extensions : public ASN1_Object @@ -65,7 +87,7 @@ class BOTAN_DLL Extensions : public ASN1_Object namespace Cert_Extension { -/* +/** * Basic Constraints Extension */ class BOTAN_DLL Basic_Constraints : public Certificate_Extension @@ -91,7 +113,7 @@ class BOTAN_DLL Basic_Constraints : public Certificate_Extension u32bit path_limit; }; -/* +/** * Key Usage Constraints Extension */ class BOTAN_DLL Key_Usage : public Certificate_Extension @@ -114,7 +136,7 @@ class BOTAN_DLL Key_Usage : public Certificate_Extension Key_Constraints constraints; }; -/* +/** * Subject Key Identifier Extension */ class BOTAN_DLL Subject_Key_ID : public Certificate_Extension @@ -138,7 +160,7 @@ class BOTAN_DLL Subject_Key_ID : public Certificate_Extension MemoryVector<byte> key_id; }; -/* +/** * Authority Key Identifier Extension */ class BOTAN_DLL Authority_Key_ID : public Certificate_Extension @@ -162,7 +184,7 @@ class BOTAN_DLL Authority_Key_ID : public Certificate_Extension MemoryVector<byte> key_id; }; -/* +/** * Alternative Name Extension Base Class */ class BOTAN_DLL Alternative_Name : public Certificate_Extension @@ -188,7 +210,7 @@ class BOTAN_DLL Alternative_Name : public Certificate_Extension AlternativeName alt_name; }; -/* +/** * Subject Alternative Name Extension */ class BOTAN_DLL Subject_Alternative_Name : public Alternative_Name @@ -200,7 +222,7 @@ class BOTAN_DLL Subject_Alternative_Name : public Alternative_Name Subject_Alternative_Name(const AlternativeName& = AlternativeName()); }; -/* +/** * Issuer Alternative Name Extension */ class BOTAN_DLL Issuer_Alternative_Name : public Alternative_Name @@ -212,7 +234,7 @@ class BOTAN_DLL Issuer_Alternative_Name : public Alternative_Name Issuer_Alternative_Name(const AlternativeName& = AlternativeName()); }; -/* +/** * Extended Key Usage Extension */ class BOTAN_DLL Extended_Key_Usage : public Certificate_Extension @@ -236,7 +258,7 @@ class BOTAN_DLL Extended_Key_Usage : public Certificate_Extension std::vector<OID> oids; }; -/* +/** * Certificate Policies Extension */ class BOTAN_DLL Certificate_Policies : public Certificate_Extension @@ -261,7 +283,7 @@ class BOTAN_DLL Certificate_Policies : public Certificate_Extension std::vector<OID> oids; }; -/* +/** * CRL Number Extension */ class BOTAN_DLL CRL_Number : public Certificate_Extension @@ -286,7 +308,7 @@ class BOTAN_DLL CRL_Number : public Certificate_Extension u32bit crl_number; }; -/* +/** * CRL Entry Reason Code Extension */ class BOTAN_DLL CRL_ReasonCode : public Certificate_Extension diff --git a/src/cert/x509/x509_obj.h b/src/cert/x509/x509_obj.h index c7f92fa9d..52b76d218 100644 --- a/src/cert/x509/x509_obj.h +++ b/src/cert/x509/x509_obj.h @@ -33,7 +33,7 @@ class BOTAN_DLL X509_Object * @param rng the random number generator to use * @param alg_id the algorithm identifier of the signature scheme * @param tbs the tbs bits to be signed - * @return the signed X509 object + * @return signed X509 object */ static MemoryVector<byte> make_signed(class PK_Signer* signer, RandomNumberGenerator& rng, diff --git a/src/cert/x509/x509cert.h b/src/cert/x509/x509cert.h index 4a9d11f7f..dc7ef4dbb 100644 --- a/src/cert/x509/x509cert.h +++ b/src/cert/x509/x509cert.h @@ -24,19 +24,19 @@ class BOTAN_DLL X509_Certificate : public X509_Object public: /** * Get the public key associated with this certificate. - * @return the subject public key of this certificate + * @return subject public key of this certificate */ Public_Key* subject_public_key() const; /** * Get the issuer certificate DN. - * @return the issuer DN of this certificate + * @return issuer DN of this certificate */ X509_DN issuer_dn() const; /** * Get the subject certificate DN. - * @return the subject DN of this certificate + * @return subject DN of this certificate */ X509_DN subject_dn() const; @@ -50,7 +50,7 @@ class BOTAN_DLL X509_Certificate : public X509_Object * "X509v3.BasicConstraints.is_ca", "X509v3.ExtendedKeyUsage", * "X509v3.CertificatePolicies", "X509v3.SubjectKeyIdentifier" or * "X509.Certificate.serial". - * @return the value(s) of the specified parameter + * @return value(s) of the specified parameter */ std::vector<std::string> subject_info(const std::string& name) const; @@ -58,43 +58,43 @@ class BOTAN_DLL X509_Certificate : public X509_Object * Get a value for a specific subject_info parameter name. * @param name the name of the paramter to look up. Possible names are * "X509.Certificate.v2.key_id" or "X509v3.AuthorityKeyIdentifier". - * @return the value(s) of the specified parameter + * @return value(s) of the specified parameter */ std::vector<std::string> issuer_info(const std::string& name) const; /** * Get the notBefore of the certificate. - * @return the notBefore of the certificate + * @return notBefore of the certificate */ std::string start_time() const; /** * Get the notAfter of the certificate. - * @return the notAfter of the certificate + * @return notAfter of the certificate */ std::string end_time() const; /** * Get the X509 version of this certificate object. - * @return the X509 version + * @return X509 version */ u32bit x509_version() const; /** * Get the serial number of this certificate. - * @return the certificates serial number + * @return certificates serial number */ MemoryVector<byte> serial_number() const; /** * Get the DER encoded AuthorityKeyIdentifier of this certificate. - * @return the DER encoded AuthorityKeyIdentifier + * @return DER encoded AuthorityKeyIdentifier */ MemoryVector<byte> authority_key_id() const; /** * Get the DER encoded SubjectKeyIdentifier of this certificate. - * @return the DER encoded SubjectKeyIdentifier + * @return DER encoded SubjectKeyIdentifier */ MemoryVector<byte> subject_key_id() const; @@ -113,14 +113,14 @@ class BOTAN_DLL X509_Certificate : public X509_Object /** * Get the path limit as defined in the BasicConstraints extension of * this certificate. - * @return the path limit + * @return path limit */ u32bit path_limit() const; /** * Get the key constraints as defined in the KeyUsage extension of this * certificate. - * @return the key constraints + * @return key constraints */ Key_Constraints constraints() const; @@ -128,14 +128,14 @@ class BOTAN_DLL X509_Certificate : public X509_Object * Get the key constraints as defined in the ExtendedKeyUsage * extension of this * certificate. - * @return the key constraints + * @return key constraints */ std::vector<std::string> ex_constraints() const; /** * Get the policies as defined in the CertificatePolicies extension * of this certificate. - * @return the certificate policies + * @return certificate policies */ std::vector<std::string> policies() const; diff --git a/src/cert/x509/x509self.cpp b/src/cert/x509/x509self.cpp index d87c5e060..6e570d3b6 100644 --- a/src/cert/x509/x509self.cpp +++ b/src/cert/x509/x509self.cpp @@ -18,22 +18,6 @@ namespace Botan { namespace { /* -* Shared setup for self-signed items -*/ -MemoryVector<byte> shared_setup(const X509_Cert_Options& opts, - const Private_Key& key) - { - opts.sanity_check(); - - Pipe key_encoder; - key_encoder.start_msg(); - X509::encode(key, key_encoder, RAW_BER); - key_encoder.end_msg(); - - return key_encoder.read_all(); - } - -/* * Load information from the X509_Cert_Options */ void load_info(const X509_Cert_Options& opts, X509_DN& subject_dn, @@ -67,7 +51,9 @@ X509_Certificate create_self_signed_cert(const X509_Cert_Options& opts, X509_DN subject_dn; AlternativeName subject_alt; - MemoryVector<byte> pub_key = shared_setup(opts, key); + opts.sanity_check(); + + MemoryVector<byte> pub_key = X509::BER_encode(key); std::unique_ptr<PK_Signer> signer(choose_sig_format(key, hash_fn, sig_algo)); load_info(opts, subject_dn, subject_alt); @@ -111,7 +97,9 @@ PKCS10_Request create_cert_req(const X509_Cert_Options& opts, X509_DN subject_dn; AlternativeName subject_alt; - MemoryVector<byte> pub_key = shared_setup(opts, key); + opts.sanity_check(); + + MemoryVector<byte> pub_key = X509::BER_encode(key); std::unique_ptr<PK_Signer> signer(choose_sig_format(key, hash_fn, sig_algo)); load_info(opts, subject_dn, subject_alt); diff --git a/src/cert/x509/x509self.h b/src/cert/x509/x509self.h index 741350067..df5731050 100644 --- a/src/cert/x509/x509self.h +++ b/src/cert/x509/x509self.h @@ -174,7 +174,7 @@ namespace X509 { * associated with this self-signed certificate * @param hash_fn the hash function to use * @param rng the rng to use -* @return the newly created self-signed certificate +* @return newly created self-signed certificate */ BOTAN_DLL X509_Certificate create_self_signed_cert(const X509_Cert_Options& opts, @@ -188,7 +188,7 @@ create_self_signed_cert(const X509_Cert_Options& opts, * @param key the key used to sign this request * @param rng the rng to use * @param hash_fn the hash function to use -* @return the newly created PKCS#10 request +* @return newly created PKCS#10 request */ BOTAN_DLL PKCS10_Request create_cert_req(const X509_Cert_Options& opts, const Private_Key& key, diff --git a/src/cert/x509/x509stor.h b/src/cert/x509/x509stor.h index 1911c6b6a..c375c19cb 100644 --- a/src/cert/x509/x509stor.h +++ b/src/cert/x509/x509stor.h @@ -15,7 +15,7 @@ namespace Botan { -/* +/** * X.509 Certificate Validation Result */ enum X509_Code { @@ -43,7 +43,7 @@ enum X509_Code { CA_CERT_NOT_FOR_CRL_ISSUER }; -/* +/** * X.509 Certificate Store */ class BOTAN_DLL X509_Store @@ -71,20 +71,6 @@ class BOTAN_DLL X509_Store std::vector<X509_Certificate> get_cert_chain(const X509_Certificate&); std::string PEM_encode() const; - /* - * Made CRL_Data public for XLC for Cell 0.9, otherwise cannot - * instantiate member variable std::vector<CRL_Data> revoked - */ - class BOTAN_DLL CRL_Data - { - public: - X509_DN issuer; - MemoryVector<byte> serial, auth_key_id; - bool operator==(const CRL_Data&) const; - bool operator!=(const CRL_Data&) const; - bool operator<(const CRL_Data&) const; - }; - X509_Code add_crl(const X509_CRL&); void add_cert(const X509_Certificate&, bool = false); void add_certs(DataSource&); @@ -106,6 +92,18 @@ class BOTAN_DLL X509_Store X509_Store(const X509_Store&); ~X509_Store(); private: + X509_Store& operator=(const X509_Store&) { return (*this); } + + class BOTAN_DLL CRL_Data + { + public: + X509_DN issuer; + MemoryVector<byte> serial, auth_key_id; + bool operator==(const CRL_Data&) const; + bool operator!=(const CRL_Data&) const; + bool operator<(const CRL_Data&) const; + }; + class BOTAN_DLL Cert_Info { public: diff --git a/src/checksum/adler32/adler32.h b/src/checksum/adler32/adler32.h index 79804a842..8cbd67f10 100644 --- a/src/checksum/adler32/adler32.h +++ b/src/checksum/adler32/adler32.h @@ -12,8 +12,8 @@ namespace Botan { -/* -* Adler32 +/** +* The Adler32 checksum, used in zlib */ class BOTAN_DLL Adler32 : public HashFunction { diff --git a/src/checksum/crc24/crc24.h b/src/checksum/crc24/crc24.h index f59ac4a45..2fc5af2ff 100644 --- a/src/checksum/crc24/crc24.h +++ b/src/checksum/crc24/crc24.h @@ -12,8 +12,8 @@ namespace Botan { -/* -* CRC24 +/** +* 24-bit cyclic redundancy check */ class BOTAN_DLL CRC24 : public HashFunction { diff --git a/src/checksum/crc32/crc32.h b/src/checksum/crc32/crc32.h index 998e8489e..9fd69670d 100644 --- a/src/checksum/crc32/crc32.h +++ b/src/checksum/crc32/crc32.h @@ -12,8 +12,8 @@ namespace Botan { -/* -* CRC32 +/** +* 32-bit cyclic redundancy check */ class BOTAN_DLL CRC32 : public HashFunction { diff --git a/src/cms/cms_dec.h b/src/cms/cms_dec.h index a00b44766..53d7114d6 100644 --- a/src/cms/cms_dec.h +++ b/src/cms/cms_dec.h @@ -16,7 +16,7 @@ namespace Botan { -/* +/** * CMS Decoding Operation */ class BOTAN_DLL CMS_Decoder diff --git a/src/cms/cms_enc.h b/src/cms/cms_enc.h index ec2fdf3b3..f8e9a5a8f 100644 --- a/src/cms/cms_enc.h +++ b/src/cms/cms_enc.h @@ -15,7 +15,7 @@ namespace Botan { -/* +/** * CMS Encoding Operation */ class BOTAN_DLL CMS_Encoder diff --git a/src/codec/openpgp/openpgp.cpp b/src/codec/openpgp/openpgp.cpp index f55caf1c8..ca1ea6d9c 100644 --- a/src/codec/openpgp/openpgp.cpp +++ b/src/codec/openpgp/openpgp.cpp @@ -13,14 +13,13 @@ namespace Botan { -namespace OpenPGP { - /* * OpenPGP Base64 encoding */ -std::string encode(const byte input[], u32bit length, - const std::string& label, - const std::map<std::string, std::string>& headers) +std::string PGP_encode( + const byte input[], u32bit length, + const std::string& label, + const std::map<std::string, std::string>& headers) { const std::string PGP_HEADER = "-----BEGIN PGP " + label + "-----\n"; const std::string PGP_TRAILER = "-----END PGP " + label + "-----\n"; @@ -58,18 +57,19 @@ std::string encode(const byte input[], u32bit length, /* * OpenPGP Base64 encoding */ -std::string encode(const byte input[], u32bit length, - const std::string& type) +std::string PGP_encode(const byte input[], u32bit length, + const std::string& type) { std::map<std::string, std::string> empty; - return encode(input, length, type, empty); + return PGP_encode(input, length, type, empty); } /* * OpenPGP Base64 decoding */ -SecureVector<byte> decode(DataSource& source, std::string& label, - std::map<std::string, std::string>& headers) +SecureVector<byte> PGP_decode(DataSource& source, + std::string& label, + std::map<std::string, std::string>& headers) { const u32bit RANDOM_CHAR_LIMIT = 5; @@ -186,13 +186,11 @@ SecureVector<byte> decode(DataSource& source, std::string& label, /* * OpenPGP Base64 decoding */ -SecureVector<byte> decode(DataSource& source, std::string& label) +SecureVector<byte> PGP_decode(DataSource& source, std::string& label) { std::map<std::string, std::string> ignored; - return decode(source, label, ignored); + return PGP_decode(source, label, ignored); } } -} - diff --git a/src/codec/openpgp/openpgp.h b/src/codec/openpgp/openpgp.h index 7021d5675..1e2cf10f0 100644 --- a/src/codec/openpgp/openpgp.h +++ b/src/codec/openpgp/openpgp.h @@ -14,20 +14,47 @@ namespace Botan { -namespace OpenPGP { - -/* -* OpenPGP Base64 encoding/decoding +/** +* @param input the input data +* @param length length of input in bytes +* @param label the human-readable label +* @param headers a set of key/value pairs included in the header */ -BOTAN_DLL std::string encode(const byte[], u32bit, const std::string&, - const std::map<std::string, std::string>&); -BOTAN_DLL SecureVector<byte> decode(DataSource&, std::string&, - std::map<std::string, std::string>&); - -BOTAN_DLL std::string encode(const byte[], u32bit, const std::string&); -BOTAN_DLL SecureVector<byte> decode(DataSource&, std::string&); - -} +BOTAN_DLL std::string PGP_encode( + const byte input[], + u32bit length, + const std::string& label, + const std::map<std::string, std::string>& headers); + +/** +* @param input the input data +* @param length length of input in bytes +* @param label the human-readable label +*/ +BOTAN_DLL std::string PGP_encode( + const byte input[], + u32bit length, + const std::string& label); + +/** +* @param source the input source +* @param label is set to the human-readable label +* @param headers is set to any headers +* @return decoded output as raw binary +*/ +BOTAN_DLL SecureVector<byte> PGP_decode( + DataSource& source, + std::string& label, + std::map<std::string, std::string>& headers); + +/** +* @param source the input source +* @param label is set to the human-readable label +* @return decoded output as raw binary +*/ +BOTAN_DLL SecureVector<byte> PGP_decode( + DataSource& source, + std::string& label); } diff --git a/src/constructs/aont/package.cpp b/src/constructs/aont/package.cpp index 5d1e674ca..e10087060 100644 --- a/src/constructs/aont/package.cpp +++ b/src/constructs/aont/package.cpp @@ -14,12 +14,10 @@ namespace Botan { -namespace AllOrNothingTransform { - -void package(RandomNumberGenerator& rng, - BlockCipher* cipher, - const byte input[], u32bit input_len, - byte output[]) +void aont_package(RandomNumberGenerator& rng, + BlockCipher* cipher, + const byte input[], u32bit input_len, + byte output[]) { if(!cipher->valid_keylength(cipher->BLOCK_SIZE)) throw Invalid_Argument("AONT::package: Invalid cipher"); @@ -66,9 +64,9 @@ void package(RandomNumberGenerator& rng, xor_buf(final_block, package_key.begin(), cipher->BLOCK_SIZE); } -void unpackage(BlockCipher* cipher, - const byte input[], u32bit input_len, - byte output[]) +void aont_unpackage(BlockCipher* cipher, + const byte input[], u32bit input_len, + byte output[]) { if(!cipher->valid_keylength(cipher->BLOCK_SIZE)) throw Invalid_Argument("AONT::unpackage: Invalid cipher"); @@ -116,5 +114,3 @@ void unpackage(BlockCipher* cipher, } } - -} diff --git a/src/constructs/aont/package.h b/src/constructs/aont/package.h index 9c23d1836..211623347 100644 --- a/src/constructs/aont/package.h +++ b/src/constructs/aont/package.h @@ -14,8 +14,6 @@ namespace Botan { -namespace AllOrNothingTransform { - /** * Rivest's Package Tranform * @arg rng the random number generator to use @@ -25,10 +23,10 @@ namespace AllOrNothingTransform { * @arg output the output data buffer (must be at least * input_len + cipher->BLOCK_SIZE bytes long) */ -void BOTAN_DLL package(RandomNumberGenerator& rng, - BlockCipher* cipher, - const byte input[], u32bit input_len, - byte output[]); +void BOTAN_DLL aont_package(RandomNumberGenerator& rng, + BlockCipher* cipher, + const byte input[], u32bit input_len, + byte output[]); /** * Rivest's Package Tranform (Inversion) @@ -39,11 +37,9 @@ void BOTAN_DLL package(RandomNumberGenerator& rng, * @arg output the output data buffer (must be at least * input_len - cipher->BLOCK_SIZE bytes long) */ -void BOTAN_DLL unpackage(BlockCipher* cipher, - const byte input[], u32bit input_len, - byte output[]); - -} +void BOTAN_DLL aont_unpackage(BlockCipher* cipher, + const byte input[], u32bit input_len, + byte output[]); } diff --git a/src/constructs/cryptobox/cryptobox.cpp b/src/constructs/cryptobox/cryptobox.cpp index 371b52e66..7d27c0523 100644 --- a/src/constructs/cryptobox/cryptobox.cpp +++ b/src/constructs/cryptobox/cryptobox.cpp @@ -18,8 +18,6 @@ namespace Botan { -namespace CryptoBox { - namespace { /* @@ -40,9 +38,9 @@ const u32bit PBKDF_OUTPUT_LEN = CIPHER_KEY_LEN + CIPHER_IV_LEN + MAC_KEY_LEN; } -std::string encrypt(const byte input[], u32bit input_len, - const std::string& passphrase, - RandomNumberGenerator& rng) +std::string cryptobox_encrypt(const byte input[], u32bit input_len, + const std::string& passphrase, + RandomNumberGenerator& rng) { SecureVector<byte> pbkdf_salt(PBKDF_SALT_LEN); rng.randomize(pbkdf_salt.begin(), pbkdf_salt.size()); @@ -91,8 +89,8 @@ std::string encrypt(const byte input[], u32bit input_len, "BOTAN CRYPTOBOX MESSAGE"); } -std::string decrypt(const byte input[], u32bit input_len, - const std::string& passphrase) +std::string cryptobox_decrypt(const byte input[], u32bit input_len, + const std::string& passphrase) { DataSource_Memory input_src(input, input_len); SecureVector<byte> ciphertext = @@ -120,7 +118,7 @@ std::string decrypt(const byte input[], u32bit input_len, CIPHER_IV_LEN); Pipe pipe(new Fork( - get_cipher("Serpent/CTR-BE", cipher_key, iv, ENCRYPTION), + get_cipher("Serpent/CTR-BE", cipher_key, iv, DECRYPTION), new MAC_Filter(new HMAC(new SHA_512), mac_key, MAC_OUTPUT_LEN))); @@ -141,5 +139,3 @@ std::string decrypt(const byte input[], u32bit input_len, } } - -} diff --git a/src/constructs/cryptobox/cryptobox.h b/src/constructs/cryptobox/cryptobox.h index a30cb244a..3dbb894ba 100644 --- a/src/constructs/cryptobox/cryptobox.h +++ b/src/constructs/cryptobox/cryptobox.h @@ -13,8 +13,6 @@ namespace Botan { -namespace CryptoBox { - /** * Encrypt a message * @param input the input data @@ -22,9 +20,9 @@ namespace CryptoBox { * @param passphrase the passphrase used to encrypt the message * @param rng a ref to a random number generator, such as AutoSeeded_RNG */ -BOTAN_DLL std::string encrypt(const byte input[], u32bit input_len, - const std::string& passphrase, - RandomNumberGenerator& rng); +BOTAN_DLL std::string cryptobox_encrypt(const byte input[], u32bit input_len, + const std::string& passphrase, + RandomNumberGenerator& rng); /** * Decrypt a message encrypted with CryptoBox::encrypt @@ -32,10 +30,8 @@ BOTAN_DLL std::string encrypt(const byte input[], u32bit input_len, * @param input_len the length of input in bytes * @param passphrase the passphrase used to encrypt the message */ -BOTAN_DLL std::string decrypt(const byte input[], u32bit input_len, - const std::string& passphrase); - -} +BOTAN_DLL std::string cryptobox_decrypt(const byte input[], u32bit input_len, + const std::string& passphrase); } diff --git a/src/constructs/passhash/passhash9.h b/src/constructs/passhash/passhash9.h index 6020dce42..8900d55d3 100644 --- a/src/constructs/passhash/passhash9.h +++ b/src/constructs/passhash/passhash9.h @@ -16,7 +16,7 @@ namespace Botan { * Create a password hash using PBKDF2 * @param password the password * @param rng a random number generator -* @Param work_factor how much work to do to slow down guessing attacks +* @param work_factor how much work to do to slow down guessing attacks */ std::string BOTAN_DLL generate_passhash9(const std::string& password, RandomNumberGenerator& rng, diff --git a/src/constructs/tss/tss.h b/src/constructs/tss/tss.h index c8b0242d8..485e42c53 100644 --- a/src/constructs/tss/tss.h +++ b/src/constructs/tss/tss.h @@ -15,16 +15,19 @@ namespace Botan { +/** +* A split secret, using the format from draft-mcgrew-tss-03 +*/ class BOTAN_DLL RTSS_Share { public: /** - * @arg M the number of shares needed to reconstruct - * @arg N the number of shares generated - * @arg secret the secret to split - * @arg secret_len the length of the secret - * @arg identifier the 16 byte share identifier - * @arg rng the random number generator to use + * @param M the number of shares needed to reconstruct + * @param N the number of shares generated + * @param secret the secret to split + * @param secret_len the length of the secret + * @param identifier the 16 byte share identifier + * @param rng the random number generator to use */ static std::vector<RTSS_Share> split(byte M, byte N, @@ -33,18 +36,36 @@ class BOTAN_DLL RTSS_Share RandomNumberGenerator& rng); /** - * @arg shares the list of shares + * @param shares the list of shares */ static SecureVector<byte> reconstruct(const std::vector<RTSS_Share>& shares); RTSS_Share() {} - RTSS_Share(const std::string&); + /** + * @param hex_input the share encoded in hexadecimal + */ + RTSS_Share(const std::string& hex_input); + + /** + * @return hex representation + */ std::string to_string() const; + + /** + * @return share identifier + */ byte share_id() const; + /** + * @return size of this share in bytes + */ u32bit size() const { return contents.size(); } + + /** + * @return if this TSS share was initialized or not + */ bool initialized() const { return (contents.size() > 0); } private: SecureVector<byte> contents; diff --git a/src/engine/aes_isa_eng/aes_isa_engine.h b/src/engine/aes_isa_eng/aes_isa_engine.h index 5f22e4105..3c4d3e936 100644 --- a/src/engine/aes_isa_eng/aes_isa_engine.h +++ b/src/engine/aes_isa_eng/aes_isa_engine.h @@ -1,4 +1,4 @@ -/** +/* * Engine for AES instructions * (C) 2009 Jack Lloyd * @@ -12,11 +12,15 @@ namespace Botan { +/** +* Engine for implementations that hook into CPU-specific +* AES implementations (eg AES-NI, VIA C7, or AMD Geode) +*/ class AES_ISA_Engine : public Engine { public: std::string provider_name() const { return "aes_isa"; } - private: + BlockCipher* find_block_cipher(const SCAN_Name&, Algorithm_Factory&) const; }; diff --git a/src/engine/amd64_eng/amd64_engine.cpp b/src/engine/amd64_eng/amd64_engine.cpp index 6de1484fb..262bd5809 100644 --- a/src/engine/amd64_eng/amd64_engine.cpp +++ b/src/engine/amd64_eng/amd64_engine.cpp @@ -1,4 +1,4 @@ -/** +/* * AMD64 Assembly Implementation Engine * (C) 1999-2008 Jack Lloyd * diff --git a/src/engine/amd64_eng/amd64_engine.h b/src/engine/amd64_eng/amd64_engine.h index dc6f3e993..dc3d4cefc 100644 --- a/src/engine/amd64_eng/amd64_engine.h +++ b/src/engine/amd64_eng/amd64_engine.h @@ -1,4 +1,4 @@ -/** +/* * x86-64 Assembly Implementation Engines * (C) 1999-2008 Jack Lloyd * @@ -12,11 +12,14 @@ namespace Botan { +/** +* Engine for implementations that are x86-64 specific +*/ class AMD64_Assembler_Engine : public Engine { public: std::string provider_name() const { return "amd64"; } - private: + HashFunction* find_hash(const SCAN_Name& reqeust, Algorithm_Factory&) const; }; diff --git a/src/engine/def_engine/default_engine.h b/src/engine/def_engine/default_engine.h index 1e40cfe46..f7e6d9746 100644 --- a/src/engine/def_engine/default_engine.h +++ b/src/engine/def_engine/default_engine.h @@ -12,7 +12,7 @@ namespace Botan { -/* +/** * Default Engine */ class Default_Engine : public Engine @@ -35,12 +35,9 @@ class Default_Engine : public Engine Modular_Exponentiator* mod_exp(const BigInt& n, Power_Mod::Usage_Hints) const; - virtual bool can_add_algorithms() { return true; } - Keyed_Filter* get_cipher(const std::string&, Cipher_Dir, Algorithm_Factory&); - private: BlockCipher* find_block_cipher(const SCAN_Name&, Algorithm_Factory&) const; diff --git a/src/engine/def_engine/lookup_hash.cpp b/src/engine/def_engine/lookup_hash.cpp index 1d96d4f3f..47c6c0a56 100644 --- a/src/engine/def_engine/lookup_hash.cpp +++ b/src/engine/def_engine/lookup_hash.cpp @@ -26,10 +26,6 @@ #include <botan/bmw_512.h> #endif -#if defined(BOTAN_HAS_FORK_256) - #include <botan/fork256.h> -#endif - #if defined(BOTAN_HAS_GOST_34_11) #include <botan/gost_3411.h> #endif @@ -116,11 +112,6 @@ Default_Engine::find_hash(const SCAN_Name& request, return new BMW_512; #endif -#if defined(BOTAN_HAS_FORK_256) - if(request.algo_name() == "FORK-256") - return new FORK_256; -#endif - #if defined(BOTAN_HAS_GOST_34_11) if(request.algo_name() == "GOST-34.11") return new GOST_34_11; diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp new file mode 100644 index 000000000..958d4148f --- /dev/null +++ b/src/engine/engine.cpp @@ -0,0 +1,84 @@ +/* +* Engine +* (C) 2010 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/engine.h> + +namespace Botan { + +BlockCipher* +Engine::find_block_cipher(const SCAN_Name&, + Algorithm_Factory&) const + { + return 0; + } + +StreamCipher* +Engine::find_stream_cipher(const SCAN_Name&, + Algorithm_Factory&) const + { + return 0; + } + +HashFunction* +Engine::find_hash(const SCAN_Name&, + Algorithm_Factory&) const + { + return 0; + } + +MessageAuthenticationCode* +Engine::find_mac(const SCAN_Name&, + Algorithm_Factory&) const + { + return 0; + } + +Modular_Exponentiator* +Engine::mod_exp(const BigInt&, + Power_Mod::Usage_Hints) const + { + return 0; + } + +Keyed_Filter* Engine::get_cipher(const std::string&, + Cipher_Dir, + Algorithm_Factory&) + { + return 0; + } + +PK_Ops::Key_Agreement* +Engine::get_key_agreement_op(const Private_Key&) const + { + return 0; + } + +PK_Ops::Signature* +Engine::get_signature_op(const Private_Key&) const + { + return 0; + } + +PK_Ops::Verification* +Engine::get_verify_op(const Public_Key&) const + { + return 0; + } + +PK_Ops::Encryption* +Engine::get_encryption_op(const Public_Key&) const + { + return 0; + } + +PK_Ops::Decryption* +Engine::get_decryption_op(const Private_Key&) const + { + return 0; + } + +} diff --git a/src/engine/engine.h b/src/engine/engine.h index 69592886c..c9bcd6126 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -26,67 +26,117 @@ namespace Botan { class Algorithm_Factory; class Keyed_Filter; -/* -* Engine Base Class +/** +* Base class for all engines. All non-pure virtual functions simply +* return NULL, indicating the algorithm in question is not +* supported. Subclasses can reimplement whichever function(s) +* they want to hook in a particular type. */ class BOTAN_DLL Engine { public: virtual ~Engine() {} + /** + * @return name of this engine + */ virtual std::string provider_name() const = 0; - // Lookup functions + /** + * @param algo_spec the algorithm name/specification + * @param af an algorithm factory object + * @return newly allocated object, or NULL + */ virtual BlockCipher* - find_block_cipher(const SCAN_Name&, Algorithm_Factory&) const - { return 0; } - + find_block_cipher(const SCAN_Name& algo_spec, + Algorithm_Factory& af) const; + + /** + * @param algo_spec the algorithm name/specification + * @param af an algorithm factory object + * @return newly allocated object, or NULL + */ virtual StreamCipher* - find_stream_cipher(const SCAN_Name&, Algorithm_Factory&) const - { return 0; } - + find_stream_cipher(const SCAN_Name& algo_spec, + Algorithm_Factory& af) const; + + /** + * @param algo_spec the algorithm name/specification + * @param af an algorithm factory object + * @return newly allocated object, or NULL + */ virtual HashFunction* - find_hash(const SCAN_Name&, Algorithm_Factory&) const - { return 0; } - + find_hash(const SCAN_Name& algo_spec, + Algorithm_Factory& af) const; + + /** + * @param algo_spec the algorithm name/specification + * @param af an algorithm factory object + * @return newly allocated object, or NULL + */ virtual MessageAuthenticationCode* - find_mac(const SCAN_Name&, Algorithm_Factory&) const - { return 0; } - + find_mac(const SCAN_Name& algo_spec, + Algorithm_Factory& af) const; + + /** + * @param n the modulus + * @param hints any use hints + * @return newly allocated object, or NULL + */ virtual Modular_Exponentiator* - mod_exp(const BigInt&, Power_Mod::Usage_Hints) const - { return 0; } - - virtual Keyed_Filter* get_cipher(const std::string&, - Cipher_Dir, - Algorithm_Factory&) - { return 0; } - + mod_exp(const BigInt& n, + Power_Mod::Usage_Hints hints) const; + + /** + * Return a new cipher object + * @param algo_spec the algorithm name/specification + * @param dir specifies if encryption or decryption is desired + * @param af an algorithm factory object + * @return newly allocated object, or NULL + */ + virtual Keyed_Filter* get_cipher(const std::string& algo_spec, + Cipher_Dir dir, + Algorithm_Factory& af); + + /** + * Return a new operator object for this key, if possible + * @param key the key we want an operator for + * @return newly allocated operator object, or NULL + */ virtual PK_Ops::Key_Agreement* - get_key_agreement_op(const Private_Key&) const - { - return 0; - } - - virtual PK_Ops::Signature* get_signature_op(const Private_Key&) const - { - return 0; - } - - virtual PK_Ops::Verification* get_verify_op(const Public_Key&) const - { - return 0; - } - - virtual PK_Ops::Encryption* get_encryption_op(const Public_Key&) const - { - return 0; - } - - virtual PK_Ops::Decryption* get_decryption_op(const Private_Key&) const - { - return 0; - } + get_key_agreement_op(const Private_Key& key) const; + + /** + * Return a new operator object for this key, if possible + * @param key the key we want an operator for + * @return newly allocated operator object, or NULL + */ + virtual PK_Ops::Signature* + get_signature_op(const Private_Key& key) const; + + /** + * Return a new operator object for this key, if possible + * @param key the key we want an operator for + * @return newly allocated operator object, or NULL + */ + virtual PK_Ops::Verification* + get_verify_op(const Public_Key& key) const; + + /** + * Return a new operator object for this key, if possible + * @param key the key we want an operator for + * @return newly allocated operator object, or NULL + */ + virtual PK_Ops::Encryption* + get_encryption_op(const Public_Key& key) const; + + /** + * Return a new operator object for this key, if possible + * @param key the key we want an operator for + * @return newly allocated operator object, or NULL + */ + virtual PK_Ops::Decryption* + get_decryption_op(const Private_Key& key) const; }; } diff --git a/src/engine/gnump/gmp_wrap.h b/src/engine/gnump/gmp_wrap.h index 82437ceba..52d130d6b 100644 --- a/src/engine/gnump/gmp_wrap.h +++ b/src/engine/gnump/gmp_wrap.h @@ -13,8 +13,8 @@ namespace Botan { -/* -* Lightweight GMP mpz_t Wrapper +/** +* Lightweight GMP mpz_t wrapper. For internal use only. */ class GMP_MPZ { diff --git a/src/engine/gnump/gnump_engine.h b/src/engine/gnump/gnump_engine.h index 1ca5a3548..fe154b914 100644 --- a/src/engine/gnump/gnump_engine.h +++ b/src/engine/gnump/gnump_engine.h @@ -12,8 +12,8 @@ namespace Botan { -/* -* GMP Engine +/** +* Engine using GNU MP */ class GMP_Engine : public Engine { diff --git a/src/engine/ia32_eng/ia32_engine.h b/src/engine/ia32_eng/ia32_engine.h index 517b88aa8..6e0a8a5f4 100644 --- a/src/engine/ia32_eng/ia32_engine.h +++ b/src/engine/ia32_eng/ia32_engine.h @@ -1,4 +1,4 @@ -/** +/* * IA-32 Assembly Implementation Engines * (C) 1999-2008 Jack Lloyd * @@ -12,11 +12,14 @@ namespace Botan { +/** +* Engine for x86-32 specific implementations +*/ class IA32_Assembler_Engine : public Engine { public: std::string provider_name() const { return "ia32"; } - private: + BlockCipher* find_block_cipher(const SCAN_Name&, Algorithm_Factory&) const; diff --git a/src/engine/info.txt b/src/engine/info.txt index 32fcf21c2..5f787cebe 100644 --- a/src/engine/info.txt +++ b/src/engine/info.txt @@ -4,6 +4,10 @@ define ENGINES engine.h </header:public> +<source> +engine.cpp +</source> + <requires> block hash diff --git a/src/engine/openssl/bn_wrap.h b/src/engine/openssl/bn_wrap.h index 02a229fdd..372f5a329 100644 --- a/src/engine/openssl/bn_wrap.h +++ b/src/engine/openssl/bn_wrap.h @@ -13,8 +13,8 @@ namespace Botan { -/* -* Lightweight OpenSSL BN Wrapper +/** +* Lightweight OpenSSL BN wrapper. For internal use only. */ class OSSL_BN { @@ -36,8 +36,8 @@ class OSSL_BN ~OSSL_BN(); }; -/* -* Lightweight OpenSSL BN_CTX Wrapper +/** +* Lightweight OpenSSL BN_CTX wrapper. For internal use only. */ class OSSL_BN_CTX { diff --git a/src/engine/openssl/openssl_engine.h b/src/engine/openssl/openssl_engine.h index 1ee7e4c11..b1f71a160 100644 --- a/src/engine/openssl/openssl_engine.h +++ b/src/engine/openssl/openssl_engine.h @@ -12,7 +12,7 @@ namespace Botan { -/* +/** * OpenSSL Engine */ class OpenSSL_Engine : public Engine @@ -37,7 +37,7 @@ class OpenSSL_Engine : public Engine Modular_Exponentiator* mod_exp(const BigInt&, Power_Mod::Usage_Hints) const; - private: + BlockCipher* find_block_cipher(const SCAN_Name&, Algorithm_Factory&) const; diff --git a/src/engine/simd_engine/simd_engine.cpp b/src/engine/simd_engine/simd_engine.cpp index e889ca161..aa434d669 100644 --- a/src/engine/simd_engine/simd_engine.cpp +++ b/src/engine/simd_engine/simd_engine.cpp @@ -1,4 +1,4 @@ -/** +/* * SIMD Engine * (C) 1999-2009 Jack Lloyd * diff --git a/src/engine/simd_engine/simd_engine.h b/src/engine/simd_engine/simd_engine.h index 722b5529b..73f7d2233 100644 --- a/src/engine/simd_engine/simd_engine.h +++ b/src/engine/simd_engine/simd_engine.h @@ -1,4 +1,4 @@ -/** +/* * SIMD Assembly Engine * (C) 1999-2009 Jack Lloyd * @@ -12,11 +12,14 @@ namespace Botan { +/** +* Engine for implementations that use some kind of SIMD +*/ class SIMD_Engine : public Engine { public: std::string provider_name() const { return "simd"; } - private: + BlockCipher* find_block_cipher(const SCAN_Name&, Algorithm_Factory&) const; diff --git a/src/entropy/beos_stats/es_beos.cpp b/src/entropy/beos_stats/es_beos.cpp index 148d38b9b..2b4a7a24f 100644 --- a/src/entropy/beos_stats/es_beos.cpp +++ b/src/entropy/beos_stats/es_beos.cpp @@ -1,4 +1,4 @@ -/** +/* * BeOS EntropySource * (C) 1999-2008 Jack Lloyd * diff --git a/src/entropy/beos_stats/es_beos.h b/src/entropy/beos_stats/es_beos.h index be80ad340..31029a88c 100644 --- a/src/entropy/beos_stats/es_beos.h +++ b/src/entropy/beos_stats/es_beos.h @@ -1,4 +1,4 @@ -/** +/* * BeOS EntropySource * (C) 1999-2008 Jack Lloyd * diff --git a/src/entropy/dev_random/dev_random.h b/src/entropy/dev_random/dev_random.h index 3ffe536e3..e20e74300 100644 --- a/src/entropy/dev_random/dev_random.h +++ b/src/entropy/dev_random/dev_random.h @@ -14,6 +14,9 @@ namespace Botan { +/** +* Entropy source reading from kernel devices like /dev/random +*/ class Device_EntropySource : public EntropySource { public: diff --git a/src/entropy/egd/es_egd.cpp b/src/entropy/egd/es_egd.cpp index bd8dc8590..29880a544 100644 --- a/src/entropy/egd/es_egd.cpp +++ b/src/entropy/egd/es_egd.cpp @@ -46,7 +46,7 @@ int EGD_EntropySource::EGD_Socket::open_socket(const std::string& path) if(sizeof(addr.sun_path) < path.length() + 1) throw std::invalid_argument("EGD socket path is too long"); - std::strcpy(addr.sun_path, path.c_str()); + std::strncpy(addr.sun_path, path.c_str(), sizeof(addr.sun_path)); int len = sizeof(addr.sun_family) + std::strlen(addr.sun_path) + 1; diff --git a/src/entropy/egd/es_egd.h b/src/entropy/egd/es_egd.h index 1a3618989..defe88a54 100644 --- a/src/entropy/egd/es_egd.h +++ b/src/entropy/egd/es_egd.h @@ -1,4 +1,4 @@ -/** +/* * EGD EntropySource * (C) 1999-2007 Jack Lloyd * diff --git a/src/entropy/entropy_src.h b/src/entropy/entropy_src.h index 4d01bce7c..fa61d9ea8 100644 --- a/src/entropy/entropy_src.h +++ b/src/entropy/entropy_src.h @@ -1,4 +1,4 @@ -/** +/* * EntropySource * (C) 2008-2009 Jack Lloyd * @@ -20,23 +20,40 @@ namespace Botan { class BOTAN_DLL Entropy_Accumulator { public: + /** + * Initialize an Entropy_Accumulator + * @param goal is how many bits we would like to collect + */ Entropy_Accumulator(u32bit goal) : entropy_goal(goal), collected_bits(0) {} virtual ~Entropy_Accumulator() {} /** - @return cached I/O buffer for repeated polls + * Get a cached I/O buffer (purely for minimizing allocation + * overhead to polls) + * + * @param size requested size for the I/O buffer + * @return cached I/O buffer for repeated polls */ MemoryRegion<byte>& get_io_buffer(u32bit size) { io_buffer.resize(size); return io_buffer; } + /** + * @return number of bits collected so far + */ u32bit bits_collected() const { return static_cast<u32bit>(collected_bits); } + /** + * @return if our polling goal has been achieved + */ bool polling_goal_achieved() const { return (collected_bits >= entropy_goal); } + /** + * @return how many bits we need to reach our polling goal + */ u32bit desired_remaining_bits() const { if(collected_bits >= entropy_goal) @@ -44,12 +61,25 @@ class BOTAN_DLL Entropy_Accumulator return static_cast<u32bit>(entropy_goal - collected_bits); } + /** + * Add entropy to the accumulator + * @param bytes the input bytes + * @param length specifies how many bytes the input is + * @param entropy_bits_per_byte is a best guess at how much + * entropy per byte is in this input + */ void add(const void* bytes, u32bit length, double entropy_bits_per_byte) { add_bytes(reinterpret_cast<const byte*>(bytes), length); collected_bits += entropy_bits_per_byte * length; } + /** + * Add entropy to the accumulator + * @param v is some value + * @param entropy_bits_per_byte is a best guess at how much + * entropy per byte is in this input + */ template<typename T> void add(const T& v, double entropy_bits_per_byte) { @@ -63,9 +93,16 @@ class BOTAN_DLL Entropy_Accumulator double collected_bits; }; +/** +* Entropy accumulator that puts the input into a BufferedComputation +*/ class BOTAN_DLL Entropy_Accumulator_BufferedComputation : public Entropy_Accumulator { public: + /** + * @param sink the hash or MAC we are feeding the poll data into + * @param goal is how many bits we want to collect in this poll + */ Entropy_Accumulator_BufferedComputation(BufferedComputation& sink, u32bit goal) : Entropy_Accumulator(goal), entropy_sink(sink) {} @@ -85,8 +122,17 @@ class BOTAN_DLL Entropy_Accumulator_BufferedComputation : public Entropy_Accumul class BOTAN_DLL EntropySource { public: + /** + * @return name identifying this entropy source + */ virtual std::string name() const = 0; + + /** + * Perform an entropy gathering poll + * @param accum is an accumulator object that will be given entropy + */ virtual void poll(Entropy_Accumulator& accum) = 0; + virtual ~EntropySource() {} }; diff --git a/src/entropy/hres_timer/hres_timer.h b/src/entropy/hres_timer/hres_timer.h index a602d5d7b..c693b8d4e 100644 --- a/src/entropy/hres_timer/hres_timer.h +++ b/src/entropy/hres_timer/hres_timer.h @@ -12,8 +12,8 @@ namespace Botan { -/* -* High Resolution Timestamp Source +/** +* Entropy source using high resolution timers */ class High_Resolution_Timestamp : public EntropySource { diff --git a/src/entropy/proc_walk/es_ftw.cpp b/src/entropy/proc_walk/es_ftw.cpp index 5e2b17860..53e39d834 100644 --- a/src/entropy/proc_walk/es_ftw.cpp +++ b/src/entropy/proc_walk/es_ftw.cpp @@ -22,9 +22,23 @@ namespace Botan { +/** +* Returns file descriptors. Until it doesn't +*/ +class File_Descriptor_Source + { + public: + /** + * @return next file descriptor, or -1 if done + */ + virtual int next_fd() = 0; + + virtual ~File_Descriptor_Source() {} + }; + namespace { -class Directory_Walker : public FTW_EntropySource::File_Descriptor_Source +class Directory_Walker : public File_Descriptor_Source { public: Directory_Walker(const std::string& root) { add_directory(root); } diff --git a/src/entropy/proc_walk/es_ftw.h b/src/entropy/proc_walk/es_ftw.h index d7a719818..3ba222d46 100644 --- a/src/entropy/proc_walk/es_ftw.h +++ b/src/entropy/proc_walk/es_ftw.h @@ -24,17 +24,9 @@ class FTW_EntropySource : public EntropySource FTW_EntropySource(const std::string& root_dir); ~FTW_EntropySource(); - - class File_Descriptor_Source - { - public: - virtual int next_fd() = 0; - virtual ~File_Descriptor_Source() {} - }; private: - std::string path; - File_Descriptor_Source* dir; + class File_Descriptor_Source* dir; }; } diff --git a/src/entropy/unix_procs/unix_cmd.cpp b/src/entropy/unix_procs/unix_cmd.cpp index 34e7c314a..c92c84b4c 100644 --- a/src/entropy/unix_procs/unix_cmd.cpp +++ b/src/entropy/unix_procs/unix_cmd.cpp @@ -37,6 +37,7 @@ void do_exec(const std::vector<std::string>& arg_list, { const std::string full_path = paths[j] + "/" + arg_list[0]; const char* fsname = full_path.c_str(); + ::execl(fsname, fsname, arg1, arg2, arg3, arg4, NULL); } } @@ -50,7 +51,9 @@ struct pipe_wrapper { int fd; pid_t pid; - pipe_wrapper() { fd = -1; pid = 0; } + + pipe_wrapper(int f, pid_t p) : fd(f), pid(p) {} + ~pipe_wrapper() { ::close(fd); } }; /** @@ -152,9 +155,7 @@ void DataSource_Command::create_pipe(const std::vector<std::string>& paths) } else if(pid > 0) { - pipe = new pipe_wrapper; - pipe->fd = pipe_fd[0]; - pipe->pid = pid; + pipe = new pipe_wrapper(pipe_fd[0], pid); ::close(pipe_fd[1]); } else @@ -200,7 +201,6 @@ void DataSource_Command::shutdown_pipe() } } - ::close(pipe->fd); delete pipe; pipe = 0; } diff --git a/src/entropy/unix_procs/unix_cmd.h b/src/entropy/unix_procs/unix_cmd.h index 7decf587f..3abca8f37 100644 --- a/src/entropy/unix_procs/unix_cmd.h +++ b/src/entropy/unix_procs/unix_cmd.h @@ -1,4 +1,4 @@ -/** +/* * Unix Command Execution * (C) 1999-2007 Jack Lloyd * @@ -20,6 +20,10 @@ namespace Botan { */ struct Unix_Program { + /** + * @param n is the name and arguments of what we are going run + * @param p is the priority level (lower prio numbers get polled first) + */ Unix_Program(const char* n, u32bit p) { name_and_args = n; priority = p; working = true; } diff --git a/src/entropy/win32_stats/es_win32.cpp b/src/entropy/win32_stats/es_win32.cpp index e9f564fee..b3d7d27e5 100644 --- a/src/entropy/win32_stats/es_win32.cpp +++ b/src/entropy/win32_stats/es_win32.cpp @@ -1,4 +1,4 @@ -/** +/* * Win32 EntropySource * (C) 1999-2009 Jack Lloyd * diff --git a/src/entropy/win32_stats/es_win32.h b/src/entropy/win32_stats/es_win32.h index 0aa9054e3..2e46c773d 100644 --- a/src/entropy/win32_stats/es_win32.h +++ b/src/entropy/win32_stats/es_win32.h @@ -1,4 +1,4 @@ -/** +/* * Win32 EntropySource * (C) 1999-2009 Jack Lloyd * diff --git a/src/filters/basefilt.cpp b/src/filters/basefilt.cpp index c91a5aa62..124c0a887 100644 --- a/src/filters/basefilt.cpp +++ b/src/filters/basefilt.cpp @@ -6,9 +6,15 @@ */ #include <botan/basefilt.h> +#include <botan/key_filt.h> namespace Botan { +void Keyed_Filter::set_iv(const InitializationVector&) + { + // assert that the iv is empty? + } + /* * Chain Constructor */ diff --git a/src/filters/buf_filt.h b/src/filters/buf_filt.h index 582f585b0..1ab402df7 100644 --- a/src/filters/buf_filt.h +++ b/src/filters/buf_filt.h @@ -12,6 +12,10 @@ namespace Botan { +/** +* Filter mixin that breaks input into blocks, useful for +* cipher modes +*/ class BOTAN_DLL Buffered_Filter { public: diff --git a/src/filters/bzip2/bzip2.cpp b/src/filters/bzip2/bzip2.cpp index 9dcee8fdf..b4b04a13e 100644 --- a/src/filters/bzip2/bzip2.cpp +++ b/src/filters/bzip2/bzip2.cpp @@ -54,8 +54,6 @@ void bzip_free(void* info_ptr, void* ptr) info->alloc->deallocate(ptr, i->second); } -} - /* * Wrapper Type for Bzip2 Stream */ @@ -79,6 +77,8 @@ class Bzip_Stream } }; +} + /* * Bzip_Compression Constructor */ diff --git a/src/filters/bzip2/bzip2.h b/src/filters/bzip2/bzip2.h index f42263537..3b40dbe40 100644 --- a/src/filters/bzip2/bzip2.h +++ b/src/filters/bzip2/bzip2.h @@ -13,7 +13,7 @@ namespace Botan { -/* +/** * Bzip Compression Filter */ class BOTAN_DLL Bzip_Compression : public Filter @@ -35,7 +35,7 @@ class BOTAN_DLL Bzip_Compression : public Filter class Bzip_Stream* bz; }; -/* +/** * Bzip Decompression Filter */ class BOTAN_DLL Bzip_Decompression : public Filter diff --git a/src/filters/data_snk.h b/src/filters/data_snk.h index fda06e492..57020e9dd 100644 --- a/src/filters/data_snk.h +++ b/src/filters/data_snk.h @@ -45,11 +45,11 @@ class BOTAN_DLL DataSink_Stream : public DataSink /** * Construct a DataSink_Stream from a stream. - * @param file the name of the file to open a stream to + * @param pathname the name of the file to open a stream to * @param use_binary indicates whether to treat the file * as a binary file or not */ - DataSink_Stream(const std::string& filename, + DataSink_Stream(const std::string& pathname, bool use_binary = false); ~DataSink_Stream(); diff --git a/src/filters/data_src.h b/src/filters/data_src.h index dea46584c..016402b61 100644 --- a/src/filters/data_src.h +++ b/src/filters/data_src.h @@ -21,22 +21,25 @@ class BOTAN_DLL DataSource { public: /** - * Read from the source. Moves the internal offset so that - * every call to read will return a new portion of the source. + * Read from the source. Moves the internal offset so that every + * call to read will return a new portion of the source. + * * @param out the byte array to write the result to * @param length the length of the byte array out - * @return the length in bytes that was actually read and put + * @return length in bytes that was actually read and put * into out */ virtual u32bit read(byte out[], u32bit length) = 0; /** - * Read from the source but do not modify the internal offset. Consecutive - * calls to peek() will return portions of the source starting at the same - * position. + * Read from the source but do not modify the internal + * offset. Consecutive calls to peek() will return portions of + * the source starting at the same position. + * * @param out the byte array to write the output to * @param length the length of the byte array out - * @return the length in bytes that was actually read and put + * @param peek_offset the offset into the stream to read at + * @return length in bytes that was actually read and put * into out */ virtual u32bit peek(byte out[], u32bit length, @@ -49,22 +52,22 @@ class BOTAN_DLL DataSource virtual bool end_of_data() const = 0; /** * return the id of this data source - * @return the std::string representing the id of this data source + * @return std::string representing the id of this data source */ virtual std::string id() const { return ""; } /** * Read one byte. - * @param the byte to read to - * @return the length in bytes that was actually read and put + * @param out the byte to read to + * @return length in bytes that was actually read and put * into out */ u32bit read_byte(byte& out); /** * Peek at one byte. - * @param the byte to read to - * @return the length in bytes that was actually read and put + * @param out an output byte + * @return length in bytes that was actually read and put * into out */ u32bit peek_byte(byte& out) const; @@ -72,7 +75,7 @@ class BOTAN_DLL DataSource /** * Discard the next N bytes of the data * @param N the number of bytes to discard - * @return the number of bytes actually discarded + * @return number of bytes actually discarded */ u32bit discard_next(u32bit N); diff --git a/src/filters/filter.h b/src/filters/filter.h index 8fc114db7..55274beae 100644 --- a/src/filters/filter.h +++ b/src/filters/filter.h @@ -31,12 +31,13 @@ class BOTAN_DLL Filter /** * Start a new message. Must be closed by end_msg() before another - * message can be startet. + * message can be started. */ virtual void start_msg() {} /** - * Tell the Filter that the current message shall be ended. + * Notify that the current message is finished; flush buffers and + * do end-of-message processing (if any). */ virtual void end_msg() {} @@ -46,6 +47,28 @@ class BOTAN_DLL Filter */ virtual bool attachable() { return true; } + virtual ~Filter() {} + protected: + /** + * @param in some input for the filter + * @param length the length of in + */ + void send(const byte in[], u32bit length); + + /** + * @param in some input for the filter + */ + void send(byte in) { send(&in, 1); } + + /** + * @param in some input for the filter + */ + void send(const MemoryRegion<byte>& in) { send(in.begin(), in.size()); } + Filter(); + private: + Filter(const Filter&) {} + Filter& operator=(const Filter&) { return (*this); } + /** * Start a new message in *this and all following filters. Only for * internal use, not intended for use in client applications. @@ -61,21 +84,28 @@ class BOTAN_DLL Filter Filter(const Filter&) = delete; Filter& operator=(const Filter&) = delete; - virtual ~Filter() {} - protected: - void send(const byte[], u32bit); - void send(byte input) { send(&input, 1); } - void send(const MemoryRegion<byte>& in) { send(in.begin(), in.size()); } - Filter(); - private: u32bit total_ports() const; u32bit current_port() const { return port_num; } - void set_port(u32bit); + + /** + * Set the active port + * @param new_port the new value + */ + void set_port(u32bit new_port); u32bit owns() const { return filter_owns; } - void attach(Filter*); - void set_next(Filter*[], u32bit); + /** + * Attach another filter to this one + * @param f filter to attach + */ + void attach(Filter* f); + + /** + * @param filters the filters to set + * @param count number of items in filters + */ + void set_next(Filter* filters[], u32bit count); Filter* get_next() const; SecureVector<byte> write_queue; @@ -92,10 +122,15 @@ class BOTAN_DLL Filter class BOTAN_DLL Fanout_Filter : public Filter { protected: + /** + * Increment the number of filters past us that we own + */ void incr_owns() { ++filter_owns; } void set_port(u32bit n) { Filter::set_port(n); } + void set_next(Filter* f[], u32bit n) { Filter::set_next(f, n); } + void attach(Filter* f) { Filter::attach(f); } }; diff --git a/src/filters/filters.h b/src/filters/filters.h index 208332a56..5953518d3 100644 --- a/src/filters/filters.h +++ b/src/filters/filters.h @@ -44,7 +44,7 @@ class BOTAN_DLL StreamCipher_Filter : public Keyed_Filter */ void write(const byte input[], u32bit input_len); - bool valid_iv_length(u32bit iv_len) + bool valid_iv_length(u32bit iv_len) const { return cipher->valid_iv_length(iv_len); } /** @@ -160,8 +160,8 @@ class BOTAN_DLL MAC_Filter : public Keyed_Filter /** * Construct a MAC filter. The MAC key will be left empty. - * @param mac the MAC to use - * @param len the output length of this filter. Leave the default + * @param mac_obj the MAC to use + * @param out_len the output length of this filter. Leave the default * value 0 if you want to use the full output of the * MAC. Otherwise, specify a smaller value here so that the * output of the MAC will be cut off. @@ -174,9 +174,9 @@ class BOTAN_DLL MAC_Filter : public Keyed_Filter /** * Construct a MAC filter. - * @param mac the MAC to use + * @param mac_obj the MAC to use * @param key the MAC key to use - * @param len the output length of this filter. Leave the default + * @param out_len the output length of this filter. Leave the default * value 0 if you want to use the full output of the * MAC. Otherwise, specify a smaller value here so that the * output of the MAC will be cut off. diff --git a/src/filters/key_filt.h b/src/filters/key_filt.h index 36af91f88..0afea446c 100644 --- a/src/filters/key_filt.h +++ b/src/filters/key_filt.h @@ -21,23 +21,32 @@ class BOTAN_DLL Keyed_Filter : public Filter { public: /** - * Set the key of this filter. - * @param key the key to set + * Set the key of this filter + * @param key the key to use */ virtual void set_key(const SymmetricKey& key) = 0; /** - * Set the initialization vector of this filter. - * @param iv the initialization vector to set + * Set the initialization vector of this filter. Note: you should + * call set_iv() only after you have called set_key() + * @param iv the initialization vector to use */ - virtual void set_iv(const InitializationVector&) {} + virtual void set_iv(const InitializationVector& iv); /** - * Check whether a key length is valid for this filter. + * Check whether a key length is valid for this filter * @param length the key length to be checked for validity * @return true if the key length is valid, false otherwise */ virtual bool valid_keylength(u32bit length) const = 0; + + /** + * Check whether an IV length is valid for this filter + * @param length the IV length to be checked for validity + * @return true if the IV length is valid, false otherwise + */ + virtual bool valid_iv_length(u32bit length) const + { return (length == 0); } }; } diff --git a/src/filters/modes/cbc/cbc.cpp b/src/filters/modes/cbc/cbc.cpp index 4f484da77..b0c3493e7 100644 --- a/src/filters/modes/cbc/cbc.cpp +++ b/src/filters/modes/cbc/cbc.cpp @@ -49,7 +49,7 @@ CBC_Encryption::CBC_Encryption(BlockCipher* ciph, */ void CBC_Encryption::set_iv(const InitializationVector& iv) { - if(iv.length() != state.size()) + if(!valid_iv_length(iv.length())) throw Invalid_IV_Length(name(), iv.length()); state = iv.bits_of(); @@ -114,8 +114,7 @@ std::string CBC_Encryption::name() const */ CBC_Decryption::CBC_Decryption(BlockCipher* ciph, BlockCipherModePaddingMethod* pad) : - Buffered_Filter(ciph->parallelism() * ciph->BLOCK_SIZE, - ciph->BLOCK_SIZE), + Buffered_Filter(ciph->parallel_bytes(), ciph->BLOCK_SIZE), cipher(ciph), padder(pad) { if(!padder->valid_blocksize(cipher->BLOCK_SIZE)) @@ -132,8 +131,7 @@ CBC_Decryption::CBC_Decryption(BlockCipher* ciph, BlockCipherModePaddingMethod* pad, const SymmetricKey& key, const InitializationVector& iv) : - Buffered_Filter(ciph->parallelism() * ciph->BLOCK_SIZE, - ciph->BLOCK_SIZE), + Buffered_Filter(ciph->parallel_bytes(), ciph->BLOCK_SIZE), cipher(ciph), padder(pad) { if(!padder->valid_blocksize(cipher->BLOCK_SIZE)) @@ -151,7 +149,7 @@ CBC_Decryption::CBC_Decryption(BlockCipher* ciph, */ void CBC_Decryption::set_iv(const InitializationVector& iv) { - if(iv.length() != state.size()) + if(!valid_iv_length(iv.length())) throw Invalid_IV_Length(name(), iv.length()); state = iv.bits_of(); diff --git a/src/filters/modes/cbc/cbc.h b/src/filters/modes/cbc/cbc.h index 6d9092041..4f682530b 100644 --- a/src/filters/modes/cbc/cbc.h +++ b/src/filters/modes/cbc/cbc.h @@ -15,7 +15,7 @@ namespace Botan { -/* +/** * CBC Encryption */ class BOTAN_DLL CBC_Encryption : public Keyed_Filter, @@ -24,13 +24,16 @@ class BOTAN_DLL CBC_Encryption : public Keyed_Filter, public: std::string name() const; - void set_iv(const InitializationVector&); + void set_iv(const InitializationVector& iv); void set_key(const SymmetricKey& key) { cipher->set_key(key); } bool valid_keylength(u32bit key_len) const { return cipher->valid_keylength(key_len); } + bool valid_iv_length(u32bit iv_len) const + { return (iv_len == cipher->BLOCK_SIZE); } + CBC_Encryption(BlockCipher* cipher, BlockCipherModePaddingMethod* padding); @@ -52,7 +55,7 @@ class BOTAN_DLL CBC_Encryption : public Keyed_Filter, SecureVector<byte> state; }; -/* +/** * CBC Decryption */ class BOTAN_DLL CBC_Decryption : public Keyed_Filter, @@ -61,13 +64,16 @@ class BOTAN_DLL CBC_Decryption : public Keyed_Filter, public: std::string name() const; - void set_iv(const InitializationVector&); + void set_iv(const InitializationVector& iv); void set_key(const SymmetricKey& key) { cipher->set_key(key); } bool valid_keylength(u32bit key_len) const { return cipher->valid_keylength(key_len); } + bool valid_iv_length(u32bit iv_len) const + { return (iv_len == cipher->BLOCK_SIZE); } + CBC_Decryption(BlockCipher* cipher, BlockCipherModePaddingMethod* padding); diff --git a/src/filters/modes/cfb/cfb.cpp b/src/filters/modes/cfb/cfb.cpp index ff1714b81..5b4575d56 100644 --- a/src/filters/modes/cfb/cfb.cpp +++ b/src/filters/modes/cfb/cfb.cpp @@ -54,7 +54,7 @@ CFB_Encryption::CFB_Encryption(BlockCipher* ciph, void CFB_Encryption::set_iv(const InitializationVector& iv) { - if(iv.length() != state.size()) + if(!valid_iv_length(iv.length())) throw Invalid_IV_Length(name(), iv.length()); state = iv.bits_of(); @@ -131,7 +131,7 @@ CFB_Decryption::CFB_Decryption(BlockCipher* ciph, void CFB_Decryption::set_iv(const InitializationVector& iv) { - if(iv.length() != state.size()) + if(!valid_iv_length(iv.length())) throw Invalid_IV_Length(name(), iv.length()); state = iv.bits_of(); diff --git a/src/filters/modes/cfb/cfb.h b/src/filters/modes/cfb/cfb.h index 249ae21db..05fb9574f 100644 --- a/src/filters/modes/cfb/cfb.h +++ b/src/filters/modes/cfb/cfb.h @@ -13,7 +13,7 @@ namespace Botan { -/* +/** * CFB Encryption */ class BOTAN_DLL CFB_Encryption : public Keyed_Filter @@ -28,6 +28,9 @@ class BOTAN_DLL CFB_Encryption : public Keyed_Filter bool valid_keylength(u32bit key_len) const { return cipher->valid_keylength(key_len); } + bool valid_iv_length(u32bit iv_len) const + { return (iv_len == cipher->BLOCK_SIZE); } + CFB_Encryption(BlockCipher* cipher, u32bit feedback = 0); CFB_Encryption(BlockCipher* cipher, @@ -44,7 +47,7 @@ class BOTAN_DLL CFB_Encryption : public Keyed_Filter u32bit position, feedback; }; -/* +/** * CFB Decryption */ class BOTAN_DLL CFB_Decryption : public Keyed_Filter @@ -59,6 +62,9 @@ class BOTAN_DLL CFB_Decryption : public Keyed_Filter bool valid_keylength(u32bit key_len) const { return cipher->valid_keylength(key_len); } + bool valid_iv_length(u32bit iv_len) const + { return (iv_len == cipher->BLOCK_SIZE); } + CFB_Decryption(BlockCipher* cipher, u32bit feedback = 0); CFB_Decryption(BlockCipher* cipher, diff --git a/src/filters/modes/cts/cts.cpp b/src/filters/modes/cts/cts.cpp index b27b9b3c5..61df8897b 100644 --- a/src/filters/modes/cts/cts.cpp +++ b/src/filters/modes/cts/cts.cpp @@ -43,7 +43,7 @@ CTS_Encryption::CTS_Encryption(BlockCipher* ciph, */ void CTS_Encryption::set_iv(const InitializationVector& iv) { - if(iv.length() != state.size()) + if(!valid_iv_length(iv.length())) throw Invalid_IV_Length(name(), iv.length()); state = iv.bits_of(); @@ -145,7 +145,7 @@ CTS_Decryption::CTS_Decryption(BlockCipher* ciph, */ void CTS_Decryption::set_iv(const InitializationVector& iv) { - if(iv.length() != state.size()) + if(!valid_iv_length(iv.length())) throw Invalid_IV_Length(name(), iv.length()); state = iv.bits_of(); diff --git a/src/filters/modes/cts/cts.h b/src/filters/modes/cts/cts.h index c15fa9510..e9c8ec592 100644 --- a/src/filters/modes/cts/cts.h +++ b/src/filters/modes/cts/cts.h @@ -13,8 +13,8 @@ namespace Botan { -/* -* CTS Encryption +/** +* CBC encryption with ciphertext stealing */ class BOTAN_DLL CTS_Encryption : public Keyed_Filter { @@ -28,6 +28,9 @@ class BOTAN_DLL CTS_Encryption : public Keyed_Filter bool valid_keylength(u32bit key_len) const { return cipher->valid_keylength(key_len); } + bool valid_iv_length(u32bit iv_len) const + { return (iv_len == cipher->BLOCK_SIZE); } + CTS_Encryption(BlockCipher* cipher); CTS_Encryption(BlockCipher* cipher, @@ -45,8 +48,8 @@ class BOTAN_DLL CTS_Encryption : public Keyed_Filter u32bit position; }; -/* -* CTS Decryption +/** +* CBC decryption with ciphertext stealing */ class BOTAN_DLL CTS_Decryption : public Keyed_Filter { @@ -60,6 +63,9 @@ class BOTAN_DLL CTS_Decryption : public Keyed_Filter bool valid_keylength(u32bit key_len) const { return cipher->valid_keylength(key_len); } + bool valid_iv_length(u32bit iv_len) const + { return (iv_len == cipher->BLOCK_SIZE); } + CTS_Decryption(BlockCipher* cipher); CTS_Decryption(BlockCipher* cipher, diff --git a/src/filters/modes/eax/eax.h b/src/filters/modes/eax/eax.h index e45e29ba8..8f79039d9 100644 --- a/src/filters/modes/eax/eax.h +++ b/src/filters/modes/eax/eax.h @@ -15,22 +15,42 @@ namespace Botan { -/* +/** * EAX Base Class */ class BOTAN_DLL EAX_Base : public Keyed_Filter { public: - void set_key(const SymmetricKey&); - void set_iv(const InitializationVector&); - void set_header(const byte[], u32bit); + void set_key(const SymmetricKey& key); + void set_iv(const InitializationVector& iv); + + /** + * Set some additional data that is not included in the + * ciphertext but that will be authenticated. + * @param header the header contents + * @param header_len length of header in bytes + */ + void set_header(const byte header[], u32bit header_len); + + /** + * @return name of this mode + */ std::string name() const; - bool valid_keylength(u32bit) const; + bool valid_keylength(u32bit key_len) const; + + /** + * EAX supports arbitrary IV lengths + */ + bool valid_iv_length(u32bit) const { return true; } ~EAX_Base() { delete ctr; delete cmac; } protected: - EAX_Base(BlockCipher*, u32bit); + /** + * @param cipher the cipher to use + * @param tag_size is how big the auth tag will be + */ + EAX_Base(BlockCipher* cipher, u32bit tag_size); void start_msg(); const u32bit BLOCK_SIZE, TAG_SIZE; @@ -43,15 +63,25 @@ class BOTAN_DLL EAX_Base : public Keyed_Filter SecureVector<byte> ctr_buf; }; -/* +/** * EAX Encryption */ class BOTAN_DLL EAX_Encryption : public EAX_Base { public: + /** + * @param ciph the cipher to use + * @param tag_size is how big the auth tag will be + */ EAX_Encryption(BlockCipher* ciph, u32bit tag_size = 0) : EAX_Base(ciph, tag_size) {} + /** + * @param ciph the cipher to use + * @param key the key to use + * @param iv the initially set IV + * @param tag_size is how big the auth tag will be + */ EAX_Encryption(BlockCipher* ciph, const SymmetricKey& key, const InitializationVector& iv, u32bit tag_size) : EAX_Base(ciph, tag_size) @@ -64,14 +94,24 @@ class BOTAN_DLL EAX_Encryption : public EAX_Base void end_msg(); }; -/* +/** * EAX Decryption */ class BOTAN_DLL EAX_Decryption : public EAX_Base { public: + /** + * @param ciph the cipher to use + * @param tag_size is how big the auth tag will be + */ EAX_Decryption(BlockCipher* ciph, u32bit tag_size = 0); + /** + * @param ciph the cipher to use + * @param key the key to use + * @param iv the initially set IV + * @param tag_size is how big the auth tag will be + */ EAX_Decryption(BlockCipher* ciph, const SymmetricKey& key, const InitializationVector& iv, u32bit tag_size = 0); diff --git a/src/filters/modes/ecb/ecb.cpp b/src/filters/modes/ecb/ecb.cpp index 948daf6c2..965212abf 100644 --- a/src/filters/modes/ecb/ecb.cpp +++ b/src/filters/modes/ecb/ecb.cpp @@ -14,7 +14,7 @@ namespace Botan { */ ECB_Encryption::ECB_Encryption(BlockCipher* ciph, BlockCipherModePaddingMethod* pad) : - Buffered_Filter(ciph->BLOCK_SIZE * ciph->parallelism(), 0) + Buffered_Filter(ciph->parallel_bytes(), 0) { cipher = ciph; padder = pad; @@ -28,7 +28,7 @@ ECB_Encryption::ECB_Encryption(BlockCipher* ciph, ECB_Encryption::ECB_Encryption(BlockCipher* ciph, BlockCipherModePaddingMethod* pad, const SymmetricKey& key) : - Buffered_Filter(ciph->BLOCK_SIZE * ciph->parallelism(), 0) + Buffered_Filter(ciph->parallel_bytes(), 0) { cipher = ciph; padder = pad; @@ -111,7 +111,7 @@ void ECB_Encryption::buffered_final(const byte input[], u32bit input_length) */ ECB_Decryption::ECB_Decryption(BlockCipher* ciph, BlockCipherModePaddingMethod* pad) : - Buffered_Filter(ciph->BLOCK_SIZE * ciph->parallelism(), 1) + Buffered_Filter(ciph->parallel_bytes(), 1) { cipher = ciph; padder = pad; @@ -125,7 +125,7 @@ ECB_Decryption::ECB_Decryption(BlockCipher* ciph, ECB_Decryption::ECB_Decryption(BlockCipher* ciph, BlockCipherModePaddingMethod* pad, const SymmetricKey& key) : - Buffered_Filter(ciph->BLOCK_SIZE * ciph->parallelism(), 1) + Buffered_Filter(ciph->parallel_bytes(), 1) { cipher = ciph; padder = pad; diff --git a/src/filters/modes/ecb/ecb.h b/src/filters/modes/ecb/ecb.h index 2b88191c7..eaf7fb143 100644 --- a/src/filters/modes/ecb/ecb.h +++ b/src/filters/modes/ecb/ecb.h @@ -15,7 +15,7 @@ namespace Botan { -/* +/** * ECB Encryption */ class BOTAN_DLL ECB_Encryption : public Keyed_Filter, @@ -49,7 +49,7 @@ class BOTAN_DLL ECB_Encryption : public Keyed_Filter, SecureVector<byte> temp; }; -/* +/** * ECB Decryption */ class BOTAN_DLL ECB_Decryption : public Keyed_Filter, diff --git a/src/filters/modes/mode_pad/mode_pad.h b/src/filters/modes/mode_pad/mode_pad.h index a486d3c1f..d6d1c5298 100644 --- a/src/filters/modes/mode_pad/mode_pad.h +++ b/src/filters/modes/mode_pad/mode_pad.h @@ -1,4 +1,4 @@ -/** +/* * CBC Padding Methods * (C) 1999-2008 Jack Lloyd * diff --git a/src/filters/modes/xts/xts.cpp b/src/filters/modes/xts/xts.cpp index 26095e830..608c315ff 100644 --- a/src/filters/modes/xts/xts.cpp +++ b/src/filters/modes/xts/xts.cpp @@ -35,7 +35,8 @@ void poly_double(byte tweak[], u32bit size) */ u32bit xts_parallelism(BlockCipher* cipher) { - return std::max<u32bit>(cipher->parallelism(), 2); + return std::max<u32bit>(cipher->parallel_bytes(), + 2 * cipher->BLOCK_SIZE); } } @@ -44,8 +45,7 @@ u32bit xts_parallelism(BlockCipher* cipher) * XTS_Encryption constructor */ XTS_Encryption::XTS_Encryption(BlockCipher* ciph) : - Buffered_Filter(xts_parallelism(ciph) * ciph->BLOCK_SIZE, - ciph->BLOCK_SIZE + 1), + Buffered_Filter(xts_parallelism(ciph), ciph->BLOCK_SIZE + 1), cipher(ciph) { if(cipher->BLOCK_SIZE != 8 && cipher->BLOCK_SIZE != 16) @@ -61,8 +61,7 @@ XTS_Encryption::XTS_Encryption(BlockCipher* ciph) : XTS_Encryption::XTS_Encryption(BlockCipher* ciph, const SymmetricKey& key, const InitializationVector& iv) : - Buffered_Filter(xts_parallelism(ciph) * ciph->BLOCK_SIZE, - ciph->BLOCK_SIZE + 1), + Buffered_Filter(xts_parallelism(ciph), ciph->BLOCK_SIZE + 1), cipher(ciph) { if(cipher->BLOCK_SIZE != 8 && cipher->BLOCK_SIZE != 16) @@ -88,7 +87,7 @@ std::string XTS_Encryption::name() const */ void XTS_Encryption::set_iv(const InitializationVector& iv) { - if(iv.length() != cipher->BLOCK_SIZE) + if(!valid_iv_length(iv.length())) throw Invalid_IV_Length(name(), iv.length()); const u32bit blocks_in_tweak = tweak.size() / cipher->BLOCK_SIZE; @@ -218,8 +217,7 @@ void XTS_Encryption::buffered_final(const byte input[], u32bit length) * XTS_Decryption constructor */ XTS_Decryption::XTS_Decryption(BlockCipher* ciph) : - Buffered_Filter(xts_parallelism(ciph) * ciph->BLOCK_SIZE, - ciph->BLOCK_SIZE + 1), + Buffered_Filter(xts_parallelism(ciph), ciph->BLOCK_SIZE + 1), cipher(ciph) { if(cipher->BLOCK_SIZE != 8 && cipher->BLOCK_SIZE != 16) @@ -235,8 +233,7 @@ XTS_Decryption::XTS_Decryption(BlockCipher* ciph) : XTS_Decryption::XTS_Decryption(BlockCipher* ciph, const SymmetricKey& key, const InitializationVector& iv) : - Buffered_Filter(xts_parallelism(ciph) * ciph->BLOCK_SIZE, - ciph->BLOCK_SIZE + 1), + Buffered_Filter(xts_parallelism(ciph), ciph->BLOCK_SIZE + 1), cipher(ciph) { if(cipher->BLOCK_SIZE != 8 && cipher->BLOCK_SIZE != 16) @@ -262,7 +259,7 @@ std::string XTS_Decryption::name() const */ void XTS_Decryption::set_iv(const InitializationVector& iv) { - if(iv.length() != cipher->BLOCK_SIZE) + if(!valid_iv_length(iv.length())) throw Invalid_IV_Length(name(), iv.length()); const u32bit blocks_in_tweak = tweak.size() / cipher->BLOCK_SIZE; diff --git a/src/filters/modes/xts/xts.h b/src/filters/modes/xts/xts.h index a01b1da1d..67c087c72 100644 --- a/src/filters/modes/xts/xts.h +++ b/src/filters/modes/xts/xts.h @@ -14,8 +14,8 @@ namespace Botan { -/* -* XTS Encryption +/** +* IEEE P1619 XTS Encryption */ class BOTAN_DLL XTS_Encryption : public Keyed_Filter, private Buffered_Filter @@ -27,6 +27,9 @@ class BOTAN_DLL XTS_Encryption : public Keyed_Filter, bool valid_keylength(u32bit key_len) const { return cipher->valid_keylength(key_len); } + bool valid_iv_length(u32bit iv_len) const + { return (iv_len == cipher->BLOCK_SIZE); } + std::string name() const; XTS_Encryption(BlockCipher* ciph); @@ -48,8 +51,8 @@ class BOTAN_DLL XTS_Encryption : public Keyed_Filter, SecureVector<byte> tweak; }; -/* -* XTS Decryption +/** +* IEEE P1619 XTS Encryption */ class BOTAN_DLL XTS_Decryption : public Keyed_Filter, private Buffered_Filter @@ -61,6 +64,9 @@ class BOTAN_DLL XTS_Decryption : public Keyed_Filter, bool valid_keylength(u32bit key_len) const { return cipher->valid_keylength(key_len); } + bool valid_iv_length(u32bit iv_len) const + { return (iv_len == cipher->BLOCK_SIZE); } + std::string name() const; XTS_Decryption(BlockCipher* ciph); diff --git a/src/filters/out_buf.h b/src/filters/out_buf.h index fecbf9191..120729de4 100644 --- a/src/filters/out_buf.h +++ b/src/filters/out_buf.h @@ -14,7 +14,7 @@ namespace Botan { -/* +/** * Container of output buffers for Pipe */ class Output_Buffers diff --git a/src/filters/pbe.h b/src/filters/pbe.h index f06d593d0..9add98872 100644 --- a/src/filters/pbe.h +++ b/src/filters/pbe.h @@ -25,16 +25,17 @@ class BOTAN_DLL PBE : public Filter * Set this filter's key. * @param pw the password to be used for the encryption */ - virtual void set_key(const std::string&) = 0; + virtual void set_key(const std::string& pw) = 0; /** * Create a new random salt value and set the default iterations value. + * @param rng a random number generator */ virtual void new_params(RandomNumberGenerator& rng) = 0; /** * DER encode the params (the number of iterations and the salt value) - * @return the encoded params + * @return encoded params */ virtual MemoryVector<byte> encode_params() const = 0; @@ -42,11 +43,11 @@ class BOTAN_DLL PBE : public Filter * Decode params and use them inside this Filter. * @param src a data source to read the encoded params from */ - virtual void decode_params(DataSource&) = 0; + virtual void decode_params(DataSource& src) = 0; /** * Get this PBE's OID. - * @return the OID + * @return object identifier */ virtual OID get_oid() const = 0; }; diff --git a/src/filters/pipe.h b/src/filters/pipe.h index a927e1a0f..92f6c62db 100644 --- a/src/filters/pipe.h +++ b/src/filters/pipe.h @@ -23,21 +23,38 @@ namespace Botan { * collected for retrieval. If you're familiar with the Unix shell * environment, this design will sound quite familiar. */ - class BOTAN_DLL Pipe : public DataSource { public: + /* + * An opaque type that identifies a message in this Pipe + */ typedef u32bit message_id; + /** + * Exception if you use an invalid message as an argument to + * read, remaining, etc + */ struct BOTAN_DLL Invalid_Message_Number : public Invalid_Argument { + /** + * @param where the error occured + * @param msg the invalid message id that was used + */ Invalid_Message_Number(const std::string& where, message_id msg) : Invalid_Argument("Pipe::" + where + ": Invalid message number " + std::to_string(msg)) {} }; + /** + * A meta-id for whatever the last message is + */ static const message_id LAST_MESSAGE; + + /** + * A meta-id for the default message (set with set_default_msg) + */ static const message_id DEFAULT_MESSAGE; /** @@ -100,7 +117,7 @@ class BOTAN_DLL Pipe : public DataSource * Find out how many bytes are ready to read. * @param msg the number identifying the message * for which the information is desired - * @return the number of bytes that can still be read + * @return number of bytes that can still be read */ u32bit remaining(message_id msg = DEFAULT_MESSAGE) const; @@ -108,9 +125,10 @@ class BOTAN_DLL Pipe : public DataSource * Read the default message from the pipe. Moves the internal * offset so that every call to read will return a new portion of * the message. + * * @param output the byte array to write the read bytes to * @param length the length of the byte array output - * @return the number of bytes actually read into output + * @return number of bytes actually read into output */ u32bit read(byte output[], u32bit length); @@ -121,29 +139,32 @@ class BOTAN_DLL Pipe : public DataSource * @param output the byte array to write the read bytes to * @param length the length of the byte array output * @param msg the number identifying the message to read from - * @return the number of bytes actually read into output + * @return number of bytes actually read into output */ u32bit read(byte output[], u32bit length, message_id msg); /** - * Read a single byte from the pipe. Moves the internal offset so that - * every call to read will return a new portion of the message. + * Read a single byte from the pipe. Moves the internal offset so + * that every call to read will return a new portion of the + * message. + * * @param output the byte to write the result to - * @return the number of bytes actually read into output + * @param msg the message to read from + * @return number of bytes actually read into output */ u32bit read(byte& output, message_id msg = DEFAULT_MESSAGE); /** * Read the full contents of the pipe. * @param msg the number identifying the message to read from - * @return a SecureVector holding the contents of the pipe + * @return SecureVector holding the contents of the pipe */ SecureVector<byte> read_all(message_id msg = DEFAULT_MESSAGE); /** * Read the full contents of the pipe. * @param msg the number identifying the message to read from - * @return a string holding the contents of the pipe + * @return string holding the contents of the pipe */ std::string read_all_as_string(message_id = DEFAULT_MESSAGE); @@ -153,7 +174,7 @@ class BOTAN_DLL Pipe : public DataSource * @param output the byte array to write the peeked message part to * @param length the length of the byte array output * @param offset the offset from the current position in message - * @return the number of bytes actually peeked and written into output + * @return number of bytes actually peeked and written into output */ u32bit peek(byte output[], u32bit length, u32bit offset) const; @@ -164,7 +185,7 @@ class BOTAN_DLL Pipe : public DataSource * @param length the length of the byte array output * @param offset the offset from the current position in message * @param msg the number identifying the message to peek from - * @return the number of bytes actually peeked and written into output + * @return number of bytes actually peeked and written into output */ u32bit peek(byte output[], u32bit length, u32bit offset, message_id msg) const; @@ -175,11 +196,14 @@ class BOTAN_DLL Pipe : public DataSource * @param output the byte to write the peeked message byte to * @param offset the offset from the current position in message * @param msg the number identifying the message to peek from - * @return the number of bytes actually peeked and written into output + * @return number of bytes actually peeked and written into output */ u32bit peek(byte& output, u32bit offset, message_id msg = DEFAULT_MESSAGE) const; + /** + * @return currently set default message + */ u32bit default_msg() const { return default_read; } /** @@ -191,7 +215,7 @@ class BOTAN_DLL Pipe : public DataSource /** * Get the number of messages the are in this pipe. - * @return the number of messages the are in this pipe + * @return number of messages the are in this pipe */ message_id message_count() const; diff --git a/src/filters/pk_filts/pk_filts.h b/src/filters/pk_filts/pk_filts.h index 8bf3fc238..81d6c9008 100644 --- a/src/filters/pk_filts/pk_filts.h +++ b/src/filters/pk_filts/pk_filts.h @@ -13,7 +13,7 @@ namespace Botan { -/* +/** * PK_Encryptor Filter */ class BOTAN_DLL PK_Encryptor_Filter : public Filter @@ -31,7 +31,7 @@ class BOTAN_DLL PK_Encryptor_Filter : public Filter SecureVector<byte> buffer; }; -/* +/** * PK_Decryptor Filter */ class BOTAN_DLL PK_Decryptor_Filter : public Filter @@ -46,7 +46,7 @@ class BOTAN_DLL PK_Decryptor_Filter : public Filter SecureVector<byte> buffer; }; -/* +/** * PK_Signer Filter */ class BOTAN_DLL PK_Signer_Filter : public Filter @@ -65,7 +65,7 @@ class BOTAN_DLL PK_Signer_Filter : public Filter RandomNumberGenerator& rng; }; -/* +/** * PK_Verifier Filter */ class BOTAN_DLL PK_Verifier_Filter : public Filter diff --git a/src/filters/secqueue.cpp b/src/filters/secqueue.cpp index c8d1c5fbf..db0366bc8 100644 --- a/src/filters/secqueue.cpp +++ b/src/filters/secqueue.cpp @@ -10,12 +10,15 @@ namespace Botan { -/* -* SecureQueueNode +/** +* A node in a SecureQueue */ class SecureQueueNode { public: + SecureQueueNode() { next = 0; start = end = 0; } + ~SecureQueueNode() { next = 0; start = end = 0; } + u32bit write(const byte input[], u32bit length) { u32bit copied = std::min(length, buffer.size() - end); @@ -23,6 +26,7 @@ class SecureQueueNode end += copied; return copied; } + u32bit read(byte output[], u32bit length) { u32bit copied = std::min(length, end - start); @@ -30,6 +34,7 @@ class SecureQueueNode start += copied; return copied; } + u32bit peek(byte output[], u32bit length, u32bit offset = 0) { const u32bit left = end - start; @@ -38,9 +43,8 @@ class SecureQueueNode copy_mem(output, buffer + start + offset, copied); return copied; } + u32bit size() const { return (end - start); } - SecureQueueNode() { next = 0; start = end = 0; } - ~SecureQueueNode() { next = 0; start = end = 0; } private: friend class SecureQueue; SecureQueueNode* next; diff --git a/src/filters/secqueue.h b/src/filters/secqueue.h index fc1fc213a..3cb486024 100644 --- a/src/filters/secqueue.h +++ b/src/filters/secqueue.h @@ -13,8 +13,8 @@ namespace Botan { -/* -* SecureQueue +/** +* A queue that knows how to zeroize itself */ class BOTAN_DLL SecureQueue : public Fanout_Filter, public DataSource { diff --git a/src/filters/zlib/zlib.cpp b/src/filters/zlib/zlib.cpp index 171caa73f..148ed3e6c 100644 --- a/src/filters/zlib/zlib.cpp +++ b/src/filters/zlib/zlib.cpp @@ -53,8 +53,6 @@ void zlib_free(void* info_ptr, void* ptr) info->alloc->deallocate(ptr, i->second); } -} - /* * Wrapper Type for Zlib z_stream */ @@ -78,6 +76,8 @@ class Zlib_Stream } }; +} + /* * Zlib_Compression Constructor */ diff --git a/src/filters/zlib/zlib.h b/src/filters/zlib/zlib.h index 4a7f3bc80..2aa83aadf 100644 --- a/src/filters/zlib/zlib.h +++ b/src/filters/zlib/zlib.h @@ -13,7 +13,7 @@ namespace Botan { -/* +/** * Zlib Compression Filter */ class BOTAN_DLL Zlib_Compression : public Filter @@ -23,9 +23,17 @@ class BOTAN_DLL Zlib_Compression : public Filter void start_msg(); void end_msg(); + /** + * Flush the compressor + */ void flush(); - Zlib_Compression(u32bit = 6); + /** + @param level how much effort to use on compressing (0 to 9); + higher levels are slower but tend to give better compression + */ + Zlib_Compression(u32bit level = 6); + ~Zlib_Compression() { clear(); } private: void clear(); @@ -34,7 +42,7 @@ class BOTAN_DLL Zlib_Compression : public Filter class Zlib_Stream* zlib; }; -/* +/** * Zlib Decompression Filter */ class BOTAN_DLL Zlib_Decompression : public Filter diff --git a/src/hash/bmw/bmw_512.h b/src/hash/bmw/bmw_512.h index c1c5238bd..d3c9c03c6 100644 --- a/src/hash/bmw/bmw_512.h +++ b/src/hash/bmw/bmw_512.h @@ -12,6 +12,9 @@ namespace Botan { +/** +* Blue Midnight Wish 512 (Round 2 tweaked version) +*/ class BOTAN_DLL BMW_512 : public MDx_HashFunction { public: diff --git a/src/hash/comb4p/comb4p.cpp b/src/hash/comb4p/comb4p.cpp index 6ae36b9d3..ecbdc4671 100644 --- a/src/hash/comb4p/comb4p.cpp +++ b/src/hash/comb4p/comb4p.cpp @@ -1,4 +1,4 @@ -/** +/* * Comb4P hash combiner * (C) 2010 Jack Lloyd * diff --git a/src/hash/comb4p/comb4p.h b/src/hash/comb4p/comb4p.h index ce66bb9c9..550b70b14 100644 --- a/src/hash/comb4p/comb4p.h +++ b/src/hash/comb4p/comb4p.h @@ -1,4 +1,4 @@ -/** +/* * Comb4P hash combiner * (C) 2010 Jack Lloyd * @@ -16,9 +16,13 @@ namespace Botan { * Combines two hash functions using a Feistel scheme. Described in * "On the Security of Hash Function Combiners", Anja Lehmann */ -class Comb4P : public HashFunction +class BOTAN_DLL Comb4P : public HashFunction { public: + /** + * @param h1 the first hash + * @param h2 the second hash + */ Comb4P(HashFunction* h1, HashFunction* h2); ~Comb4P() { delete hash1; delete hash2; } diff --git a/src/hash/fork256/fork256.cpp b/src/hash/fork256/fork256.cpp deleted file mode 100644 index bd85dfd7c..000000000 --- a/src/hash/fork256/fork256.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/* -* FORK-256 -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/fork256.h> -#include <botan/loadstor.h> -#include <botan/rotate.h> - -namespace Botan { - -namespace { - -/* -* FORK-256 Step Function -*/ -inline void step(u32bit& A, u32bit& B, u32bit& C, u32bit& D, - u32bit& E, u32bit& F, u32bit& G, u32bit& H, - u32bit M1, u32bit M2, u32bit D1, u32bit D2) - { - u32bit T0, T1; - - A += M1; T0 = A + (rotate_left(A, 7) ^ rotate_left(A, 22)); - A += D1; T1 = A ^ (rotate_left(A, 13) + rotate_left(A, 27)); - - B = (B + T0) ^ T1; - C = (C + rotate_left(T0, 5)) ^ rotate_left(T1, 9); - D = (D + rotate_left(T0, 17)) ^ rotate_left(T1, 21); - - E += M2; T0 = E ^ (rotate_left(E, 13) + rotate_left(E, 27)); - E += D2; T1 = E + (rotate_left(E, 7) ^ rotate_left(E, 22)); - - F = (F + T0) ^ T1; - G = (G + rotate_left(T0, 9)) ^ rotate_left(T1, 5); - H = (H + rotate_left(T0, 21)) ^ rotate_left(T1, 17); - } - -} - -/* -* FORK-256 Compression Function -*/ -void FORK_256::compress_n(const byte input[], u32bit blocks) - { - const u32bit DELTA[16] = { - 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 0x3956C25B, 0x59F111F1, - 0x923F82A4, 0xAB1C5ED5, 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, - 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174 - }; - - for(u32bit i = 0; i != blocks; ++i) - { - u32bit A1, B1, C1, D1, E1, F1, G1, H1; - u32bit A2, B2, C2, D2, E2, F2, G2, H2; - u32bit A3, B3, C3, D3, E3, F3, G3, H3; - u32bit A4, B4, C4, D4, E4, F4, G4, H4; - - A1 = A2 = A3 = A4 = digest[0]; - B1 = B2 = B3 = B4 = digest[1]; - C1 = C2 = C3 = C4 = digest[2]; - D1 = D2 = D3 = D4 = digest[3]; - E1 = E2 = E3 = E4 = digest[4]; - F1 = F2 = F3 = F4 = digest[5]; - G1 = G2 = G3 = G4 = digest[6]; - H1 = H2 = H3 = H4 = digest[7]; - - load_be(M.begin(), input, M.size()); - - step(A1, B1, C1, D1, E1, F1, G1, H1, M[ 0], M[ 1], DELTA[ 0], DELTA[ 1]); - step(A2, B2, C2, D2, E2, F2, G2, H2, M[14], M[15], DELTA[15], DELTA[14]); - step(A3, B3, C3, D3, E3, F3, G3, H3, M[ 7], M[ 6], DELTA[ 1], DELTA[ 0]); - step(A4, B4, C4, D4, E4, F4, G4, H4, M[ 5], M[12], DELTA[14], DELTA[15]); - - step(H1, A1, B1, C1, D1, E1, F1, G1, M[ 2], M[ 3], DELTA[ 2], DELTA[ 3]); - step(H2, A2, B2, C2, D2, E2, F2, G2, M[11], M[ 9], DELTA[13], DELTA[12]); - step(H3, A3, B3, C3, D3, E3, F3, G3, M[10], M[14], DELTA[ 3], DELTA[ 2]); - step(H4, A4, B4, C4, D4, E4, F4, G4, M[ 1], M[ 8], DELTA[12], DELTA[13]); - - step(G1, H1, A1, B1, C1, D1, E1, F1, M[ 4], M[ 5], DELTA[ 4], DELTA[ 5]); - step(G2, H2, A2, B2, C2, D2, E2, F2, M[ 8], M[10], DELTA[11], DELTA[10]); - step(G3, H3, A3, B3, C3, D3, E3, F3, M[13], M[ 2], DELTA[ 5], DELTA[ 4]); - step(G4, H4, A4, B4, C4, D4, E4, F4, M[15], M[ 0], DELTA[10], DELTA[11]); - - step(F1, G1, H1, A1, B1, C1, D1, E1, M[ 6], M[ 7], DELTA[ 6], DELTA[ 7]); - step(F2, G2, H2, A2, B2, C2, D2, E2, M[ 3], M[ 4], DELTA[ 9], DELTA[ 8]); - step(F3, G3, H3, A3, B3, C3, D3, E3, M[ 9], M[12], DELTA[ 7], DELTA[ 6]); - step(F4, G4, H4, A4, B4, C4, D4, E4, M[13], M[11], DELTA[ 8], DELTA[ 9]); - - step(E1, F1, G1, H1, A1, B1, C1, D1, M[ 8], M[ 9], DELTA[ 8], DELTA[ 9]); - step(E2, F2, G2, H2, A2, B2, C2, D2, M[ 2], M[13], DELTA[ 7], DELTA[ 6]); - step(E3, F3, G3, H3, A3, B3, C3, D3, M[11], M[ 4], DELTA[ 9], DELTA[ 8]); - step(E4, F4, G4, H4, A4, B4, C4, D4, M[ 3], M[10], DELTA[ 6], DELTA[ 7]); - - step(D1, E1, F1, G1, H1, A1, B1, C1, M[10], M[11], DELTA[10], DELTA[11]); - step(D2, E2, F2, G2, H2, A2, B2, C2, M[ 0], M[ 5], DELTA[ 5], DELTA[ 4]); - step(D3, E3, F3, G3, H3, A3, B3, C3, M[15], M[ 8], DELTA[11], DELTA[10]); - step(D4, E4, F4, G4, H4, A4, B4, C4, M[ 9], M[ 2], DELTA[ 4], DELTA[ 5]); - - step(C1, D1, E1, F1, G1, H1, A1, B1, M[12], M[13], DELTA[12], DELTA[13]); - step(C2, D2, E2, F2, G2, H2, A2, B2, M[ 6], M[ 7], DELTA[ 3], DELTA[ 2]); - step(C3, D3, E3, F3, G3, H3, A3, B3, M[ 5], M[ 0], DELTA[13], DELTA[12]); - step(C4, D4, E4, F4, G4, H4, A4, B4, M[ 7], M[14], DELTA[ 2], DELTA[ 3]); - - step(B1, C1, D1, E1, F1, G1, H1, A1, M[14], M[15], DELTA[14], DELTA[15]); - step(B2, C2, D2, E2, F2, G2, H2, A2, M[12], M[ 1], DELTA[ 1], DELTA[ 0]); - step(B3, C3, D3, E3, F3, G3, H3, A3, M[ 1], M[ 3], DELTA[15], DELTA[14]); - step(B4, C4, D4, E4, F4, G4, H4, A4, M[ 4], M[ 6], DELTA[ 0], DELTA[ 1]); - - digest[0] += (A1 + A2) ^ (A3 + A4); - digest[1] += (B1 + B2) ^ (B3 + B4); - digest[2] += (C1 + C2) ^ (C3 + C4); - digest[3] += (D1 + D2) ^ (D3 + D4); - digest[4] += (E1 + E2) ^ (E3 + E4); - digest[5] += (F1 + F2) ^ (F3 + F4); - digest[6] += (G1 + G2) ^ (G3 + G4); - digest[7] += (H1 + H2) ^ (H3 + H4); - - input += HASH_BLOCK_SIZE; - } - } - -/* -* Copy out the digest -*/ -void FORK_256::copy_out(byte output[]) - { - for(u32bit j = 0; j != OUTPUT_LENGTH; j += 4) - store_be(digest[j/4], output + j); - } - -/* -* Clear memory of sensitive data -*/ -void FORK_256::clear() - { - MDx_HashFunction::clear(); - digest[0] = 0x6A09E667; - digest[1] = 0xBB67AE85; - digest[2] = 0x3C6EF372; - digest[3] = 0xA54FF53A; - digest[4] = 0x510E527F; - digest[5] = 0x9B05688C; - digest[6] = 0x1F83D9AB; - digest[7] = 0x5BE0CD19; - } - -} diff --git a/src/hash/fork256/fork256.h b/src/hash/fork256/fork256.h deleted file mode 100644 index ed945b9d8..000000000 --- a/src/hash/fork256/fork256.h +++ /dev/null @@ -1,35 +0,0 @@ -/* -* FORK-256 -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_FORK_256_H__ -#define BOTAN_FORK_256_H__ - -#include <botan/mdx_hash.h> - -namespace Botan { - -/* -* FORK-256 -*/ -class BOTAN_DLL FORK_256 : public MDx_HashFunction - { - public: - void clear(); - std::string name() const { return "FORK-256"; } - HashFunction* clone() const { return new FORK_256; } - FORK_256() : MDx_HashFunction(32, 64, true, true) { clear(); } - private: - void compress_n(const byte[], u32bit blocks); - void copy_out(byte[]); - - SecureVector<u32bit, 8> digest; - SecureVector<u32bit, 16> M; - }; - -} - -#endif diff --git a/src/hash/fork256/info.txt b/src/hash/fork256/info.txt deleted file mode 100644 index c2f8c47f2..000000000 --- a/src/hash/fork256/info.txt +++ /dev/null @@ -1,5 +0,0 @@ -define FORK_256 - -<requires> -mdx_hash -</requires> diff --git a/src/hash/gost_3411/gost_3411.h b/src/hash/gost_3411/gost_3411.h index d2bada7ab..04417d6fd 100644 --- a/src/hash/gost_3411/gost_3411.h +++ b/src/hash/gost_3411/gost_3411.h @@ -1,4 +1,4 @@ -/** +/* * GOST 34.11 * (C) 2009 Jack Lloyd * @@ -24,7 +24,7 @@ class BOTAN_DLL GOST_34_11 : public HashFunction HashFunction* clone() const { return new GOST_34_11; } GOST_34_11(); - protected: + private: void compress_n(const byte input[], u32bit blocks); void add_data(const byte[], u32bit); diff --git a/src/hash/has160/has160.h b/src/hash/has160/has160.h index 210145484..a82e4c579 100644 --- a/src/hash/has160/has160.h +++ b/src/hash/has160/has160.h @@ -12,8 +12,9 @@ namespace Botan { -/* -* HAS-160 +/** +* HAS-160, a Korean hash function standardized in +* TTAS.KO-12.0011/R1. Used in conjuction with KCDSA */ class BOTAN_DLL HAS_160 : public MDx_HashFunction { diff --git a/src/hash/hash.h b/src/hash/hash.h index 1098951d8..cdf90f184 100644 --- a/src/hash/hash.h +++ b/src/hash/hash.h @@ -1,4 +1,4 @@ -/** +/* * Hash Function Base Class * (C) 1999-2008 Jack Lloyd * @@ -31,7 +31,7 @@ class BOTAN_DLL HashFunction : public BufferedComputation /** * Get the name of this algorithm. - * @return the name of this algorithm + * @return name of this algorithm */ virtual std::string name() const = 0; @@ -40,8 +40,13 @@ class BOTAN_DLL HashFunction : public BufferedComputation */ virtual void clear() = 0; + /** + * @param hash_len the output length + * @param block_len the internal block size (if applicable) + */ HashFunction(u32bit hash_len, u32bit block_len = 0) : BufferedComputation(hash_len), HASH_BLOCK_SIZE(block_len) {} + virtual ~HashFunction() {} private: HashFunction& operator=(const HashFunction&); diff --git a/src/hash/md2/md2.h b/src/hash/md2/md2.h index df056dc12..9d39d8913 100644 --- a/src/hash/md2/md2.h +++ b/src/hash/md2/md2.h @@ -12,7 +12,7 @@ namespace Botan { -/* +/** * MD2 */ class BOTAN_DLL MD2 : public HashFunction diff --git a/src/hash/md4/md4.h b/src/hash/md4/md4.h index 843727f6d..44d60406a 100644 --- a/src/hash/md4/md4.h +++ b/src/hash/md4/md4.h @@ -12,7 +12,7 @@ namespace Botan { -/* +/** * MD4 */ class BOTAN_DLL MD4 : public MDx_HashFunction @@ -24,7 +24,6 @@ class BOTAN_DLL MD4 : public MDx_HashFunction MD4() : MDx_HashFunction(16, 64, false, true) { clear(); } protected: void compress_n(const byte input[], u32bit blocks); - void hash_old(const byte[]); void copy_out(byte[]); SecureVector<u32bit, 16> M; diff --git a/src/hash/md4_ia32/md4_ia32.h b/src/hash/md4_ia32/md4_ia32.h index f01d148f4..ef8060d3f 100644 --- a/src/hash/md4_ia32/md4_ia32.h +++ b/src/hash/md4_ia32/md4_ia32.h @@ -12,8 +12,8 @@ namespace Botan { -/* -* MD4 +/** +* MD4 using x86 assembly */ class BOTAN_DLL MD4_IA32 : public MD4 { diff --git a/src/hash/md5/md5.h b/src/hash/md5/md5.h index d1f294a87..d0706ab4b 100644 --- a/src/hash/md5/md5.h +++ b/src/hash/md5/md5.h @@ -1,4 +1,4 @@ -/** +/* * MD5 * (C) 1999-2008 Jack Lloyd * diff --git a/src/hash/md5_ia32/md5_ia32.h b/src/hash/md5_ia32/md5_ia32.h index 723d724de..b65490760 100644 --- a/src/hash/md5_ia32/md5_ia32.h +++ b/src/hash/md5_ia32/md5_ia32.h @@ -12,8 +12,8 @@ namespace Botan { -/* -* MD5 +/** +* MD5 in x86 assembly */ class BOTAN_DLL MD5_IA32 : public MD5 { diff --git a/src/hash/mdx_hash/mdx_hash.cpp b/src/hash/mdx_hash/mdx_hash.cpp index 28402c2c5..bf571076e 100644 --- a/src/hash/mdx_hash/mdx_hash.cpp +++ b/src/hash/mdx_hash/mdx_hash.cpp @@ -1,4 +1,4 @@ -/** +/* * Merkle-Damgard Hash Function * (C) 1999-2008 Jack Lloyd * @@ -11,7 +11,7 @@ namespace Botan { -/** +/* * MDx_HashFunction Constructor */ MDx_HashFunction::MDx_HashFunction(u32bit hash_len, u32bit block_len, @@ -25,7 +25,7 @@ MDx_HashFunction::MDx_HashFunction(u32bit hash_len, u32bit block_len, count = position = 0; } -/** +/* * Clear memory of sensitive data */ void MDx_HashFunction::clear() @@ -34,7 +34,7 @@ void MDx_HashFunction::clear() count = position = 0; } -/** +/* * Update the hash */ void MDx_HashFunction::add_data(const byte input[], u32bit length) @@ -64,7 +64,7 @@ void MDx_HashFunction::add_data(const byte input[], u32bit length) position += remaining; } -/** +/* * Finalize a hash */ void MDx_HashFunction::final_result(byte output[]) @@ -86,7 +86,7 @@ void MDx_HashFunction::final_result(byte output[]) clear(); } -/** +/* * Write the count bits to the buffer */ void MDx_HashFunction::write_count(byte out[]) diff --git a/src/hash/mdx_hash/mdx_hash.h b/src/hash/mdx_hash/mdx_hash.h index 2d70deed3..087c7fc46 100644 --- a/src/hash/mdx_hash/mdx_hash.h +++ b/src/hash/mdx_hash/mdx_hash.h @@ -1,4 +1,4 @@ -/** +/* * MDx Hash Function * (C) 1999-2008 Jack Lloyd * @@ -18,16 +18,44 @@ namespace Botan { class BOTAN_DLL MDx_HashFunction : public HashFunction { public: - MDx_HashFunction(u32bit, u32bit, bool, bool, u32bit = 8); + /** + * @param hash_length is the output length of this hash + * @param block_length is the number of bytes per block + * @param big_byte_endian specifies if the hash uses big-endian bytes + * @param big_bit_endian specifies if the hash uses big-endian bits + * @param counter_size specifies the size of the counter var in bytes + */ + MDx_HashFunction(u32bit hash_length, + u32bit block_length, + bool big_byte_endian, + bool big_bit_endian, + u32bit counter_size = 8); + virtual ~MDx_HashFunction() {} protected: - void add_data(const byte[], u32bit); + void add_data(const byte input[], u32bit length); void final_result(byte output[]); - virtual void compress_n(const byte block[], u32bit block_n) = 0; + + /** + * Run the hash's compression function over a set of blocks + * @param blocks the input + * @param block_n the number of blocks + */ + virtual void compress_n(const byte blocks[], u32bit block_n) = 0; void clear(); - virtual void copy_out(byte[]) = 0; - virtual void write_count(byte[]); + + /** + * Copy the output to the buffer + * @param buffer to put the output into + */ + virtual void copy_out(byte buffer[]) = 0; + + /** + * Write the count, if used, to this spot + * @param out where to write the counter to + */ + virtual void write_count(byte out[]); private: SecureVector<byte> buffer; u64bit count; diff --git a/src/hash/par_hash/par_hash.h b/src/hash/par_hash/par_hash.h index 874e491b1..d82a74a19 100644 --- a/src/hash/par_hash/par_hash.h +++ b/src/hash/par_hash/par_hash.h @@ -13,8 +13,8 @@ namespace Botan { -/* -* Parallel +/** +* Parallel Hashes */ class BOTAN_DLL Parallel : public HashFunction { @@ -23,7 +23,10 @@ class BOTAN_DLL Parallel : public HashFunction std::string name() const; HashFunction* clone() const; - Parallel(const std::vector<HashFunction*>&); + /** + * @param hashes a set of hashes to compute in parallel + */ + Parallel(const std::vector<HashFunction*>& hashes); ~Parallel(); private: void add_data(const byte[], u32bit); diff --git a/src/hash/rmd128/rmd128.h b/src/hash/rmd128/rmd128.h index 9ae43483c..c7c7f4580 100644 --- a/src/hash/rmd128/rmd128.h +++ b/src/hash/rmd128/rmd128.h @@ -12,7 +12,7 @@ namespace Botan { -/* +/** * RIPEMD-128 */ class BOTAN_DLL RIPEMD_128 : public MDx_HashFunction @@ -22,7 +22,7 @@ class BOTAN_DLL RIPEMD_128 : public MDx_HashFunction std::string name() const { return "RIPEMD-128"; } HashFunction* clone() const { return new RIPEMD_128; } RIPEMD_128() : MDx_HashFunction(16, 64, false, true) { clear(); } - private: + private: void compress_n(const byte[], u32bit blocks); void copy_out(byte[]); diff --git a/src/hash/rmd160/rmd160.h b/src/hash/rmd160/rmd160.h index 399d5a7c3..0b6e847f0 100644 --- a/src/hash/rmd160/rmd160.h +++ b/src/hash/rmd160/rmd160.h @@ -12,7 +12,7 @@ namespace Botan { -/* +/** * RIPEMD-160 */ class BOTAN_DLL RIPEMD_160 : public MDx_HashFunction diff --git a/src/hash/sha1/sha160.h b/src/hash/sha1/sha160.h index cb7e63821..c66831a1e 100644 --- a/src/hash/sha1/sha160.h +++ b/src/hash/sha1/sha160.h @@ -12,8 +12,8 @@ namespace Botan { -/* -* SHA-160 +/** +* NIST's SHA-160 */ class BOTAN_DLL SHA_160 : public MDx_HashFunction { @@ -24,6 +24,12 @@ class BOTAN_DLL SHA_160 : public MDx_HashFunction SHA_160(); protected: + /** + * Set a custom size for the W array. Normally 80, but some + * subclasses need slightly more for best performance/internal + * constraints + * @param W_size how big to make W + */ SHA_160(u32bit W_size); void compress_n(const byte[], u32bit blocks); diff --git a/src/hash/sha1_amd64/sha1_amd64.h b/src/hash/sha1_amd64/sha1_amd64.h index f182627a8..6cf3b0fb7 100644 --- a/src/hash/sha1_amd64/sha1_amd64.h +++ b/src/hash/sha1_amd64/sha1_amd64.h @@ -12,8 +12,8 @@ namespace Botan { -/* -* SHA-160 +/** +* SHA-160 in x86-64 assembly */ class BOTAN_DLL SHA_160_AMD64 : public SHA_160 { diff --git a/src/hash/sha1_ia32/sha1_ia32.h b/src/hash/sha1_ia32/sha1_ia32.h index fd34971cb..f579fbc90 100644 --- a/src/hash/sha1_ia32/sha1_ia32.h +++ b/src/hash/sha1_ia32/sha1_ia32.h @@ -12,8 +12,8 @@ namespace Botan { -/* -* SHA-160 +/** +* SHA-160 in x86 assembly */ class BOTAN_DLL SHA_160_IA32 : public SHA_160 { diff --git a/src/hash/sha1_sse2/sha1_sse2.h b/src/hash/sha1_sse2/sha1_sse2.h index 1c4b4cca7..90935c737 100644 --- a/src/hash/sha1_sse2/sha1_sse2.h +++ b/src/hash/sha1_sse2/sha1_sse2.h @@ -12,8 +12,8 @@ namespace Botan { -/* -* SHA-160 +/** +* SHA-160 using SSE2 for the message expansion */ class BOTAN_DLL SHA_160_SSE2 : public SHA_160 { diff --git a/src/hash/sha2/sha2_32.h b/src/hash/sha2/sha2_32.h index e157fd657..e8e60d07c 100644 --- a/src/hash/sha2/sha2_32.h +++ b/src/hash/sha2/sha2_32.h @@ -13,13 +13,17 @@ namespace Botan { -/* -* SHA-{224,256} Base +/** +* Base class for the 32-bit SHA-2 hashes (SHA-224 and SHA-256) */ class BOTAN_DLL SHA_224_256_BASE : public MDx_HashFunction { protected: void clear(); + + /** + * @param out output size in bytes + */ SHA_224_256_BASE(u32bit out) : MDx_HashFunction(out, 64, true, true) { clear(); } @@ -30,7 +34,7 @@ class BOTAN_DLL SHA_224_256_BASE : public MDx_HashFunction void copy_out(byte[]); }; -/* +/** * SHA-224 */ class BOTAN_DLL SHA_224 : public SHA_224_256_BASE @@ -42,7 +46,7 @@ class BOTAN_DLL SHA_224 : public SHA_224_256_BASE SHA_224() : SHA_224_256_BASE(28) { clear(); } }; -/* +/** * SHA-256 */ class BOTAN_DLL SHA_256 : public SHA_224_256_BASE diff --git a/src/hash/sha2/sha2_64.h b/src/hash/sha2/sha2_64.h index ed261b1c2..bf87eb62d 100644 --- a/src/hash/sha2/sha2_64.h +++ b/src/hash/sha2/sha2_64.h @@ -12,14 +12,17 @@ namespace Botan { -/* -* SHA-{384,512} Base +/** +* Base class for the 64-bit SHA-2 hashes (SHA-384 and SHA-512) */ class BOTAN_DLL SHA_384_512_BASE : public MDx_HashFunction { protected: void clear(); + /** + * @param out output size in bytes + */ SHA_384_512_BASE(u32bit out) : MDx_HashFunction(out, 128, true, true, 16) {} @@ -31,7 +34,7 @@ class BOTAN_DLL SHA_384_512_BASE : public MDx_HashFunction SecureVector<u64bit, 80> W; }; -/* +/** * SHA-384 */ class BOTAN_DLL SHA_384 : public SHA_384_512_BASE @@ -43,7 +46,7 @@ class BOTAN_DLL SHA_384 : public SHA_384_512_BASE SHA_384() : SHA_384_512_BASE(48) { clear(); } }; -/* +/** * SHA-512 */ class BOTAN_DLL SHA_512 : public SHA_384_512_BASE diff --git a/src/hash/skein/skein_512.cpp b/src/hash/skein/skein_512.cpp index 42fc4ba37..3330f4925 100644 --- a/src/hash/skein/skein_512.cpp +++ b/src/hash/skein/skein_512.cpp @@ -1,4 +1,4 @@ -/** +/* * The Skein-512 hash function * (C) 2009 Jack Lloyd * diff --git a/src/hash/skein/skein_512.h b/src/hash/skein/skein_512.h index 222db5d68..5d17fa564 100644 --- a/src/hash/skein/skein_512.h +++ b/src/hash/skein/skein_512.h @@ -1,4 +1,4 @@ -/** +/* * The Skein-512 hash function * (C) 2009 Jack Lloyd * @@ -14,9 +14,17 @@ namespace Botan { +/** +* Skein-512, a SHA-3 candidate +*/ class BOTAN_DLL Skein_512 : public HashFunction { public: + /** + * @param output_bits the output size of Skein in bits + * @param personalization is a string that will paramaterize the + * hash output + */ Skein_512(u32bit output_bits = 512, const std::string& personalization = ""); diff --git a/src/hash/tiger/tiger.h b/src/hash/tiger/tiger.h index 918e2de3c..380f6eb24 100644 --- a/src/hash/tiger/tiger.h +++ b/src/hash/tiger/tiger.h @@ -12,7 +12,7 @@ namespace Botan { -/* +/** * Tiger */ class BOTAN_DLL Tiger : public MDx_HashFunction @@ -20,8 +20,17 @@ class BOTAN_DLL Tiger : public MDx_HashFunction public: void clear(); std::string name() const; - HashFunction* clone() const { return new Tiger(OUTPUT_LENGTH); } - Tiger(u32bit = 24, u32bit = 3); + + HashFunction* clone() const + { + return new Tiger(OUTPUT_LENGTH, PASS); + } + + /** + * @param out_size specifies the output length; can be 16, 20, or 24 + * @param passes to make in the algorithm + */ + Tiger(u32bit out_size = 24, u32bit passes = 3); private: void compress_n(const byte[], u32bit block); void copy_out(byte[]); diff --git a/src/hash/whirlpool/whrlpool.h b/src/hash/whirlpool/whrlpool.h index 4711fafa3..e28053d4f 100644 --- a/src/hash/whirlpool/whrlpool.h +++ b/src/hash/whirlpool/whrlpool.h @@ -12,7 +12,7 @@ namespace Botan { -/* +/** * Whirlpool */ class BOTAN_DLL Whirlpool : public MDx_HashFunction diff --git a/src/kdf/kdf.h b/src/kdf/kdf.h index 67078218f..ecf7f4621 100644 --- a/src/kdf/kdf.h +++ b/src/kdf/kdf.h @@ -13,31 +13,69 @@ namespace Botan { -/* +/** * Key Derivation Function */ class BOTAN_DLL KDF { public: + /** + * Derive a key + * @param key_len the desired output length in bytes + * @param secret the secret input + * @param salt a diversifier + */ SecureVector<byte> derive_key(u32bit key_len, const MemoryRegion<byte>& secret, const std::string& salt = "") const; + /** + * Derive a key + * @param key_len the desired output length in bytes + * @param secret the secret input + * @param salt a diversifier + */ SecureVector<byte> derive_key(u32bit key_len, const MemoryRegion<byte>& secret, const MemoryRegion<byte>& salt) const; + /** + * Derive a key + * @param key_len the desired output length in bytes + * @param secret the secret input + * @param salt a diversifier + * @param salt_len size of salt in bytes + */ SecureVector<byte> derive_key(u32bit key_len, const MemoryRegion<byte>& secret, - const byte salt[], u32bit salt_len) const; + const byte salt[], + u32bit salt_len) const; + /** + * Derive a key + * @param key_len the desired output length in bytes + * @param secret the secret input + * @param secret_len size of secret in bytes + * @param salt a diversifier + */ SecureVector<byte> derive_key(u32bit key_len, - const byte secret[], u32bit secret_len, + const byte secret[], + u32bit secret_len, const std::string& salt = "") const; + /** + * Derive a key + * @param key_len the desired output length in bytes + * @param secret the secret input + * @param secret_len size of secret in bytes + * @param salt a diversifier + * @param salt_len size of salt in bytes + */ SecureVector<byte> derive_key(u32bit key_len, - const byte secret[], u32bit secret_len, - const byte salt[], u32bit salt_len) const; + const byte secret[], + u32bit secret_len, + const byte salt[], + u32bit salt_len) const; virtual ~KDF() {} private: @@ -47,7 +85,7 @@ class BOTAN_DLL KDF const byte salt[], u32bit salt_len) const = 0; }; -/* +/** * Mask Generation Function */ class BOTAN_DLL MGF diff --git a/src/kdf/kdf1/kdf1.h b/src/kdf/kdf1/kdf1.h index d657cccc2..80ea470a9 100644 --- a/src/kdf/kdf1/kdf1.h +++ b/src/kdf/kdf1/kdf1.h @@ -13,8 +13,8 @@ namespace Botan { -/* -* KDF1 +/** +* KDF1, from IEEE 1363 */ class BOTAN_DLL KDF1 : public KDF { diff --git a/src/kdf/kdf2/kdf2.h b/src/kdf/kdf2/kdf2.h index f748bed0f..1f01008c0 100644 --- a/src/kdf/kdf2/kdf2.h +++ b/src/kdf/kdf2/kdf2.h @@ -13,8 +13,8 @@ namespace Botan { -/* -* KDF2 +/** +* KDF2, from IEEE 1363 */ class BOTAN_DLL KDF2 : public KDF { diff --git a/src/kdf/mgf1/mgf1.h b/src/kdf/mgf1/mgf1.h index 799ba7eed..2f7655fe2 100644 --- a/src/kdf/mgf1/mgf1.h +++ b/src/kdf/mgf1/mgf1.h @@ -13,8 +13,8 @@ namespace Botan { -/* -* MGF1 (Mask Generation Function) +/** +* MGF1 from PKCS #1 v2.0 */ class BOTAN_DLL MGF1 : public MGF { diff --git a/src/kdf/ssl_prf/prf_ssl3.h b/src/kdf/ssl_prf/prf_ssl3.h index 165fc7c3c..7d968eda1 100644 --- a/src/kdf/ssl_prf/prf_ssl3.h +++ b/src/kdf/ssl_prf/prf_ssl3.h @@ -12,8 +12,8 @@ namespace Botan { -/* -* SSL3 PRF +/** +* PRF used in SSLv3 */ class BOTAN_DLL SSL3_PRF : public KDF { diff --git a/src/kdf/tls_prf/prf_tls.h b/src/kdf/tls_prf/prf_tls.h index 6d1787609..c7ad81a97 100644 --- a/src/kdf/tls_prf/prf_tls.h +++ b/src/kdf/tls_prf/prf_tls.h @@ -14,8 +14,8 @@ namespace Botan { -/* -* TLS PRF +/** +* PRF used in TLS 1.0/1.1 */ class BOTAN_DLL TLS_PRF : public KDF { @@ -31,8 +31,8 @@ class BOTAN_DLL TLS_PRF : public KDF MessageAuthenticationCode* hmac_sha1; }; -/* -* TLS 1.2 PRF +/** +* PRF used in TLS 1.2 */ class BOTAN_DLL TLS_12_PRF : public KDF { diff --git a/src/kdf/x942_prf/prf_x942.h b/src/kdf/x942_prf/prf_x942.h index f957566b0..a5fe9f351 100644 --- a/src/kdf/x942_prf/prf_x942.h +++ b/src/kdf/x942_prf/prf_x942.h @@ -12,8 +12,8 @@ namespace Botan { -/* -* X9.42 PRF +/** +* PRF from ANSI X9.42 */ class BOTAN_DLL X942_PRF : public KDF { diff --git a/src/libstate/botan.h b/src/libstate/botan.h index a88edb59b..42d3dc392 100644 --- a/src/libstate/botan.h +++ b/src/libstate/botan.h @@ -1,4 +1,4 @@ -/** +/* * A vague catch all include file for Botan * (C) 1999-2007 Jack Lloyd * diff --git a/src/libstate/init.cpp b/src/libstate/init.cpp index 0d9a2420c..a65098d5a 100644 --- a/src/libstate/init.cpp +++ b/src/libstate/init.cpp @@ -1,4 +1,4 @@ -/** +/* * Default Initialization Function * (C) 1999-2009 Jack Lloyd * diff --git a/src/libstate/init.h b/src/libstate/init.h index 254f9458b..2d70e4370 100644 --- a/src/libstate/init.h +++ b/src/libstate/init.h @@ -1,4 +1,4 @@ -/** +/* * Library Initialization * (C) 1999-2008 Jack Lloyd * @@ -22,13 +22,20 @@ namespace Botan { class BOTAN_DLL LibraryInitializer { public: + /** + * Initialize the library + * @param options a string listing initialization options + */ static void initialize(const std::string& options = ""); + /** + * Shutdown the library + */ static void deinitialize(); /** * Initialize the library - * @param thread_safe if the library should use a thread-safe mutex + * @param options a string listing initialization options */ LibraryInitializer(const std::string& options = "") { LibraryInitializer::initialize(options); } diff --git a/src/libstate/libstate.h b/src/libstate/libstate.h index 5af55e9d8..f3abdf87a 100644 --- a/src/libstate/libstate.h +++ b/src/libstate/libstate.h @@ -34,12 +34,12 @@ class BOTAN_DLL Library_State void initialize(); /** - * @return the global Algorithm_Factory + * @return global Algorithm_Factory */ Algorithm_Factory& algorithm_factory() const; /** - * @return the global RandomNumberGenerator + * @return global RandomNumberGenerator */ RandomNumberGenerator& global_rng(); @@ -71,8 +71,7 @@ class BOTAN_DLL Library_State const std::string& key); /** - * Check whether a certain parameter is set - * or not. + * Check whether a certain parameter is set or not. * @param section the section of the desired key * @param key the desired keys name * @result true if the parameters value is set, @@ -85,6 +84,7 @@ class BOTAN_DLL Library_State * Set a configuration parameter. * @param section the section of the desired key * @param key the desired keys name + * @param value the new value * @param overwrite if set to true, the parameters value * will be overwritten even if it is already set, otherwise * no existing values will be overwritten. @@ -144,7 +144,7 @@ BOTAN_DLL void set_global_state(Library_State* state); /** * Swap the current state for another * @param new_state the new state object to use -* @return the previous state (or NULL if none) +* @return previous state (or NULL if none) */ BOTAN_DLL Library_State* swap_global_state(Library_State* new_state); diff --git a/src/libstate/look_pk.h b/src/libstate/look_pk.h index 833b28f67..c980e5f8d 100644 --- a/src/libstate/look_pk.h +++ b/src/libstate/look_pk.h @@ -15,9 +15,11 @@ namespace Botan { /** * Public key encryptor factory method. +* @deprecated Instantiate object from pubkey.h directly +* * @param key the key that will work inside the encryptor * @param eme determines the algorithm and encoding -* @return the public key encryptor object +* @return public key encryptor object */ inline PK_Encryptor* get_pk_encryptor(const Public_Key& key, const std::string& eme) @@ -27,9 +29,11 @@ inline PK_Encryptor* get_pk_encryptor(const Public_Key& key, /** * Public key decryptor factory method. +* @deprecated Instantiate object from pubkey.h directly +* * @param key the key that will work inside the decryptor * @param eme determines the algorithm and encoding -* @return the public key decryptor object +* @return public key decryptor object */ inline PK_Decryptor* get_pk_decryptor(const Private_Key& key, const std::string& eme) @@ -39,10 +43,12 @@ inline PK_Decryptor* get_pk_decryptor(const Private_Key& key, /** * Public key signer factory method. +* @deprecated Instantiate object from pubkey.h directly +* * @param key the key that will work inside the signer * @param emsa determines the algorithm, encoding and hash algorithm * @param sig_format the signature format to be used -* @return the public key signer object +* @return public key signer object */ inline PK_Signer* get_pk_signer(const Private_Key& key, const std::string& emsa, @@ -53,10 +59,12 @@ inline PK_Signer* get_pk_signer(const Private_Key& key, /** * Public key verifier factory method. +* @deprecated Instantiate object from pubkey.h directly +* * @param key the key that will work inside the verifier * @param emsa determines the algorithm, encoding and hash algorithm * @param sig_format the signature format to be used -* @return the public key verifier object +* @return public key verifier object */ inline PK_Verifier* get_pk_verifier(const Public_Key& key, const std::string& emsa, @@ -67,9 +75,11 @@ inline PK_Verifier* get_pk_verifier(const Public_Key& key, /** * Public key key agreement factory method. +* @deprecated Instantiate object from pubkey.h directly +* * @param key the key that will work inside the key agreement * @param kdf the kdf algorithm to use -* @return the key agreement algorithm +* @return key agreement algorithm */ inline PK_Key_Agreement* get_pk_kas(const PK_Key_Agreement_Key& key, const std::string& kdf) diff --git a/src/libstate/lookup.cpp b/src/libstate/lookup.cpp index 01f4a3d42..586c335e6 100644 --- a/src/libstate/lookup.cpp +++ b/src/libstate/lookup.cpp @@ -11,7 +11,7 @@ namespace Botan { -/** +/* * Query if an algorithm exists */ bool have_algorithm(const std::string& name) @@ -29,7 +29,7 @@ bool have_algorithm(const std::string& name) return false; } -/** +/* * Query the block size of a cipher or hash */ u32bit block_size_of(const std::string& name) @@ -45,7 +45,7 @@ u32bit block_size_of(const std::string& name) throw Algorithm_Not_Found(name); } -/** +/* * Query the OUTPUT_LENGTH of a hash or MAC */ u32bit output_length_of(const std::string& name) @@ -61,7 +61,7 @@ u32bit output_length_of(const std::string& name) throw Algorithm_Not_Found(name); } -/** +/* * Check if a keylength is valid for this algo */ bool valid_keylength_for(u32bit key_len, const std::string& name) @@ -80,7 +80,7 @@ bool valid_keylength_for(u32bit key_len, const std::string& name) throw Algorithm_Not_Found(name); } -/** +/* * Query the MINIMUM_KEYLENGTH of an algorithm */ u32bit min_keylength_of(const std::string& name) @@ -99,7 +99,7 @@ u32bit min_keylength_of(const std::string& name) throw Algorithm_Not_Found(name); } -/** +/* * Query the MAXIMUM_KEYLENGTH of an algorithm */ u32bit max_keylength_of(const std::string& name) @@ -118,7 +118,7 @@ u32bit max_keylength_of(const std::string& name) throw Algorithm_Not_Found(name); } -/** +/* * Query the KEYLENGTH_MULTIPLE of an algorithm */ u32bit keylength_multiple_of(const std::string& name) @@ -137,7 +137,7 @@ u32bit keylength_multiple_of(const std::string& name) throw Algorithm_Not_Found(name); } -/** +/* * Get a cipher object */ Keyed_Filter* get_cipher(const std::string& algo_spec, @@ -156,7 +156,7 @@ Keyed_Filter* get_cipher(const std::string& algo_spec, throw Algorithm_Not_Found(algo_spec); } -/** +/* * Get a cipher object */ Keyed_Filter* get_cipher(const std::string& algo_spec, @@ -173,7 +173,7 @@ Keyed_Filter* get_cipher(const std::string& algo_spec, return cipher; } -/** +/* * Get a cipher object */ Keyed_Filter* get_cipher(const std::string& algo_spec, diff --git a/src/libstate/lookup.h b/src/libstate/lookup.h index 5f10bb3f8..76e06b2de 100644 --- a/src/libstate/lookup.h +++ b/src/libstate/lookup.h @@ -61,8 +61,10 @@ retrieve_mac(const std::string& algo_spec) /** * Block cipher factory method. +* @deprecated Call algorithm_factory() directly +* * @param algo_spec the name of the desired block cipher -* @return a pointer to the block cipher object +* @return pointer to the block cipher object */ inline BlockCipher* get_block_cipher(const std::string& algo_spec) { @@ -72,8 +74,10 @@ inline BlockCipher* get_block_cipher(const std::string& algo_spec) /** * Stream cipher factory method. +* @deprecated Call algorithm_factory() directly +* * @param algo_spec the name of the desired stream cipher -* @return a pointer to the stream cipher object +* @return pointer to the stream cipher object */ inline StreamCipher* get_stream_cipher(const std::string& algo_spec) { @@ -83,8 +87,10 @@ inline StreamCipher* get_stream_cipher(const std::string& algo_spec) /** * Hash function factory method. +* @deprecated Call algorithm_factory() directly +* * @param algo_spec the name of the desired hash function -* @return a pointer to the hash function object +* @return pointer to the hash function object */ inline HashFunction* get_hash(const std::string& algo_spec) { @@ -94,8 +100,10 @@ inline HashFunction* get_hash(const std::string& algo_spec) /** * MAC factory method. +* @deprecated Call algorithm_factory() directly +* * @param algo_spec the name of the desired MAC -* @return a pointer to the MAC object +* @return pointer to the MAC object */ inline MessageAuthenticationCode* get_mac(const std::string& algo_spec) { @@ -105,8 +113,8 @@ inline MessageAuthenticationCode* get_mac(const std::string& algo_spec) /** * String to key algorithm factory method. -* @param name the name of the desired string to key (S2K) algorithm -* @return a pointer to the string to key algorithm object +* @param algo_spec the name of the desired string to key (S2K) algorithm +* @return pointer to the string to key algorithm object */ BOTAN_DLL S2K* get_s2k(const std::string& algo_spec); @@ -118,23 +126,23 @@ BOTAN_DLL S2K* get_s2k(const std::string& algo_spec); /** * Factory method for EME (message-encoding methods for encryption) objects -* @param name the name of the EME to create -* @return a pointer to the desired EME object +* @param algo_spec the name of the EME to create +* @return pointer to the desired EME object */ BOTAN_DLL EME* get_eme(const std::string& algo_spec); /** * Factory method for EMSA (message-encoding methods for signatures * with appendix) objects -* @param name the name of the EME to create -* @return a pointer to the desired EME object +* @param algo_spec the name of the EME to create +* @return pointer to the desired EME object */ BOTAN_DLL EMSA* get_emsa(const std::string& algo_spec); /** * Factory method for KDF (key derivation function) -* @param name the name of the KDF to create -* @return a pointer to the desired KDF object +* @param algo_spec the name of the KDF to create +* @return pointer to the desired KDF object */ BOTAN_DLL KDF* get_kdf(const std::string& algo_spec); @@ -150,12 +158,13 @@ BOTAN_DLL KDF* get_kdf(const std::string& algo_spec); * @param iv the initialization vector to be used * @param direction determines whether the filter will be an encrypting * or decrypting filter -* @return a pointer to the encryption or decryption filter +* @return pointer to the encryption or decryption filter */ -BOTAN_DLL Keyed_Filter* get_cipher(const std::string& name, +BOTAN_DLL Keyed_Filter* get_cipher(const std::string& algo_spec, const SymmetricKey& key, const InitializationVector& iv, - Cipher_Dir dir); + Cipher_Dir direction); + /** * Factory method for general symmetric cipher filters. * @param algo_spec the name of the desired cipher @@ -163,32 +172,36 @@ BOTAN_DLL Keyed_Filter* get_cipher(const std::string& name, * the filter * @param direction determines whether the filter will be an encrypting * or decrypting filter -* @return a pointer to the encryption or decryption filter +* @return pointer to the encryption or decryption filter */ -BOTAN_DLL Keyed_Filter* get_cipher(const std::string& name, +BOTAN_DLL Keyed_Filter* get_cipher(const std::string& algo_spec, const SymmetricKey& key, - Cipher_Dir dir); + Cipher_Dir direction); -/** Factory method for general symmetric cipher filters. No key will -* be set in the filter. +/** +* Factory method for general symmetric cipher filters. No key will be +* set in the filter. +* * @param algo_spec the name of the desired cipher - * @param direction determines whether the filter will be an encrypting or * decrypting filter -* @return a pointer to the encryption or decryption filter +* @return pointer to the encryption or decryption filter */ -BOTAN_DLL Keyed_Filter* get_cipher(const std::string& name, Cipher_Dir dir); +BOTAN_DLL Keyed_Filter* get_cipher(const std::string& algo_spec, + Cipher_Dir direction); /** * Check if an algorithm exists. -* @param name the name of the algorithm to check for +* @param algo_spec the name of the algorithm to check for * @return true if the algorithm exists, false otherwise */ BOTAN_DLL bool have_algorithm(const std::string& algo_spec); /** * Check if a block cipher algorithm exists. -* @param name the name of the algorithm to check for +* @deprecated Call algorithm_factory() directly +* +* @param algo_spec the name of the algorithm to check for * @return true if the algorithm exists, false otherwise */ inline bool have_block_cipher(const std::string& algo_spec) @@ -199,7 +212,9 @@ inline bool have_block_cipher(const std::string& algo_spec) /** * Check if a stream cipher algorithm exists. -* @param name the name of the algorithm to check for +* @deprecated Call algorithm_factory() directly +* +* @param algo_spec the name of the algorithm to check for * @return true if the algorithm exists, false otherwise */ inline bool have_stream_cipher(const std::string& algo_spec) @@ -210,6 +225,8 @@ inline bool have_stream_cipher(const std::string& algo_spec) /** * Check if a hash algorithm exists. +* @deprecated Call algorithm_factory() directly +* * @param algo_spec the name of the algorithm to check for * @return true if the algorithm exists, false otherwise */ @@ -221,6 +238,8 @@ inline bool have_hash(const std::string& algo_spec) /** * Check if a MAC algorithm exists. +* @deprecated Call algorithm_factory() directly +* * @param algo_spec the name of the algorithm to check for * @return true if the algorithm exists, false otherwise */ @@ -236,46 +255,58 @@ inline bool have_mac(const std::string& algo_spec) /** * Find out the block size of a certain symmetric algorithm. -* @param name the name of the algorithm -* @return the block size of the specified algorithm +* @deprecated Call algorithm_factory() directly +* +* @param algo_spec the name of the algorithm +* @return block size of the specified algorithm */ BOTAN_DLL u32bit block_size_of(const std::string& algo_spec); /** * Find out the output length of a certain symmetric algorithm. -* @param name the name of the algorithm -* @return the output length of the specified algorithm +* @deprecated Call algorithm_factory() directly +* +* @param algo_spec the name of the algorithm +* @return output length of the specified algorithm */ BOTAN_DLL u32bit output_length_of(const std::string& algo_spec); /** * Find out the whether a certain key length is allowd for a given * symmetric algorithm. +* @deprecated Call algorithm_factory() directly +* * @param key_len the key length in question -* @param name the name of the algorithm +* @param algo_spec the name of the algorithm * @return true if the key length is valid for that algorithm, false otherwise */ -BOTAN_DLL bool valid_keylength_for(u32bit keylen, +BOTAN_DLL bool valid_keylength_for(u32bit key_len, const std::string& algo_spec); /** * Find out the minimum key size of a certain symmetric algorithm. -* @param name the name of the algorithm -* @return the minimum key length of the specified algorithm +* @deprecated Call algorithm_factory() directly +* +* @param algo_spec the name of the algorithm +* @return minimum key length of the specified algorithm */ BOTAN_DLL u32bit min_keylength_of(const std::string& algo_spec); /** * Find out the maximum key size of a certain symmetric algorithm. -* @param name the name of the algorithm -* @return the maximum key length of the specified algorithm +* @deprecated Call algorithm_factory() directly +* +* @param algo_spec the name of the algorithm +* @return maximum key length of the specified algorithm */ BOTAN_DLL u32bit max_keylength_of(const std::string& algo_spec); /** * Find out the size any valid key is a multiple of for a certain algorithm. -* @param name the name of the algorithm -* @return the size any valid key is a multiple of +* @deprecated Call algorithm_factory() directly +* +* @param algo_spec the name of the algorithm +* @return size any valid key is a multiple of */ BOTAN_DLL u32bit keylength_multiple_of(const std::string& algo_spec); diff --git a/src/libstate/oid_lookup/oids.h b/src/libstate/oid_lookup/oids.h index fdfe61f7c..70b7dee81 100644 --- a/src/libstate/oid_lookup/oids.h +++ b/src/libstate/oid_lookup/oids.h @@ -31,7 +31,7 @@ BOTAN_DLL bool have_oid(const std::string& oid); /** * Resolve an OID * @param oid the OID to look up -* @return the name associated with this OID +* @return name associated with this OID */ BOTAN_DLL std::string lookup(const OID& oid); @@ -39,7 +39,7 @@ BOTAN_DLL std::string lookup(const OID& oid); * Find the OID to a name. The lookup will be performed in the * general OID section of the configuration. * @param name the name to resolve -* @return the OID associated with the specified name +* @return OID associated with the specified name */ BOTAN_DLL OID lookup(const std::string& name); diff --git a/src/libstate/scan_name.cpp b/src/libstate/scan_name.cpp index eccb15565..7c2e4b28d 100644 --- a/src/libstate/scan_name.cpp +++ b/src/libstate/scan_name.cpp @@ -1,4 +1,4 @@ -/** +/* * SCAN Name Abstraction * (C) 2008-2009 Jack Lloyd * diff --git a/src/libstate/scan_name.h b/src/libstate/scan_name.h index 4350dca86..3d11d54f6 100644 --- a/src/libstate/scan_name.h +++ b/src/libstate/scan_name.h @@ -1,4 +1,4 @@ -/** +/* * SCAN Name Abstraction * (C) 2008 Jack Lloyd * @@ -23,64 +23,66 @@ class BOTAN_DLL SCAN_Name { public: /** - @param algo_spec A SCAN-format name + * @param algo_spec A SCAN-format name */ SCAN_Name(std::string algo_spec); /** - @return the original input string + * @return original input string */ std::string as_string() const { return orig_algo_spec; } /** - @return the algorithm name + * @return algorithm name */ std::string algo_name() const { return alg_name; } /** - @return the algorithm name plus any arguments + * @return algorithm name plus any arguments */ std::string algo_name_and_args() const; /** - @return the number of arguments + * @return number of arguments */ u32bit arg_count() const { return args.size(); } /** - @return if the number of arguments is between lower and upper + * @param lower is the lower bound + * @param upper is the upper bound + * @return if the number of arguments is between lower and upper */ bool arg_count_between(u32bit lower, u32bit upper) const { return ((arg_count() >= lower) && (arg_count() <= upper)); } /** - @param i which argument - @return the ith argument + * @param i which argument + * @return ith argument */ std::string arg(u32bit i) const; /** - @param i which argument - @param def_value the default value - @return the ith argument or the default value + * @param i which argument + * @param def_value the default value + * @return ith argument or the default value */ std::string arg(u32bit i, const std::string& def_value) const; /** - @param i which argument - @param def_value the default value - @return the ith argument as a u32bit, or the default value + * @param i which argument + * @param def_value the default value + * @return ith argument as a u32bit, or the default value */ u32bit arg_as_u32bit(u32bit i, u32bit def_value) const; /** - @return the cipher mode (if any) + * @return cipher mode (if any) */ std::string cipher_mode() const { return (mode_info.size() >= 1) ? mode_info[0] : ""; } /** - @return the cipher mode padding (if any) + * @return cipher mode padding (if any) */ std::string cipher_mode_pad() const { return (mode_info.size() >= 2) ? mode_info[1] : ""; } diff --git a/src/mac/cbc_mac/cbc_mac.h b/src/mac/cbc_mac/cbc_mac.h index 15026c0a9..772abd38f 100644 --- a/src/mac/cbc_mac/cbc_mac.h +++ b/src/mac/cbc_mac/cbc_mac.h @@ -13,7 +13,7 @@ namespace Botan { -/* +/** * CBC-MAC */ class BOTAN_DLL CBC_MAC : public MessageAuthenticationCode @@ -23,7 +23,10 @@ class BOTAN_DLL CBC_MAC : public MessageAuthenticationCode std::string name() const; MessageAuthenticationCode* clone() const; - CBC_MAC(BlockCipher* e); + /** + * @param cipher the underlying block cipher to use + */ + CBC_MAC(BlockCipher* cipher); ~CBC_MAC(); private: void add_data(const byte[], u32bit); diff --git a/src/mac/cmac/cmac.h b/src/mac/cmac/cmac.h index 8297e5ea1..b5f3eec1a 100644 --- a/src/mac/cmac/cmac.h +++ b/src/mac/cmac/cmac.h @@ -13,8 +13,8 @@ namespace Botan { -/* -* CMAC +/** +* CMAC, also known as OMAC1 */ class BOTAN_DLL CMAC : public MessageAuthenticationCode { @@ -23,10 +23,18 @@ class BOTAN_DLL CMAC : public MessageAuthenticationCode std::string name() const; MessageAuthenticationCode* clone() const; + /** + * CMAC's polynomial doubling operation + * @param in the input + * @param polynomial the byte value of the polynomial + */ static SecureVector<byte> poly_double(const MemoryRegion<byte>& in, byte polynomial); - CMAC(BlockCipher* e); + /** + * @param cipher the underlying block cipher to use + */ + CMAC(BlockCipher* cipher); ~CMAC(); private: void add_data(const byte[], u32bit); diff --git a/src/mac/hmac/hmac.h b/src/mac/hmac/hmac.h index 62bb69853..43a5d22a4 100644 --- a/src/mac/hmac/hmac.h +++ b/src/mac/hmac/hmac.h @@ -13,7 +13,7 @@ namespace Botan { -/* +/** * HMAC */ class BOTAN_DLL HMAC : public MessageAuthenticationCode @@ -23,6 +23,9 @@ class BOTAN_DLL HMAC : public MessageAuthenticationCode std::string name() const; MessageAuthenticationCode* clone() const; + /** + * @param hash the hash to use for HMACing + */ HMAC(HashFunction* hash); ~HMAC() { delete hash; } private: diff --git a/src/mac/mac.cpp b/src/mac/mac.cpp index 04b259647..cb89e872a 100644 --- a/src/mac/mac.cpp +++ b/src/mac/mac.cpp @@ -1,4 +1,4 @@ -/** +/* * Message Authentication Code base class * (C) 1999-2008 Jack Lloyd * @@ -9,7 +9,7 @@ namespace Botan { -/** +/* * Default (deterministic) MAC verification operation */ bool MessageAuthenticationCode::verify_mac(const byte mac[], u32bit length) diff --git a/src/mac/mac.h b/src/mac/mac.h index 7c73a2900..4518d91ad 100644 --- a/src/mac/mac.h +++ b/src/mac/mac.h @@ -1,4 +1,4 @@ -/** +/* * Base class for message authentiction codes * (C) 1999-2007 Jack Lloyd * @@ -24,10 +24,10 @@ class BOTAN_DLL MessageAuthenticationCode : public BufferedComputation, /** * Verify a MAC. * @param in the MAC to verify as a byte array - * @param length the length of the byte array + * @param length the length of param in * @return true if the MAC is valid, false otherwise */ - virtual bool verify_mac(const byte[], u32bit); + virtual bool verify_mac(const byte in[], u32bit length); /** * Get a new object representing the same algorithm as *this @@ -36,7 +36,7 @@ class BOTAN_DLL MessageAuthenticationCode : public BufferedComputation, /** * Get the name of this algorithm. - * @return the name of this algorithm + * @return name of this algorithm */ virtual std::string name() const = 0; @@ -45,6 +45,12 @@ class BOTAN_DLL MessageAuthenticationCode : public BufferedComputation, */ virtual void clear() = 0; + /** + * @param mac_len the output length of this MAC + * @param key_min the minimum key size + * @param key_max the maximum key size + * @param key_mod the modulo restriction on the key size + */ MessageAuthenticationCode(u32bit mac_len, u32bit key_min, u32bit key_max = 0, diff --git a/src/mac/ssl3mac/ssl3_mac.h b/src/mac/ssl3mac/ssl3_mac.h index 828b072ed..019163ec8 100644 --- a/src/mac/ssl3mac/ssl3_mac.h +++ b/src/mac/ssl3mac/ssl3_mac.h @@ -13,8 +13,8 @@ namespace Botan { -/* -* SSL3-MAC +/** +* A MAC only used in SSLv3. Do not use elsewhere! Use HMAC instead. */ class BOTAN_DLL SSL3_MAC : public MessageAuthenticationCode { @@ -23,7 +23,10 @@ class BOTAN_DLL SSL3_MAC : public MessageAuthenticationCode std::string name() const; MessageAuthenticationCode* clone() const; - SSL3_MAC(HashFunction*); + /** + * @param hash the underlying hash to use + */ + SSL3_MAC(HashFunction* hash); ~SSL3_MAC() { delete hash; } private: void add_data(const byte[], u32bit); diff --git a/src/mac/x919_mac/x919_mac.h b/src/mac/x919_mac/x919_mac.h index abd149ecd..8432db7d1 100644 --- a/src/mac/x919_mac/x919_mac.h +++ b/src/mac/x919_mac/x919_mac.h @@ -23,7 +23,10 @@ class BOTAN_DLL ANSI_X919_MAC : public MessageAuthenticationCode std::string name() const; MessageAuthenticationCode* clone() const; - ANSI_X919_MAC(BlockCipher*); + /** + * @param cipher the underlying block cipher to use + */ + ANSI_X919_MAC(BlockCipher* cipher); ~ANSI_X919_MAC(); private: void add_data(const byte[], u32bit); diff --git a/src/math/bigint/bigint.cpp b/src/math/bigint/bigint.cpp index b92cd359e..85d7c48ff 100644 --- a/src/math/bigint/bigint.cpp +++ b/src/math/bigint/bigint.cpp @@ -268,10 +268,12 @@ u32bit BigInt::bytes() const */ u32bit BigInt::bits() const { - if(sig_words() == 0) + const u32bit words = sig_words(); + + if(words == 0) return 0; - u32bit full_words = sig_words() - 1, top_bits = MP_WORD_BITS; + u32bit full_words = words - 1, top_bits = MP_WORD_BITS; word top_word = word_at(full_words), mask = MP_WORD_TOP_BIT; while(top_bits && ((top_word & mask) == 0)) diff --git a/src/math/bigint/bigint.h b/src/math/bigint/bigint.h index 3756da51f..2b95bfc90 100644 --- a/src/math/bigint/bigint.h +++ b/src/math/bigint/bigint.h @@ -44,90 +44,96 @@ class BOTAN_DLL BigInt { DivideByZero() : Exception("BigInt divide by zero") {} }; /** - * += Operator + * += operator * @param y the BigInt to add to this */ BigInt& operator+=(const BigInt& y); /** - * -= Operator + * -= operator * @param y the BigInt to subtract from this */ BigInt& operator-=(const BigInt& y); /** - * *= Operator + * *= operator * @param y the BigInt to multiply with this */ BigInt& operator*=(const BigInt& y); /** - * /= Operator + * /= operator * @param y the BigInt to divide this by */ BigInt& operator/=(const BigInt& y); /** - * %= Operator, modulo operator. + * Modulo operator * @param y the modulus to reduce this by */ BigInt& operator%=(const BigInt& y); /** - * %= Operator + * Modulo operator * @param y the modulus (word) to reduce this by */ word operator%=(word y); /** - * <<= Operator - * @param y the amount of bits to shift this left + * Left shift operator + * @param shift the number of bits to shift this left by */ - BigInt& operator<<=(u32bit y); + BigInt& operator<<=(u32bit shift); /** - * >>= Operator - * @param y the amount of bits to shift this right + * Right shift operator + * @param shift the number of bits to shift this right by */ - BigInt& operator>>=(u32bit y); + BigInt& operator>>=(u32bit shift); /** - * ++ Operator + * Increment operator */ BigInt& operator++() { return (*this += 1); } /** - * -- Operator + * Decrement operator */ BigInt& operator--() { return (*this -= 1); } /** - * ++ Operator (postfix) + * Postfix increment operator */ BigInt operator++(int) { BigInt x = (*this); ++(*this); return x; } /** - * -- Operator (postfix) + * Postfix decrement operator */ BigInt operator--(int) { BigInt x = (*this); --(*this); return x; } /** - * Unary - Operator + * Unary negation operator + * @return negative this */ BigInt operator-() const; /** - * ! Operator + * ! operator + * @return true iff this is zero, otherwise false */ bool operator !() const { return (!is_nonzero()); } /** - * [] Operator (array access) + * [] operator (array access) + * @param i a word index + * @return the word at index i */ word& operator[](u32bit i) { return reg[i]; } /** - * [] Operator (array access) + * [] operator (array access) + * @param i a word index + * @return the word at index i */ word operator[](u32bit i) const { return reg[i]; } @@ -137,8 +143,8 @@ class BOTAN_DLL BigInt void clear() { get_reg().clear(); } /** - * Compare *this to another BigInt. - * @param n the BigInt value to compare to this. + * Compare this to another BigInt + * @param n the BigInt value to compare with * @param check_signs include sign in comparison? * @result if (this<n) return -1, if (this>n) return 1, if both * values are identical return 0 [like Perl's <=> operator] @@ -158,13 +164,13 @@ class BOTAN_DLL BigInt bool is_odd() const { return (get_bit(0) == 1); } /** - * Test if the integer is not zero. + * Test if the integer is not zero * @result true if the integer is non-zero, false otherwise */ bool is_nonzero() const { return (!is_zero()); } /** - * Test if the integer is zero. + * Test if the integer is zero * @result true if the integer is zero, false otherwise */ bool is_zero() const @@ -220,28 +226,29 @@ class BOTAN_DLL BigInt /** * Return the word at a specified position of the internal register * @param n position in the register - * @return the value at position n + * @return value at position n */ word word_at(u32bit n) const { return ((n < size()) ? reg[n] : 0); } /** * Return the integer as an unsigned 32bit-integer-value. If the - * value is negative OR to big to be stored in 32bits, this + * value is negative OR too big to be stored in a u32bit, this * function will throw an exception. - * @result a 32bit-integer + * + * @result unsigned 32 bit representation of this */ u32bit to_u32bit() const; /** - * Tests if the sign of the integer is negative. - * @result true, if the integer has a negative sign, + * Tests if the sign of the integer is negative + * @result true, iff the integer has a negative sign */ bool is_negative() const { return (sign() == Negative); } /** - * Tests if the sign of the integer is positive. - * @result true, if the integer has a positive sign, + * Tests if the sign of the integer is positive + * @result true, iff the integer has a positive sign */ bool is_positive() const { return (sign() == Positive); } @@ -252,13 +259,12 @@ class BOTAN_DLL BigInt Sign sign() const { return (signedness); } /** - * Return the opposite sign of the represented integer value * @result the opposite sign of the represented integer value */ Sign reverse_sign() const; /** - * Flip (mutate) the sign of the integer to its opposite value + * Flip the sign of this BigInt */ void flip_sign(); @@ -280,7 +286,7 @@ class BOTAN_DLL BigInt u32bit size() const { return get_reg().size(); } /** - * Give significant words of the represented integer value + * Return how many words we need to hold this value * @result significant words of the represented integer value */ u32bit sig_words() const @@ -294,19 +300,19 @@ class BOTAN_DLL BigInt } /** - * Give byte-length of the integer - * @result byte-length of the represented integer value + * Give byte length of the integer + * @result byte length of the represented integer value */ u32bit bytes() const; /** - * Get the bit-length of the integer. - * @result bit-length of the represented integer value + * Get the bit length of the integer + * @result bit length of the represented integer value */ u32bit bits() const; /** - * Return a pointer to the big integer word register. + * Return a pointer to the big integer word register * @result a pointer to the start of the internal register of * the integer value */ @@ -357,18 +363,25 @@ class BOTAN_DLL BigInt /** * Read integer value from a byte array (MemoryRegion<byte>) - * @param buf the BigInt value to compare to this. + * @param buf the array to load from */ void binary_decode(const MemoryRegion<byte>& buf); - u32bit encoded_size(Base = Binary) const; + /** + * @param base the base to measure the size for + * @return size of this integer in base base + */ + u32bit encoded_size(Base base = Binary) const; /** - @param rng a random number generator - @result a random integer between min and max + * @param rng a random number generator + * @param min the minimum value + * @param max the maximum value + * @return random integer between min and max */ static BigInt random_integer(RandomNumberGenerator& rng, - const BigInt& min, const BigInt& max); + const BigInt& min, + const BigInt& max); /** * Encode the integer value from a BigInt to a SecureVector of bytes @@ -389,15 +402,22 @@ class BOTAN_DLL BigInt /** * Create a BigInt from an integer in a byte array - * @param buf the BigInt value to compare to this. + * @param buf the binary value to load * @param length size of buf * @param base number-base of the integer in buf - * @result BigInt-representing the given integer read from the byte array + * @result BigInt representing the integer in the byte array */ static BigInt decode(const byte buf[], u32bit length, Base base = Binary); - static BigInt decode(const MemoryRegion<byte>&, Base = Binary); + /** + * Create a BigInt from an integer in a byte array + * @param buf the binary value to load + * @param base number-base of the integer in buf + * @result BigInt representing the integer in the byte array + */ + static BigInt decode(const MemoryRegion<byte>& buf, + Base base = Binary); /** * Encode a BigInt to a byte array according to IEEE 1363 @@ -408,10 +428,10 @@ class BOTAN_DLL BigInt static SecureVector<byte> encode_1363(const BigInt& n, u32bit bytes); /** - * Swap BigInt-value with given BigInt. - * @param bigint the BigInt to swap values with + * Swap this value with another + * @param other BigInt to swap values with */ - void swap(BigInt& bigint); + void swap(BigInt& other); /** * Create empty BigInt @@ -419,38 +439,34 @@ class BOTAN_DLL BigInt BigInt() { signedness = Positive; } /** - * Create BigInt from 64bit-Integer value - * @param n 64bit-integer + * Create BigInt from 64 bit integer + * @param n initial value of this BigInt */ BigInt(u64bit n); /** - * Copy constructor + * Copy Constructor + * @param other the BigInt to copy */ BigInt(const BigInt& other); /** - * Assignment operator - */ - BigInt& operator=(const BigInt&) = default; - - /** - * Create BigInt from a string. - * If the string starts with 0x the rest of the string will be - * interpreted as hexadecimal digits. - * If the string starts with 0 and the second character is NOT - * an 'x' the string will be interpreted as octal digits. - * If the string starts with non-zero digit, it will be - * interpreted as a decimal number. + * Create BigInt from a string. If the string starts with 0x the + * rest of the string will be interpreted as hexadecimal digits. + * If the string starts with 0 and the second character is NOT an + * 'x' the string will be interpreted as octal digits. If the + * string starts with non-zero digit, it will be interpreted as a + * decimal number. + * * @param str the string to parse for an integer value */ BigInt(const std::string& str); /** * Create a BigInt from an integer in a byte array - * @param buf the BigInt value to compare to this. + * @param buf the byte array holding the value * @param length size of buf - * @param base number-base of the integer in buf + * @param base is the number base of the integer in buf */ BigInt(const byte buf[], u32bit length, Base base = Binary); @@ -464,14 +480,16 @@ class BOTAN_DLL BigInt /** * Create BigInt of specified size, all zeros * @param sign the sign - * @param n integer value + * @param n size of the internal register in words */ BigInt(Sign sign, u32bit n); /** * Create a number of the specified type and size - * @param type the type of number to create - * @param n the size + * @param type the type of number to create. For Power2, + * will create the integer 2^n + * @param n a size/length parameter, interpretation depends upon + * the value of type */ BigInt(NumberType type, u32bit n); diff --git a/src/math/bigint/divide.h b/src/math/bigint/divide.h index 9445b137b..36aed7854 100644 --- a/src/math/bigint/divide.h +++ b/src/math/bigint/divide.h @@ -12,7 +12,17 @@ namespace Botan { -void BOTAN_DLL divide(const BigInt&, const BigInt&, BigInt&, BigInt&); +/** +* BigInt Division +* @param x an integer +* @param y a non-zero integer +* @param q will be set to x / y +* @param r will be set to x % y +*/ +void BOTAN_DLL divide(const BigInt& x, + const BigInt& y, + BigInt& q, + BigInt& r); } diff --git a/src/math/bigint/info.txt b/src/math/bigint/info.txt index d5741943f..0511c2d8d 100644 --- a/src/math/bigint/info.txt +++ b/src/math/bigint/info.txt @@ -30,7 +30,7 @@ mp_shift.cpp <requires> alloc hex -mp_amd64|mp_asm64|mp_ia32|mp_ia32_msvc|mp_generic +mp_amd64|mp_amd64_msvc|mp_asm64|mp_ia32|mp_ia32_msvc|mp_generic monty_generic mulop_generic rng diff --git a/src/math/bigint/mp_amd64_msvc/info.txt b/src/math/bigint/mp_amd64_msvc/info.txt new file mode 100644 index 000000000..56ae05927 --- /dev/null +++ b/src/math/bigint/mp_amd64_msvc/info.txt @@ -0,0 +1,17 @@ +load_on dep + +mp_bits 64 + +<header:internal> +mp_asm.h +mp_generic:mp_asmi.h +</header:internal> + +<arch> +amd64 +ia64 +</arch> + +<cc> +msvc +</cc> diff --git a/src/math/bigint/mp_amd64_msvc/mp_asm.h b/src/math/bigint/mp_amd64_msvc/mp_asm.h new file mode 100644 index 000000000..3acbe11bb --- /dev/null +++ b/src/math/bigint/mp_amd64_msvc/mp_asm.h @@ -0,0 +1,61 @@ +/* +* Multiply-Add for 64-bit MSVC +* (C) 2010 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_MP_ASM_H__ +#define BOTAN_MP_ASM_H__ + +#include <botan/mp_types.h> +#include <intrin.h> + +#if (BOTAN_MP_WORD_BITS != 64) + #error The mp_amd64_msvc module requires that BOTAN_MP_WORD_BITS == 64 +#endif + +#pragma intrinsic(_umul128) + +namespace Botan { + +extern "C" { + +/* +* Word Multiply +*/ +inline word word_madd2(word a, word b, word* c) + { + word hi, lo; + lo = _umul128(a, b, &hi); + + lo += *c; + hi += (lo < *c); // carry? + + *c = hi; + return lo; + } + +/* +* Word Multiply/Add +*/ +inline word word_madd3(word a, word b, word c, word* d) + { + word hi, lo; + lo = _umul128(a, b, &hi); + + lo += c; + hi += (lo < c); // carry? + + lo += *d; + hi += (lo < *d); // carry? + + *d = hi; + return lo; + } + +} + +} + +#endif diff --git a/src/math/bigint/mp_asm64/mp_asm.h b/src/math/bigint/mp_asm64/mp_asm.h index c9159eaa7..b0906095d 100644 --- a/src/math/bigint/mp_asm64/mp_asm.h +++ b/src/math/bigint/mp_asm64/mp_asm.h @@ -47,7 +47,10 @@ namespace Botan { #elif defined(BOTAN_TARGET_ARCH_IS_MIPS64) #define BOTAN_WORD_MUL(a,b,z1,z0) do { \ - asm("dmultu %2,%3" : "=h" (z0), "=l" (z1) : "r" (a), "r" (b)); \ + typedef unsigned int uint128_t __attribute__((mode(TI))); \ + uint128_t r = (uint128_t)a * b; \ + z0 = (r >> 64) & 0xFFFFFFFFFFFFFFFF; \ + z1 = (r ) & 0xFFFFFFFFFFFFFFFF; \ } while(0); #else diff --git a/src/math/numbertheory/def_powm.h b/src/math/numbertheory/def_powm.h index 5b8a5a591..ce128b965 100644 --- a/src/math/numbertheory/def_powm.h +++ b/src/math/numbertheory/def_powm.h @@ -14,7 +14,7 @@ namespace Botan { -/* +/** * Fixed Window Exponentiator */ class Fixed_Window_Exponentiator : public Modular_Exponentiator @@ -36,7 +36,7 @@ class Fixed_Window_Exponentiator : public Modular_Exponentiator Power_Mod::Usage_Hints hints; }; -/* +/** * Montgomery Exponentiator */ class Montgomery_Exponentiator : public Modular_Exponentiator diff --git a/src/math/numbertheory/numthry.h b/src/math/numbertheory/numthry.h index 2d889a68a..9a1005413 100644 --- a/src/math/numbertheory/numthry.h +++ b/src/math/numbertheory/numthry.h @@ -14,8 +14,8 @@ namespace Botan { -/* -* Fused Arithmetic Operations +/** +* Fused Arithmetic Operation */ BigInt BOTAN_DLL mul_add(const BigInt&, const BigInt&, const BigInt&); BigInt BOTAN_DLL sub_mul(const BigInt&, const BigInt&, const BigInt&); @@ -25,27 +25,70 @@ BigInt BOTAN_DLL sub_mul(const BigInt&, const BigInt&, const BigInt&); */ inline BigInt abs(const BigInt& n) { return n.abs(); } -void BOTAN_DLL divide(const BigInt&, const BigInt&, BigInt&, BigInt&); - +/** +* Compute the greatest common divisor +* @param x a positive integer +* @param y a positive integer +* @return gcd(x,y) +*/ BigInt BOTAN_DLL gcd(const BigInt& x, const BigInt& y); + +/** +* Least common multiple +* @param x a positive integer +* @param y a positive integer +* @return z, smallest integer such that z % x == 0 and z % y == 0 +*/ BigInt BOTAN_DLL lcm(const BigInt& x, const BigInt& y); -BigInt BOTAN_DLL square(const BigInt&); -BigInt BOTAN_DLL inverse_mod(const BigInt&, const BigInt&); -s32bit BOTAN_DLL jacobi(const BigInt&, const BigInt&); +/** +* @param x an integer +* @return (x*x) +*/ +BigInt BOTAN_DLL square(const BigInt& x); + +/** +* Modular inversion +* @param x a positive integer +* @param modulus a positive integer +* @return y st (x*y) % modulus == 1 +*/ +BigInt BOTAN_DLL inverse_mod(const BigInt& x, + const BigInt& modulus); +/** +* Compute the Jacobi symbol. If n is prime, this is equivalent +* to the Legendre symbol. +* @see http://mathworld.wolfram.com/JacobiSymbol.html +* +* @param a is a non-negative integer +* @param n is an odd integer > 1 +* @return (n / m) +*/ +s32bit BOTAN_DLL jacobi(const BigInt& a, + const BigInt& n); + +/** +* Modular exponentation +*/ BigInt BOTAN_DLL power_mod(const BigInt&, const BigInt&, const BigInt&); -/* -* Compute the square root of x modulo a prime -* using the Shanks-Tonnelli algorithm +/** +* Compute the square root of x modulo a prime using the +* Shanks-Tonnelli algorithm +* +* @param x the input +* @param p the prime +* @return y such that (y*y)%p == x, or -1 if no such integer */ BigInt BOTAN_DLL ressol(const BigInt& x, const BigInt& p); -/* -* Utility Functions +/** +* @param x an integer +* @return count of the zero bits in x, or, equivalently, the largest +* value of n such that 2^n divides x evently */ -u32bit BOTAN_DLL low_zero_bits(const BigInt&); +u32bit BOTAN_DLL low_zero_bits(const BigInt& x); /* * Primality Testing diff --git a/src/math/numbertheory/point_gfp.h b/src/math/numbertheory/point_gfp.h index 0708493fe..5b3e32c7d 100644 --- a/src/math/numbertheory/point_gfp.h +++ b/src/math/numbertheory/point_gfp.h @@ -15,6 +15,10 @@ namespace Botan { +/** +* Exception thrown if you try to convert a zero point to an affine +* coordinate +*/ struct BOTAN_DLL Illegal_Transformation : public Exception { Illegal_Transformation(const std::string& err = @@ -22,6 +26,9 @@ struct BOTAN_DLL Illegal_Transformation : public Exception Exception(err) {} }; +/** +* Exception thrown if some form of illegal point is decoded +*/ struct BOTAN_DLL Illegal_Point : public Exception { Illegal_Point(const std::string& err = "Malformed ECP point detected") : diff --git a/src/math/numbertheory/pow_mod.h b/src/math/numbertheory/pow_mod.h index 7b92f0ec4..1a60ca05f 100644 --- a/src/math/numbertheory/pow_mod.h +++ b/src/math/numbertheory/pow_mod.h @@ -12,7 +12,7 @@ namespace Botan { -/* +/** * Modular Exponentiator Interface */ class BOTAN_DLL Modular_Exponentiator @@ -25,7 +25,7 @@ class BOTAN_DLL Modular_Exponentiator virtual ~Modular_Exponentiator() {} }; -/* +/** * Modular Exponentiator Proxy */ class BOTAN_DLL Power_Mod @@ -67,7 +67,7 @@ class BOTAN_DLL Power_Mod Usage_Hints hints; }; -/* +/** * Fixed Exponent Modular Exponentiator Proxy */ class BOTAN_DLL Fixed_Exponent_Power_Mod : public Power_Mod @@ -81,7 +81,7 @@ class BOTAN_DLL Fixed_Exponent_Power_Mod : public Power_Mod Usage_Hints = NO_HINTS); }; -/* +/** * Fixed Base Modular Exponentiator Proxy */ class BOTAN_DLL Fixed_Base_Power_Mod : public Power_Mod diff --git a/src/math/numbertheory/reducer.h b/src/math/numbertheory/reducer.h index c121f1499..861983ef0 100644 --- a/src/math/numbertheory/reducer.h +++ b/src/math/numbertheory/reducer.h @@ -12,7 +12,7 @@ namespace Botan { -/* +/** * Modular Reducer */ class BOTAN_DLL Modular_Reducer @@ -24,18 +24,25 @@ class BOTAN_DLL Modular_Reducer /** * Multiply mod p + * @param x + * @param y + * @return (x * y) % p */ BigInt multiply(const BigInt& x, const BigInt& y) const { return reduce(x * y); } /** * Square mod p + * @param x + * @return (x * x) % p */ BigInt square(const BigInt& x) const { return reduce(Botan::square(x)); } /** * Cube mod p + * @param x + * @return (x * x * x) % p */ BigInt cube(const BigInt& x) const { return multiply(x, this->square(x)); } diff --git a/src/pbe/get_pbe.h b/src/pbe/get_pbe.h index 04eda6696..73c53497c 100644 --- a/src/pbe/get_pbe.h +++ b/src/pbe/get_pbe.h @@ -16,17 +16,18 @@ namespace Botan { /** * Factory function for PBEs. * @param algo_spec the name of the PBE algorithm to retrieve -* @return a pointer to a PBE with randomly created parameters +* @return pointer to a PBE with randomly created parameters */ -BOTAN_DLL PBE* get_pbe(const std::string&); +BOTAN_DLL PBE* get_pbe(const std::string& algo_spec); /** * Factory function for PBEs. * @param pbe_oid the oid of the desired PBE * @param params a DataSource providing the DER encoded parameters to use -* @return a pointer to the PBE with the specified parameters +* @return pointer to the PBE with the specified parameters */ -BOTAN_DLL PBE* get_pbe(const OID&, DataSource&); +BOTAN_DLL PBE* get_pbe(const OID& pbe_oid, + DataSource& params); } diff --git a/src/pbe/pbes1/pbes1.cpp b/src/pbe/pbes1/pbes1.cpp index 36cfaa6b4..a3e08d679 100644 --- a/src/pbe/pbes1/pbes1.cpp +++ b/src/pbe/pbes1/pbes1.cpp @@ -93,7 +93,7 @@ void PBE_PKCS5v15::set_key(const std::string& passphrase) */ void PBE_PKCS5v15::new_params(RandomNumberGenerator& rng) { - iterations = 2048; + iterations = 10000; salt.resize(8); rng.randomize(salt, salt.size()); } diff --git a/src/pbe/pbes1/pbes1.h b/src/pbe/pbes1/pbes1.h index 2e1855dc2..d50c01f53 100644 --- a/src/pbe/pbes1/pbes1.h +++ b/src/pbe/pbes1/pbes1.h @@ -15,8 +15,8 @@ namespace Botan { -/* -* PKCS#5 v1.5 PBE +/** +* PKCS #5 v1.5 PBE */ class BOTAN_DLL PBE_PKCS5v15 : public PBE { @@ -25,9 +25,14 @@ class BOTAN_DLL PBE_PKCS5v15 : public PBE void start_msg(); void end_msg(); + /** + * @param cipher the block cipher to use (DES or RC2) + * @param hash the hash function to use + * @param direction are we encrypting or decrypting + */ PBE_PKCS5v15(BlockCipher* cipher, HashFunction* hash, - Cipher_Dir); + Cipher_Dir direction); ~PBE_PKCS5v15(); private: diff --git a/src/pbe/pbes2/pbes2.cpp b/src/pbe/pbes2/pbes2.cpp index 63772263f..1ac16af8d 100644 --- a/src/pbe/pbes2/pbes2.cpp +++ b/src/pbe/pbes2/pbes2.cpp @@ -1,4 +1,4 @@ -/** +/* * PKCS #5 PBES2 * (C) 1999-2008 Jack Lloyd * @@ -21,7 +21,7 @@ namespace Botan { -/** +/* * Encrypt some bytes using PBES2 */ void PBE_PKCS5v20::write(const byte input[], u32bit length) @@ -35,7 +35,7 @@ void PBE_PKCS5v20::write(const byte input[], u32bit length) } } -/** +/* * Start encrypting with PBES2 */ void PBE_PKCS5v20::start_msg() @@ -54,7 +54,7 @@ void PBE_PKCS5v20::start_msg() pipe.set_default_msg(pipe.default_msg() + 1); } -/** +/* * Finish encrypting with PBES2 */ void PBE_PKCS5v20::end_msg() @@ -64,7 +64,7 @@ void PBE_PKCS5v20::end_msg() pipe.reset(); } -/** +/* * Flush the pipe */ void PBE_PKCS5v20::flush_pipe(bool safe_to_skip) @@ -80,7 +80,7 @@ void PBE_PKCS5v20::flush_pipe(bool safe_to_skip) } } -/** +/* * Set the passphrase to use */ void PBE_PKCS5v20::set_key(const std::string& passphrase) @@ -92,22 +92,22 @@ void PBE_PKCS5v20::set_key(const std::string& passphrase) iterations).bits_of(); } -/** +/* * Create a new set of PBES2 parameters */ void PBE_PKCS5v20::new_params(RandomNumberGenerator& rng) { - iterations = 2048; + iterations = 10000; key_length = block_cipher->MAXIMUM_KEYLENGTH; - salt.resize(8); + salt.resize(12); rng.randomize(salt, salt.size()); iv.resize(block_cipher->BLOCK_SIZE); rng.randomize(iv, iv.size()); } -/** +/* * Encode PKCS#5 PBES2 parameters */ MemoryVector<byte> PBE_PKCS5v20::encode_params() const @@ -136,7 +136,7 @@ MemoryVector<byte> PBE_PKCS5v20::encode_params() const .get_contents(); } -/** +/* * Decode PKCS#5 PBES2 parameters */ void PBE_PKCS5v20::decode_params(DataSource& source) @@ -187,7 +187,7 @@ void PBE_PKCS5v20::decode_params(DataSource& source) throw Decoding_Error("PBE-PKCS5 v2.0: Encoded salt is too small"); } -/** +/* * Return an OID for PBES2 */ OID PBE_PKCS5v20::get_oid() const @@ -195,7 +195,7 @@ OID PBE_PKCS5v20::get_oid() const return OIDS::lookup("PBE-PKCS5v20"); } -/** +/* * Check if this is a known PBES2 cipher */ bool PBE_PKCS5v20::known_cipher(const std::string& algo) @@ -207,7 +207,7 @@ bool PBE_PKCS5v20::known_cipher(const std::string& algo) return false; } -/** +/* * PKCS#5 v2.0 PBE Constructor */ PBE_PKCS5v20::PBE_PKCS5v20(BlockCipher* cipher, @@ -220,7 +220,7 @@ PBE_PKCS5v20::PBE_PKCS5v20(BlockCipher* cipher, throw Invalid_Argument("PBE-PKCS5 v2.0: Invalid digest " + digest->name()); } -/** +/* * PKCS#5 v2.0 PBE Constructor */ PBE_PKCS5v20::PBE_PKCS5v20(DataSource& params) : direction(DECRYPTION) diff --git a/src/pbe/pbes2/pbes2.h b/src/pbe/pbes2/pbes2.h index fc460a228..f24d572d0 100644 --- a/src/pbe/pbes2/pbes2.h +++ b/src/pbe/pbes2/pbes2.h @@ -15,20 +15,33 @@ namespace Botan { -/* -* PKCS#5 v2.0 PBE +/** +* PKCS #5 v2.0 PBE */ class BOTAN_DLL PBE_PKCS5v20 : public PBE { public: - static bool known_cipher(const std::string&); + /** + * @param cipher names a block cipher + * @return true iff PKCS #5 knows how to use this cipher + */ + static bool known_cipher(const std::string& cipher); void write(const byte[], u32bit); void start_msg(); void end_msg(); - PBE_PKCS5v20(DataSource&); - PBE_PKCS5v20(BlockCipher*, HashFunction*); + /** + * Load a PKCS #5 v2.0 encrypted stream + * @param input is the input source + */ + PBE_PKCS5v20(DataSource& input); + + /** + * @param cipher the block cipher to use + * @param hash the hash function to use + */ + PBE_PKCS5v20(BlockCipher* cipher, HashFunction* hash); ~PBE_PKCS5v20(); private: diff --git a/src/pk_pad/eme.h b/src/pk_pad/eme.h index 321c1d01e..02b8208ef 100644 --- a/src/pk_pad/eme.h +++ b/src/pk_pad/eme.h @@ -13,7 +13,7 @@ namespace Botan { -/* +/** * Encoding Method for Encryption */ class BOTAN_DLL EME diff --git a/src/pk_pad/eme1/eme1.h b/src/pk_pad/eme1/eme1.h index 4df5c5f1c..d00eeeeb9 100644 --- a/src/pk_pad/eme1/eme1.h +++ b/src/pk_pad/eme1/eme1.h @@ -14,8 +14,8 @@ namespace Botan { -/* -* EME1 +/** +* EME1, aka OAEP */ class BOTAN_DLL EME1 : public EME { diff --git a/src/pk_pad/eme_pkcs/eme_pkcs.h b/src/pk_pad/eme_pkcs/eme_pkcs.h index 1aeedf5d7..450d668d7 100644 --- a/src/pk_pad/eme_pkcs/eme_pkcs.h +++ b/src/pk_pad/eme_pkcs/eme_pkcs.h @@ -12,8 +12,8 @@ namespace Botan { -/* -* EME_PKCS1v15 +/** +* EME from PKCS #1 v1.5 */ class BOTAN_DLL EME_PKCS1v15 : public EME { diff --git a/src/pk_pad/emsa.h b/src/pk_pad/emsa.h index 8b19d3cb2..6d01beb7f 100644 --- a/src/pk_pad/emsa.h +++ b/src/pk_pad/emsa.h @@ -13,7 +13,7 @@ namespace Botan { -/* +/** * Encoding Method for Signatures, Appendix */ class BOTAN_DLL EMSA diff --git a/src/pk_pad/emsa1/emsa1.h b/src/pk_pad/emsa1/emsa1.h index d86020966..28d856525 100644 --- a/src/pk_pad/emsa1/emsa1.h +++ b/src/pk_pad/emsa1/emsa1.h @@ -13,8 +13,9 @@ namespace Botan { -/* -* EMSA1 +/** +* EMSA1 from IEEE 1363 +* Essentially, sign the hash directly */ class BOTAN_DLL EMSA1 : public EMSA { diff --git a/src/pk_pad/emsa2/emsa2.h b/src/pk_pad/emsa2/emsa2.h index 7efc80873..bda34fbd1 100644 --- a/src/pk_pad/emsa2/emsa2.h +++ b/src/pk_pad/emsa2/emsa2.h @@ -13,8 +13,9 @@ namespace Botan { -/* -* EMSA2 +/** +* EMSA2 from IEEE 1363 +* Useful for Rabin-Williams */ class BOTAN_DLL EMSA2 : public EMSA { diff --git a/src/pk_pad/emsa3/emsa3.h b/src/pk_pad/emsa3/emsa3.h index c4a3d658b..1e080aab6 100644 --- a/src/pk_pad/emsa3/emsa3.h +++ b/src/pk_pad/emsa3/emsa3.h @@ -14,7 +14,7 @@ namespace Botan { /** -* EMSA3 +* EMSA3 from IEEE 1363 * aka PKCS #1 v1.5 signature padding * aka PKCS #1 block type 1 */ diff --git a/src/pk_pad/emsa4/emsa4.h b/src/pk_pad/emsa4/emsa4.h index 9e37684f5..6315c424e 100644 --- a/src/pk_pad/emsa4/emsa4.h +++ b/src/pk_pad/emsa4/emsa4.h @@ -14,8 +14,8 @@ namespace Botan { -/* -* EMSA4 +/** +* EMSA4 aka PSS-R */ class BOTAN_DLL EMSA4 : public EMSA { diff --git a/src/pk_pad/emsa_raw/emsa_raw.h b/src/pk_pad/emsa_raw/emsa_raw.h index 5f2eaa2fe..ab27877a6 100644 --- a/src/pk_pad/emsa_raw/emsa_raw.h +++ b/src/pk_pad/emsa_raw/emsa_raw.h @@ -12,8 +12,9 @@ namespace Botan { -/* -* EMSA-Raw +/** +* EMSA-Raw - sign inputs directly +* Don't use this unless you know what you are doing. */ class BOTAN_DLL EMSA_Raw : public EMSA { diff --git a/src/pk_pad/hash_id/hash_id.cpp b/src/pk_pad/hash_id/hash_id.cpp index c83ad87ac..203c27f14 100644 --- a/src/pk_pad/hash_id/hash_id.cpp +++ b/src/pk_pad/hash_id/hash_id.cpp @@ -10,45 +10,45 @@ namespace Botan { -namespace PKCS_IDS { +namespace { -const byte MD2_ID[] = { +const byte MD2_PKCS_ID[] = { 0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x02, 0x05, 0x00, 0x04, 0x10 }; -const byte MD5_ID[] = { +const byte MD5_PKCS_ID[] = { 0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10 }; -const byte RIPEMD_128_ID[] = { +const byte RIPEMD_128_PKCS_ID[] = { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x24, 0x03, 0x02, 0x02, 0x05, 0x00, 0x04, 0x14 }; -const byte RIPEMD_160_ID[] = { +const byte RIPEMD_160_PKCS_ID[] = { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x24, 0x03, 0x02, 0x01, 0x05, 0x00, 0x04, 0x14 }; -const byte SHA_160_ID[] = { +const byte SHA_160_PKCS_ID[] = { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14 }; -const byte SHA_224_ID[] = { +const byte SHA_224_PKCS_ID[] = { 0x30, 0x2D, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1C }; -const byte SHA_256_ID[] = { +const byte SHA_256_PKCS_ID[] = { 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 }; -const byte SHA_384_ID[] = { +const byte SHA_384_PKCS_ID[] = { 0x30, 0x41, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30 }; -const byte SHA_512_ID[] = { +const byte SHA_512_PKCS_ID[] = { 0x30, 0x51, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40 }; -const byte TIGER_ID[] = { +const byte TIGER_PKCS_ID[] = { 0x30, 0x29, 0x30, 0x0D, 0x06, 0x09, 0x2B, 0x06, 0x01, 0x04, 0x01, 0xDA, 0x47, 0x0C, 0x02, 0x05, 0x00, 0x04, 0x18 }; @@ -63,29 +63,30 @@ MemoryVector<byte> pkcs_hash_id(const std::string& name) { MemoryVector<byte> out; + // Special case for SSL/TLS RSA signatures if(name == "Parallel(MD5,SHA-160)") return out; if(name == "MD2") - out.set(PKCS_IDS::MD2_ID, sizeof(PKCS_IDS::MD2_ID)); + out.set(MD2_PKCS_ID, sizeof(MD2_PKCS_ID)); else if(name == "MD5") - out.set(PKCS_IDS::MD5_ID, sizeof(PKCS_IDS::MD5_ID)); + out.set(MD5_PKCS_ID, sizeof(MD5_PKCS_ID)); else if(name == "RIPEMD-128") - out.set(PKCS_IDS::RIPEMD_128_ID, sizeof(PKCS_IDS::RIPEMD_128_ID)); + out.set(RIPEMD_128_PKCS_ID, sizeof(RIPEMD_128_PKCS_ID)); else if(name == "RIPEMD-160") - out.set(PKCS_IDS::RIPEMD_160_ID, sizeof(PKCS_IDS::RIPEMD_160_ID)); + out.set(RIPEMD_160_PKCS_ID, sizeof(RIPEMD_160_PKCS_ID)); else if(name == "SHA-160") - out.set(PKCS_IDS::SHA_160_ID, sizeof(PKCS_IDS::SHA_160_ID)); + out.set(SHA_160_PKCS_ID, sizeof(SHA_160_PKCS_ID)); else if(name == "SHA-224") - out.set(PKCS_IDS::SHA_224_ID, sizeof(PKCS_IDS::SHA_224_ID)); + out.set(SHA_224_PKCS_ID, sizeof(SHA_224_PKCS_ID)); else if(name == "SHA-256") - out.set(PKCS_IDS::SHA_256_ID, sizeof(PKCS_IDS::SHA_256_ID)); + out.set(SHA_256_PKCS_ID, sizeof(SHA_256_PKCS_ID)); else if(name == "SHA-384") - out.set(PKCS_IDS::SHA_384_ID, sizeof(PKCS_IDS::SHA_384_ID)); + out.set(SHA_384_PKCS_ID, sizeof(SHA_384_PKCS_ID)); else if(name == "SHA-512") - out.set(PKCS_IDS::SHA_512_ID, sizeof(PKCS_IDS::SHA_512_ID)); + out.set(SHA_512_PKCS_ID, sizeof(SHA_512_PKCS_ID)); else if(name == "Tiger(24,3)") - out.set(PKCS_IDS::TIGER_ID, sizeof(PKCS_IDS::TIGER_ID)); + out.set(TIGER_PKCS_ID, sizeof(TIGER_PKCS_ID)); if(out.size()) return out; diff --git a/src/pubkey/blinding.h b/src/pubkey/blinding.h index 03c9043dd..712030e4d 100644 --- a/src/pubkey/blinding.h +++ b/src/pubkey/blinding.h @@ -13,7 +13,7 @@ namespace Botan { -/* +/** * Blinding Function Object */ class BOTAN_DLL Blinder diff --git a/src/pubkey/dh/dh.h b/src/pubkey/dh/dh.h index 738b3f9c4..88b57922d 100644 --- a/src/pubkey/dh/dh.h +++ b/src/pubkey/dh/dh.h @@ -56,7 +56,7 @@ class BOTAN_DLL DH_PrivateKey : public DH_PublicKey, * Load a DH private key * @param alg_id the algorithm id * @param key_bits the subject public key - * @rng a random number generator + * @param rng a random number generator */ DH_PrivateKey(const AlgorithmIdentifier& alg_id, const MemoryRegion<byte>& key_bits, diff --git a/src/pubkey/dl_algo/dl_algo.h b/src/pubkey/dl_algo/dl_algo.h index 445f6c3f9..429bfb554 100644 --- a/src/pubkey/dl_algo/dl_algo.h +++ b/src/pubkey/dl_algo/dl_algo.h @@ -28,7 +28,7 @@ class BOTAN_DLL DL_Scheme_PublicKey : public virtual Public_Key /** * Get the DL domain parameters of this key. - * @return the DL domain parameters of this key + * @return DL domain parameters of this key */ const DL_Group& get_domain() const { return group; } @@ -39,25 +39,25 @@ class BOTAN_DLL DL_Scheme_PublicKey : public virtual Public_Key /** * Get the prime p of the underlying DL group. - * @return the prime p + * @return prime p */ const BigInt& group_p() const { return group.get_p(); } /** * Get the prime q of the underlying DL group. - * @return the prime q + * @return prime q */ const BigInt& group_q() const { return group.get_q(); } /** * Get the generator g of the underlying DL group. - * @return the generator g + * @return generator g */ const BigInt& group_g() const { return group.get_g(); } /** * Get the underlying groups encoding format. - * @return the encoding format + * @return encoding format */ virtual DL_Group::Format group_format() const = 0; @@ -82,7 +82,7 @@ class BOTAN_DLL DL_Scheme_PrivateKey : public virtual DL_Scheme_PublicKey, /** * Get the secret key x. - * @return the secret key + * @return secret key */ const BigInt& get_x() const { return x; } diff --git a/src/pubkey/dl_group/dl_group.cpp b/src/pubkey/dl_group/dl_group.cpp index 22c72480e..cd75e5796 100644 --- a/src/pubkey/dl_group/dl_group.cpp +++ b/src/pubkey/dl_group/dl_group.cpp @@ -55,31 +55,32 @@ DL_Group::DL_Group(RandomNumberGenerator& rng, q = (p - 1) / 2; g = 2; } - else if(type == Prime_Subgroup || type == DSA_Kosherizer) + else if(type == Prime_Subgroup) { - if(type == Prime_Subgroup) - { - if(!qbits) - qbits = 2 * dl_work_factor(pbits); - - q = random_prime(rng, qbits); - BigInt X; - while(p.bits() != pbits || !check_prime(p, rng)) - { - X.randomize(rng, pbits); - p = X - (X % (2*q) - 1); - } - } - else + if(!qbits) + qbits = 2 * dl_work_factor(pbits); + + q = random_prime(rng, qbits); + BigInt X; + while(p.bits() != pbits || !check_prime(p, rng)) { - qbits = qbits ? qbits : ((pbits == 1024) ? 160 : 256); - generate_dsa_primes(rng, - global_state().algorithm_factory(), - p, q, pbits, qbits); + X.randomize(rng, pbits); + p = X - (X % (2*q) - 1); } g = make_dsa_generator(p, q); } + else if(type == DSA_Kosherizer) + { + qbits = qbits ? qbits : ((pbits <= 1024) ? 160 : 256); + + generate_dsa_primes(rng, + global_state().algorithm_factory(), + p, q, + pbits, qbits); + + g = make_dsa_generator(p, q); + } initialized = true; } diff --git a/src/pubkey/dl_group/dl_group.h b/src/pubkey/dl_group/dl_group.h index a84a85f87..885ccd2f9 100644 --- a/src/pubkey/dl_group/dl_group.h +++ b/src/pubkey/dl_group/dl_group.h @@ -22,19 +22,19 @@ class BOTAN_DLL DL_Group public: /** * Get the prime p. - * @return the prime p + * @return prime p */ const BigInt& get_p() const; /** * Get the prime q. - * @return the prime q + * @return prime q */ const BigInt& get_q() const; /** * Get the base g. - * @return the base g + * @return base g */ const BigInt& get_g() const; @@ -68,14 +68,14 @@ class BOTAN_DLL DL_Group /** * Encode this group into a string using PEM encoding. * @param format the encoding format - * @return the string holding the PEM encoded group + * @return string holding the PEM encoded group */ std::string PEM_encode(Format format) const; /** * Encode this group into a string using DER encoding. * @param format the encoding format - * @return the string holding the DER encoded group + * @return string holding the DER encoded group */ SecureVector<byte> DER_encode(Format format) const; diff --git a/src/pubkey/dlies/dlies.h b/src/pubkey/dlies/dlies.h index fd2cefe4a..ad8f36b40 100644 --- a/src/pubkey/dlies/dlies.h +++ b/src/pubkey/dlies/dlies.h @@ -14,7 +14,7 @@ namespace Botan { -/* +/** * DLIES Encryption */ class BOTAN_DLL DLIES_Encryptor : public PK_Encryptor @@ -41,7 +41,7 @@ class BOTAN_DLL DLIES_Encryptor : public PK_Encryptor u32bit mac_keylen; }; -/* +/** * DLIES Decryption */ class BOTAN_DLL DLIES_Decryptor : public PK_Decryptor diff --git a/src/pubkey/dsa/dsa.h b/src/pubkey/dsa/dsa.h index 8121cfbbc..65b6edd98 100644 --- a/src/pubkey/dsa/dsa.h +++ b/src/pubkey/dsa/dsa.h @@ -15,7 +15,7 @@ namespace Botan { -/* +/** * DSA Public Key */ class BOTAN_DLL DSA_PublicKey : public virtual DL_Scheme_PublicKey @@ -39,7 +39,7 @@ class BOTAN_DLL DSA_PublicKey : public virtual DL_Scheme_PublicKey DSA_PublicKey() {} }; -/* +/** * DSA Private Key */ class BOTAN_DLL DSA_PrivateKey : public DSA_PublicKey, @@ -57,6 +57,9 @@ class BOTAN_DLL DSA_PrivateKey : public DSA_PublicKey, bool check_key(RandomNumberGenerator& rng, bool strong) const; }; +/** +* Object that can create a DSA signature +*/ class BOTAN_DLL DSA_Signature_Operation : public PK_Ops::Signature { public: @@ -75,6 +78,9 @@ class BOTAN_DLL DSA_Signature_Operation : public PK_Ops::Signature Modular_Reducer mod_q; }; +/** +* Object that can verify a DSA signature +*/ class BOTAN_DLL DSA_Verification_Operation : public PK_Ops::Verification { public: diff --git a/src/pubkey/ec_dompar/ec_dompar.h b/src/pubkey/ec_dompar/ec_dompar.h index 15143373a..546624bf6 100644 --- a/src/pubkey/ec_dompar/ec_dompar.h +++ b/src/pubkey/ec_dompar/ec_dompar.h @@ -25,6 +25,9 @@ enum EC_Domain_Params_Encoding { EC_DOMPAR_ENC_OID = 2 }; +/** +* Class representing an elliptic curve +*/ class BOTAN_DLL EC_Domain_Params { public: diff --git a/src/pubkey/ecc_key/ecc_key.cpp b/src/pubkey/ecc_key/ecc_key.cpp index 2c66dc97f..4f90fa321 100644 --- a/src/pubkey/ecc_key/ecc_key.cpp +++ b/src/pubkey/ecc_key/ecc_key.cpp @@ -24,9 +24,6 @@ EC_PublicKey::EC_PublicKey(const EC_Domain_Params& dom_par, { if(domain().get_curve() != public_point().get_curve()) throw Invalid_Argument("EC_PublicKey: curve mismatch in constructor"); - - if(!public_point().on_the_curve()) - throw Invalid_State("Public key was not on the curve"); } EC_PublicKey::EC_PublicKey(const AlgorithmIdentifier& alg_id, @@ -38,6 +35,12 @@ EC_PublicKey::EC_PublicKey(const AlgorithmIdentifier& alg_id, public_key = OS2ECP(key_bits, domain().get_curve()); } +bool EC_PublicKey::check_key(RandomNumberGenerator&, + bool) const + { + return public_point().on_the_curve(); + } + AlgorithmIdentifier EC_PublicKey::algorithm_identifier() const { return AlgorithmIdentifier(get_oid(), DER_domain()); diff --git a/src/pubkey/ecc_key/ecc_key.h b/src/pubkey/ecc_key/ecc_key.h index 92f02613c..8155543da 100644 --- a/src/pubkey/ecc_key/ecc_key.h +++ b/src/pubkey/ecc_key/ecc_key.h @@ -49,6 +49,9 @@ class BOTAN_DLL EC_PublicKey : public virtual Public_Key MemoryVector<byte> x509_subject_public_key() const; + bool check_key(RandomNumberGenerator& rng, + bool strong) const; + /** * Get the domain parameters of this key. * @throw Invalid_State is thrown if the diff --git a/src/pubkey/ecdh/ecdh.h b/src/pubkey/ecdh/ecdh.h index 19621f2ca..f0872c5cc 100644 --- a/src/pubkey/ecdh/ecdh.h +++ b/src/pubkey/ecdh/ecdh.h @@ -46,12 +46,12 @@ class BOTAN_DLL ECDH_PublicKey : public virtual EC_PublicKey * Get the maximum number of bits allowed to be fed to this key. * This is the bitlength of the order of the base point. - * @return the maximum number of input bits + * @return maximum number of input bits */ u32bit max_input_bits() const { return domain().get_order().bits(); } /** - * @return the public point value + * @return public point value */ MemoryVector<byte> public_value() const { return EC2OSP(public_point(), PointGFp::UNCOMPRESSED); } @@ -75,7 +75,8 @@ class BOTAN_DLL ECDH_PrivateKey : public ECDH_PublicKey, /** * Generate a new private key - * @param the domain parameters to used for this key + * @param rng a random number generator + * @param domain parameters to used for this key */ ECDH_PrivateKey(RandomNumberGenerator& rng, const EC_Domain_Params& domain) : diff --git a/src/pubkey/ecdsa/ecdsa.h b/src/pubkey/ecdsa/ecdsa.h index 62bd007f9..7e7d85ab8 100644 --- a/src/pubkey/ecdsa/ecdsa.h +++ b/src/pubkey/ecdsa/ecdsa.h @@ -72,7 +72,8 @@ class BOTAN_DLL ECDSA_PrivateKey : public ECDSA_PublicKey, /** * Generate a new private key - * @param the domain parameters to used for this key + * @param rng a random number generator + * @param domain parameters to used for this key */ ECDSA_PrivateKey(RandomNumberGenerator& rng, const EC_Domain_Params& domain) : @@ -83,12 +84,16 @@ class BOTAN_DLL ECDSA_PrivateKey : public ECDSA_PublicKey, * @param domain parameters * @param x the private key */ - ECDSA_PrivateKey(const EC_Domain_Params& domain, const BigInt& x) : + ECDSA_PrivateKey(const EC_Domain_Params& domain, + const BigInt& x) : EC_PrivateKey(domain, x) {} bool check_key(RandomNumberGenerator& rng, bool) const; }; +/** +* ECDSA signature operation +*/ class BOTAN_DLL ECDSA_Signature_Operation : public PK_Ops::Signature { public: @@ -108,6 +113,9 @@ class BOTAN_DLL ECDSA_Signature_Operation : public PK_Ops::Signature Modular_Reducer mod_order; }; +/** +* ECDSA verification operation +*/ class BOTAN_DLL ECDSA_Verification_Operation : public PK_Ops::Verification { public: diff --git a/src/pubkey/elgamal/elgamal.h b/src/pubkey/elgamal/elgamal.h index 143b417ec..f9b52c7b8 100644 --- a/src/pubkey/elgamal/elgamal.h +++ b/src/pubkey/elgamal/elgamal.h @@ -16,7 +16,7 @@ namespace Botan { -/* +/** * ElGamal Public Key */ class BOTAN_DLL ElGamal_PublicKey : public virtual DL_Scheme_PublicKey @@ -37,7 +37,7 @@ class BOTAN_DLL ElGamal_PublicKey : public virtual DL_Scheme_PublicKey ElGamal_PublicKey() {} }; -/* +/** * ElGamal Private Key */ class BOTAN_DLL ElGamal_PrivateKey : public ElGamal_PublicKey, @@ -55,6 +55,9 @@ class BOTAN_DLL ElGamal_PrivateKey : public ElGamal_PublicKey, const BigInt& priv_key = 0); }; +/** +* ElGamal encryption operation +*/ class BOTAN_DLL ElGamal_Encryption_Operation : public PK_Ops::Encryption { public: @@ -70,6 +73,9 @@ class BOTAN_DLL ElGamal_Encryption_Operation : public PK_Ops::Encryption Modular_Reducer mod_p; }; +/** +* ElGamal decryption operation +*/ class BOTAN_DLL ElGamal_Decryption_Operation : public PK_Ops::Decryption { public: diff --git a/src/pubkey/gost_3410/gost_3410.h b/src/pubkey/gost_3410/gost_3410.h index 36fa2912d..9d6a15386 100644 --- a/src/pubkey/gost_3410/gost_3410.h +++ b/src/pubkey/gost_3410/gost_3410.h @@ -16,7 +16,7 @@ namespace Botan { /** -* This class represents GOST_3410 Public Keys. +* GOST-34.10 Public Key */ class BOTAN_DLL GOST_3410_PublicKey : public virtual EC_PublicKey { @@ -65,7 +65,7 @@ class BOTAN_DLL GOST_3410_PublicKey : public virtual EC_PublicKey }; /** -* This class represents GOST_3410 Private Keys +* GOST-34.10 Private Key */ class BOTAN_DLL GOST_3410_PrivateKey : public GOST_3410_PublicKey, public EC_PrivateKey @@ -78,7 +78,8 @@ class BOTAN_DLL GOST_3410_PrivateKey : public GOST_3410_PublicKey, /** * Generate a new private key - * @param the domain parameters to used for this key + * @param rng a random number generator + * @param domain parameters to used for this key */ GOST_3410_PrivateKey(RandomNumberGenerator& rng, const EC_Domain_Params& domain) : @@ -96,6 +97,9 @@ class BOTAN_DLL GOST_3410_PrivateKey : public GOST_3410_PublicKey, { return EC_PublicKey::algorithm_identifier(); } }; +/** +* GOST-34.10 signature operation +*/ class BOTAN_DLL GOST_3410_Signature_Operation : public PK_Ops::Signature { public: @@ -114,6 +118,9 @@ class BOTAN_DLL GOST_3410_Signature_Operation : public PK_Ops::Signature const BigInt& x; }; +/** +* GOST-34.10 verification operation +*/ class BOTAN_DLL GOST_3410_Verification_Operation : public PK_Ops::Verification { public: diff --git a/src/pubkey/if_algo/if_algo.h b/src/pubkey/if_algo/if_algo.h index 764a99e13..d0a1ec197 100644 --- a/src/pubkey/if_algo/if_algo.h +++ b/src/pubkey/if_algo/if_algo.h @@ -34,12 +34,12 @@ class BOTAN_DLL IF_Scheme_PublicKey : public virtual Public_Key MemoryVector<byte> x509_subject_public_key() const; /** - * @return the public modulus + * @return public modulus */ const BigInt& get_n() const { return n; } /** - * @return the public exponent + * @return public exponent */ const BigInt& get_e() const { return e; } @@ -73,13 +73,13 @@ class BOTAN_DLL IF_Scheme_PrivateKey : public virtual IF_Scheme_PublicKey, /** * Get the first prime p. - * @return the prime p + * @return prime p */ const BigInt& get_p() const { return p; } /** * Get the second prime q. - * @return the prime q + * @return prime q */ const BigInt& get_q() const { return q; } diff --git a/src/pubkey/nr/nr.h b/src/pubkey/nr/nr.h index bd125ab92..cd12001ad 100644 --- a/src/pubkey/nr/nr.h +++ b/src/pubkey/nr/nr.h @@ -15,7 +15,7 @@ namespace Botan { -/* +/** * Nyberg-Rueppel Public Key */ class BOTAN_DLL NR_PublicKey : public virtual DL_Scheme_PublicKey @@ -37,7 +37,7 @@ class BOTAN_DLL NR_PublicKey : public virtual DL_Scheme_PublicKey NR_PublicKey() {} }; -/* +/** * Nyberg-Rueppel Private Key */ class BOTAN_DLL NR_PrivateKey : public NR_PublicKey, @@ -55,6 +55,9 @@ class BOTAN_DLL NR_PrivateKey : public NR_PublicKey, const BigInt& x = 0); }; +/** +* Nyberg-Rueppel signature operation +*/ class BOTAN_DLL NR_Signature_Operation : public PK_Ops::Signature { public: @@ -73,6 +76,9 @@ class BOTAN_DLL NR_Signature_Operation : public PK_Ops::Signature Modular_Reducer mod_q; }; +/** +* Nyberg-Rueppel verification operation +*/ class BOTAN_DLL NR_Verification_Operation : public PK_Ops::Verification { public: diff --git a/src/pubkey/pk_keys.cpp b/src/pubkey/pk_keys.cpp index b93158558..c19c676ab 100644 --- a/src/pubkey/pk_keys.cpp +++ b/src/pubkey/pk_keys.cpp @@ -6,6 +6,7 @@ */ #include <botan/pk_keys.h> +#include <botan/der_enc.h> #include <botan/oids.h> namespace Botan { diff --git a/src/pubkey/pk_keys.h b/src/pubkey/pk_keys.h index da73db0ee..8f086c617 100644 --- a/src/pubkey/pk_keys.h +++ b/src/pubkey/pk_keys.h @@ -23,13 +23,13 @@ class BOTAN_DLL Public_Key public: /** * Get the name of the underlying public key scheme. - * @return the name of the public key scheme + * @return name of the public key scheme */ virtual std::string algo_name() const = 0; /** * Get the OID of the underlying public key scheme. - * @return the OID of the public key scheme + * @return OID of the public key scheme */ virtual OID get_oid() const; @@ -40,24 +40,24 @@ class BOTAN_DLL Public_Key * of the test * @return true if the test is passed */ - virtual bool check_key(RandomNumberGenerator&, bool) const - { return true; } + virtual bool check_key(RandomNumberGenerator& rng, + bool strong) const = 0; /** * Find out the number of message parts supported by this scheme. - * @return the number of message parts + * @return number of message parts */ virtual u32bit message_parts() const { return 1; } /** * Find out the message part size supported by this scheme/key. - * @return the size of the message parts + * @return size of the message parts in bits */ virtual u32bit message_part_size() const { return 0; } /** * Get the maximum message size in bits supported by this public key. - * @return the maximum message in bits + * @return maximum message size in bits */ virtual u32bit max_input_bits() const = 0; @@ -73,7 +73,11 @@ class BOTAN_DLL Public_Key virtual ~Public_Key() {} protected: - virtual void load_check(RandomNumberGenerator&) const; + /** + * Self-test after loading a key + * @param rng a random number generator + */ + virtual void load_check(RandomNumberGenerator& rng) const; }; /** @@ -95,8 +99,17 @@ class BOTAN_DLL Private_Key : public virtual Public_Key { return algorithm_identifier(); } protected: - void load_check(RandomNumberGenerator&) const; - void gen_check(RandomNumberGenerator&) const; + /** + * Self-test after loading a key + * @param rng a random number generator + */ + void load_check(RandomNumberGenerator& rng) const; + + /** + * Self-test after generating a key + * @param rng a random number generator + */ + void gen_check(RandomNumberGenerator& rng) const; }; /** @@ -105,6 +118,9 @@ class BOTAN_DLL Private_Key : public virtual Public_Key class BOTAN_DLL PK_Key_Agreement_Key : public virtual Private_Key { public: + /* + * @return public component of this key + */ virtual MemoryVector<byte> public_value() const = 0; virtual ~PK_Key_Agreement_Key() {} diff --git a/src/pubkey/pk_ops.h b/src/pubkey/pk_ops.h index 97ba372c2..b15a8d8cd 100644 --- a/src/pubkey/pk_ops.h +++ b/src/pubkey/pk_ops.h @@ -15,6 +15,9 @@ namespace Botan { namespace PK_Ops { +/** +* Public key encryption interface +*/ class BOTAN_DLL Encryption { public: @@ -26,6 +29,9 @@ class BOTAN_DLL Encryption virtual ~Encryption() {} }; +/** +* Public key decryption interface +*/ class BOTAN_DLL Decryption { public: @@ -37,24 +43,27 @@ class BOTAN_DLL Decryption virtual ~Decryption() {} }; +/** +* Public key signature creation interface +*/ class BOTAN_DLL Signature { public: /** * Find out the number of message parts supported by this scheme. - * @return the number of message parts + * @return number of message parts */ virtual u32bit message_parts() const { return 1; } /** * Find out the message part size supported by this scheme/key. - * @return the size of the message parts + * @return size of the message parts */ virtual u32bit message_part_size() const { return 0; } /** * Get the maximum message size in bits supported by this public key. - * @return the maximum message in bits + * @return maximum message in bits */ virtual u32bit max_input_bits() const = 0; @@ -70,24 +79,27 @@ class BOTAN_DLL Signature virtual ~Signature() {} }; +/** +* Public key signature verification interface +*/ class BOTAN_DLL Verification { public: /** * Get the maximum message size in bits supported by this public key. - * @return the maximum message in bits + * @return maximum message in bits */ virtual u32bit max_input_bits() const = 0; /** * Find out the number of message parts supported by this scheme. - * @return the number of message parts + * @return number of message parts */ virtual u32bit message_parts() const { return 1; } /** * Find out the message part size supported by this scheme/key. - * @return the size of the message parts + * @return size of the message parts */ virtual u32bit message_part_size() const { return 0; } @@ -127,8 +139,8 @@ class BOTAN_DLL Verification virtual ~Verification() {} }; -/* -* A generic Key Agreement Operation (eg DH or ECDH) +/** +* A generic key agreement Operation (eg DH or ECDH) */ class BOTAN_DLL Key_Agreement { diff --git a/src/pubkey/pkcs8.cpp b/src/pubkey/pkcs8.cpp index 7353be42f..7d9c0d834 100644 --- a/src/pubkey/pkcs8.cpp +++ b/src/pubkey/pkcs8.cpp @@ -129,43 +129,39 @@ SecureVector<byte> PKCS8_decode(DataSource& source, const User_Interface& ui, } /* -* DER or PEM encode a PKCS #8 private key +* BER encode a PKCS #8 private key, unencrypted */ -void encode(const Private_Key& key, Pipe& pipe, X509_Encoding encoding) +SecureVector<byte> BER_encode(const Private_Key& key) { const u32bit PKCS8_VERSION = 0; - SecureVector<byte> contents = - DER_Encoder() + return DER_Encoder() .start_cons(SEQUENCE) .encode(PKCS8_VERSION) .encode(key.pkcs8_algorithm_identifier()) .encode(key.pkcs8_private_key(), OCTET_STRING) .end_cons() .get_contents(); + } - if(encoding == PEM) - pipe.write(PEM_Code::encode(contents, "PRIVATE KEY")); - else - pipe.write(contents); +/* +* PEM encode a PKCS #8 private key, unencrypted +*/ +std::string PEM_encode(const Private_Key& key) + { + return PEM_Code::encode(PKCS8::BER_encode(key), "PRIVATE KEY"); } /* -* Encode and encrypt a PKCS #8 private key +* BER encode a PKCS #8 private key, encrypted */ -void encrypt_key(const Private_Key& key, - Pipe& pipe, - RandomNumberGenerator& rng, - const std::string& pass, const std::string& pbe_algo, - X509_Encoding encoding) +SecureVector<byte> BER_encode(const Private_Key& key, + RandomNumberGenerator& rng, + const std::string& pass, + const std::string& pbe_algo) { const std::string DEFAULT_PBE = "PBE-PKCS5v20(SHA-1,AES-128/CBC)"; - Pipe raw_key; - raw_key.start_msg(); - encode(key, raw_key, RAW_BER); - raw_key.end_msg(); - std::unique_ptr<PBE> pbe(get_pbe(((pbe_algo != "") ? pbe_algo : DEFAULT_PBE))); pbe->new_params(rng); @@ -174,36 +170,18 @@ void encrypt_key(const Private_Key& key, AlgorithmIdentifier pbe_algid(pbe->get_oid(), pbe->encode_params()); Pipe key_encrytor(pbe.release()); - key_encrytor.process_msg(raw_key); + key_encrytor.process_msg(PKCS8::BER_encode(key)); - SecureVector<byte> enc_key = - DER_Encoder() + return DER_Encoder() .start_cons(SEQUENCE) .encode(pbe_algid) .encode(key_encrytor.read_all(), OCTET_STRING) .end_cons() .get_contents(); - - if(encoding == PEM) - pipe.write(PEM_Code::encode(enc_key, "ENCRYPTED PRIVATE KEY")); - else - pipe.write(enc_key); } /* -* PEM encode a PKCS #8 private key -*/ -std::string PEM_encode(const Private_Key& key) - { - Pipe pem; - pem.start_msg(); - encode(key, pem, PEM); - pem.end_msg(); - return pem.read_all_as_string(); - } - -/* -* Encrypt and PEM encode a PKCS #8 private key +* PEM encode a PKCS #8 private key, encrypted */ std::string PEM_encode(const Private_Key& key, RandomNumberGenerator& rng, @@ -213,11 +191,8 @@ std::string PEM_encode(const Private_Key& key, if(pass == "") return PEM_encode(key); - Pipe pem; - pem.start_msg(); - encrypt_key(key, pem, rng, pass, pbe_algo, PEM); - pem.end_msg(); - return pem.read_all_as_string(); + return PEM_Code::encode(PKCS8::BER_encode(key, rng, pass, pbe_algo), + "ENCRYPTED PRIVATE KEY"); } /* @@ -275,13 +250,7 @@ Private_Key* load_key(const std::string& fsname, Private_Key* copy_key(const Private_Key& key, RandomNumberGenerator& rng) { - Pipe bits; - - bits.start_msg(); - PKCS8::encode(key, bits); - bits.end_msg(); - - DataSource_Memory source(bits.read_all()); + DataSource_Memory source(PEM_encode(key)); return PKCS8::load_key(source, rng); } diff --git a/src/pubkey/pkcs8.h b/src/pubkey/pkcs8.h index 920f8c24a..3da96d840 100644 --- a/src/pubkey/pkcs8.h +++ b/src/pubkey/pkcs8.h @@ -25,38 +25,33 @@ struct BOTAN_DLL PKCS8_Exception : public Decoding_Error namespace PKCS8 { /** -* Encode a private key into a pipe. +* BER encode a private key * @param key the private key to encode -* @param pipe the pipe to feed the encoded key into -* @param enc the encoding type to use +* @return BER encoded key */ -BOTAN_DLL void encode(const Private_Key& key, Pipe& pipe, - X509_Encoding enc = PEM); +BOTAN_DLL SecureVector<byte> BER_encode(const Private_Key& key); /** -* Encode and encrypt a private key into a pipe. -* @param key the private key to encode -* @param pipe the pipe to feed the encoded key into -* @param pass the password to use for encryption -* @param rng the rng to use -* @param pbe_algo the name of the desired password-based encryption algorithm; - if empty ("") a reasonable (portable/secure) default will be chosen. -* @param enc the encoding type to use +* Get a string containing a PEM encoded private key. +* @param key the key to encode +* @return encoded key */ -BOTAN_DLL void encrypt_key(const Private_Key& key, - Pipe& pipe, - RandomNumberGenerator& rng, - const std::string& pass, - const std::string& pbe_algo = "", - X509_Encoding enc = PEM); - +BOTAN_DLL std::string PEM_encode(const Private_Key& key); /** -* Get a string containing a PEM encoded private key. +* Encrypt a key using PKCS #8 encryption * @param key the key to encode -* @return the encoded key +* @param rng the rng to use +* @param pass the password to use for encryption +* @param pbe_algo the name of the desired password-based encryption + algorithm; if empty ("") a reasonable (portable/secure) + default will be chosen. +* @return encrypted key in binary BER form */ -BOTAN_DLL std::string PEM_encode(const Private_Key& key); +BOTAN_DLL SecureVector<byte> BER_encode(const Private_Key& key, + RandomNumberGenerator& rng, + const std::string& pass, + const std::string& pbe_algo = ""); /** * Get a string containing a PEM encoded private key, encrypting it with a @@ -64,20 +59,67 @@ BOTAN_DLL std::string PEM_encode(const Private_Key& key); * @param key the key to encode * @param rng the rng to use * @param pass the password to use for encryption -* @param pbe_algo the name of the desired password-based encryption algorithm; - if empty ("") a reasonable (portable/secure) default will be chosen. +* @param pbe_algo the name of the desired password-based encryption + algorithm; if empty ("") a reasonable (portable/secure) + default will be chosen. +* @return encrypted key in PEM form */ BOTAN_DLL std::string PEM_encode(const Private_Key& key, RandomNumberGenerator& rng, const std::string& pass, const std::string& pbe_algo = ""); + +/** +* Encode a private key into a pipe. +* @deprecated Use PEM_encode or BER_encode instead +* +* @param key the private key to encode +* @param pipe the pipe to feed the encoded key into +* @param encoding the encoding type to use +*/ +inline void encode(const Private_Key& key, + Pipe& pipe, + X509_Encoding encoding = PEM) + { + if(encoding == PEM) + pipe.write(PKCS8::PEM_encode(key)); + else + pipe.write(PKCS8::BER_encode(key)); + } + +/** +* Encode and encrypt a private key into a pipe. +* @deprecated Use PEM_encode or BER_encode instead +* +* @param key the private key to encode +* @param pipe the pipe to feed the encoded key into +* @param pass the password to use for encryption +* @param rng the rng to use +* @param pbe_algo the name of the desired password-based encryption + algorithm; if empty ("") a reasonable (portable/secure) + default will be chosen. +* @param encoding the encoding type to use +*/ +inline void encrypt_key(const Private_Key& key, + Pipe& pipe, + RandomNumberGenerator& rng, + const std::string& pass, + const std::string& pbe_algo = "", + X509_Encoding encoding = PEM) + { + if(encoding == PEM) + pipe.write(PKCS8::PEM_encode(key, rng, pass, pbe_algo)); + else + pipe.write(PKCS8::BER_encode(key, rng, pass, pbe_algo)); + } + /** * Load a key from a data source. * @param source the data source providing the encoded key * @param rng the rng to use * @param ui the user interface to be used for passphrase dialog -* @return the loaded private key object +* @return loaded private key object */ BOTAN_DLL Private_Key* load_key(DataSource& source, RandomNumberGenerator& rng, @@ -88,7 +130,7 @@ BOTAN_DLL Private_Key* load_key(DataSource& source, * @param rng the rng to use * @param pass the passphrase to decrypt the key. Provide an empty * string if the key is not encoded. -* @return the loaded private key object +* @return loaded private key object */ BOTAN_DLL Private_Key* load_key(DataSource& source, RandomNumberGenerator& rng, @@ -99,7 +141,7 @@ BOTAN_DLL Private_Key* load_key(DataSource& source, * @param filename the path to the file containing the encoded key * @param rng the rng to use * @param ui the user interface to be used for passphrase dialog -* @return the loaded private key object +* @return loaded private key object */ BOTAN_DLL Private_Key* load_key(const std::string& filename, RandomNumberGenerator& rng, @@ -110,7 +152,7 @@ BOTAN_DLL Private_Key* load_key(const std::string& filename, * @param rng the rng to use * @param pass the passphrase to decrypt the key. Provide an empty * string if the key is not encoded. -* @return the loaded private key object +* @return loaded private key object */ BOTAN_DLL Private_Key* load_key(const std::string& filename, RandomNumberGenerator& rng, @@ -120,7 +162,7 @@ BOTAN_DLL Private_Key* load_key(const std::string& filename, * Copy an existing encoded key object. * @param key the key to copy * @param rng the rng to use -* @return the new copy of the key +* @return new copy of the key */ BOTAN_DLL Private_Key* copy_key(const Private_Key& key, RandomNumberGenerator& rng); diff --git a/src/pubkey/pubkey.h b/src/pubkey/pubkey.h index eeb4d5841..ff4355675 100644 --- a/src/pubkey/pubkey.h +++ b/src/pubkey/pubkey.h @@ -43,7 +43,7 @@ class BOTAN_DLL PK_Encryptor * @param in the message as a byte array * @param length the length of the above byte array * @param rng the random number source to use - * @return the encrypted message + * @return encrypted message */ SecureVector<byte> encrypt(const byte in[], u32bit length, RandomNumberGenerator& rng) const @@ -55,7 +55,7 @@ class BOTAN_DLL PK_Encryptor * Encrypt a message. * @param in the message * @param rng the random number source to use - * @return the encrypted message + * @return encrypted message */ SecureVector<byte> encrypt(const MemoryRegion<byte>& in, RandomNumberGenerator& rng) const @@ -65,7 +65,7 @@ class BOTAN_DLL PK_Encryptor /** * Return the maximum allowed message size in bytes. - * @return the maximum message size in bytes + * @return maximum message size in bytes */ virtual u32bit maximum_input_size() const = 0; @@ -89,7 +89,7 @@ class BOTAN_DLL PK_Decryptor * Decrypt a ciphertext. * @param in the ciphertext as a byte array * @param length the length of the above byte array - * @return the decrypted message + * @return decrypted message */ SecureVector<byte> decrypt(const byte in[], u32bit length) const { @@ -99,7 +99,7 @@ class BOTAN_DLL PK_Decryptor /** * Decrypt a ciphertext. * @param in the ciphertext - * @return the decrypted message + * @return decrypted message */ SecureVector<byte> decrypt(const MemoryRegion<byte>& in) const { @@ -128,7 +128,7 @@ class BOTAN_DLL PK_Signer * @param in the message to sign as a byte array * @param length the length of the above byte array * @param rng the rng to use - * @return the signature + * @return signature */ SecureVector<byte> sign_message(const byte in[], u32bit length, RandomNumberGenerator& rng); @@ -137,7 +137,7 @@ class BOTAN_DLL PK_Signer * Sign a message. * @param in the message to sign * @param rng the rng to use - * @return the signature + * @return signature */ SecureVector<byte> sign_message(const MemoryRegion<byte>& in, RandomNumberGenerator& rng) @@ -145,7 +145,7 @@ class BOTAN_DLL PK_Signer /** * Add a message part (single byte). - * @param the byte to add + * @param in the byte to add */ void update(byte in) { update(&in, 1); } @@ -166,7 +166,7 @@ class BOTAN_DLL PK_Signer * Get the signature of the so far processed message (provided by the * calls to update()). * @param rng the rng to use - * @return the signature of the total message + * @return signature of the total message */ SecureVector<byte> signature(RandomNumberGenerator& rng); @@ -305,8 +305,8 @@ class BOTAN_DLL PK_Verifier Signature_Format sig_format; }; -/* -* Key Agreement +/** +* Key used for key agreement */ class BOTAN_DLL PK_Key_Agreement { @@ -438,6 +438,12 @@ class BOTAN_DLL PK_Decryptor_EME : public PK_Decryptor const EME* eme; }; +/* +* Typedefs for compatability with 1.8 +*/ +typedef PK_Encryptor_EME PK_Encryptor_MR_with_EME; +typedef PK_Decryptor_EME PK_Decryptor_MR_with_EME; + } #endif diff --git a/src/pubkey/rsa/rsa.h b/src/pubkey/rsa/rsa.h index e2da173f9..f7700e08c 100644 --- a/src/pubkey/rsa/rsa.h +++ b/src/pubkey/rsa/rsa.h @@ -42,7 +42,7 @@ class BOTAN_DLL RSA_PublicKey : public virtual IF_Scheme_PublicKey }; /** -* RSA Private Key class. +* RSA Private Key */ class BOTAN_DLL RSA_PrivateKey : public RSA_PublicKey, public IF_Scheme_PrivateKey @@ -83,6 +83,9 @@ class BOTAN_DLL RSA_PrivateKey : public RSA_PublicKey, u32bit bits, u32bit exp = 65537); }; +/** +* RSA private (decrypt/sign) operation +*/ class BOTAN_DLL RSA_Private_Operation : public PK_Ops::Signature, public PK_Ops::Decryption { @@ -107,6 +110,9 @@ class BOTAN_DLL RSA_Private_Operation : public PK_Ops::Signature, Blinder blinder; }; +/** +* RSA public (encrypt/verify) operation +*/ class BOTAN_DLL RSA_Public_Operation : public PK_Ops::Verification, public PK_Ops::Encryption { diff --git a/src/pubkey/rw/rw.h b/src/pubkey/rw/rw.h index 831c7a960..24f4ffab6 100644 --- a/src/pubkey/rw/rw.h +++ b/src/pubkey/rw/rw.h @@ -15,7 +15,7 @@ namespace Botan { -/* +/** * Rabin-Williams Public Key */ class BOTAN_DLL RW_PublicKey : public virtual IF_Scheme_PublicKey @@ -36,7 +36,7 @@ class BOTAN_DLL RW_PublicKey : public virtual IF_Scheme_PublicKey RW_PublicKey() {} }; -/* +/** * Rabin-Williams Private Key */ class BOTAN_DLL RW_PrivateKey : public RW_PublicKey, @@ -59,6 +59,9 @@ class BOTAN_DLL RW_PrivateKey : public RW_PublicKey, bool check_key(RandomNumberGenerator& rng, bool) const; }; +/** +* Rabin-Williams Signature Operation +*/ class BOTAN_DLL RW_Signature_Operation : public PK_Ops::Signature { public: @@ -79,6 +82,9 @@ class BOTAN_DLL RW_Signature_Operation : public PK_Ops::Signature Blinder blinder; }; +/** +* Rabin-Williams Verification Operation +*/ class BOTAN_DLL RW_Verification_Operation : public PK_Ops::Verification { public: diff --git a/src/pubkey/x509_key.cpp b/src/pubkey/x509_key.cpp index babeb517f..d321ce338 100644 --- a/src/pubkey/x509_key.cpp +++ b/src/pubkey/x509_key.cpp @@ -1,6 +1,6 @@ /* * X.509 Public Key -* (C) 1999-2007 Jack Lloyd +* (C) 1999-2010 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -18,23 +18,14 @@ namespace Botan { namespace X509 { -/* -* DER or PEM encode a X.509 public key -*/ -void encode(const Public_Key& key, Pipe& pipe, X509_Encoding encoding) +MemoryVector<byte> BER_encode(const Public_Key& key) { - MemoryVector<byte> der = - DER_Encoder() + return DER_Encoder() .start_cons(SEQUENCE) .encode(key.algorithm_identifier()) .encode(key.x509_subject_public_key(), BIT_STRING) .end_cons() .get_contents(); - - if(encoding == PEM) - pipe.write(PEM_Code::encode(der, "PUBLIC KEY")); - else - pipe.write(der); } /* @@ -42,11 +33,8 @@ void encode(const Public_Key& key, Pipe& pipe, X509_Encoding encoding) */ std::string PEM_encode(const Public_Key& key) { - Pipe pem; - pem.start_msg(); - encode(key, pem, PEM); - pem.end_msg(); - return pem.read_all_as_string(); + return PEM_Code::encode(X509::BER_encode(key), + "PUBLIC KEY"); } /* @@ -115,11 +103,7 @@ Public_Key* load_key(const MemoryRegion<byte>& mem) */ Public_Key* copy_key(const Public_Key& key) { - Pipe bits; - bits.start_msg(); - X509::encode(key, bits, RAW_BER); - bits.end_msg(); - DataSource_Memory source(bits.read_all()); + DataSource_Memory source(PEM_encode(key)); return X509::load_key(source); } diff --git a/src/pubkey/x509_key.h b/src/pubkey/x509_key.h index 13f11646e..4b17f9974 100644 --- a/src/pubkey/x509_key.h +++ b/src/pubkey/x509_key.h @@ -1,6 +1,6 @@ /* * X.509 Public Key -* (C) 1999-2007 Jack Lloyd +* (C) 1999-2010 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -16,51 +16,49 @@ namespace Botan { /** -* This namespace contains functions for handling X509 objects. +* This namespace contains functions for handling X.509 public keys */ namespace X509 { /** -* Encode a key into a pipe. +* BER encode a key * @param key the public key to encode -* @param pipe the pipe to feed the encoded key into -* @param enc the encoding type to use +* @return BER encoding of this key */ -BOTAN_DLL void encode(const Public_Key& key, Pipe& pipe, - X509_Encoding enc = PEM); +BOTAN_DLL MemoryVector<byte> BER_encode(const Public_Key& key); /** * PEM encode a public key into a string. * @param key the key to encode -* @return the PEM encoded key +* @return PEM encoded key */ BOTAN_DLL std::string PEM_encode(const Public_Key& key); /** * Create a public key from a data source. * @param source the source providing the DER or PEM encoded key -* @return the new public key object +* @return new public key object */ BOTAN_DLL Public_Key* load_key(DataSource& source); /** -* Create a public key from a string. -* @param enc the string containing the PEM encoded key -* @return the new public key object +* Create a public key from a file +* @param filename pathname to the file to load +* @return new public key object */ -BOTAN_DLL Public_Key* load_key(const std::string& enc); +BOTAN_DLL Public_Key* load_key(const std::string& filename); /** * Create a public key from a memory region. * @param enc the memory region containing the DER or PEM encoded key -* @return the new public key object +* @return new public key object */ BOTAN_DLL Public_Key* load_key(const MemoryRegion<byte>& enc); /** * Copy a key. * @param key the public key to copy -* @return the new public key object +* @return new public key object */ BOTAN_DLL Public_Key* copy_key(const Public_Key& key); @@ -70,13 +68,30 @@ BOTAN_DLL Public_Key* copy_key(const Public_Key& key); * constraints to be placed in the return value is derived * @param limits additional limits that will be incorporated into the * return value -* @return the combination of key type specific constraints and +* @return combination of key type specific constraints and * additional limits */ - BOTAN_DLL Key_Constraints find_constraints(const Public_Key& pub_key, Key_Constraints limits); +/** +* Encode a key into a pipe. +* @deprecated Use PEM_encode or BER_encode instead +* +* @param key the public key to encode +* @param pipe the pipe to feed the encoded key into +* @param encoding the encoding type to use +*/ +inline void encode(const Public_Key& key, + Pipe& pipe, + X509_Encoding encoding = PEM) + { + if(encoding == PEM) + pipe.write(X509::PEM_encode(key)); + else + pipe.write(X509::BER_encode(key)); + } + } } diff --git a/src/rng/auto_rng/auto_rng.h b/src/rng/auto_rng/auto_rng.h index 90f342a50..28a603feb 100644 --- a/src/rng/auto_rng/auto_rng.h +++ b/src/rng/auto_rng/auto_rng.h @@ -14,6 +14,9 @@ namespace Botan { +/** +* An automatically seeded PRNG +*/ class BOTAN_DLL AutoSeeded_RNG : public RandomNumberGenerator { public: diff --git a/src/rng/hmac_rng/hmac_rng.cpp b/src/rng/hmac_rng/hmac_rng.cpp index c185a5643..d8c031f6b 100644 --- a/src/rng/hmac_rng/hmac_rng.cpp +++ b/src/rng/hmac_rng/hmac_rng.cpp @@ -30,7 +30,7 @@ void hmac_prf(MessageAuthenticationCode* prf, } -/** +/* * Generate a buffer of random bytes */ void HMAC_RNG::randomize(byte out[], u32bit length) @@ -53,7 +53,7 @@ void HMAC_RNG::randomize(byte out[], u32bit length) } } -/** +/* * Poll for entropy and reset the internal keys */ void HMAC_RNG::reseed(u32bit poll_bits) @@ -114,7 +114,7 @@ void HMAC_RNG::reseed(u32bit poll_bits) seeded = true; } -/** +/* * Add user-supplied entropy to the extractor input */ void HMAC_RNG::add_entropy(const byte input[], u32bit length) @@ -131,7 +131,7 @@ void HMAC_RNG::add_entropy(const byte input[], u32bit length) reseed(128); } -/** +/* * Add another entropy source to the list */ void HMAC_RNG::add_entropy_source(EntropySource* src) @@ -139,7 +139,7 @@ void HMAC_RNG::add_entropy_source(EntropySource* src) entropy_sources.push_back(src); } -/** +/* * Clear memory of sensitive data */ void HMAC_RNG::clear() @@ -152,7 +152,7 @@ void HMAC_RNG::clear() seeded = false; } -/** +/* * Return the name of this type */ std::string HMAC_RNG::name() const @@ -160,7 +160,7 @@ std::string HMAC_RNG::name() const return "HMAC_RNG(" + extractor->name() + "," + prf->name() + ")"; } -/** +/* * HMAC_RNG Constructor */ HMAC_RNG::HMAC_RNG(MessageAuthenticationCode* extractor_mac, @@ -208,7 +208,7 @@ HMAC_RNG::HMAC_RNG(MessageAuthenticationCode* extractor_mac, extractor->set_key(prf->process("Botan HMAC_RNG XTS")); } -/** +/* * HMAC_RNG Destructor */ HMAC_RNG::~HMAC_RNG() diff --git a/src/rng/hmac_rng/hmac_rng.h b/src/rng/hmac_rng/hmac_rng.h index 452357130..fc712b3ec 100644 --- a/src/rng/hmac_rng/hmac_rng.h +++ b/src/rng/hmac_rng/hmac_rng.h @@ -36,6 +36,10 @@ class BOTAN_DLL HMAC_RNG : public RandomNumberGenerator void add_entropy_source(EntropySource* es); void add_entropy(const byte[], u32bit); + /** + * @param extractor a MAC used for extracting the entropy + * @param prf a MAC used as a PRF using HKDF construction + */ HMAC_RNG(MessageAuthenticationCode* extractor, MessageAuthenticationCode* prf); diff --git a/src/rng/randpool/randpool.cpp b/src/rng/randpool/randpool.cpp index c58378b32..d75885a76 100644 --- a/src/rng/randpool/randpool.cpp +++ b/src/rng/randpool/randpool.cpp @@ -15,7 +15,7 @@ namespace Botan { namespace { -/** +/* * PRF based on a MAC */ enum RANDPOOL_PRF_TAG { @@ -26,7 +26,7 @@ enum RANDPOOL_PRF_TAG { } -/** +/* * Generate a buffer of random bytes */ void Randpool::randomize(byte out[], u32bit length) @@ -45,7 +45,7 @@ void Randpool::randomize(byte out[], u32bit length) } } -/** +/* * Refill the output buffer */ void Randpool::update_buffer() @@ -66,7 +66,7 @@ void Randpool::update_buffer() mix_pool(); } -/** +/* * Mix the entropy pool */ void Randpool::mix_pool() @@ -94,7 +94,7 @@ void Randpool::mix_pool() update_buffer(); } -/** +/* * Reseed the internal state */ void Randpool::reseed(u32bit poll_bits) @@ -121,7 +121,7 @@ void Randpool::reseed(u32bit poll_bits) seeded = true; } -/** +/* * Add user-supplied entropy */ void Randpool::add_entropy(const byte input[], u32bit length) @@ -134,7 +134,7 @@ void Randpool::add_entropy(const byte input[], u32bit length) seeded = true; } -/** +/* * Add another entropy source to the list */ void Randpool::add_entropy_source(EntropySource* src) @@ -142,7 +142,7 @@ void Randpool::add_entropy_source(EntropySource* src) entropy_sources.push_back(src); } -/** +/* * Clear memory of sensitive data */ void Randpool::clear() @@ -155,7 +155,7 @@ void Randpool::clear() seeded = false; } -/** +/* * Return the name of this type */ std::string Randpool::name() const @@ -163,7 +163,7 @@ std::string Randpool::name() const return "Randpool(" + cipher->name() + "," + mac->name() + ")"; } -/** +/* * Randpool Constructor */ Randpool::Randpool(BlockCipher* cipher_in, @@ -194,7 +194,7 @@ Randpool::Randpool(BlockCipher* cipher_in, seeded = false; } -/** +/* * Randpool Destructor */ Randpool::~Randpool() diff --git a/src/rng/randpool/randpool.h b/src/rng/randpool/randpool.h index ab6ed6748..471bb791a 100644 --- a/src/rng/randpool/randpool.h +++ b/src/rng/randpool/randpool.h @@ -30,7 +30,15 @@ class BOTAN_DLL Randpool : public RandomNumberGenerator void add_entropy_source(EntropySource* es); void add_entropy(const byte input[], u32bit length); - Randpool(BlockCipher* cipher, MessageAuthenticationCode* mac, + /** + * @param cipher a block cipher to use + * @param mac a message authentication code to use + * @param pool_blocks how many cipher blocks to use for the pool + * @param iterations_before_reseed how many times we'll use the + * internal state to generate output before reseeding + */ + Randpool(BlockCipher* cipher, + MessageAuthenticationCode* mac, u32bit pool_blocks = 32, u32bit iterations_before_reseed = 128); diff --git a/src/rng/rng.h b/src/rng/rng.h index c53d8e22d..687f98d13 100644 --- a/src/rng/rng.h +++ b/src/rng/rng.h @@ -82,8 +82,8 @@ class BOTAN_DLL RandomNumberGenerator { return (*this); } }; -/* -* Null Random Number Generator +/** +* Null/stub RNG - fails if you try to use it for anything */ class BOTAN_DLL Null_RNG : public RandomNumberGenerator { diff --git a/src/rng/x931_rng/x931_rng.cpp b/src/rng/x931_rng/x931_rng.cpp index 3ff180898..f812377ed 100644 --- a/src/rng/x931_rng/x931_rng.cpp +++ b/src/rng/x931_rng/x931_rng.cpp @@ -11,7 +11,7 @@ namespace Botan { -/** +/* * Generate a buffer of random bytes */ void ANSI_X931_RNG::randomize(byte out[], u32bit length) @@ -33,7 +33,7 @@ void ANSI_X931_RNG::randomize(byte out[], u32bit length) } } -/** +/* * Refill the internal state */ void ANSI_X931_RNG::update_buffer() @@ -52,7 +52,7 @@ void ANSI_X931_RNG::update_buffer() position = 0; } -/** +/* * Reset V and the cipher key with new values */ void ANSI_X931_RNG::rekey() @@ -71,7 +71,7 @@ void ANSI_X931_RNG::rekey() } } -/** +/* * Reseed the internal state */ void ANSI_X931_RNG::reseed(u32bit poll_bits) @@ -80,7 +80,7 @@ void ANSI_X931_RNG::reseed(u32bit poll_bits) rekey(); } -/** +/* * Add a entropy source to the underlying PRNG */ void ANSI_X931_RNG::add_entropy_source(EntropySource* src) @@ -88,7 +88,7 @@ void ANSI_X931_RNG::add_entropy_source(EntropySource* src) prng->add_entropy_source(src); } -/** +/* * Add some entropy to the underlying PRNG */ void ANSI_X931_RNG::add_entropy(const byte input[], u32bit length) @@ -97,7 +97,7 @@ void ANSI_X931_RNG::add_entropy(const byte input[], u32bit length) rekey(); } -/** +/* * Check if the the PRNG is seeded */ bool ANSI_X931_RNG::is_seeded() const @@ -105,7 +105,7 @@ bool ANSI_X931_RNG::is_seeded() const return (V.size() > 0); } -/** +/* * Clear memory of sensitive data */ void ANSI_X931_RNG::clear() @@ -118,7 +118,7 @@ void ANSI_X931_RNG::clear() position = 0; } -/** +/* * Return the name of this type */ std::string ANSI_X931_RNG::name() const @@ -126,7 +126,7 @@ std::string ANSI_X931_RNG::name() const return "X9.31(" + cipher->name() + ")"; } -/** +/* * ANSI X931 RNG Constructor */ ANSI_X931_RNG::ANSI_X931_RNG(BlockCipher* cipher_in, @@ -142,7 +142,7 @@ ANSI_X931_RNG::ANSI_X931_RNG(BlockCipher* cipher_in, position = 0; } -/** +/* * ANSI X931 RNG Destructor */ ANSI_X931_RNG::~ANSI_X931_RNG() diff --git a/src/rng/x931_rng/x931_rng.h b/src/rng/x931_rng/x931_rng.h index d5ba2e9eb..345ee3ca9 100644 --- a/src/rng/x931_rng/x931_rng.h +++ b/src/rng/x931_rng/x931_rng.h @@ -28,7 +28,13 @@ class BOTAN_DLL ANSI_X931_RNG : public RandomNumberGenerator void add_entropy_source(EntropySource*); void add_entropy(const byte[], u32bit); - ANSI_X931_RNG(BlockCipher*, RandomNumberGenerator*); + /** + * @param cipher the block cipher to use in this PRNG + * @param rng the underlying PRNG for generating inputs + * (eg, an HMAC_RNG) + */ + ANSI_X931_RNG(BlockCipher* cipher, + RandomNumberGenerator* rng); ~ANSI_X931_RNG(); private: void rekey(); diff --git a/src/s2k/pbkdf1/pbkdf1.h b/src/s2k/pbkdf1/pbkdf1.h index 053a2dbe1..c0508d127 100644 --- a/src/s2k/pbkdf1/pbkdf1.h +++ b/src/s2k/pbkdf1/pbkdf1.h @@ -29,10 +29,14 @@ class BOTAN_DLL PKCS5_PBKDF1 : public S2K /** * Create a PKCS #5 instance using the specified hash function. - * @param hash a pointer to a hash function object to use + * @param hash_in pointer to a hash function object to use */ PKCS5_PBKDF1(HashFunction* hash_in) : hash(hash_in) {} + /** + * Copy constructor + * @param other the object to copy + */ PKCS5_PBKDF1(const PKCS5_PBKDF1& other) : S2K(), hash(other.hash->clone()) {} diff --git a/src/s2k/pgps2k/pgp_s2k.h b/src/s2k/pgps2k/pgp_s2k.h index 7f25623f3..cfe9bf5d5 100644 --- a/src/s2k/pgps2k/pgp_s2k.h +++ b/src/s2k/pgps2k/pgp_s2k.h @@ -13,8 +13,8 @@ namespace Botan { -/* -* OpenPGP S2K +/** +* OpenPGP's S2K */ class BOTAN_DLL OpenPGP_S2K : public S2K { @@ -27,6 +27,9 @@ class BOTAN_DLL OpenPGP_S2K : public S2K const byte salt[], u32bit salt_len, u32bit iterations) const; + /** + * @param hash_in the hash function to use + */ OpenPGP_S2K(HashFunction* hash_in) : hash(hash_in) {} ~OpenPGP_S2K() { delete hash; } private: diff --git a/src/s2k/s2k.h b/src/s2k/s2k.h index db59a5fe8..d6880db5d 100644 --- a/src/s2k/s2k.h +++ b/src/s2k/s2k.h @@ -12,21 +12,22 @@ namespace Botan { -/* -* S2K Interface +/** +* Base class for S2K (string to key) operations, which convert a +* password/passphrase into a key */ class BOTAN_DLL S2K { public: /** - * @return a new instance of this same algorithm + * @return new instance of this same algorithm */ virtual S2K* clone() const = 0; /** * Get the algorithm name. - * @return the name of this S2K algorithm + * @return name of this S2K algorithm */ virtual std::string name() const = 0; diff --git a/src/selftest/selftest.cpp b/src/selftest/selftest.cpp index a11accbd3..783fa3b00 100644 --- a/src/selftest/selftest.cpp +++ b/src/selftest/selftest.cpp @@ -49,8 +49,9 @@ algorithm_kat(const SCAN_Name& algo_name, const std::string input = search_map(vars, std::string("input")); const std::string output = search_map(vars, std::string("output")); - const std::string key = search_map(vars, std::string("key")); - const std::string iv = search_map(vars, std::string("iv")); + + SymmetricKey key(search_map(vars, std::string("key"))); + InitializationVector iv(search_map(vars, std::string("iv"))); for(u32bit i = 0; i != providers.size(); ++i) { @@ -96,10 +97,18 @@ algorithm_kat(const SCAN_Name& algo_name, } enc->set_key(key); - enc->set_iv(iv); + + if(enc->valid_iv_length(iv.length())) + enc->set_iv(iv); + else if(!enc->valid_iv_length(0)) + throw Invalid_IV_Length(algo, iv.length()); dec->set_key(key); - dec->set_iv(iv); + + if(dec->valid_iv_length(iv.length())) + dec->set_iv(iv); + else if(!dec->valid_iv_length(0)) + throw Invalid_IV_Length(algo, iv.length()); bool enc_ok = test_filter_kat(enc, input, output); bool dec_ok = test_filter_kat(dec, output, input); diff --git a/src/ssl/c_kex.cpp b/src/ssl/c_kex.cpp index db2198627..5194c8c3d 100644 --- a/src/ssl/c_kex.cpp +++ b/src/ssl/c_kex.cpp @@ -1,4 +1,4 @@ -/** +/* * Client Key Exchange Message * (C) 2004-2010 Jack Lloyd * diff --git a/src/ssl/cert_req.cpp b/src/ssl/cert_req.cpp index 4431a4a39..04d7867c6 100644 --- a/src/ssl/cert_req.cpp +++ b/src/ssl/cert_req.cpp @@ -1,5 +1,5 @@ -/** -* Certificate Request Message +/* +* Certificate Request Message * (C) 2004-2006 Jack Lloyd * * Released under the terms of the Botan license diff --git a/src/ssl/cert_ver.cpp b/src/ssl/cert_ver.cpp index 3edf4266d..dfcf6c7c3 100644 --- a/src/ssl/cert_ver.cpp +++ b/src/ssl/cert_ver.cpp @@ -1,4 +1,4 @@ -/** +/* * Certificate Verify Message * (C) 2004-2010 Jack Lloyd * diff --git a/src/ssl/finished.cpp b/src/ssl/finished.cpp index b0f6abd25..6648a2c3e 100644 --- a/src/ssl/finished.cpp +++ b/src/ssl/finished.cpp @@ -1,5 +1,5 @@ -/** -* Finished Message +/* +* Finished Message * (C) 2004-2006 Jack Lloyd * * Released under the terms of the Botan license diff --git a/src/ssl/handshake_hash.cpp b/src/ssl/handshake_hash.cpp index d94fa0178..2331d015e 100644 --- a/src/ssl/handshake_hash.cpp +++ b/src/ssl/handshake_hash.cpp @@ -1,5 +1,5 @@ -/** -* TLS Handshake Hash +/* +* TLS Handshake Hash * (C) 2004-2006 Jack Lloyd * * Released under the terms of the Botan license diff --git a/src/ssl/handshake_hash.h b/src/ssl/handshake_hash.h index cfb351765..8e068f3de 100644 --- a/src/ssl/handshake_hash.h +++ b/src/ssl/handshake_hash.h @@ -1,4 +1,4 @@ -/** +/* * TLS Handshake Hash * (C) 2004-2006 Jack Lloyd * diff --git a/src/ssl/handshake_state.cpp b/src/ssl/handshake_state.cpp index 314625057..373d4b57c 100644 --- a/src/ssl/handshake_state.cpp +++ b/src/ssl/handshake_state.cpp @@ -1,5 +1,5 @@ -/** -* TLS Handshaking +/* +* TLS Handshaking * (C) 2004-2006 Jack Lloyd * * Released under the terms of the Botan license diff --git a/src/ssl/hello.cpp b/src/ssl/hello.cpp index 5b3c32278..2fb5bb567 100644 --- a/src/ssl/hello.cpp +++ b/src/ssl/hello.cpp @@ -1,4 +1,4 @@ -/** +/* * TLS Hello Messages * (C) 2004-2010 Jack Lloyd * diff --git a/src/ssl/rec_read.cpp b/src/ssl/rec_read.cpp index f07744c2a..3c008641d 100644 --- a/src/ssl/rec_read.cpp +++ b/src/ssl/rec_read.cpp @@ -1,4 +1,4 @@ -/** +/* * TLS Record Reading * (C) 2004-2010 Jack Lloyd * @@ -12,7 +12,7 @@ namespace Botan { -/** +/* * Reset the state */ void Record_Reader::reset() @@ -26,7 +26,7 @@ void Record_Reader::reset() seq_no = 0; } -/** +/* * Set the version to use */ void Record_Reader::set_version(Version_Code version) @@ -38,7 +38,7 @@ void Record_Reader::set_version(Version_Code version) minor = (version & 0xFF); } -/** +/* * Set the keys for reading */ void Record_Reader::set_keys(const CipherSuite& suite, const SessionKeys& keys, @@ -74,7 +74,7 @@ void Record_Reader::set_keys(const CipherSuite& suite, const SessionKeys& keys, ); block_size = block_size_of(cipher_algo); - if(major == 3 && minor >= 2) + if(major > 3 || (major == 3 && minor >= 2)) iv_size = block_size; else iv_size = 0; @@ -106,7 +106,7 @@ void Record_Reader::add_input(const byte input[], u32bit input_size) input_queue.write(input, input_size); } -/** +/* * Retrieve the next record */ u32bit Record_Reader::get_record(byte& msg_type, diff --git a/src/ssl/rec_wri.cpp b/src/ssl/rec_wri.cpp index f8079c235..2ee0e20d3 100644 --- a/src/ssl/rec_wri.cpp +++ b/src/ssl/rec_wri.cpp @@ -1,4 +1,4 @@ -/** +/* * TLS Record Writing * (C) 2004-2010 Jack Lloyd * @@ -89,7 +89,7 @@ void Record_Writer::set_keys(const CipherSuite& suite, const SessionKeys& keys, ); block_size = block_size_of(cipher_algo); - if(major == 3 && minor >= 2) + if(major > 3 || (major == 3 && minor >= 2)) iv_size = block_size; else iv_size = 0; diff --git a/src/ssl/s_kex.cpp b/src/ssl/s_kex.cpp index 9b8a3171d..4617d9fb4 100644 --- a/src/ssl/s_kex.cpp +++ b/src/ssl/s_kex.cpp @@ -1,4 +1,4 @@ -/** +/* * Server Key Exchange Message * (C) 2004-2010 Jack Lloyd * diff --git a/src/ssl/socket.h b/src/ssl/socket.h index 62ceed028..6d88bd48a 100644 --- a/src/ssl/socket.h +++ b/src/ssl/socket.h @@ -1,5 +1,5 @@ -/** -* Socket Interface +/* +* Socket Interface * (C) 2004-2006 Jack Lloyd * * Released under the terms of the Botan license diff --git a/src/ssl/tls_alerts.h b/src/ssl/tls_alerts.h index 894bca4af..f189cf507 100644 --- a/src/ssl/tls_alerts.h +++ b/src/ssl/tls_alerts.h @@ -1,5 +1,5 @@ -/** -* Alert Message +/* +* Alert Message * (C) 2004-2006 Jack Lloyd * * Released under the terms of the Botan license @@ -18,11 +18,19 @@ namespace Botan { class BOTAN_DLL Alert { public: + /** + * @return if this alert is a fatal one or not + */ bool is_fatal() const { return fatal; } + + /** + * @return type of alert + */ Alert_Type type() const { return type_code; } /** * Deserialize an Alert message + * @param buf the serialized alert */ Alert(const MemoryRegion<byte>& buf) { diff --git a/src/ssl/tls_client.cpp b/src/ssl/tls_client.cpp index 8a4275d93..3b63b2119 100644 --- a/src/ssl/tls_client.cpp +++ b/src/ssl/tls_client.cpp @@ -1,4 +1,4 @@ -/** +/* * TLS Client * (C) 2004-2010 Jack Lloyd * diff --git a/src/ssl/tls_client.h b/src/ssl/tls_client.h index 2439a58f0..c9ed3ca37 100644 --- a/src/ssl/tls_client.h +++ b/src/ssl/tls_client.h @@ -1,4 +1,4 @@ -/** +/* * TLS Client * (C) 2004-2010 Jack Lloyd * diff --git a/src/ssl/tls_connection.h b/src/ssl/tls_connection.h index ff55cceab..a6de659c4 100644 --- a/src/ssl/tls_connection.h +++ b/src/ssl/tls_connection.h @@ -1,5 +1,5 @@ -/** -* TLS Connection +/* +* TLS Connection * (C) 2004-2006 Jack Lloyd * * Released under the terms of the Botan license diff --git a/src/ssl/tls_exceptn.h b/src/ssl/tls_exceptn.h index 3ba852875..a9efc718a 100644 --- a/src/ssl/tls_exceptn.h +++ b/src/ssl/tls_exceptn.h @@ -1,5 +1,5 @@ -/** -* Exceptions +/* +* Exceptions * (C) 2004-2006 Jack Lloyd * * Released under the terms of the Botan license diff --git a/src/ssl/tls_magic.h b/src/ssl/tls_magic.h index 93b56d96d..2a0c61e18 100644 --- a/src/ssl/tls_magic.h +++ b/src/ssl/tls_magic.h @@ -1,4 +1,4 @@ -/** +/* * SSL/TLS Protocol Constants * (C) 2004-2010 Jack Lloyd * diff --git a/src/ssl/tls_messages.h b/src/ssl/tls_messages.h index 5c0c06c88..20aa9b930 100644 --- a/src/ssl/tls_messages.h +++ b/src/ssl/tls_messages.h @@ -1,4 +1,4 @@ -/** +/* * TLS Messages * (C) 2004-2010 Jack Lloyd * diff --git a/src/ssl/tls_policy.cpp b/src/ssl/tls_policy.cpp index 57fcdb5cc..03a83319c 100644 --- a/src/ssl/tls_policy.cpp +++ b/src/ssl/tls_policy.cpp @@ -1,4 +1,4 @@ -/** +/* * Policies for TLS * (C) 2004-2010 Jack Lloyd * diff --git a/src/ssl/tls_policy.h b/src/ssl/tls_policy.h index 75d6d7663..5555f0ca6 100644 --- a/src/ssl/tls_policy.h +++ b/src/ssl/tls_policy.h @@ -1,5 +1,5 @@ -/** -* Policies +/* +* Policies * (C) 2004-2006 Jack Lloyd * * Released under the terms of the Botan license diff --git a/src/ssl/tls_reader.h b/src/ssl/tls_reader.h index ff3e63ae8..641d1ecdb 100644 --- a/src/ssl/tls_reader.h +++ b/src/ssl/tls_reader.h @@ -13,6 +13,9 @@ namespace Botan { +/** +* Helper class for decoding TLS protocol messages +*/ class TLS_Data_Reader { public: diff --git a/src/ssl/tls_record.h b/src/ssl/tls_record.h index 2058933d0..863e2c801 100644 --- a/src/ssl/tls_record.h +++ b/src/ssl/tls_record.h @@ -1,4 +1,4 @@ -/** +/* * TLS Record Handling * (C) 2004-2010 Jack Lloyd * diff --git a/src/ssl/tls_server.cpp b/src/ssl/tls_server.cpp index a4cfcf7de..2a84fa063 100644 --- a/src/ssl/tls_server.cpp +++ b/src/ssl/tls_server.cpp @@ -1,4 +1,4 @@ -/** +/* * TLS Server * (C) 2004-2010 Jack Lloyd * diff --git a/src/ssl/tls_server.h b/src/ssl/tls_server.h index 5cf830a64..673f16580 100644 --- a/src/ssl/tls_server.h +++ b/src/ssl/tls_server.h @@ -1,4 +1,4 @@ -/** +/* * TLS Server * (C) 2004-2010 Jack Lloyd * diff --git a/src/ssl/tls_session_key.cpp b/src/ssl/tls_session_key.cpp index 13575adac..594b99e19 100644 --- a/src/ssl/tls_session_key.cpp +++ b/src/ssl/tls_session_key.cpp @@ -1,5 +1,5 @@ -/** -* TLS Session Key +/* +* TLS Session Key * (C) 2004-2006 Jack Lloyd * * Released under the terms of the Botan license diff --git a/src/ssl/tls_session_key.h b/src/ssl/tls_session_key.h index b0eba2eb1..98c1b92ff 100644 --- a/src/ssl/tls_session_key.h +++ b/src/ssl/tls_session_key.h @@ -1,5 +1,5 @@ -/** -* TLS Session Key +/* +* TLS Session Key * (C) 2004-2006 Jack Lloyd * * Released under the terms of the Botan license diff --git a/src/ssl/tls_state.h b/src/ssl/tls_state.h index ddf03a822..1472271e3 100644 --- a/src/ssl/tls_state.h +++ b/src/ssl/tls_state.h @@ -1,5 +1,5 @@ -/** -* TLS Handshaking +/* +* TLS Handshaking * (C) 2004-2006 Jack Lloyd * * Released under the terms of the Botan license diff --git a/src/ssl/tls_suites.cpp b/src/ssl/tls_suites.cpp index 5e52e7de2..56e8fee01 100644 --- a/src/ssl/tls_suites.cpp +++ b/src/ssl/tls_suites.cpp @@ -1,4 +1,4 @@ -/** +/* * TLS Cipher Suites * (C) 2004-2010 Jack Lloyd * diff --git a/src/ssl/tls_suites.h b/src/ssl/tls_suites.h index fa015c28f..612c148e6 100644 --- a/src/ssl/tls_suites.h +++ b/src/ssl/tls_suites.h @@ -1,4 +1,4 @@ -/** +/* * Cipher Suites * (C) 2004-2010 Jack Lloyd * diff --git a/src/ssl/unix_socket/info.txt b/src/ssl/unix_socket/info.txt index 205d0c700..15fc50f5b 100644 --- a/src/ssl/unix_socket/info.txt +++ b/src/ssl/unix_socket/info.txt @@ -16,6 +16,5 @@ ssl linux freebsd netbsd -openbsd solaris </os> diff --git a/src/ssl/unix_socket/unx_sock.cpp b/src/ssl/unix_socket/unx_sock.cpp index 9954cdc06..a7c19b70c 100644 --- a/src/ssl/unix_socket/unx_sock.cpp +++ b/src/ssl/unix_socket/unx_sock.cpp @@ -1,4 +1,4 @@ -/** +/* * Unix Socket * (C) 2004-2010 Jack Lloyd * diff --git a/src/stream/arc4/arc4.h b/src/stream/arc4/arc4.h index 07633f9ef..0488783ef 100644 --- a/src/stream/arc4/arc4.h +++ b/src/stream/arc4/arc4.h @@ -13,8 +13,8 @@ namespace Botan { -/* -* ARC4 +/** +* Alleged RC4 */ class BOTAN_DLL ARC4 : public StreamCipher { @@ -26,7 +26,11 @@ class BOTAN_DLL ARC4 : public StreamCipher StreamCipher* clone() const { return new ARC4(SKIP); } - ARC4(u32bit = 0); + /** + * @param skip skip this many initial bytes in the keystream + */ + ARC4(u32bit skip = 0); + ~ARC4() { clear(); } private: void key_schedule(const byte[], u32bit); diff --git a/src/stream/ctr/ctr.cpp b/src/stream/ctr/ctr.cpp index 421c9f0c0..8a24cd4d0 100644 --- a/src/stream/ctr/ctr.cpp +++ b/src/stream/ctr/ctr.cpp @@ -22,7 +22,7 @@ CTR_BE::CTR_BE(BlockCipher* ciph) : { position = 0; - counter.resize(permutation->BLOCK_SIZE * permutation->parallelism()); + counter.resize(permutation->parallel_bytes()); buffer.resize(counter.size()); } diff --git a/src/stream/ctr/ctr.h b/src/stream/ctr/ctr.h index 5f94170cc..fc7ba522f 100644 --- a/src/stream/ctr/ctr.h +++ b/src/stream/ctr/ctr.h @@ -13,8 +13,8 @@ namespace Botan { -/* -* CTR-BE (Counter, big-endian) +/** +* CTR-BE (Counter mode, big-endian) */ class BOTAN_DLL CTR_BE : public StreamCipher { @@ -33,7 +33,10 @@ class BOTAN_DLL CTR_BE : public StreamCipher void clear(); - CTR_BE(BlockCipher*); + /** + * @param cipher the underlying block cipher to use + */ + CTR_BE(BlockCipher* cipher); ~CTR_BE(); private: void key_schedule(const byte key[], u32bit key_len); diff --git a/src/stream/ofb/ofb.h b/src/stream/ofb/ofb.h index 1985ae5a9..2871dd8ee 100644 --- a/src/stream/ofb/ofb.h +++ b/src/stream/ofb/ofb.h @@ -13,8 +13,8 @@ namespace Botan { -/* -* OFB Mode +/** +* Output Feedback Mode */ class BOTAN_DLL OFB : public StreamCipher { @@ -33,7 +33,10 @@ class BOTAN_DLL OFB : public StreamCipher void clear(); - OFB(BlockCipher*); + /** + * @param cipher the underlying block cipher to use + */ + OFB(BlockCipher* cipher); ~OFB(); private: void key_schedule(const byte key[], u32bit key_len); diff --git a/src/stream/salsa20/salsa20.h b/src/stream/salsa20/salsa20.h index 67fe54dda..4ba483082 100644 --- a/src/stream/salsa20/salsa20.h +++ b/src/stream/salsa20/salsa20.h @@ -12,8 +12,8 @@ namespace Botan { -/* -* Salsa20 (and XSalsa20) +/** +* DJB's Salsa20 (and XSalsa20) */ class BOTAN_DLL Salsa20 : public StreamCipher { diff --git a/src/stream/stream_cipher.cpp b/src/stream/stream_cipher.cpp new file mode 100644 index 000000000..9ae548a9e --- /dev/null +++ b/src/stream/stream_cipher.cpp @@ -0,0 +1,24 @@ +/* +* Stream Cipher +* (C) 1999-2010 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/stream_cipher.h> + +namespace Botan { + +void StreamCipher::set_iv(const byte[], u32bit iv_len) + { + if(iv_len) + throw Invalid_Argument("The stream cipher " + name() + + " does not support resyncronization"); + } + +bool StreamCipher::valid_iv_length(u32bit iv_len) const + { + return (iv_len == 0); + } + +} diff --git a/src/stream/stream_cipher.h b/src/stream/stream_cipher.h index cb6fb3481..edeb1aff5 100644 --- a/src/stream/stream_cipher.h +++ b/src/stream/stream_cipher.h @@ -1,4 +1,4 @@ -/** +/* * Stream Cipher * (C) 1999-2007 Jack Lloyd * @@ -12,8 +12,8 @@ namespace Botan { -/* -* Stream Cipher +/** +* Base class for all stream ciphers */ class BOTAN_DLL StreamCipher : public SymmetricAlgorithm { @@ -39,19 +39,13 @@ class BOTAN_DLL StreamCipher : public SymmetricAlgorithm * @param iv the initialization vector * @param iv_len the length of the IV in bytes */ - virtual void set_iv(const byte[], u32bit iv_len) - { - if(iv_len) - throw Invalid_Argument("The stream cipher " + name() + - " does not support resyncronization"); - } + virtual void set_iv(const byte iv[], u32bit iv_len); /** * @param iv_len the length of the IV in bytes * @return if the length is valid for this algorithm */ - virtual bool valid_iv_length(u32bit iv_len) const - { return (iv_len == 0); } + virtual bool valid_iv_length(u32bit iv_len) const; /** * Get a new object representing the same algorithm as *this @@ -65,6 +59,9 @@ class BOTAN_DLL StreamCipher : public SymmetricAlgorithm /** * StreamCipher constructor + * @param key_min the minimum key size + * @param key_max the maximum key size + * @param key_mod the modulo restriction on the key size */ StreamCipher(u32bit key_min, u32bit key_max = 0, diff --git a/src/stream/turing/turing.h b/src/stream/turing/turing.h index 19d151fca..92c5083a4 100644 --- a/src/stream/turing/turing.h +++ b/src/stream/turing/turing.h @@ -12,14 +12,14 @@ namespace Botan { -/* +/** * Turing */ class BOTAN_DLL Turing : public StreamCipher { public: void cipher(const byte in[], byte out[], u32bit length); - void set_iv(const byte[], u32bit); + void set_iv(const byte iv[], u32bit iv_length); bool valid_iv_length(u32bit iv_len) const { return (iv_len % 4 == 0 && iv_len <= 16); } diff --git a/src/stream/wid_wake/wid_wake.h b/src/stream/wid_wake/wid_wake.h index 1c52e8ba1..365a6d9ff 100644 --- a/src/stream/wid_wake/wid_wake.h +++ b/src/stream/wid_wake/wid_wake.h @@ -12,8 +12,11 @@ namespace Botan { -/* +/** * WiderWake4+1-BE +* +* Note: quite old and possibly not safe; use XSalsa20 or a block +* cipher in counter mode. */ class BOTAN_DLL WiderWake_41_BE : public StreamCipher { diff --git a/src/sym_algo/sym_algo.h b/src/sym_algo/sym_algo.h index 929f2a6f0..60180de90 100644 --- a/src/sym_algo/sym_algo.h +++ b/src/sym_algo/sym_algo.h @@ -1,4 +1,4 @@ -/** +/* * Symmetric Algorithm Base Class * (C) 1999-2007 Jack Lloyd * @@ -38,7 +38,7 @@ class BOTAN_DLL SymmetricAlgorithm /** * The name of the algorithm. - * @return the name of the algorithm + * @return name of the algorithm */ virtual std::string name() const = 0; @@ -52,7 +52,7 @@ class BOTAN_DLL SymmetricAlgorithm /** * Set the symmetric key of this object. * @param key the to be set as a byte array. - * @param the length of the byte array. + * @param length in bytes of key param */ void set_key(const byte key[], u32bit length) { @@ -87,7 +87,12 @@ class BOTAN_DLL SymmetricAlgorithm virtual ~SymmetricAlgorithm() {} private: - virtual void key_schedule(const byte[], u32bit) = 0; + /** + * Run the key schedule + * @param key the key + * @param length of key + */ + virtual void key_schedule(const byte key[], u32bit length) = 0; }; /** diff --git a/src/sym_algo/symkey.h b/src/sym_algo/symkey.h index 5504297a4..450dab306 100644 --- a/src/sym_algo/symkey.h +++ b/src/sym_algo/symkey.h @@ -13,43 +13,132 @@ namespace Botan { -/* +/** * Octet String */ class BOTAN_DLL OctetString { public: + /** + * @return size of this octet string in bytes + */ u32bit length() const { return bits.size(); } + + /** + * @return this object as a SecureVector<byte> + */ SecureVector<byte> bits_of() const { return bits; } + /** + * @return start of this string + */ const byte* begin() const { return bits.begin(); } + + /** + * @return end of this string + */ const byte* end() const { return bits.end(); } + /** + * @return this encoded as hex + */ std::string as_string() const; - OctetString& operator^=(const OctetString&); + /** + * XOR the contents of another octet string into this one + * @param other octet string + * @return reference to this + */ + OctetString& operator^=(const OctetString& other); + /** + * Force to have odd parity + */ void set_odd_parity(); - void change(const std::string&); - void change(const byte[], u32bit); + /** + * Change the contents of this octet string + * @param hex_string a hex encoded bytestring + */ + void change(const std::string& hex_string); + + /** + * Change the contents of this octet string + * @param in the input + * @param length of in in bytes + */ + void change(const byte in[], u32bit length); + + /** + * Change the contents of this octet string + * @param in the input + */ void change(const MemoryRegion<byte>& in) { bits = in; } - OctetString(class RandomNumberGenerator&, u32bit len); + /** + * Create a new random OctetString + * @param rng is a random number generator + * @param len is the desired length in bytes + */ + OctetString(class RandomNumberGenerator& rng, u32bit len); + + /** + * Create a new OctetString + * @param str is a hex encoded string + */ OctetString(const std::string& str = "") { change(str); } + + /** + * Create a new OctetString + * @param in is an array + * @param len is the length of in in bytes + */ OctetString(const byte in[], u32bit len) { change(in, len); } + + /** + * Create a new OctetString + * @param in a bytestring + */ OctetString(const MemoryRegion<byte>& in) { change(in); } private: SecureVector<byte> bits; }; -/* -* Operations on Octet Strings +/** +* Compare two strings +* @param x an octet string +* @param y an octet string +* @return if x is equal to y +*/ +BOTAN_DLL bool operator==(const OctetString& x, + const OctetString& y); + +/** +* Compare two strings +* @param x an octet string +* @param y an octet string +* @return if x is not equal to y +*/ +BOTAN_DLL bool operator!=(const OctetString& x, + const OctetString& y); + +/** +* Concatenate two strings +* @param x an octet string +* @param y an octet string +* @return x concatenated with y +*/ +BOTAN_DLL OctetString operator+(const OctetString& x, + const OctetString& y); + +/** +* XOR two strings +* @param x an octet string +* @param y an octet string +* @return x XORed with y */ -BOTAN_DLL bool operator==(const OctetString&, const OctetString&); -BOTAN_DLL bool operator!=(const OctetString&, const OctetString&); -BOTAN_DLL OctetString operator+(const OctetString&, const OctetString&); -BOTAN_DLL OctetString operator^(const OctetString&, const OctetString&); +BOTAN_DLL OctetString operator^(const OctetString& x, + const OctetString& y); /* * Alternate Names diff --git a/src/utils/buf_comp/buf_comp.h b/src/utils/buf_comp/buf_comp.h index 3f1e90bad..e807e6abf 100644 --- a/src/utils/buf_comp/buf_comp.h +++ b/src/utils/buf_comp/buf_comp.h @@ -1,4 +1,4 @@ -/** +/* * BufferedComputation * (C) 1999-2007 Jack Lloyd * @@ -29,7 +29,7 @@ class BOTAN_DLL BufferedComputation /** * Add new input to process. * @param in the input to process as a byte array - * @param the length of the byte array + * @param length of param in in bytes */ void update(const byte in[], u32bit length) { add_data(in, length); } @@ -67,7 +67,7 @@ class BOTAN_DLL BufferedComputation /** * Complete the computation and retrieve the * final result. - * @return a SecureVector holding the result + * @return SecureVector holding the result */ SecureVector<byte> final() { @@ -113,12 +113,27 @@ class BOTAN_DLL BufferedComputation return final(); } + /** + * @param out_len the output length of this computation + */ BufferedComputation(u32bit out_len) : OUTPUT_LENGTH(out_len) {} + virtual ~BufferedComputation() {} private: BufferedComputation& operator=(const BufferedComputation&); - virtual void add_data(const byte[], u32bit) = 0; - virtual void final_result(byte[]) = 0; + + /** + * Add more data to the computation + * @param input is an input buffer + * @param length is the length of input in bytes + */ + virtual void add_data(const byte input[], u32bit length) = 0; + + /** + * Write the final output to out + * @param out is an output buffer of OUTPUT_LENGTH + */ + virtual void final_result(byte out[]) = 0; }; } diff --git a/src/utils/cpuid.cpp b/src/utils/cpuid.cpp index 19a2db788..4837e7ac4 100644 --- a/src/utils/cpuid.cpp +++ b/src/utils/cpuid.cpp @@ -1,4 +1,4 @@ -/** +/* * Runtime CPU detection * (C) 2009 Jack Lloyd * diff --git a/src/utils/cpuid.h b/src/utils/cpuid.h index 1de97f129..a41e932fb 100644 --- a/src/utils/cpuid.h +++ b/src/utils/cpuid.h @@ -1,4 +1,4 @@ -/** +/* * Runtime CPU detection * (C) 2009 Jack Lloyd * @@ -12,6 +12,9 @@ namespace Botan { +/** +* A class handling runtime CPU feature detection +*/ class BOTAN_DLL CPUID { public: diff --git a/src/utils/datastor/datastor.h b/src/utils/datastor/datastor.h index 516d0a16b..26a0d418c 100644 --- a/src/utils/datastor/datastor.h +++ b/src/utils/datastor/datastor.h @@ -23,6 +23,9 @@ namespace Botan { class BOTAN_DLL Data_Store { public: + /** + * A search function + */ bool operator==(const Data_Store&) const; std::multimap<std::string, std::string> search_for( diff --git a/src/utils/debug.h b/src/utils/debug.h index 271e0047b..11de7010e 100644 --- a/src/utils/debug.h +++ b/src/utils/debug.h @@ -1,4 +1,4 @@ -/** +/* * Internal-use debugging functions for Botan * (C) 2009 Jack Lloyd * diff --git a/src/utils/exceptn.h b/src/utils/exceptn.h index 2ac88aaf6..6dff970b6 100644 --- a/src/utils/exceptn.h +++ b/src/utils/exceptn.h @@ -19,7 +19,7 @@ namespace Botan { typedef std::runtime_error Exception; typedef std::invalid_argument Invalid_Argument; -/* +/** * Invalid_State Exception */ struct BOTAN_DLL Invalid_State : public Exception @@ -29,7 +29,7 @@ struct BOTAN_DLL Invalid_State : public Exception {} }; -/* +/** * Lookup_Error Exception */ struct BOTAN_DLL Lookup_Error : public Exception @@ -39,7 +39,7 @@ struct BOTAN_DLL Lookup_Error : public Exception {} }; -/* +/** * Internal_Error Exception */ struct BOTAN_DLL Internal_Error : public Exception @@ -49,7 +49,7 @@ struct BOTAN_DLL Internal_Error : public Exception {} }; -/* +/** * Invalid_Key_Length Exception */ struct BOTAN_DLL Invalid_Key_Length : public Invalid_Argument @@ -60,7 +60,7 @@ struct BOTAN_DLL Invalid_Key_Length : public Invalid_Argument {} }; -/* +/** * Invalid_Block_Size Exception */ struct BOTAN_DLL Invalid_Block_Size : public Invalid_Argument @@ -72,7 +72,7 @@ struct BOTAN_DLL Invalid_Block_Size : public Invalid_Argument {} }; -/* +/** * Invalid_IV_Length Exception */ struct BOTAN_DLL Invalid_IV_Length : public Invalid_Argument @@ -83,7 +83,7 @@ struct BOTAN_DLL Invalid_IV_Length : public Invalid_Argument {} }; -/* +/** * PRNG_Unseeded Exception */ struct BOTAN_DLL PRNG_Unseeded : public Invalid_State @@ -93,7 +93,7 @@ struct BOTAN_DLL PRNG_Unseeded : public Invalid_State {} }; -/* +/** * Policy_Violation Exception */ struct BOTAN_DLL Policy_Violation : public Invalid_State @@ -103,7 +103,7 @@ struct BOTAN_DLL Policy_Violation : public Invalid_State {} }; -/* +/** * Algorithm_Not_Found Exception */ struct BOTAN_DLL Algorithm_Not_Found : public Lookup_Error @@ -113,7 +113,7 @@ struct BOTAN_DLL Algorithm_Not_Found : public Lookup_Error {} }; -/* +/** * Invalid_Algorithm_Name Exception */ struct BOTAN_DLL Invalid_Algorithm_Name : public Invalid_Argument @@ -123,7 +123,7 @@ struct BOTAN_DLL Invalid_Algorithm_Name : public Invalid_Argument {} }; -/* +/** * Encoding_Error Exception */ struct BOTAN_DLL Encoding_Error : public Invalid_Argument @@ -132,7 +132,7 @@ struct BOTAN_DLL Encoding_Error : public Invalid_Argument Invalid_Argument("Encoding error: " + name) {} }; -/* +/** * Decoding_Error Exception */ struct BOTAN_DLL Decoding_Error : public Invalid_Argument @@ -141,7 +141,7 @@ struct BOTAN_DLL Decoding_Error : public Invalid_Argument Invalid_Argument("Decoding error: " + name) {} }; -/* +/** * Integrity_Failure Exception */ struct BOTAN_DLL Integrity_Failure : public Exception @@ -150,7 +150,7 @@ struct BOTAN_DLL Integrity_Failure : public Exception Exception("Integrity failure: " + what) {} }; -/* +/** * Invalid_OID Exception */ struct BOTAN_DLL Invalid_OID : public Decoding_Error @@ -159,7 +159,7 @@ struct BOTAN_DLL Invalid_OID : public Decoding_Error Decoding_Error("Invalid ASN.1 OID: " + oid) {} }; -/* +/** * Stream_IO_Error Exception */ struct BOTAN_DLL Stream_IO_Error : public Exception @@ -169,7 +169,7 @@ struct BOTAN_DLL Stream_IO_Error : public Exception {} }; -/* +/** * Self Test Failure Exception */ struct BOTAN_DLL Self_Test_Failure : public Internal_Error @@ -179,7 +179,7 @@ struct BOTAN_DLL Self_Test_Failure : public Internal_Error {} }; -/* +/** * Memory Allocation Exception */ struct BOTAN_DLL Memory_Exhaustion : public std::bad_alloc diff --git a/src/utils/prefetch.h b/src/utils/prefetch.h index ede196692..4928c44a0 100644 --- a/src/utils/prefetch.h +++ b/src/utils/prefetch.h @@ -12,10 +12,8 @@ namespace Botan { -namespace PREFETCH { - template<typename T> -inline void readonly(const T* addr, u32bit length) +inline void prefetch_readonly(const T* addr, u32bit length) { #if defined(__GNUG__) const u32bit Ts_per_cache_line = CPUID::cache_line_size() / sizeof(T); @@ -26,7 +24,7 @@ inline void readonly(const T* addr, u32bit length) } template<typename T> -inline void readwrite(const T* addr, u32bit length) +inline void prefetch_readwrite(const T* addr, u32bit length) { #if defined(__GNUG__) const u32bit Ts_per_cache_line = CPUID::cache_line_size() / sizeof(T); @@ -38,6 +36,4 @@ inline void readwrite(const T* addr, u32bit length) } -} - #endif diff --git a/src/utils/simd_32/simd_32.h b/src/utils/simd_32/simd_32.h index 23dce0305..15be7713d 100644 --- a/src/utils/simd_32/simd_32.h +++ b/src/utils/simd_32/simd_32.h @@ -1,4 +1,4 @@ -/** +/* * Lightweight wrappers for SIMD operations * (C) 2009 Jack Lloyd * diff --git a/src/utils/simd_32/simd_altivec.h b/src/utils/simd_32/simd_altivec.h index 859a48a5f..44e2a4d2b 100644 --- a/src/utils/simd_32/simd_altivec.h +++ b/src/utils/simd_32/simd_altivec.h @@ -1,4 +1,4 @@ -/** +/* * Lightweight wrappers around AltiVec for 32-bit operations * (C) 2009 Jack Lloyd * diff --git a/src/utils/simd_32/simd_scalar.h b/src/utils/simd_32/simd_scalar.h index 5cf1a11c3..56b529025 100644 --- a/src/utils/simd_32/simd_scalar.h +++ b/src/utils/simd_32/simd_scalar.h @@ -1,4 +1,4 @@ -/** +/* * Scalar emulation of SIMD 32-bit operations * (C) 2009 Jack Lloyd * @@ -13,6 +13,10 @@ namespace Botan { +/** +* Fake SIMD, using plain scalar operations +* Often still faster than iterative on superscalar machines +*/ class SIMD_Scalar { public: diff --git a/src/utils/simd_32/simd_sse.h b/src/utils/simd_32/simd_sse.h index 0189c2e4d..ad3857fbf 100644 --- a/src/utils/simd_32/simd_sse.h +++ b/src/utils/simd_32/simd_sse.h @@ -1,4 +1,4 @@ -/** +/* * Lightweight wrappers for SSE2 intrinsics for 32-bit operations * (C) 2009 Jack Lloyd * diff --git a/src/utils/time.cpp b/src/utils/time.cpp index bc9aa8a2f..4fea41c52 100644 --- a/src/utils/time.cpp +++ b/src/utils/time.cpp @@ -1,4 +1,4 @@ -/** +/* * Time Functions * (C) 1999-2010 Jack Lloyd * diff --git a/src/utils/time.h b/src/utils/time.h index 44ec704a4..c7a7e0e1a 100644 --- a/src/utils/time.h +++ b/src/utils/time.h @@ -1,4 +1,4 @@ -/** +/* * Time Functions * (C) 1999-2009 Jack Lloyd * @@ -25,13 +25,22 @@ struct BOTAN_DLL calendar_point byte minutes; byte seconds; + /** + * Initialize a calendar_point + * @param y the year + * @param mon the month + * @param d the day + * @param h the hour + * @param min the minute + * @param sec the second + */ calendar_point(u32bit y, byte mon, byte d, byte h, byte min, byte sec) : year(y), month(mon), day(d), hour(h), minutes(min), seconds(sec) {} }; /* * @param time_point a time point from the system clock -* @returns calendar_point object representing this time point +* @return calendar_point object representing this time point */ BOTAN_DLL calendar_point calendar_value( const std::chrono::system_clock::time_point& time_point); diff --git a/src/utils/ui.h b/src/utils/ui.h index fe62c60fc..f69bb2c6d 100644 --- a/src/utils/ui.h +++ b/src/utils/ui.h @@ -13,8 +13,9 @@ namespace Botan { -/* +/** * User Interface +* Only really used for callbacks for PKCS #8 decryption */ class BOTAN_DLL User_Interface { diff --git a/src/utils/version.cpp b/src/utils/version.cpp index ef591b4d7..ce2083bc0 100644 --- a/src/utils/version.cpp +++ b/src/utils/version.cpp @@ -26,6 +26,8 @@ std::string version_string() std::to_string(version_patch()); } +u32bit version_datestamp() { return BOTAN_VERSION_DATESTAMP; } + /* * Return parts of the version as integers */ diff --git a/src/utils/version.h b/src/utils/version.h index 3cc44e806..13d0ac8bb 100644 --- a/src/utils/version.h +++ b/src/utils/version.h @@ -19,25 +19,33 @@ namespace Botan { /** * Get the version string identifying the version of Botan. -* @return the version string +* @return version string */ BOTAN_DLL std::string version_string(); /** +* Return the date this version of botan was released, in an +* integer of the form YYYYMMDD. For instance a version released +* on May 21, 2013 would return the integer 20130521 +* @return release date +*/ +BOTAN_DLL u32bit version_datestamp(); + +/** * Get the major version number. -* @return the major version number +* @return major version number */ BOTAN_DLL u32bit version_major(); /** * Get the minor version number. -* @return the minor version number +* @return minor version number */ BOTAN_DLL u32bit version_minor(); /** * Get the patch number. -* @return the patch number +* @return patch number */ BOTAN_DLL u32bit version_patch(); diff --git a/src/utils/xor_buf.h b/src/utils/xor_buf.h index 0d7d587c8..34abb48d3 100644 --- a/src/utils/xor_buf.h +++ b/src/utils/xor_buf.h @@ -1,4 +1,4 @@ -/** +/* * XOR operations * (C) 1999-2008 Jack Lloyd * diff --git a/src/wrap/python/rsa.cpp b/src/wrap/python/rsa.cpp index 41d9bd4d1..903516f11 100644 --- a/src/wrap/python/rsa.cpp +++ b/src/wrap/python/rsa.cpp @@ -36,6 +36,14 @@ class Py_RSA_PrivateKey return PKCS8::PEM_encode(*rsa_key); } + std::string to_ber() const + { + SecureVector<byte> bits = PKCS8::BER_encode(*rsa_key); + + return std;:string(reinterpret_cast<const char*>(&bits[0]), + bits.size()); + } + std::string get_N() const { return bigint2str(get_bigint_N()); } std::string get_E() const { return bigint2str(get_bigint_E()); } @@ -113,6 +121,14 @@ class Py_RSA_PublicKey return X509::PEM_encode(*rsa_key); } + std::string to_ber() const + { + SecureVector<byte> bits = X509::BER_encode(*rsa_key); + + return std;:string(reinterpret_cast<const char*>(&bits[0]), + bits.size()); + } + std::string encrypt(const std::string& in, const std::string& padding, Python_RandomNumberGenerator& rng); @@ -171,6 +187,7 @@ void export_rsa() ("RSA_PublicKey", python::init<std::string>()) .def(python::init<const Py_RSA_PrivateKey&>()) .def("to_string", &Py_RSA_PublicKey::to_string) + .def("to_ber", &Py_RSA_PublicKey::to_ber) .def("encrypt", &Py_RSA_PublicKey::encrypt) .def("verify", &Py_RSA_PublicKey::verify) .def("get_N", &Py_RSA_PublicKey::get_N) @@ -180,6 +197,7 @@ void export_rsa() ("RSA_PrivateKey", python::init<std::string, Python_RandomNumberGenerator&, std::string>()) .def(python::init<u32bit, Python_RandomNumberGenerator&>()) .def("to_string", &Py_RSA_PrivateKey::to_string) + .def("to_ber", &Py_RSA_PrivateKey::to_ber) .def("decrypt", &Py_RSA_PrivateKey::decrypt) .def("sign", &Py_RSA_PrivateKey::sign) .def("get_N", &Py_RSA_PrivateKey::get_N) |