BIND 10 trac781, updated. 34ba5055b70c9de09d406b3e51ad2e02b98f6439 [trac781] add tests from rfc4231 for sha256, and support keys>blocksize

BIND 10 source code commits bind10-changes at lists.isc.org
Mon Apr 11 12:59:17 UTC 2011


The branch, trac781 has been updated
       via  34ba5055b70c9de09d406b3e51ad2e02b98f6439 (commit)
       via  238dca82160452df0eb732ce014166777380767e (commit)
      from  253d063204f1e0656c89650999c76f942b4840f6 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 34ba5055b70c9de09d406b3e51ad2e02b98f6439
Author: Jelte Jansen <jelte at isc.org>
Date:   Mon Apr 11 14:58:50 2011 +0200

    [trac781] add tests from rfc4231 for sha256, and support keys>blocksize

commit 238dca82160452df0eb732ce014166777380767e
Author: Jelte Jansen <jelte at isc.org>
Date:   Mon Apr 11 14:22:43 2011 +0200

    [trac781] document to/from string

-----------------------------------------------------------------------

Summary of changes:
 src/lib/crypto/crypto.cc                 |   41 ++++++++--
 src/lib/crypto/crypto.h                  |   24 ++++++
 src/lib/crypto/tests/crypto_unittests.cc |  125 ++++++++++++++++++++++++++++++
 3 files changed, 181 insertions(+), 9 deletions(-)

-----------------------------------------------------------------------
diff --git a/src/lib/crypto/crypto.cc b/src/lib/crypto/crypto.cc
index 2437ecf..ba4fa40 100644
--- a/src/lib/crypto/crypto.cc
+++ b/src/lib/crypto/crypto.cc
@@ -20,6 +20,7 @@
 #include "crypto_botan.h"
 #include <botan/botan.h>
 #include <botan/hmac.h>
+#include <botan/hash.h>
 #include <botan/types.h>
 
 #include <dns/buffer.h>
@@ -47,10 +48,10 @@ HashFunction* getHash(const Name& hash_name) {
     }
 }
 
-    // Library needs to have been inited during the entire program
-    // should we make this a singleton? (for hsm we'll need more
-    // initialization, and dynamic loading)
-    LibraryInitializer init;
+// Library needs to have been inited during the entire program
+// should we make this a singleton? (for hsm we'll need more
+// initialization, and dynamic loading)
+LibraryInitializer init;
 
 } // local namespace
 
@@ -66,9 +67,18 @@ signHMAC(const OutputBuffer& data, TSIGKey key,
     HMAC::HMAC hmac(hash);
 
     // Take the 'secret' from the key
+    // If the key length is larger than the block size, we hash the
+    // key itself first.
     try {
-        hmac.set_key(static_cast<const byte*>(key.getSecret()),
-                    key.getSecretLength());
+        if (key.getSecretLength() > hash->HASH_BLOCK_SIZE) {
+            SecureVector<byte> hashed_key =
+                hash->process(static_cast<const byte*>(key.getSecret()),
+                              key.getSecretLength());
+            hmac.set_key(hashed_key.begin(), hashed_key.size());
+        } else {
+            hmac.set_key(static_cast<const byte*>(key.getSecret()),
+                         key.getSecretLength());
+        }
     } catch (Invalid_Key_Length ikl) {
         isc_throw(BadKey, ikl.what());
     }
@@ -90,14 +100,27 @@ verifyHMAC(const OutputBuffer& data, TSIGKey key,
 {
     HashFunction* hash = getHash(key.getAlgorithmName());
     HMAC::HMAC hmac(hash);
+    // If the key length is larger than the block size, we hash the
+    // key itself first.
     try {
-        hmac.set_key(static_cast<const byte*>(key.getSecret()), key.getSecretLength());
+        if (key.getSecretLength() > hash->HASH_BLOCK_SIZE) {
+            SecureVector<byte> hashed_key =
+                hash->process(static_cast<const byte*>(key.getSecret()),
+                              key.getSecretLength());
+            hmac.set_key(hashed_key.begin(), hashed_key.size());
+        } else {
+            hmac.set_key(static_cast<const byte*>(key.getSecret()),
+                         key.getSecretLength());
+        }
     } catch (Invalid_Key_Length ikl) {
         isc_throw(BadKey, ikl.what());
     }
-    hmac.update(static_cast<const byte*>(data.getData()), data.getLength());
 
-    return hmac.verify_mac(static_cast<const byte*>(result.getData()), result.getLength());
+    hmac.update(static_cast<const byte*>(data.getData()),
+                data.getLength());
+
+    return hmac.verify_mac(static_cast<const byte*>(result.getData()),
+                           result.getLength());
 }
 
 isc::dns::TSIGKey
diff --git a/src/lib/crypto/crypto.h b/src/lib/crypto/crypto.h
index 5a9dbe8..7b60624 100644
--- a/src/lib/crypto/crypto.h
+++ b/src/lib/crypto/crypto.h
@@ -84,8 +84,32 @@ bool verifyHMAC(const isc::dns::OutputBuffer& data,
                 isc::dns::TSIGKey key,
                 const isc::dns::OutputBuffer& mac);
 
+/// \brief Create a TSIGKey from an input string
+///
+/// This function takes an input string and creates a TSIG key
+/// from it. The string must be of the form:
+/// <name>:<secret>[:<algorithm>]
+/// Where <name> is a domain name for the key, <secret> is a
+/// base64 representation of the key secret, and the optional
+/// algorithm is an algorithm identifier as specified in RFC4635
+///
+/// Raises an InvalidParameter exception if the input string is
+/// invalid.
+///
+/// \param str The string to make a TSIGKey from
+/// \return The TSIGKey build from the string
 isc::dns::TSIGKey TSIGKeyFromString(const std::string& str);
 
+/// \brief Converts the given TSIGKey to a string value
+///
+/// The resulting string will be of the form
+/// name:secret:algorithm
+/// Where <name> is a domain name for the key, <secret> is a
+/// base64 representation of the key secret, and algorithm is
+/// an algorithm identifier as specified in RFC4635
+///
+/// \param key the TSIG key to convert
+/// \return The string representation of the given TSIGKey.
 std::string TSIGKeyToString(const isc::dns::TSIGKey& key);
 
 } // namespace crypto
diff --git a/src/lib/crypto/tests/crypto_unittests.cc b/src/lib/crypto/tests/crypto_unittests.cc
index 9680346..0167b8a 100644
--- a/src/lib/crypto/tests/crypto_unittests.cc
+++ b/src/lib/crypto/tests/crypto_unittests.cc
@@ -44,6 +44,7 @@ namespace {
         
         signHMAC(data_buf, key, hmac_sig);
         checkBuffer(hmac_sig, expected_hmac, hmac_len);
+        EXPECT_TRUE(verifyHMAC(data_buf, key, hmac_sig));
     }
 }
 
