YACA: Test vector helpers 08/75608/6
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Mon, 20 Jun 2016 10:50:44 +0000 (12:50 +0200)
committerKrzysztof Jackiewicz <k.jackiewicz@samsung.com>
Thu, 23 Jun 2016 10:12:39 +0000 (12:12 +0200)
Change-Id: I09bb1c03a8ae960f1f788b9a8dca8c1331f5f07f

CMakeLists.txt
src/yaca/CMakeLists.txt
src/yaca/yaca-test-common.cpp
src/yaca/yaca-test-common.h
src/yaca/yaca-test-sign.cpp
src/yaca/yaca-test-vector.cpp [new file with mode: 0644]
src/yaca/yaca-test-vector.h [new file with mode: 0644]

index c27dd7f..1c898a3 100644 (file)
@@ -90,6 +90,10 @@ IF(SMACK_ENABLE)
     ADD_DEFINITIONS("-DWRT_SMACK_ENABLED")
 ENDIF(SMACK_ENABLE)
 
+IF(NOT DEFINED SHARE_INSTALL_PREFIX)
+       SET(SHARE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}/share")
+ENDIF(NOT DEFINED SHARE_INSTALL_PREFIX)
+
 ############################# Targets names ###################################
 
 SET(TARGET_CKM_TESTS "ckm-tests")
index a712aa3..f23396c 100644 (file)
@@ -29,6 +29,12 @@ FILE(GLOB  yaca_test_SRCS *.cpp)
 SET(YACA_TEST "yaca-test")
 ADD_EXECUTABLE(${YACA_TEST} ${yaca_test_SRCS})
 
+IF(NOT DEFINED YACA_TEST_DIR)
+       SET(YACA_TEST_DIR "${SHARE_INSTALL_PREFIX}/${YACA_TEST}")
+ENDIF(NOT DEFINED YACA_TEST_DIR)
+ADD_DEFINITIONS("-DYACA_TEST_DIR=\"${YACA_TEST_DIR}\"")
+MESSAGE(STATUS "YACA_TEST_DIR: ${YACA_TEST_DIR}")
+
 ## Link libraries ##############################################################
 PKG_CHECK_MODULES(YACA_TEST_DEPS REQUIRED yaca)
 
index b779194..bee1575 100644 (file)
@@ -56,9 +56,9 @@ const char *yaca_error(int error)
     return yaca_debug_translate_error(static_cast<yaca_error_e>(error));
 }
 
-BufPtr wrap_ptr(char* buffer)
+ChrPtr wrap_ptr(char* buffer)
 {
-    return BufPtr(buffer, yaca_free);
+    return ChrPtr(buffer, yaca_free);
 }
 
 KeyPtr wrap_ptr(yaca_key_h key)
@@ -71,7 +71,7 @@ CtxPtr wrap_ptr(yaca_context_h ctx)
     return CtxPtr(ctx, yaca_context_destroy);
 }
 
-BufPtr create_yaca_buffer(size_t size)
+ChrPtr create_yaca_buffer(size_t size)
 {
     char *buffer;
     YACA_SUCCESS(yaca_malloc(size, (void**)&buffer));
@@ -188,11 +188,11 @@ CtxPtr digest_init(yaca_digest_algorithm_e algo)
     return wrap_ptr(ctx);
 }
 
