Botan  1.11.15
src/lib/kdf/prf_tls/prf_tls.cpp
Go to the documentation of this file.
00001 /*
00002 * TLS v1.0 and v1.2 PRFs
00003 * (C) 2004-2010 Jack Lloyd
00004 *
00005 * Botan is released under the Simplified BSD License (see license.txt)
00006 */
00007 
00008 #include <botan/internal/kdf_utils.h>
00009 #include <botan/prf_tls.h>
00010 #include <botan/hmac.h>
00011 
00012 namespace Botan {
00013 
00014 TLS_12_PRF* TLS_12_PRF::make(const Spec& spec)
00015    {
00016    if(auto mac = make_a<MessageAuthenticationCode>(spec.arg(0)))
00017       return new TLS_12_PRF(mac);
00018    if(auto hash = make_a<HashFunction>(spec.arg(0)))
00019       return new TLS_12_PRF(new HMAC(hash));
00020    return nullptr;
00021    }
00022 
00023 BOTAN_REGISTER_NAMED_T(KDF, "TLS-12-PRF", TLS_12_PRF, TLS_12_PRF::make);
00024 BOTAN_REGISTER_KDF_NOARGS(TLS_PRF, "TLS-PRF");
00025 
00026 TLS_PRF::TLS_PRF()
00027    {
00028    m_hmac_md5.reset(make_a<MessageAuthenticationCode>("HMAC(MD5)"));
00029    m_hmac_sha1.reset(make_a<MessageAuthenticationCode>("HMAC(SHA-1)"));
00030    }
00031 
00032 namespace {
00033 
00034 /*
00035 * TLS PRF P_hash function
00036 */
00037 void P_hash(byte out[], size_t out_len,
00038             MessageAuthenticationCode& mac,
00039             const byte secret[], size_t secret_len,
00040             const byte salt[], size_t salt_len)
00041    {
00042    try
00043       {
00044       mac.set_key(secret, secret_len);
00045       }
00046    catch(Invalid_Key_Length)
00047       {
00048       throw Internal_Error("The premaster secret of " +
00049                            std::to_string(secret_len) +
00050                            " bytes is too long for the PRF");
00051       }
00052 
00053    secure_vector<byte> A(salt, salt + salt_len);
00054    secure_vector<byte> h;
00055 
00056    size_t offset = 0;
00057 
00058    while(offset != out_len)
00059       {
00060       A = mac.process(A);
00061 
00062       mac.update(A);
00063       mac.update(salt, salt_len);
00064       mac.final(h);
00065 
00066       const size_t writing = std::min(h.size(), out_len - offset);
00067       xor_buf(&out[offset], &h[0], writing);
00068       offset += writing;
00069       }
00070    }
00071 
00072 }
00073 
00074 size_t TLS_PRF::kdf(byte key[], size_t key_len,
00075                     const byte secret[], size_t secret_len,
00076                     const byte salt[], size_t salt_len) const
00077    {
00078    const size_t S1_len = (secret_len + 1) / 2,
00079                 S2_len = (secret_len + 1) / 2;
00080    const byte* S1 = secret;
00081    const byte* S2 = secret + (secret_len - S2_len);
00082 
00083    P_hash(key, key_len, *m_hmac_md5,  S1, S1_len, salt, salt_len);
00084    P_hash(key, key_len, *m_hmac_sha1, S2, S2_len, salt, salt_len);
00085    return key_len;
00086    }
00087 
00088 size_t TLS_12_PRF::kdf(byte key[], size_t key_len,
00089                        const byte secret[], size_t secret_len,
00090                        const byte salt[], size_t salt_len) const
00091    {
00092    P_hash(key, key_len, *m_mac, secret, secret_len, salt, salt_len);
00093    return key_len;
00094    }
00095 
00096 }