Botan
1.11.15
|
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 }