Add support for cipher suite 17

cipher suite 17 uses RAKP_HMAC_SHA256 for authentication and
RAKP_HMAC_SHA256_128 for integrity. This adds those in and fixes up the
lookups so the stack knows about the new algorithms.

Change-Id: Icdc66563d08060fc0e541ceaf3bee9dd5f89fdb2
Signed-off-by: Vernon Mauery <vernon.mauery@linux.intel.com>
diff --git a/test/cipher.cpp b/test/cipher.cpp
index ed8ccb7..3fa985c 100644
--- a/test/cipher.cpp
+++ b/test/cipher.cpp
@@ -180,6 +180,179 @@
     EXPECT_EQ(false, check);
 }
 
+TEST(IntegrityAlgo, HMAC_SHA256_128_GenerateIntegrityDataCheck)
+{
+    /*
+     * Step-1 Generate Integrity Data for the packet, using the implemented API
+     */
+    // Packet = RMCP Session Header (4 bytes) + Packet (8 bytes)
+    std::vector<uint8_t> packet = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
+
+    // Hardcoded Session Integrity Key
+    std::vector<uint8_t> sik = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+                                 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+                                 23, 24, 25, 26, 27, 28, 29, 30, 31, 32 };
+
+    auto algoPtr = std::make_unique<cipher::integrity::AlgoSHA256>(sik);
+
+    ASSERT_EQ(true, (algoPtr != NULL));
+
+    // Generate the Integrity Data
+    auto response = algoPtr->generateIntegrityData(packet);
+
+    EXPECT_EQ(true, (response.size() ==
+                    cipher::integrity::AlgoSHA256::SHA256_128_AUTHCODE_LENGTH));
+
+    /*
+     * Step-2 Generate Integrity data using OpenSSL SHA256 algorithm
+     */
+    std::vector<uint8_t> k1(SHA256_DIGEST_LENGTH);
+    constexpr rmcp::Const_n const1 = { 0x01, 0x01, 0x01, 0x01, 0x01,
+                                       0x01, 0x01, 0x01, 0x01, 0x01,
+                                       0x01, 0x01, 0x01, 0x01, 0x01,
+                                       0x01, 0x01, 0x01, 0x01, 0x01
+                                     };
+
+    // Generated K1 for the integrity algorithm with the additional key keyed
+    // with SIK.
+    unsigned int mdLen = 0;
+    if (HMAC(EVP_sha256(), sik.data(), sik.size(), const1.data(),
+             const1.size(), k1.data(), &mdLen) == NULL)
+    {
+        FAIL() << "Generating Key1 failed";
+    }
+
+    mdLen = 0;
+    std::vector<uint8_t> output(SHA256_DIGEST_LENGTH);
+    size_t length = packet.size() - message::parser::RMCP_SESSION_HEADER_SIZE;
+
+    if (HMAC(EVP_sha256(), k1.data(), k1.size(),
+             packet.data() + message::parser::RMCP_SESSION_HEADER_SIZE,
+             length,
+             output.data(), &mdLen) == NULL)
+    {
+        FAIL() << "Generating integrity data failed";
+    }
+
+    output.resize(cipher::integrity::AlgoSHA256::SHA256_128_AUTHCODE_LENGTH);
+
+    /*
+     * Step-3 Check if the integrity data we generated using the implemented API
+     * matches with one generated by OpenSSL SHA256 algorithm.
+     */
+    auto check = std::equal(output.begin(), output.end(), response.begin());
+    EXPECT_EQ(true, check);
+}
+
+TEST(IntegrityAlgo, HMAC_SHA256_128_VerifyIntegrityDataPass)
+{
+    /*
+     * Step-1 Generate Integrity data using OpenSSL SHA256 algorithm
+     */
+
+    // Packet = RMCP Session Header (4 bytes) + Packet (8 bytes)
+    std::vector<uint8_t> packet = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
+
+    // Hardcoded Session Integrity Key
+    std::vector<uint8_t> sik = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+                                 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+                                 23, 24, 25, 26, 27, 28, 29, 30, 31, 32 };
+
+    std::vector<uint8_t> k1(SHA256_DIGEST_LENGTH);
+    constexpr rmcp::Const_n const1 = { 0x01, 0x01, 0x01, 0x01, 0x01,
+                                       0x01, 0x01, 0x01, 0x01, 0x01,
+                                       0x01, 0x01, 0x01, 0x01, 0x01,
+                                       0x01, 0x01, 0x01, 0x01, 0x01
+                                     };
+
+    // Generated K1 for the integrity algorithm with the additional key keyed
+    // with SIK.
+    unsigned int mdLen = 0;
+    if (HMAC(EVP_sha256(), sik.data(), sik.size(), const1.data(),
+             const1.size(), k1.data(), &mdLen) == NULL)
+    {
+        FAIL() << "Generating Key1 failed";
+    }
+
+    mdLen = 0;
+    std::vector<uint8_t> output(SHA256_DIGEST_LENGTH);
+    size_t length = packet.size() - message::parser::RMCP_SESSION_HEADER_SIZE;
+
+    if (HMAC(EVP_sha256(), k1.data(), k1.size(),
+             packet.data() + message::parser::RMCP_SESSION_HEADER_SIZE,
+             length,
+             output.data(), &mdLen) == NULL)
+    {
+        FAIL() << "Generating integrity data failed";
+    }
+
+    output.resize(cipher::integrity::AlgoSHA256::SHA256_128_AUTHCODE_LENGTH);
+
+    /*
+     * Step-2 Insert the integrity data into the packet
+     */
+    auto packetSize = packet.size();
+    packet.insert(packet.end(), output.begin(), output.end());
+
+    // Point to the integrity data in the packet
+    auto integrityIter = packet.cbegin();
+    std::advance(integrityIter, packetSize);
+
+    /*
+     * Step-3 Invoke the verifyIntegrityData API and validate the response
+     */
+
+    auto algoPtr = std::make_unique<cipher::integrity::AlgoSHA256>(sik);
+    ASSERT_EQ(true, (algoPtr != NULL));
+
+    auto check = algoPtr->verifyIntegrityData(
+            packet,
+            packetSize - message::parser::RMCP_SESSION_HEADER_SIZE,
+            integrityIter);
+
+    EXPECT_EQ(true, check);
+}
+
+TEST(IntegrityAlgo, HMAC_SHA256_128_VerifyIntegrityDataFail)
+{
+    /*
+     * Step-1 Add hardcoded Integrity data to the packet
+     */
+
+    // Packet = RMCP Session Header (4 bytes) + Packet (8 bytes)
+    std::vector<uint8_t> packet = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
+
+    std::vector<uint8_t> integrity = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
+
+    packet.insert(packet.end(), integrity.begin(), integrity.end());
+
+    // Point to the integrity data in the packet
+    auto integrityIter = packet.cbegin();
+    std::advance(integrityIter, packet.size());
+
+    /*
+     * Step-2 Invoke the verifyIntegrityData API and validate the response
+     */
+
+    // Hardcoded Session Integrity Key
+    std::vector<uint8_t> sik = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
+                                 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
+                                 23, 24, 25, 26, 27, 28, 29, 30, 31, 32 };
+
+    auto algoPtr = std::make_unique<cipher::integrity::AlgoSHA256>(sik);
+
+    ASSERT_EQ(true, (algoPtr != NULL));
+
+
+    // Verify the Integrity Data
+    auto check = algoPtr->verifyIntegrityData(
+            packet,
+            packet.size() - message::parser::RMCP_SESSION_HEADER_SIZE,
+            integrityIter);
+
+    EXPECT_EQ(false, check);
+}
+
 TEST(CryptAlgo, AES_CBC_128_EncryptPayloadValidate)
 {
     /*