Add AntiForensics 87/109587/7
authorSeok Hong <seok85.hong@samsung.com>
Tue, 17 Jan 2017 01:47:31 +0000 (10:47 +0900)
committerSeok Hong <seok85.hong@samsung.com>
Wed, 18 Jan 2017 00:28:21 +0000 (09:28 +0900)
Change-Id: I9a48648c96507e5d0a964c8afa4ea8a1729b8743
Signed-off-by: Seok Hong <seok85.hong@samsung.com>
server/CMakeLists.txt
server/key-manager/anti-forensics.cpp [new file with mode: 0644]
server/key-manager/anti-forensics.h [new file with mode: 0644]
server/key-manager/key-manager.cpp
tests/CMakeLists.txt
tests/af.cpp [new file with mode: 0644]

index 49d0d731a849547215d9695834c4229e0400a031..79ab0428f1d5b71c9f3cbbca669afaae0407fae6 100644 (file)
@@ -29,6 +29,7 @@ SET(SERVER_SRCS       main.cpp
                                key-manager/key-store.cpp
                                key-manager/key-manager.cpp
                                key-manager/key-generator.cpp
+                               key-manager/anti-forensics.cpp
 )
 
 SET(DEPENDENCY klay
diff --git a/server/key-manager/anti-forensics.cpp b/server/key-manager/anti-forensics.cpp
new file mode 100644 (file)
index 0000000..4f32bce
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ *  Copyright (c) 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
+ */
+#include <string.h>
+#include <netinet/in.h>
+
+#include <openssl/rand.h>
+#include <openssl/sha.h>
+
+#include <klay/error.h>
+#include <klay/exception.h>
+
+#include "anti-forensics.h"
+
+#define SECTOR_SHIFT   9
+#define SECTOR_SIZE            (1 << SECTOR_SHIFT)
+
+namespace ode {
+
+static void RNG(unsigned char *buf, size_t resultSize)
+{
+       ::RAND_bytes(buf, resultSize);
+}
+
+static void XORBlock(const unsigned char *src1, const unsigned char *src2, unsigned char *dst, size_t size)
+{
+       for (size_t i = 0; i < size; i++)
+               dst[i] = src1[i] ^ src2[i];
+}
+
+static void hashBuf(unsigned char *src, unsigned char *dst, uint32_t iv,
+                                       size_t size)
+{
+       char *ivChar = (char *)&iv;
+       iv = htonl(iv);
+
+       uint32_t digestSize = 168 / 8;  // use SHA1 in default
+       unsigned char buf[digestSize] = {0x00, };
+
+       SHA_CTX context;
+       if (!::SHA1_Init(&context))
+               throw runtime::Exception("SHA1 Init Failed");
+       if (!::SHA1_Update(&context, ivChar, sizeof(uint32_t)))
+               throw runtime::Exception("SHA1 Update IV Failed");
+       if (!::SHA1_Update(&context, src, size))
+               throw runtime::Exception("SHA1 Update Source Failed");
+       if (!::SHA1_Final(buf, &context))
+               throw runtime::Exception("SHA1 Final Failed");
+
+       ::memcpy(dst, buf, size);
+}
+
+static void diffuse(unsigned char *src, unsigned char *dst, size_t size)
+{
+       uint32_t digestSize = 168 / 8;  // use SHA1 in default
+       uint32_t blocks = size / digestSize;
+       uint32_t padding = size % digestSize;
+
+       uint32_t i;
+       for (i = 0; i < blocks; i++) {
+               hashBuf(src + (digestSize * i),
+                               dst + (digestSize * i),
+                               i,
+                               (size_t)digestSize);
+       }
+
+       if (padding) {
+               hashBuf(src + (digestSize * i),
+                               dst + (digestSize * i),
+                               i,
+                               (size_t)padding);
+       }
+}
+
+AntiForensics::data AntiForensics::AFSplit(const AntiForensics::data &src,
+               uint32_t blockSize, uint32_t blockNumbers)
+{
+       if (blockSize != src.size())
+               throw runtime::Exception("Source size check failed");
+
+       data buf(blockSize + 1, 0);
+       data dst(blockSize * blockNumbers, 0);
+
+       uint32_t i;
+       for (i = 0; i < blockNumbers - 1; i++) {
+               RNG(dst.data() + (blockSize * i), blockSize);
+               XORBlock(dst.data() + (blockSize * i), buf.data(), buf.data(), blockSize);
+               diffuse(buf.data(), buf.data(), blockSize);
+       }
+
+       XORBlock(src.data(), buf.data(), dst.data() + (blockSize * i), blockSize);
+
+       return dst;
+}
+
+AntiForensics::data AntiForensics::AFMerge(const AntiForensics::data &src,
+               uint32_t blockSize, uint32_t blockNumbers)
+{
+       if (blockSize * blockNumbers != src.size())
+               throw runtime::Exception("Source size check failed");
+
+       data buf(blockSize, 0);
+       data dst(blockSize, 0);
+
+       uint32_t i;
+       for (i = 0; i < blockNumbers - 1; i++) {
+               XORBlock(src.data() + (blockSize * i), buf.data(), buf.data(), blockSize);
+               diffuse(buf.data(), buf.data(), blockSize);
+       }
+
+       XORBlock(src.data() + (blockSize * i), buf.data(), dst.data(), blockSize);
+
+       return dst;
+}
+
+} // namespace ode
diff --git a/server/key-manager/anti-forensics.h b/server/key-manager/anti-forensics.h
new file mode 100644 (file)
index 0000000..9b0dec8
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ *  Copyright (c) 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
+ */
+#ifndef __ANTI_FORENSICS_H__
+#define __ANTI_FORENSICS_H__
+
+#include <stdint.h>
+#include <vector>
+
+namespace ode {
+
+class AntiForensics final {
+public:
+       AntiForensics() = delete;
+
+       typedef std::vector<unsigned char> data;
+
+       static data AFSplit(const data &src, uint32_t blockSize, uint32_t blockNumbers);
+       static data AFMerge(const data &src, uint32_t blockSize, uint32_t blockNumbers);
+};
+
+} // namespace ode
+
+#endif // __ANTI_FORENSICS_H__
index 2bff609a15e55ec96dfb48712783982c8b950fa0..7d3c647d8bdca97180f5de9b0b291257c17979ea 100644 (file)
 
 #include "key-manager.h"
 #include "key-generator.h"
+#include "anti-forensics.h"
 
 #define MASTER_KEY_LENGTH (256 / 8)
 #define ITERATION_COUNT 1000
+#define LUKS_STRIPES 3
 
 namespace ode {
 
@@ -65,11 +67,13 @@ const KeyManager::data KeyManager::getMasterKey(const data& password) const
                store.getPasswordIteration(),
                store.getMasterKeyLength());
 
-       data masterKeyCandidate = KeyGenerator::AESDecrypt(
+       data splittedMasterKey = KeyGenerator::AESDecrypt(
                store.getEncryptedMasterKey(),
                derivedPassword,
                KeyGenerator::SHA256(derivedPassword));
 
+       data masterKeyCandidate = AntiForensics::AFMerge(splittedMasterKey, store.getMasterKeyLength(), LUKS_STRIPES);
+
        data masterKeyCandidateDigest = KeyGenerator::PBKDF(masterKeyCandidate,
                store.getMasterKeyDigestSalt(),
                store.getMasterKeyDigestIteration(),
@@ -93,8 +97,10 @@ void KeyManager::setPassword(const data& masterKey, const data& password) {
                store.getPasswordIteration(),
                store.getMasterKeyLength());
 
+       data splittedMasterKey = AntiForensics::AFSplit(masterKey, masterKey.size(), LUKS_STRIPES);
+
        store.setEncryptedMasterKey(KeyGenerator::AESEncrypt(
-               masterKey,
+               splittedMasterKey,
                derivedPassword,
                KeyGenerator::SHA256(derivedPassword)));
 }
index 4fc81290d1f71e21fc10440e41042afcada5ee78..eff1d8b7153510519caec6f1590f3ff6321ba0c4 100755 (executable)
@@ -19,10 +19,12 @@ SET(TEST_SRC        main.cpp
                                ext4-engine.cpp
                                dmcrypt-engine.cpp
                                ecryptfs-engine.cpp
+                               af.cpp
                                ../server/file-footer.cpp
                                ../server/engine/ext4-engine.cpp
                                ../server/engine/ecryptfs-engine.cpp
                                ../server/key-manager/key-generator.cpp
+                               ../server/key-manager/anti-forensics.cpp
 )
 
 ADD_EXECUTABLE(${PROJECT_NAME} ${TEST_SRC})
diff --git a/tests/af.cpp b/tests/af.cpp
new file mode 100644 (file)
index 0000000..e5e99ab
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ *  Copyright (c) 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
+ */
+
+#include <unistd.h>
+#include <linux/loop.h>
+
+#include <cstdio>
+#include <cstdlib>
+#include <string>
+#include <fstream>
+#include <vector>
+#include <algorithm>
+#include <iostream>
+
+#include <klay/error.h>
+#include <klay/exception.h>
+#include <klay/testbench.h>
+#include <klay/process.h>
+
+#include "../server/key-manager/anti-forensics.h"
+
+#define LUKS_STRIPES 3 // this constans will be placed in key-manager
+
+TESTCASE(AntiForensics)
+{
+       try {
+               typedef ode::AntiForensics::data data;
+
+               std::string Key = "Master_Key";
+               data MasterKey(Key.begin(), Key.end());
+               data SplittedMasterKey = ode::AntiForensics::AFSplit(MasterKey, MasterKey.size(), LUKS_STRIPES);
+               data UnSplittedMasterKey = ode::AntiForensics::AFMerge(SplittedMasterKey, MasterKey.size(), LUKS_STRIPES);
+
+               // check size
+               TEST_EXPECT(MasterKey.size(), UnSplittedMasterKey.size());
+
+               // check data
+               for (unsigned i = 0; i < MasterKey.size(); i++)
+                       TEST_EXPECT(MasterKey[i], UnSplittedMasterKey[i]);
+
+               // display unsplitted master_key
+               for (unsigned char c : UnSplittedMasterKey)
+                       std::cout << c;
+               std::cout << std::endl;
+               //
+       } catch (runtime::Exception &e) {
+               TEST_FAIL(e.what());
+       } catch (...) {
+               TEST_FAIL("UNKNOWN ERROR");
+       }
+
+
+}
\ No newline at end of file