aboutsummaryrefslogtreecommitdiffstats
path: root/lib/kdf/prf_x942
diff options
context:
space:
mode:
Diffstat (limited to 'lib/kdf/prf_x942')
-rw-r--r--lib/kdf/prf_x942/info.txt7
-rw-r--r--lib/kdf/prf_x942/prf_x942.cpp92
-rw-r--r--lib/kdf/prf_x942/prf_x942.h34
3 files changed, 133 insertions, 0 deletions
diff --git a/lib/kdf/prf_x942/info.txt b/lib/kdf/prf_x942/info.txt
new file mode 100644
index 000000000..ff4a6f160
--- /dev/null
+++ b/lib/kdf/prf_x942/info.txt
@@ -0,0 +1,7 @@
+define X942_PRF 20131128
+
+<requires>
+asn1
+oid_lookup
+sha1
+</requires>
diff --git a/lib/kdf/prf_x942/prf_x942.cpp b/lib/kdf/prf_x942/prf_x942.cpp
new file mode 100644
index 000000000..149be163f
--- /dev/null
+++ b/lib/kdf/prf_x942/prf_x942.cpp
@@ -0,0 +1,92 @@
+/*
+* X9.42 PRF
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/prf_x942.h>
+#include <botan/der_enc.h>
+#include <botan/oids.h>
+#include <botan/sha160.h>
+#include <botan/loadstor.h>
+#include <algorithm>
+#include <memory>
+
+namespace Botan {
+
+namespace {
+
+/*
+* Encode an integer as an OCTET STRING
+*/
+std::vector<byte> encode_x942_int(u32bit n)
+ {
+ byte n_buf[4] = { 0 };
+ store_be(n, n_buf);
+ return DER_Encoder().encode(n_buf, 4, OCTET_STRING).get_contents_unlocked();
+ }
+
+}
+
+/*
+* X9.42 PRF
+*/
+secure_vector<byte> X942_PRF::derive(size_t key_len,
+ const byte secret[], size_t secret_len,
+ const byte salt[], size_t salt_len) const
+ {
+ SHA_160 hash;
+ const OID kek_algo(key_wrap_oid);
+
+ secure_vector<byte> key;
+ u32bit counter = 1;
+
+ while(key.size() != key_len && counter)
+ {
+ hash.update(secret, secret_len);
+
+ hash.update(
+ DER_Encoder().start_cons(SEQUENCE)
+
+ .start_cons(SEQUENCE)
+ .encode(kek_algo)
+ .raw_bytes(encode_x942_int(counter))
+ .end_cons()
+
+ .encode_if(salt_len != 0,
+ DER_Encoder()
+ .start_explicit(0)
+ .encode(salt, salt_len, OCTET_STRING)
+ .end_explicit()
+ )
+
+ .start_explicit(2)
+ .raw_bytes(encode_x942_int(static_cast<u32bit>(8 * key_len)))
+ .end_explicit()
+
+ .end_cons().get_contents()
+ );
+
+ secure_vector<byte> digest = hash.final();
+ const size_t needed = std::min(digest.size(), key_len - key.size());
+ key += std::make_pair(&digest[0], needed);
+
+ ++counter;
+ }
+
+ return key;
+ }
+
+/*
+* X9.42 Constructor
+*/
+X942_PRF::X942_PRF(const std::string& oid)
+ {
+ if(OIDS::have_oid(oid))
+ key_wrap_oid = OIDS::lookup(oid).as_string();
+ else
+ key_wrap_oid = oid;
+ }
+
+}
diff --git a/lib/kdf/prf_x942/prf_x942.h b/lib/kdf/prf_x942/prf_x942.h
new file mode 100644
index 000000000..f86b1bdd5
--- /dev/null
+++ b/lib/kdf/prf_x942/prf_x942.h
@@ -0,0 +1,34 @@
+/*
+* X9.42 PRF
+* (C) 1999-2007 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_ANSI_X942_PRF_H__
+#define BOTAN_ANSI_X942_PRF_H__
+
+#include <botan/kdf.h>
+
+namespace Botan {
+
+/**
+* PRF from ANSI X9.42
+*/
+class BOTAN_DLL X942_PRF : public KDF
+ {
+ public:
+ secure_vector<byte> derive(size_t, const byte[], size_t,
+ const byte[], size_t) const;
+
+ std::string name() const { return "X942_PRF(" + key_wrap_oid + ")"; }
+ KDF* clone() const { return new X942_PRF(key_wrap_oid); }
+
+ X942_PRF(const std::string& oid);
+ private:
+ std::string key_wrap_oid;
+ };
+
+}
+
+#endif