aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlloyd <[email protected]>2008-09-27 15:46:02 +0000
committerlloyd <[email protected]>2008-09-27 15:46:02 +0000
commit4e5e7ed847a2f39a1f059e0c5403488571ef8e96 (patch)
tree84c9658717113585c9e96839874bd59eea7b2924
parent224b5e6ed8e3154d185cf07e99bfd1e5556250fe (diff)
Add back from Ajisai 0.5.0 the implementations of the SSLv3 MAC and PRF
and the TLS v1.0 PRF. These were removed from Botan in v1.4.5. Initially I had felt that since these protocols were specific to SSL/TLS they should be placed in Ajisai (an SSL/TLS library based on Botan). However upon further reflection I have realized it is quite possible that other alternate implementations of SSL/TLS based on Botan would be quite desirable, and so to make that (a very slightly bit) easier I am adding back the SSL/TLS functions to Botan, so other SSL/TLS libs can use them directly.
-rw-r--r--checks/validate.dat240
-rw-r--r--include/kdf.h34
-rw-r--r--include/ssl3_mac.h34
-rw-r--r--src/def_alg.cpp2
-rw-r--r--src/get_enc.cpp10
-rw-r--r--src/ssl3_mac.cpp88
-rw-r--r--src/ssl3_prf.cpp71
-rw-r--r--src/tls_prf.cpp63
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;
+ }
+
+}