aboutsummaryrefslogtreecommitdiffstats
path: root/src/kdf/prf_ssl3/prf_ssl3.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/kdf/prf_ssl3/prf_ssl3.cpp')
-rw-r--r--src/kdf/prf_ssl3/prf_ssl3.cpp76
1 files changed, 76 insertions, 0 deletions
diff --git a/src/kdf/prf_ssl3/prf_ssl3.cpp b/src/kdf/prf_ssl3/prf_ssl3.cpp
new file mode 100644
index 000000000..72cf023e2
--- /dev/null
+++ b/src/kdf/prf_ssl3/prf_ssl3.cpp
@@ -0,0 +1,76 @@
+/*
+* SSLv3 PRF
+* (C) 2004-2006 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/prf_ssl3.h>
+#include <botan/symkey.h>
+#include <botan/exceptn.h>
+#include <botan/sha160.h>
+#include <botan/md5.h>
+#include <botan/internal/assert.h>
+#include <memory>
+
+namespace Botan {
+
+namespace {
+
+/*
+* Return the next inner hash
+*/
+OctetString next_hash(size_t where, size_t want,
+ HashFunction& md5, HashFunction& sha1,
+ const byte secret[], size_t secret_len,
+ const byte seed[], size_t seed_len)
+ {
+ BOTAN_ASSERT(want <= md5.output_length(), "Desired output too large");
+
+ const byte ASCII_A_CHAR = 0x41;
+
+ for(size_t j = 0; j != where + 1; j++)
+ sha1.update(static_cast<byte>(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[0], want);
+ }
+
+}
+
+/*
+* SSL3 PRF
+*/
+SecureVector<byte> SSL3_PRF::derive(size_t key_len,
+ const byte secret[], size_t secret_len,
+ const byte seed[], size_t seed_len) const
+ {
+ if(key_len > 416)
+ throw Invalid_Argument("SSL3_PRF: Requested key length is too large");
+
+ MD5 md5;
+ SHA_160 sha1;
+
+ OctetString output;
+
+ int counter = 0;
+ while(key_len)
+ {
+ const size_t produce = std::min<size_t>(key_len, md5.output_length());
+
+ output = output + next_hash(counter++, produce, md5, sha1,
+ secret, secret_len, seed, seed_len);
+
+ key_len -= produce;
+ }
+
+ return output.bits_of();
+ }
+
+}