@@ -179,6 +180,130 @@ TEST(CryptoTest, HMAC_SHA1_RFC2202_SIGN) {
                hmac_expected7, 20);
 }
 
+//
+// Test values taken from RFC 4231
+//
+TEST(CryptoTest, HMAC_SHA256_RFC2202_SIGN) {
+    uint8_t hmac_expected[] = { 0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb,
+                                0x38, 0x53, 0x5c, 0xa8, 0xaf, 0xce,
+                                0xaf, 0x0b, 0xf1, 0x2b, 0x88, 0x1d,
+                                0xc2, 0x00, 0xc9, 0x83, 0x3d, 0xa7,
+                                0x26, 0xe9, 0x37, 0x6c, 0x2e, 0x32,
+                                0xcf, 0xf7 };
+    doHMACTest("Hi There",
+               "test.example:CwsLCwsLCwsLCwsLCwsLCwsLCws=:hmac-sha256",
+               hmac_expected, 32);
+
+    uint8_t hmac_expected2[] = { 0x5b, 0xdc, 0xc1, 0x46, 0xbf, 0x60,
+                                 0x75, 0x4e, 0x6a, 0x04, 0x24, 0x26,
+                                 0x08, 0x95, 0x75, 0xc7, 0x5a, 0x00,
+                                 0x3f, 0x08, 0x9d, 0x27, 0x39, 0x83,
+                                 0x9d, 0xec, 0x58, 0xb9, 0x64, 0xec,
+                                 0x38, 0x43 };
+    doHMACTest("what do ya want for nothing?",
+               "test.example:SmVmZQ==:hmac-sha256",
+               hmac_expected2, 32);
+
+    std::string data3;
+    for (int i = 0; i < 50; ++i) {
+        data3.push_back(0xdd);
+    }
+    uint8_t hmac_expected3[] = { 0x77, 0x3e, 0xa9, 0x1e, 0x36, 0x80,
+                                 0x0e, 0x46, 0x85, 0x4d, 0xb8, 0xeb,
+                                 0xd0, 0x91, 0x81, 0xa7, 0x29, 0x59,
+                                 0x09, 0x8b, 0x3e, 0xf8, 0xc1, 0x22,
+                                 0xd9, 0x63, 0x55, 0x14, 0xce, 0xd5,
+                                 0x65, 0xfe };
+    doHMACTest(data3,
+               "test.example:qqqqqqqqqqqqqqqqqqqqqqqqqqo=:hmac-sha256",
+               hmac_expected3, 32);
+
+    std::string data4;
+    for (int i = 0; i < 50; ++i) {
+        data4.push_back(0xcd);
+    }
+    uint8_t hmac_expected4[] = { 0x82, 0x55, 0x8a, 0x38, 0x9a, 0x44,
+                                 0x3c, 0x0e, 0xa4, 0xcc, 0x81, 0x98,
+                                 0x99, 0xf2, 0x08, 0x3a, 0x85, 0xf0,
+                                 0xfa, 0xa3, 0xe5, 0x78, 0xf8, 0x07,
+                                 0x7a, 0x2e, 0x3f, 0xf4, 0x67, 0x29,
+                                 0x66, 0x5b };
+    doHMACTest(data4,
+               "test.example:AQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGQ==:hmac-sha256",
+               hmac_expected4, 32);
+
+/*
+    uint8_t hmac_expected5[] = {  };
+    doHMACTest("Test With Truncation",
+               "test.example:DAwMDAwMDAwMDAwMDAwMDAwMDAw=:hmac-sha256",
+               hmac_expected5, 32);
+*/
+    uint8_t hmac_expected6[] = { 0x60, 0xe4, 0x31, 0x59, 0x1e, 0xe0,
+                                 0xb6, 0x7f, 0x0d, 0x8a, 0x26, 0xaa,
+                                 0xcb, 0xf5, 0xb7, 0x7f, 0x8e, 0x0b,
+                                 0xc6, 0x21, 0x37, 0x28, 0xc5, 0x14,
+                                 0x05, 0x46, 0x04, 0x0f, 0x0e, 0xe3,
+                                 0x7f, 0x54 };
+    doHMACTest("Test Using Larger Than Block-Size Key - Hash Key First",
+               "test.example:qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqo=:hmac-sha256",
+               hmac_expected6, 32);
+
+    uint8_t hmac_expected7[] = { 0x9b, 0x09, 0xff, 0xa7, 0x1b, 0x94,
+                                 0x2f, 0xcb, 0x27, 0x63, 0x5f, 0xbc,
+                                 0xd5, 0xb0, 0xe9, 0x44, 0xbf, 0xdc,
+                                 0x63, 0x64, 0x4f, 0x07, 0x13, 0x93,
+                                 0x8a, 0x7f, 0x51, 0x53, 0x5c, 0x3a,
+                                 0x35, 0xe2 };
+    doHMACTest("This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.",
+               "test.example:qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqo=:hmac-sha256",
+               hmac_expected7, 32);
+}
+/*
+TEST(CryptoTest, HMAC_SHA256_RFC2202_SIGN) {
+    uint8_t hmac_expected[] = {  };
+    doHMACTest("Hi There",
+               "test.example:CwsLCwsLCwsLCwsLCwsLCwsLCws=:hmac-sha1",
+               hmac_expected, 20);
+
+    uint8_t hmac_expected2[] = {  };
+    doHMACTest("what do ya want for nothing?",
+               "test.example:SmVmZQ==:hmac-sha1",
+               hmac_expected2, 20);
+
+    std::string data3;
+    for (int i = 0; i < 50; ++i) {
+        data3.push_back(0xdd);
+    }
+    uint8_t hmac_expected3[] = {  };
+    doHMACTest(data3,
+               "test.example:qqqqqqqqqqqqqqqqqqqqqqqqqqo=:hmac-sha1",
+               hmac_expected3, 20);
+
+    std::string data4;
+    for (int i = 0; i < 50; ++i) {
+        data4.push_back(0xcd);
+    }
+    uint8_t hmac_expected4[] = {  };
+    doHMACTest(data4,
+               "test.example:AQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGQ==:hmac-sha1",
+               hmac_expected4, 20);
+
+    uint8_t hmac_expected5[] = {  };
+    doHMACTest("Test With Truncation",
+               "test.example:DAwMDAwMDAwMDAwMDAwMDAwMDAw=:hmac-sha1",
+               hmac_expected5, 20);
+               
+    uint8_t hmac_expected6[] = {  };
+    doHMACTest("Test Using Larger Than Block-Size Key - Hash Key First",
+               "test.example:qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqo=:hmac-sha1",
+               hmac_expected6, 20);
+
+    uint8_t hmac_expected7[] = {  };
+    doHMACTest("Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data",
+               "test.example:qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqo=:hmac-sha1",
+               hmac_expected7, 20);
+}
+*/
 TEST(CryptoTest, BadKey) {
     TSIGKey bad_key = TSIGKey(Name("test.example."), Name("hmac-sha1."),
                               NULL, 0);




More information about the bind10-changes mailing list