diff options
Diffstat (limited to 'src/kdf/ssl_prf')
-rw-r--r-- | src/kdf/ssl_prf/info.txt | 10 | ||||
-rw-r--r-- | src/kdf/ssl_prf/prf_ssl3.cpp | 71 | ||||
-rw-r--r-- | src/kdf/ssl_prf/prf_ssl3.h | 25 |
3 files changed, 106 insertions, 0 deletions
diff --git a/src/kdf/ssl_prf/info.txt b/src/kdf/ssl_prf/info.txt new file mode 100644 index 000000000..c41b59b12 --- /dev/null +++ b/src/kdf/ssl_prf/info.txt @@ -0,0 +1,10 @@ +realname "SSLv3 PRF" + +define SSL_V3_PRF + +load_on auto + +<add> +prf_ssl3.h +prf_ssl3.cpp +</add> diff --git a/src/kdf/ssl_prf/prf_ssl3.cpp b/src/kdf/ssl_prf/prf_ssl3.cpp new file mode 100644 index 000000000..b241bf60f --- /dev/null +++ b/src/kdf/ssl_prf/prf_ssl3.cpp @@ -0,0 +1,71 @@ +/************************************************* +* SSLv3 PRF Source File * +* (C) 2004-2006 Jack Lloyd * +*************************************************/ + +#include <botan/prf_ssl3.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/kdf/ssl_prf/prf_ssl3.h b/src/kdf/ssl_prf/prf_ssl3.h new file mode 100644 index 000000000..b8f498832 --- /dev/null +++ b/src/kdf/ssl_prf/prf_ssl3.h @@ -0,0 +1,25 @@ +/************************************************* +* SSLv3 PRF Header File * +* (C) 1999-2007 Jack Lloyd * +*************************************************/ + +#ifndef BOTAN_SSLV3_PRF_H__ +#define BOTAN_SSLV3_PRF_H__ + +#include <botan/kdf.h> + +namespace Botan { + +/************************************************* +* SSL3 PRF * +*************************************************/ +class BOTAN_DLL SSL3_PRF : public KDF + { + public: + SecureVector<byte> derive(u32bit, const byte[], u32bit, + const byte[], u32bit) const; + }; + +} + +#endif |