aboutsummaryrefslogtreecommitdiffstats
path: root/src/constructs
diff options
context:
space:
mode:
authorlloyd <[email protected]>2011-03-08 22:18:37 +0000
committerlloyd <[email protected]>2011-03-08 22:18:37 +0000
commite8ae96510f3d87e3b142df81b51c3b15e30e77f9 (patch)
tree4f61ddba33a8e06b85ba2edc1b74d1a02e7c4739 /src/constructs
parent5f4aafe005d1031b955718fbb94d6beec3e6ea48 (diff)
parent41da07c02a36add833965be5ddc60ef1cf089beb (diff)
propagate from branch 'net.randombit.botan' (head dd068808e5bf87c982765a8bcc314996053a5bdd)
to branch 'net.randombit.botan.c++0x' (head 34696d52a8148d64f7021b3e193fc56f051b9dd2)
Diffstat (limited to 'src/constructs')
-rw-r--r--src/constructs/aont/package.cpp8
-rw-r--r--src/constructs/passhash/info.txt9
-rw-r--r--src/constructs/passhash/passhash9.cpp148
-rw-r--r--src/constructs/passhash/passhash9.h51
-rw-r--r--src/constructs/rfc3394/info.txt1
-rw-r--r--src/constructs/rfc3394/rfc3394.cpp122
-rw-r--r--src/constructs/rfc3394/rfc3394.h45
7 files changed, 172 insertions, 212 deletions
diff --git a/src/constructs/aont/package.cpp b/src/constructs/aont/package.cpp
index 4d92a789c..4d46f6b61 100644
--- a/src/constructs/aont/package.cpp
+++ b/src/constructs/aont/package.cpp
@@ -46,13 +46,13 @@ void aont_package(RandomNumberGenerator& rng,
clear_mem(final_block, BLOCK_SIZE);
// XOR the hash blocks into the final block
- for(u32bit i = 0; i != blocks; ++i)
+ for(size_t i = 0; i != blocks; ++i)
{
const size_t left = std::min<size_t>(BLOCK_SIZE,
input_len - BLOCK_SIZE * i);
zeroise(buf);
- copy_mem(&buf[0], output + BLOCK_SIZE * i, left);
+ copy_mem(&buf[0], output + (BLOCK_SIZE * i), left);
for(size_t j = 0; j != sizeof(i); ++j)
buf[BLOCK_SIZE - 1 - j] ^= get_byte(sizeof(i)-1-j, i);
@@ -94,13 +94,13 @@ void aont_unpackage(BlockCipher* cipher,
const size_t blocks = ((input_len - 1) / BLOCK_SIZE);
// XOR the blocks into the package key bits
- for(u32bit i = 0; i != blocks; ++i)
+ for(size_t i = 0; i != blocks; ++i)
{
const size_t left = std::min<size_t>(BLOCK_SIZE,
input_len - BLOCK_SIZE * (i+1));
zeroise(buf);
- copy_mem(&buf[0], input + BLOCK_SIZE * i, left);
+ copy_mem(&buf[0], input + (BLOCK_SIZE * i), left);
for(size_t j = 0; j != sizeof(i); ++j)
buf[BLOCK_SIZE - 1 - j] ^= get_byte(sizeof(i)-1-j, i);
diff --git a/src/constructs/passhash/info.txt b/src/constructs/passhash/info.txt
deleted file mode 100644
index f96809f29..000000000
--- a/src/constructs/passhash/info.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-define PASSHASH9
-
-<requires>
-libstate
-pbkdf2
-rng
-base64
-</requires>
-
diff --git a/src/constructs/passhash/passhash9.cpp b/src/constructs/passhash/passhash9.cpp
deleted file mode 100644
index 367583a0a..000000000
--- a/src/constructs/passhash/passhash9.cpp
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
-* Passhash9 Password Hashing
-* (C) 2010 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#include <botan/passhash9.h>
-#include <botan/loadstor.h>
-#include <botan/libstate.h>
-#include <botan/pbkdf2.h>
-#include <botan/b64_filt.h>
-#include <botan/pipe.h>
-
-namespace Botan {
-
-namespace {
-
-const std::string MAGIC_PREFIX = "$9$";
-
-const size_t WORKFACTOR_BYTES = 2;
-const size_t ALGID_BYTES = 1;
-const size_t SALT_BYTES = 12; // 96 bits of salt
-const size_t PASSHASH9_PBKDF_OUTPUT_LEN = 24; // 192 bits output
-
-const byte PASSHASH9_DEFAULT_ALGO = 0; // HMAC(SHA-1)
-
-const size_t WORK_FACTOR_SCALE = 10000;
-
-MessageAuthenticationCode* get_pbkdf_prf(byte alg_id)
- {
- Algorithm_Factory& af = global_state().algorithm_factory();
-
- try
- {
- if(alg_id == 0)
- return af.make_mac("HMAC(SHA-1)");
- else if(alg_id == 1)
- return af.make_mac("HMAC(SHA-256)");
- else if(alg_id == 2)
- return af.make_mac("CMAC(Blowfish)");
- }
- catch(Algorithm_Not_Found) {}
-
- return 0;
- }
-
-}
-
-std::string generate_passhash9(const std::string& pass,
- RandomNumberGenerator& rng,
- u16bit work_factor)
- {
- return generate_passhash9(pass, PASSHASH9_DEFAULT_ALGO, rng, work_factor);
- }
-
-std::string generate_passhash9(const std::string& pass,
- byte alg_id,
- RandomNumberGenerator& rng,
- u16bit work_factor)
- {
- MessageAuthenticationCode* prf = get_pbkdf_prf(alg_id);
-
- if(!prf)
- throw Invalid_Argument("Passhash9: Algorithm id " +
- std::to_string(alg_id) +
- " is not defined");
-
- PKCS5_PBKDF2 kdf(prf); // takes ownership of pointer
-
- SecureVector<byte> salt(SALT_BYTES);
- rng.randomize(&salt[0], salt.size());
-
- const size_t kdf_iterations = WORK_FACTOR_SCALE * work_factor;
-
- SecureVector<byte> pbkdf2_output =
- kdf.derive_key(PASSHASH9_PBKDF_OUTPUT_LEN,
- pass,
- &salt[0], salt.size(),
- kdf_iterations).bits_of();
-
- Pipe pipe(new Base64_Encoder);
- pipe.start_msg();
- pipe.write(alg_id);
- pipe.write(get_byte(0, work_factor));
- pipe.write(get_byte(1, work_factor));
- pipe.write(salt);
- pipe.write(pbkdf2_output);
- pipe.end_msg();
-
- return MAGIC_PREFIX + pipe.read_all_as_string();
- }
-
-bool check_passhash9(const std::string& pass, const std::string& hash)
- {
- const size_t BINARY_LENGTH =
- ALGID_BYTES +
- WORKFACTOR_BYTES +
- PASSHASH9_PBKDF_OUTPUT_LEN +
- SALT_BYTES;
-
- const size_t BASE64_LENGTH =
- MAGIC_PREFIX.size() + (BINARY_LENGTH * 8) / 6;
-
- if(hash.size() != BASE64_LENGTH)
- return false;
-
- for(size_t i = 0; i != MAGIC_PREFIX.size(); ++i)
- if(hash[i] != MAGIC_PREFIX[i])
- return false;
-
- Pipe pipe(new Base64_Decoder);
- pipe.start_msg();
- pipe.write(hash.c_str() + MAGIC_PREFIX.size());
- pipe.end_msg();
-
- SecureVector<byte> bin = pipe.read_all();
-
- if(bin.size() != BINARY_LENGTH)
- return false;
-
- byte alg_id = bin[0];
-
- const size_t kdf_iterations =
- WORK_FACTOR_SCALE * load_be<u16bit>(&bin[ALGID_BYTES], 0);
-
- if(kdf_iterations == 0)
- return false;
-
- MessageAuthenticationCode* pbkdf_prf = get_pbkdf_prf(alg_id);
-
- if(pbkdf_prf == 0)
- return false; // unknown algorithm, reject
-
- PKCS5_PBKDF2 kdf(pbkdf_prf); // takes ownership of pointer
-
- SecureVector<byte> cmp = kdf.derive_key(
- PASSHASH9_PBKDF_OUTPUT_LEN,
- pass,
- &bin[ALGID_BYTES + WORKFACTOR_BYTES], SALT_BYTES,
- kdf_iterations).bits_of();
-
- return same_mem(&cmp[0],
- &bin[ALGID_BYTES + WORKFACTOR_BYTES + SALT_BYTES],
- PASSHASH9_PBKDF_OUTPUT_LEN);
- }
-
-}
diff --git a/src/constructs/passhash/passhash9.h b/src/constructs/passhash/passhash9.h
deleted file mode 100644
index 92cc391dc..000000000
--- a/src/constructs/passhash/passhash9.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
-* Passhash9 Password Hashing
-* (C) 2010 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#ifndef BOTAN_PASSHASH9_H__
-#define BOTAN_PASSHASH9_H__
-
-#include <botan/rng.h>
-
-namespace Botan {
-
-/**
-* Create a password hash using PBKDF2
-* @param password the password
-* @param rng a random number generator
-* @param work_factor how much work to do to slow down guessing attacks
-*/
-std::string BOTAN_DLL generate_passhash9(const std::string& password,
- RandomNumberGenerator& rng,
- u16bit work_factor = 10);
-
-/**
-* Create a password hash using PBKDF2
-* @param password the password
-* @param alg_id specifies which PRF to use with PBKDF2
-* 0 is HMAC(SHA-1)
-* 1 is HMAC(SHA-256)
-* 2 is CMAC(Blowfish)
-* all other values are currently undefined
-* @param rng a random number generator
-* @param work_factor how much work to do to slow down guessing attacks
-*/
-std::string BOTAN_DLL generate_passhash9(const std::string& password,
- byte alg_id,
- RandomNumberGenerator& rng,
- u16bit work_factor = 10);
-
-/**
-* Check a previously created password hash
-* @param password the password to check against
-* @param hash the stored hash to check against
-*/
-bool BOTAN_DLL check_passhash9(const std::string& password,
- const std::string& hash);
-
-}
-
-#endif
diff --git a/src/constructs/rfc3394/info.txt b/src/constructs/rfc3394/info.txt
new file mode 100644
index 000000000..496f3e138
--- /dev/null
+++ b/src/constructs/rfc3394/info.txt
@@ -0,0 +1 @@
+define RFC3394_KEYWRAP
diff --git a/src/constructs/rfc3394/rfc3394.cpp b/src/constructs/rfc3394/rfc3394.cpp
new file mode 100644
index 000000000..b000873fd
--- /dev/null
+++ b/src/constructs/rfc3394/rfc3394.cpp
@@ -0,0 +1,122 @@
+/*
+* AES Key Wrap (RFC 3394)
+* (C) 2011 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/rfc3394.h>
+#include <botan/algo_factory.h>
+#include <botan/block_cipher.h>
+#include <botan/loadstor.h>
+#include <botan/exceptn.h>
+#include <botan/internal/xor_buf.h>
+#include <memory>
+
+namespace Botan {
+
+namespace {
+
+BlockCipher* make_aes(size_t keylength,
+ Algorithm_Factory& af)
+ {
+ if(keylength == 16)
+ return af.make_block_cipher("AES-128");
+ else if(keylength == 24)
+ return af.make_block_cipher("AES-192");
+ else if(keylength == 32)
+ return af.make_block_cipher("AES-256");
+ else
+ throw std::invalid_argument("Bad KEK length for NIST keywrap");
+ }
+
+}
+
+SecureVector<byte> rfc3394_keywrap(const MemoryRegion<byte>& key,
+ const SymmetricKey& kek,
+ Algorithm_Factory& af)
+ {
+ if(key.size() % 8 != 0)
+ throw std::invalid_argument("Bad input key size for NIST key wrap");
+
+ std::auto_ptr<BlockCipher> aes(make_aes(kek.length(), af));
+ aes->set_key(kek);
+
+ const size_t n = key.size() / 8;
+
+ SecureVector<byte> R((n + 1) * 8);
+ SecureVector<byte> A(16);
+
+ for(size_t i = 0; i != 8; ++i)
+ A[i] = 0xA6;
+
+ copy_mem(&R[8], key.begin(), key.size());
+
+ for(size_t j = 0; j <= 5; ++j)
+ {
+ for(size_t i = 1; i <= n; ++i)
+ {
+ const u32bit t = (n * j) + i;
+
+ copy_mem(&A[8], &R[8*i], 8);
+
+ aes->encrypt(&A[0]);
+ copy_mem(&R[8*i], &A[8], 8);
+
+ byte t_buf[4] = { 0 };
+ store_be(t, t_buf);
+ xor_buf(&A[4], &t_buf[0], 4);
+ }
+ }
+
+ copy_mem(&R[0], &A[0], 8);
+
+ return R;
+ }
+
+SecureVector<byte> rfc3394_keyunwrap(const MemoryRegion<byte>& key,
+ const SymmetricKey& kek,
+ Algorithm_Factory& af)
+ {
+ if(key.size() < 16 || key.size() % 8 != 0)
+ throw std::invalid_argument("Bad input key size for NIST key unwrap");
+
+ std::auto_ptr<BlockCipher> aes(make_aes(kek.length(), af));
+ aes->set_key(kek);
+
+ const size_t n = (key.size() - 8) / 8;
+
+ SecureVector<byte> R(n * 8);
+ SecureVector<byte> A(16);
+
+ for(size_t i = 0; i != 8; ++i)
+ A[i] = key[i];
+
+ copy_mem(&R[0], key.begin() + 8, key.size() - 8);
+
+ for(size_t j = 0; j <= 5; ++j)
+ {
+ for(size_t i = n; i != 0; --i)
+ {
+ const u32bit t = (5 - j) * n + i;
+
+ byte t_buf[4] = { 0 };
+ store_be(t, t_buf);
+
+ xor_buf(&A[4], &t_buf[0], 4);
+
+ copy_mem(&A[8], &R[8*(i-1)], 8);
+
+ aes->decrypt(&A[0]);
+
+ copy_mem(&R[8*(i-1)], &A[8], 8);
+ }
+ }
+
+ if(load_be<u64bit>(&A[0], 0) != 0xA6A6A6A6A6A6A6A6)
+ throw Integrity_Failure("NIST key unwrap failed");
+
+ return R;
+ }
+
+}
diff --git a/src/constructs/rfc3394/rfc3394.h b/src/constructs/rfc3394/rfc3394.h
new file mode 100644
index 000000000..645586ee2
--- /dev/null
+++ b/src/constructs/rfc3394/rfc3394.h
@@ -0,0 +1,45 @@
+/*
+* AES Key Wrap (RFC 3394)
+* (C) 2011 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_AES_KEY_WRAP_H__
+#define BOTAN_AES_KEY_WRAP_H__
+
+#include <botan/symkey.h>
+
+namespace Botan {
+
+class Algorithm_Factory;
+
+/**
+* Encrypt a key under a key encryption key using the algorithm
+* described in RFC 3394
+*
+* @param key the plaintext key to encrypt
+* @param kek the key encryption key
+* @param af an algorithm factory
+* @return key encrypted under kek
+*/
+SecureVector<byte> BOTAN_DLL rfc3394_keywrap(const MemoryRegion<byte>& key,
+ const SymmetricKey& kek,
+ Algorithm_Factory& af);
+
+/**
+* Decrypt a key under a key encryption key using the algorithm
+* described in RFC 3394
+*
+* @param key the encrypted key to decrypt
+* @param kek the key encryption key
+* @param af an algorithm factory
+* @return key decrypted under kek
+*/
+SecureVector<byte> BOTAN_DLL rfc3394_keyunwrap(const MemoryRegion<byte>& key,
+ const SymmetricKey& kek,
+ Algorithm_Factory& af);
+
+}
+
+#endif