Botan  1.11.15
src/lib/kdf/prf_x942/prf_x942.cpp
Go to the documentation of this file.
00001 /*
00002 * X9.42 PRF
00003 * (C) 1999-2007 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_x942.h>
00010 #include <botan/der_enc.h>
00011 #include <botan/oids.h>
00012 #include <botan/hash.h>
00013 #include <botan/loadstor.h>
00014 #include <algorithm>
00015 
00016 namespace Botan {
00017 
00018 BOTAN_REGISTER_KDF_NAMED_1STR(X942_PRF, "X9.42-PRF");
00019 
00020 namespace {
00021 
00022 /*
00023 * Encode an integer as an OCTET STRING
00024 */
00025 std::vector<byte> encode_x942_int(u32bit n)
00026    {
00027    byte n_buf[4] = { 0 };
00028    store_be(n, n_buf);
00029    return DER_Encoder().encode(n_buf, 4, OCTET_STRING).get_contents_unlocked();
00030    }
00031 
00032 }
00033 
00034 size_t X942_PRF::kdf(byte key[], size_t key_len,
00035                      const byte secret[], size_t secret_len,
00036                      const byte salt[], size_t salt_len) const
00037    {
00038    std::unique_ptr<HashFunction> hash(make_a<HashFunction>("SHA-160"));
00039    const OID kek_algo(m_key_wrap_oid);
00040 
00041    secure_vector<byte> h;
00042    size_t offset = 0;
00043    u32bit counter = 1;
00044 
00045    while(offset != key_len && counter)
00046       {
00047       hash->update(secret, secret_len);
00048 
00049       hash->update(
00050          DER_Encoder().start_cons(SEQUENCE)
00051 
00052             .start_cons(SEQUENCE)
00053                .encode(kek_algo)
00054                .raw_bytes(encode_x942_int(counter))
00055             .end_cons()
00056 
00057             .encode_if(salt_len != 0,
00058                DER_Encoder()
00059                   .start_explicit(0)
00060                      .encode(salt, salt_len, OCTET_STRING)
00061                   .end_explicit()
00062                )
00063 
00064             .start_explicit(2)
00065                .raw_bytes(encode_x942_int(static_cast<u32bit>(8 * key_len)))
00066             .end_explicit()
00067 
00068          .end_cons().get_contents()
00069          );
00070 
00071       hash->final(h);
00072       const size_t copied = std::min(h.size(), key_len - offset);
00073       copy_mem(&key[offset], &h[0], copied);
00074       offset += copied;
00075 
00076       ++counter;
00077       }
00078 
00079    return offset;
00080    }
00081 
00082 /*
00083 * X9.42 Constructor
00084 */
00085 X942_PRF::X942_PRF(const std::string& oid)
00086    {
00087    if(OIDS::have_oid(oid))
00088       m_key_wrap_oid = OIDS::lookup(oid).as_string();
00089    else
00090       m_key_wrap_oid = oid;
00091    }
00092 
00093 }