diff options
-rw-r--r-- | checks/validate.dat | 240 | ||||
-rw-r--r-- | include/kdf.h | 34 | ||||
-rw-r--r-- | include/ssl3_mac.h | 34 | ||||
-rw-r--r-- | src/def_alg.cpp | 2 | ||||
-rw-r--r-- | src/get_enc.cpp | 10 | ||||
-rw-r--r-- | src/ssl3_mac.cpp | 88 | ||||
-rw-r--r-- | src/ssl3_prf.cpp | 71 | ||||
-rw-r--r-- | src/tls_prf.cpp | 63 |
8 files changed, 537 insertions, 5 deletions
diff --git a/checks/validate.dat b/checks/validate.dat index 6f5b9d006..ba76359f8 100644 --- a/checks/validate.dat +++ b/checks/validate.dat @@ -31887,6 +31887,29 @@ C65D515D8FDF3465396DBEA4C44F6F069C597FF9AAA32227:\ 39F2933F156616549749CCAEBF682322:\ 0398D70C12CE6F7ED28828647FB18A56 +# SSL3-MAC vectors were posted by Thomas Pornin to sci.crypt +[SSL3-MAC(MD5)] +00:A856430AF077AE2C328D9FFE4E56813A:0123456789ABCDEF0123456789ABCDEF + +01:96279D16E7812EDDA2EC64DAC996348F:0123456789ABCDEF0123456789ABCDEF + +0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF\ +0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF\ +0123456789ABCDEF0123456789ABCDEF:475006C7DC7A3F371352D948B4BE950E:\ +0123456789ABCDEF0123456789ABCDEF + +[SSL3-MAC(SHA-1)] +00:DD2BA1F4A721F22C8A9BA7350B5CD6838B225827:\ +0123456789ABCDEF0123456789ABCDEF01234567 + +01:CD6289A1FEC0BB104C271BE488343BA92328B073:\ +0123456789ABCDEF0123456789ABCDEF01234567 + +0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF\ +0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF\ +0123456789ABCDEF0123456789ABCDEF:98E523EADE38B3BF4EBF51D7EE814316C9EB3159:\ +0123456789ABCDEF0123456789ABCDEF01234567 + # From draft-ietf-tls-seedhas-00.txt [HMAC(HAS-160)] 4869205468657265:\ @@ -32326,6 +32349,223 @@ EF4AAB69:37 02AEB40A3D4B66FBA540F9D4B20006F2046E0F3A029DEAB201FC692B79EB27CEF7E16069046A:\ DBB986:38 +[SSL3-PRF] +6E60:D626B75AB8BD4F5B9458BDDA8589FD39:17FEBCA565786528F84A:16 + +66BEEC6EDE7FCDF50B76EBCD5C0FE0A472F2EA8B1E2BE2971E49CA:\ +EB:5C461D77ACDB631ABAE2E7AFED5E9ABBBAA99B:1 + +1171D78F812512DEFBA258574E41F2832BB9B359EB0CA79E7669:\ +2C8B:73D677854D88F62417774A2A5645CCAE9C1AEF8E9D1B48:2 + +6162DEC990B2132C30C153F2B200:1B9430:2666F0B22E8E48DB1640:3 + +D3C0DD69C18F17D35C5296FE45F0:C7C19FCD:320C9EEC122C19AFB8E90F72:4 + +EE6A733EC671DA7477AE18916895A133CC92E23DBACEE2634846CAEF0B08:\ +C264D9D0C9:B7F9722B37389C11:5 + +97D7F3D2AFB3198862F6FAC8B17CCEFB26:C1CB767626AC:\ +D3583CD13AC119CAFBD44CAEA5AB:6 + +E87A9BBC656884A13295B8D4DD4645905846C249D2470ACD2BE5:\ +3DC5B6402F451C:542D044668EDC104A9266C2EC79EC37F72A0C6B7301EFDF267CF39:7 + +7463F0B9F822E17311E47680DC5B505811E9:FE4B1DA4EDA36820:02AB98439528C994:8 + +EE8999703E5D9C628AA404235F3C94C3A890B1:EF317D3E81DAEF0F89:161DEB5AB705BD15:9 + +AE531918E679D2D7B32C61BA31415484E9725B2905095819:18D5272345C1695BE38C:\ +A162AC0F0AB41CB80735D1EDAEA3C562CF261C0067:10 + +8FE402D6ED0BD018A532FC063E7D81D97CDEA7:D61088CA1CE8944B17CD3E:\ +BF7F091B6E0DDB90897B6BF80A4F:11 + +4279DB52505E7B505BBC26CE0FBF2F4353086C1363:4A84A8E829528393FF890129:\ +8710A8A12B2D18A27A50E5F32C37448A:12 + +B80B58DAB89B1C4D1335C48E479220E253B8EACFD64319544A:1450E50B7D86B76015930BA420:\ +E9158BA5F6E25D013A37B9D65406E989CB77D05D97B2B04F9C7F26DF987A:13 + +965F1BC656F01C1C7F977419A5F99FB54FA34548C332EA79B5B0EE:\ +CEE11A3A9A406FE9DA77FE6FB007:\ +3F6FF94F05596ACBAF5AE7CBD97E3FF3233992D988361E:14 + +657B5F618710AF88BF4F0328E7071D022D02EA5E:8EA957C330D55CC208326CEA06D25A:\ +BD0A575481E823931F68BE84E31DE56B2D95F3ECE4F614CBFD31CE:15 + +33CE7917528009F2A1011CFCD494B80D4BBFD901:2FB1FDD16FCE41C9C563226A564D1647:\ +81851CC61D3E910E04D5EC38A465:16 + +40ED568CFC6C0A17866C67B7660C96BF9DA54C:321118AA031C5C9EFF145542B4426C3C71:\ +A3502B96214854E5AF5720E8970D3F240AAB2E21319A88E901:17 + +12695F5B19541C8B0092418A72A7ED8482F35FCC4A82D4E1C5AE:\ +22BC94F745F6E247054DDA2C772E5D2D3EC4:\ +2CE5F4676C06D0CB61E91F7D751F0F:18 + +F36E535A1C2C6F6771:6004BBD20BB68E2F1FFC65977807EE25A3FBFE:\ +290BE26068D887AA6E86500E85C606:19 + +7C7EE43D46AE85D23F0D5264DBD410:0E1FE69316D67CF65D62196C25CC4F517664BD43:\ +FC4A7F986331A012CBDAD765288C2CEC08AAD045:20 + +C580B05EC577F45434C13640AAB31B:937E22F90D1493317B0B068A44859036905540AF67:\ +6C9F5929EA435A86E117BD586B34F7E4F97794573C0B4C90:21 + +E275AEB758A949CBB11256E74412E1DA3743899F9007DD5D80A7:\ +69C2640797F38E87F1C870891164F0B31F1A3A02627A:\ +585B267A9E08EF4DBF48F6:22 + +DCF06E7AC257DA73CC6FC0A086B4:30CCF63491F642A55E45136E42FDD0355DB272502EA1B0:\ +16F0355230F105EB316F558512EC3B51871741:23 + +C4C38EC6A1EA975D0ECA535B0CC4D6D0:\ +3B50F91EDFDD96CBA8B6329616D4F5964CD8C961CB1D9332:\ +E84EE4D9DC701DE04E250768F2DFB9B6A2:24 + +7B557AC16D60B74ECAA87641887E6467BAC107:\ +CA148D27F3DC362B0F43C68312058C1CD9B92ECAC2CFDD601F:\ +D7B9EB91BCDE1F6C144A0799:25 + +B23EFA7FAA11D0E597F00867992CB3B9DA93D607FAC0:\ +510297144BA4E0FB5C94749576F756AA36F51289CA463419DC06:\ +DA5E3A17C6DDE81CC69A5AC11904D2E9E969D9F2D1731E842C:26 + +1A5063B374A5F7769AD59432CFFA6B:\ +3437D8B56E573E724B72DD08A5D144E86E646BD24EA0795BA2C3BD:\ +FE0314911D4C07803C48A9EA86:27 + +870515C65F0AF7AAB10C365AF8AC535E1AA8997D139645A21F71FD23ABBB:\ +1895554BD0A1DE7F48FA8776D314EAE2B9E8D7E3CF2A418D17659DC1:\ +AA33C0BFF91FC9F1C97BFD00D5F5AC2953C6D1EC43E5838887A2F984C5A53F:28 + +1BAE220F6AFEB0A2F51D44721A7A9B9C:\ +13720151D256DEBAAA668359A876A9A9788D540F509E90372952A91757:\ +11555530CBAECFF82C76147416A50831532A40BD29F15F1E0EA49129:29 + +BC55F2BAC14370BB5832575A233F1FCE32322E5B4CE1955153CAF3C84493DF:\ +972B190F7EC73DA7C5B8B38E9B6DCEE452AB0BC2220F37BEA3FAC596B2F6:\ +00E8D1BAA9142A646C5DBCC680FB:30 + +834CD382FBF84FF54CC8D3BCB778ACD7DDE8FE32ABA212ABB1:\ +6151C82D7384ED41264424827766B6A7279593C86DCBAC9A4D711009E30EC3:\ +EE768F1AAF889EFB5B20F7536FECA037BF:31 + +E0BDEBC1D1EEDB393368D489:\ +F3D8ED6D46280C3694F33D2D4A210248D657277DD78ACD3B34063D085657A58E:\ +5D2B46C7BB5258ABC13514995E518FD4D77BECB738D77909:32 + +[TLS-PRF] +6C81AF87ABD86BE83C37CE981F6BFE11BD53A8:A8:\ +A6D455CB1B2929E43D63CCE55CE89D66F252549729C19C1511:1 + +6BB61D34AF2BCCF45A850850BCDE35E55A92BA:5E75:\ +510194C9C9F90D98452FB914F636D5E5297C:2 + +3CC54F5F3EF82C93CE60EB62DC9DF005280DD1:706F52:\ +7FC24D382379A9CD54D53458947CB28E298A1DCC5EB2556F71ACAC1B:3 + +BD3462DC587DFA992AE48BD7643B62A9971928:841D7339:\ +9F6FAFED1F241A1E40ADEAF2AD80:4 + +1235A061FA3867B8E51511D1E672CE141E2FA6:D856787D41:\ +1026B9224FC59706BEADAE58EBD161FD2EAC:5 + +63A22C3C7C5651103648F5CFC9764A7BDE821F:F13096FEED6E:\ +512FBF47D9DA2915:6 + +AA15082F10F25EC4F96DFFE9DC3D80BBA6361B:B637FCADE57896:\ +519B87DB85FBE92FB4070F3BEF6E3D97DF69B66061EB83B4A334E8EEDC0F8E:7 + +775B727CE679B8696171C7BE60FC2E3F4DE516:3431016193616501:\ +453C2549058B063C83E8B85E5CEF3570DF51B7D79B486F4F33:8 + +AB299AD69DC581F13D86562AE2BE8B08015FF8:A624CC363499B1EA64:5569FC:9 + +AE4947624D877916E5B01EDDAB8E4CDC817630:5B908EB5B2A7F115CF57:\ +7FDE51EFB4044017C95E3608F8FB6F:10 + +4F13EB6FBE1FA2FCD7B5B21C9F20980D1986A4:EE73EEE90E35AF2BC3575D:\ +514DBCE520AB34:11 + +41BC094049008CBAE99CAC0BA901D0B2DD15DF:BD859DAE2729A348774146B5:\ +CB6C0544FF8CF74C71E910F2220D54C509DC442CB3:12 + +95751B37945DD9DE515B45927A229AAB40F7D0:FE310AF0913149D53718AC53E5:\ +75318F49A11F42A24AF48267411FDD0831:13 + +FC250F36E5C1365C3EAD122E63F90612DBBDA7:C0107D144E53227EDE5E677A35BE:\ +8A4B5AEA3AC0B2FF777D77B5EFB6E7D8AF:14 + +F6A8A67ACA60F25080100F3F5C928038936E57:A1FCD686295E3DE32C438A8FFD63CE:\ +F8B663768421BA77861F1EBEBF4C8341DC01ED1F7D4B054B7C:15 + +77BF131D53997B1FB2ACE2137E26992B36BF3E:60D0A09FCFDE24AB73F62A7C9F594766:\ +859D1EE9A694865ECC1830C361D24485AC1026:16 + +39CF412177DD47B8E97A4D92D104138CD4E41C:F7D49D2C112F3EE64411F50B264AE15BB4:\ +9CD35F26E8A89C25410B3394A957B781BBD0D190DA:17 + +5C40AF252D0A4F445E638D954993BCB0673281:\ +FDA100D44E2F839C21199A56ACAF57454C21:\ +2DFB810DC9ED5B291754144937E6052666D476D1F5F94C:18 + +2A8B07B082F2A4C95611B20685A4410E90B8D2:\ +A5CCE186AFDB9C0EB664C719DD1A69C1BA6059:\ +320ADFA586F7EBF346646DE9:19 + +BCBD1EFDA490B9D541BA9DF50FE9A451DD0313:\ +2291E19459725562F106F63FE2F81E73BA23F04A:\ +255230A341E671BC31B1:20 + +B361B123993602D0BA62567BF9B81992DB108EAE:\ +A71CB3E9C58E83414D69775CF7127E9C95AF10B7E2:\ +20878A3A703785DE37846086C097619E9823F7FCD2B7B3A9466FA6:21 + +8E7CC0EED8BFF691B370C08FE0DB32D06700B088:\ +25DA6B3027CBBCA4352EFB85D3FCB9060285BC39ECB8:\ +02F3B9155F5CFF08B9F47A2FDC701BA3F08BCDDF21292911D06FC0A5A99B:22 + +041CC7ED27C01A701A0F15269DA6CA6D806B10C3:\ +E3B7F0D721C05663166B43A75F2997F9F029886FC069D0:\ +8E5F4FADE80AF92D495AF5A50C8E:23 + +A7421C0D96D2455E57408C2BF02E86DCEE71B060:\ +46948B1DD4C7977AA7241ABD74A88E7838E575DD34AA9B75:\ +BD2623716653B538C885FA2ED4B0A2:24 + +56DAD2D1AF95F938E073D10A1A779F80BB0F76FE:\ +53B1169FA52AABC427D1C41501B612DF6D726F55DAD9D246E9:\ +D1DA1DEF7BD5C327894B7A992AA7A694664470F642:25 + +4F2E4F77820A686894B90A0AFD0ABA772D0CC6B0:\ +30ED285AE596143BE7998901C2F35530D81CA4DD14E03D17DF2C:\ +062577E22854BAF0E68A51A27644FFB0:26 + +86173BD0F3C5E7052482B53BD8604E197112F3D8:\ +BB3BD1CBFA7889441E930C4B5E8EC7AB00D9612E9D762D42427AD9:\ +12B4E5F24ADC8A:27 + +2B9CE8B0AB3041D6A1803BDD342E6537E40BE305:\ +88F8AFCB8109C7B359B18CCED73A1B09404CC9EABB23695BF353ED9E:\ +517D3D00850F48912B713E653CB4F38703B6A6:28 + +819CB722AA4475D8301A8E24DCD9D82DF2B081F4:\ +83FD6F33AD11819019E086F0683E26D59D57C9E5AF26C81738E44D47A3:\ +56872A31A10E8C:29 + +80F1F9B0D05F41C448E5306E41833918B9E688ED:\ +0C00B5F50565FDD5345C63773D5FCC8B3C8E412DFFF23B95490EFB4E53FA:\ +6175CDE230DF6691F4E8A36B265C53CAD736AD6F34F895D5C6633D66B5:30 + +0AE876A7BB96C24CEFA6ED53CEE7B0A41B8FF7B3:\ +881B99C3E43B1A42F096CF556D3143D5C5DBC4E984D26C5F3075BCB08B73DA::31 + +2212169D33FADC6FF94A3E5E0020587953CF1964:\ +1E1C646C2BFBDC62FA4C81F1D0781F5F269D3F45E5C33CAC8A2640226C8C5D16:\ +FCD5C9637A21E43F3CFF6ECF65B6E2F97933779F101AD6:32 + # From RFC 2631 [X9.42-PRF(KeyWrap.TripleDES)] diff --git a/include/kdf.h b/include/kdf.h index 57f1dc047..ad7a11dbe 100644 --- a/include/kdf.h +++ b/include/kdf.h @@ -16,11 +16,11 @@ namespace Botan { class BOTAN_DLL KDF1 : public KDF { public: - KDF1(const std::string&); - private: SecureVector<byte> derive(u32bit, const byte[], u32bit, const byte[], u32bit) const; + KDF1(const std::string&); + private: const std::string hash_name; }; @@ -30,11 +30,11 @@ class BOTAN_DLL KDF1 : public KDF class BOTAN_DLL KDF2 : public KDF { public: + SecureVector<byte> derive(u32bit, const byte[], u32bit, + const byte[], u32bit) const; KDF2(const std::string&); private: - SecureVector<byte> derive(u32bit, const byte[], u32bit, - const byte[], u32bit) const; const std::string hash_name; }; @@ -44,12 +44,36 @@ class BOTAN_DLL KDF2 : public KDF class BOTAN_DLL X942_PRF : public KDF { public: + SecureVector<byte> derive(u32bit, const byte[], u32bit, + const byte[], u32bit) const; + X942_PRF(const std::string&); private: + std::string key_wrap_oid; + }; + +/************************************************* +* SSL3 PRF * +*************************************************/ +class BOTAN_DLL SSL3_PRF : public KDF + { + public: SecureVector<byte> derive(u32bit, const byte[], u32bit, const byte[], u32bit) const; + }; - std::string key_wrap_oid; +/************************************************* +* TLS PRF * +*************************************************/ +class BOTAN_DLL TLS_PRF : public KDF + { + public: + SecureVector<byte> derive(u32bit, const byte[], u32bit, + const byte[], u32bit) const; + private: + SecureVector<byte> P_hash(const std::string&, u32bit, + const byte[], u32bit, + const byte[], u32bit) const; }; } diff --git a/include/ssl3_mac.h b/include/ssl3_mac.h new file mode 100644 index 000000000..8ab08c97d --- /dev/null +++ b/include/ssl3_mac.h @@ -0,0 +1,34 @@ +/************************************************* +* SSL3-MAC Header File * +* (C) 1999-2004 Jack Lloyd * +*************************************************/ + +#ifndef BOTAN_SSL3_MAC_H__ +#define BOTAN_SSL3_MAC_H__ + +#include <botan/base.h> + +namespace Botan { + +/************************************************* +* SSL3-MAC * +*************************************************/ +class SSL3_MAC : public MessageAuthenticationCode + { + public: + void clear() throw(); + std::string name() const; + MessageAuthenticationCode* clone() const; + SSL3_MAC(const std::string&); + ~SSL3_MAC() { delete hash; } + private: + void add_data(const byte[], u32bit); + void final_result(byte[]); + void key(const byte[], u32bit); + HashFunction* hash; + SecureVector<byte> i_key, o_key; + }; + +} + +#endif diff --git a/src/def_alg.cpp b/src/def_alg.cpp index 29e99d6a0..bba904b11 100644 --- a/src/def_alg.cpp +++ b/src/def_alg.cpp @@ -57,6 +57,7 @@ #include <botan/cbc_mac.h> #include <botan/cmac.h> #include <botan/hmac.h> +#include <botan/ssl3_mac.h> #include <botan/x919_mac.h> #include <botan/mode_pad.h> @@ -233,6 +234,7 @@ Default_Engine::find_mac(const std::string& algo_spec) const HANDLE_TYPE_ONE_STRING("CBC-MAC", CBC_MAC); HANDLE_TYPE_ONE_STRING("CMAC", CMAC); HANDLE_TYPE_ONE_STRING("HMAC", HMAC); + HANDLE_TYPE_ONE_STRING("SSL3-MAC", SSL3_MAC); HANDLE_TYPE_NO_ARGS("X9.19-MAC", ANSI_X919_MAC); return 0; diff --git a/src/get_enc.cpp b/src/get_enc.cpp index 29a166b2c..31c1e06aa 100644 --- a/src/get_enc.cpp +++ b/src/get_enc.cpp @@ -106,6 +106,16 @@ KDF* get_kdf(const std::string& algo_spec) if(name.size() == 2) return new X942_PRF(name[1]); } + if(kdf_name == "TLS-PRF") + { + if(name.size() == 1) + return new TLS_PRF; + } + else if(kdf_name == "SSL3-PRF") + { + if(name.size() == 1) + return new SSL3_PRF; + } else throw Algorithm_Not_Found(algo_spec); diff --git a/src/ssl3_mac.cpp b/src/ssl3_mac.cpp new file mode 100644 index 000000000..ceb04bf44 --- /dev/null +++ b/src/ssl3_mac.cpp @@ -0,0 +1,88 @@ +/************************************************* +* SSL3-MAC Source File * +* (C) 1999-2004 Jack Lloyd * +*************************************************/ + +#include <botan/ssl3_mac.h> +#include <botan/lookup.h> + +namespace Botan { + +/************************************************* +* Update a SSL3-MAC Calculation * +*************************************************/ +void SSL3_MAC::add_data(const byte input[], u32bit length) + { + hash->update(input, length); + } + +/************************************************* +* Finalize a SSL3-MAC Calculation * +*************************************************/ +void SSL3_MAC::final_result(byte mac[]) + { + hash->final(mac); + hash->update(o_key); + hash->update(mac, OUTPUT_LENGTH); + hash->final(mac); + hash->update(i_key); + } + +/************************************************* +* SSL3-MAC Key Schedule * +*************************************************/ +void SSL3_MAC::key(const byte key[], u32bit length) + { + hash->clear(); + std::fill(i_key.begin(), i_key.end(), 0x36); + std::fill(o_key.begin(), o_key.end(), 0x5C); + + i_key.copy(key, length); + o_key.copy(key, length); + hash->update(i_key); + } + +/************************************************* +* Clear memory of sensitive data * +*************************************************/ +void SSL3_MAC::clear() throw() + { + hash->clear(); + i_key.clear(); + o_key.clear(); + } + +/************************************************* +* Return the name of this type * +*************************************************/ +std::string SSL3_MAC::name() const + { + return "SSL3-MAC(" + hash->name() + ")"; + } + +/************************************************* +* Return a clone of this object * +*************************************************/ +MessageAuthenticationCode* SSL3_MAC::clone() const + { + return new SSL3_MAC(hash->name()); + } + +/************************************************* +* SSL3-MAC Constructor * +*************************************************/ +SSL3_MAC::SSL3_MAC(const std::string& hash_name) : + MessageAuthenticationCode(output_length_of(hash_name), + output_length_of(hash_name)), + hash(get_hash(hash_name)) + { + if(hash->name() != "MD5" && hash->name() != "SHA-160") + throw Invalid_Argument("SSL3-MAC cannot be used with " + hash->name()); + + const u32bit INNER_HASH_LENGTH = (hash->name() == "MD5") ? 64 : 60; + + i_key.create(INNER_HASH_LENGTH); + o_key.create(INNER_HASH_LENGTH); + } + +} diff --git a/src/ssl3_prf.cpp b/src/ssl3_prf.cpp new file mode 100644 index 000000000..a86ed8ff7 --- /dev/null +++ b/src/ssl3_prf.cpp @@ -0,0 +1,71 @@ +/************************************************* +* SSL3 PRF Source File * +* (C) 2004-2006 Jack Lloyd * +*************************************************/ + +#include <botan/kdf.h> +#include <botan/lookup.h> +#include <memory> + +namespace Botan { + +namespace { + +/************************************************* +* Return the next inner hash * +*************************************************/ +OctetString next_hash(u32bit where, u32bit want, + HashFunction* md5, HashFunction* sha1, + const byte secret[], u32bit secret_len, + const byte seed[], u32bit seed_len) + { + if(want > md5->OUTPUT_LENGTH) + throw Internal_Error("SSL3_PRF:next_hash: want is too big"); + + const byte ASCII_A_CHAR = 0x41; + + for(u32bit j = 0; j != where + 1; j++) + sha1->update(ASCII_A_CHAR + where); + sha1->update(secret, secret_len); + sha1->update(seed, seed_len); + SecureVector<byte> sha1_hash = sha1->final(); + + md5->update(secret, secret_len); + md5->update(sha1_hash); + SecureVector<byte> md5_hash = md5->final(); + + return OctetString(md5_hash, want); + } + +} + +/************************************************* +* SSL3 PRF * +*************************************************/ +SecureVector<byte> SSL3_PRF::derive(u32bit key_len, + const byte secret[], u32bit secret_len, + const byte seed[], u32bit seed_len) const + { + if(key_len > 416) + throw Internal_Error("SSL3_PRF: Requested key length is too large"); + + std::auto_ptr<HashFunction> md5(get_hash("MD5")); + std::auto_ptr<HashFunction> sha1(get_hash("SHA-1")); + + OctetString output; + + int counter = 0; + while(key_len) + { + const u32bit produce = std::min(key_len, md5->OUTPUT_LENGTH); + + output = output + next_hash(counter++, produce, md5.get(), sha1.get(), + secret, secret_len, seed, seed_len); + + key_len -= produce; + } + + return output.bits_of(); + } + +} diff --git a/src/tls_prf.cpp b/src/tls_prf.cpp new file mode 100644 index 000000000..2222e3baa --- /dev/null +++ b/src/tls_prf.cpp @@ -0,0 +1,63 @@ +/************************************************* +* TLS PRF Source File * +* (C) 2004-2006 Jack Lloyd * +*************************************************/ + +#include <botan/kdf.h> +#include <botan/lookup.h> +#include <botan/xor_buf.h> +#include <botan/hmac.h> + +namespace Botan { + +/************************************************* +* TLS PRF * +*************************************************/ +SecureVector<byte> TLS_PRF::derive(u32bit key_len, + const byte secret[], u32bit secret_len, + const byte seed[], u32bit seed_len) const + { + u32bit S1_len = (secret_len + 1) / 2, + S2_len = (secret_len + 1) / 2; + const byte* S1 = secret; + const byte* S2 = secret + (secret_len - S2_len); + + SecureVector<byte> key1, key2; + key1 = P_hash("MD5", key_len, S1, S1_len, seed, seed_len); + key2 = P_hash("SHA-1", key_len, S2, S2_len, seed, seed_len); + + xor_buf(key1.begin(), key2.begin(), key2.size()); + + return key1; + } + +/************************************************* +* TLS PRF P_hash function * +*************************************************/ +SecureVector<byte> TLS_PRF::P_hash(const std::string& hash, u32bit len, + const byte secret[], u32bit secret_len, + const byte seed[], u32bit seed_len) const + { + SecureVector<byte> out; + + HMAC hmac(hash); + hmac.set_key(secret, secret_len); + + SecureVector<byte> A(seed, seed_len); + while(len) + { + const u32bit this_block_len = std::min(hmac.OUTPUT_LENGTH, len); + + A = hmac.process(A); + + hmac.update(A); + hmac.update(seed, seed_len); + SecureVector<byte> block = hmac.final(); + + out.append(block, this_block_len); + len -= this_block_len; + } + return out; + } + +} |