-std::vector<char> random_buffer(size_t length)
+Buffer random_buffer(size_t length)
 {
     RUNNER_ASSERT(length > 0);
 
-    std::vector<char> buffer(length);
+    Buffer buffer(length);
     std::ifstream is("/dev/urandom", std::ifstream::binary);
     RUNNER_ASSERT_MSG(is, "Failed to open /dev/urandom");
     is.read(buffer.data(), length);
index 2fc7e3d..73f5ce2 100644 (file)
@@ -108,15 +108,17 @@ do {                                                                           \
 
 #define YACA_INVALID_PARAM(func) YACA_RESULT(YACA_ERROR_INVALID_PARAMETER, func);
 
-typedef std::unique_ptr<char, int (*)(void*)> BufPtr;
+typedef std::unique_ptr<char, int (*)(void*)> ChrPtr;
 typedef std::unique_ptr<yaca_key_s, int (*)(yaca_key_h)> KeyPtr;
 typedef std::unique_ptr<yaca_context_s, int (*)(yaca_context_h)> CtxPtr;
 
-BufPtr wrap_ptr(char* buffer);
+typedef std::vector<char> Buffer;
+
+ChrPtr wrap_ptr(char* buffer);
 KeyPtr wrap_ptr(yaca_key_h key);
 CtxPtr wrap_ptr(yaca_context_h ctx);
 
-BufPtr create_yaca_buffer(size_t size);
+ChrPtr create_yaca_buffer(size_t size);
 
 KeyPtr null_key();
 
@@ -152,14 +154,10 @@ CtxPtr hmac_init(yaca_digest_algorithm_e algo, const KeyPtr& key);
 
 CtxPtr digest_init(yaca_digest_algorithm_e algo);
 
-std::vector<char> random_buffer(size_t length);
-
-/* Converts string representing hex to array of bytes, for example: "d41d" -> { 0xd4, 0x1d } */
-std::vector<char> str2data(const std::string& hex_str);
+Buffer random_buffer(size_t length);
 
 const char* digest2str(yaca_digest_algorithm_e algo);
 
 /* If input is longer than len it is truncated and an ellipsis is appended.
  * Otherwise the original string is returned. */
 std::string truncate_str(const std::string& input, size_t len);
-
index 68b9507..b65b69d 100644 (file)
@@ -83,7 +83,7 @@ RUNNER_TEST(T6030_yaca_sign_final_invalid_param, YacaTest)
     KeyPtr prv = generate_key(YACA_KEY_TYPE_RSA_PRIV, YACA_KEY_LENGTH_1024BIT);
     CtxPtr ctx = sign_init(YACA_DIGEST_MD5, prv);
     size_t sign_len = get_output_length(ctx);
-    BufPtr sign = create_yaca_buffer(sign_len);
+    ChrPtr sign = create_yaca_buffer(sign_len);
 
     YACA_INVALID_PARAM(yaca_sign_finalize(YACA_CONTEXT_NULL, sign.get(), &sign_len));
     YACA_INVALID_PARAM(yaca_sign_finalize(ctx.get(), nullptr, &sign_len));
diff --git a/src/yaca/yaca-test-vector.cpp b/src/yaca/yaca-test-vector.cpp
new file mode 100644 (file)
index 0000000..c8c3e91
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ *  Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+/*
+ * @file       yaca-test-vector.cpp
+ * @author     Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
+ * @version    1.0
+ */
+
+#include <fstream>
+
+#include <yaca_types.h>
+
+#include <dpl/test/test_runner.h>
+
+#include "yaca-test-vector.h"
+
+namespace {
+
+Buffer hex2bin(const std::string &hex_str)
+{
+    RUNNER_ASSERT_MSG(hex_str.size() % 2 == 0,
+                      "Length of the provided string is not divisable by 2");
+
+    /* convert a string representing hex to an array of bytes */
+    Buffer data(hex_str.size() / 2);
+    for (size_t i = 0; i < hex_str.size(); i += 2) {
+        std::string byte_str = hex_str.substr(i, 2);
+        std::stringstream ss;
+        int byte;
+
+        /* Will throw if it can't handle it and that's fine */
+        ss << std::hex << byte_str;
+        ss >> byte;
+
+        RUNNER_ASSERT_MSG(byte == (byte & 0xff), "Byte value out of range");
+
+        data[i / 2] = static_cast<char>(byte);
+    }
+
+    return data;
+}
+
+std::map<std::string, yaca_digest_algorithm_e> str2digest = {
+        std::make_pair("MD5",       YACA_DIGEST_MD5),
+        std::make_pair("SHA1",      YACA_DIGEST_SHA1),
+        std::make_pair("SHA224",    YACA_DIGEST_SHA224),
+        std::make_pair("SHA256",    YACA_DIGEST_SHA256),
+        std::make_pair("SHA384",    YACA_DIGEST_SHA384),
+        std::make_pair("SHA512",    YACA_DIGEST_SHA512)
+};
+
+std::map<std::string, yaca_encrypt_algorithm_e> str2encrypt = {
+        std::make_pair("AES",           YACA_ENCRYPT_AES),
+        std::make_pair("DES",           YACA_ENCRYPT_UNSAFE_DES),
+        std::make_pair("3DES_2TDEA",    YACA_ENCRYPT_UNSAFE_3DES_2TDEA),
+        std::make_pair("3DES_3TDEA",    YACA_ENCRYPT_3DES_3TDEA),
+        std::make_pair("RC2",           YACA_ENCRYPT_UNSAFE_RC2),
+        std::make_pair("RC4",           YACA_ENCRYPT_UNSAFE_RC4),
+        std::make_pair("CAST5",         YACA_ENCRYPT_CAST5)
+};
+
+std::map<std::string, yaca_block_cipher_mode_e> str2bcm = {
+        std::make_pair("ECB",   YACA_BCM_ECB),
+        std::make_pair("CTR",   YACA_BCM_CTR),
+        std::make_pair("CBC",   YACA_BCM_CBC),
+        std::make_pair("GCM",   YACA_BCM_GCM),
+        std::make_pair("CFB",   YACA_BCM_CFB),
+        std::make_pair("CFB1",  YACA_BCM_CFB1),
+        std::make_pair("CFB8",  YACA_BCM_CFB8),
+        std::make_pair("OFB",   YACA_BCM_OFB),
+        std::make_pair("CCM",   YACA_BCM_CCM)
+};
+
+} // anonymous namespace
+
+
+void TestVector::add(const std::string &key, const std::string &val)
+{
+    RUNNER_ASSERT_MSG(m_data.find(key) == m_data.end(),
+                      "The key " << key << " already exists in this test vector");
+    m_data[key] = val;
+}
+
+void TestVector::get(const std::string &key, std::string &val) const
+{
+    val = value(key);
+}
+
+void TestVector::get(const std::string &key, Buffer &val) const
+{
+    val = hex2bin(value(key));
+}
+
+void TestVector::get(const std::string &key, yaca_digest_algorithm_e &val) const
+{
+    val = str2digest.at(value(key));
+}
+
+void TestVector::get(const std::string &key, yaca_encrypt_algorithm_e &val) const
+{
+    val = str2encrypt.at(value(key));
+}
+
+void TestVector::get(const std::string &key, yaca_block_cipher_mode_e &val) const
+{
+    val = str2bcm.at(value(key));
+}
+
+void TestVector::reset()
+{
+    m_data.clear();
+}
+
+bool TestVector::empty() const
+{
+    return m_data.empty();
+}
+
+std::string TestVector::value(const std::string &key) const
+{
+    auto it = m_data.find(key);
+    RUNNER_ASSERT_MSG(it != m_data.end(),
+                      "No entry for key \"" << key << "\" in current test vector");
+    return it->second;
+}
+
+TestVectorVector loadTestVector(const std::string &filename)
+{
+    std::string path = std::string(YACA_TEST_DIR"/test-vectors/") + filename;
+
+    TestVectorVector tvv;
+
+    std::ifstream ifs(path, std::ifstream::in);
+
+    RUNNER_ASSERT_MSG(ifs, "Failed to open " << path);
+    std::string line;
+    TestVector tv;
+    while (std::getline(ifs, line))
+    {
+        if (line.empty()) {
+            /* next test vector */
+            if (!tv.empty()) {
+                tvv.push_back(tv);
+                tv.reset();
+            }
+        } else {
+            size_t equals = line.find('=');
+
+            /* ignore lines without '=' */
+            if (equals != std::string::npos)
+            {
+                std::string key = line.substr(0, equals);
+                std::string value = line.substr(equals + 1);
+                tv.add(key, value);
+            }
+        }
+
+        if (ifs.eof())
+            break;
+    }
+    RUNNER_ASSERT_MSG(ifs.eof(), "Failed to read " << path);
+    if (!tv.empty())
+        tvv.push_back(tv);
+    return tvv;
+}
diff --git a/src/yaca/yaca-test-vector.h b/src/yaca/yaca-test-vector.h
new file mode 100644 (file)
index 0000000..d36295f
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ *  Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+/*
+ * @file       yaca-test-vector.h
+ * @author     Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
+ * @version    1.0
+ */
+#pragma once
+
+#include <string>
+#include <vector>
+#include <map>
+#include <sstream>
+
+#include "yaca-test-common.h"
+
+class TestVector {
+public:
+    TestVector() {}
+
+    void add(const std::string &key, const std::string &value);
+
+    template <typename T>
+    void get(const std::string &key, T &val) const
+    {
+        std::stringstream ss(value(key));
+        ss >> val;
+    }
+    /* special case for string (because >> stops on whitespace) */
+    void get(const std::string &key, std::string &val) const;
+    /* special case for buffer */
+    void get(const std::string &key, Buffer &val) const;
+    /* special case for message digest */
+    void get(const std::string &key, yaca_digest_algorithm_e &val) const;
+    /* special case for encryption algorithm */
+    void get(const std::string &key, yaca_encrypt_algorithm_e &val) const;
+    /* special case for bcm */
+    void get(const std::string &key, yaca_block_cipher_mode_e &val) const;
+
+    void reset();
+
+    bool empty() const;
+private:
+    std::string value(const std::string &key) const;
+
+    // key, value
+    std::map<std::string, std::string> m_data;
+};
+
+typedef std::vector<TestVector> TestVectorVector;
+
+TestVectorVector loadTestVector(const std::string &filename);