From 013ab791c6249bab7128855283f5bb97fcf2637b Mon Sep 17 00:00:00 2001 From: Sungbae Yoo Date: Thu, 13 Apr 2017 17:13:14 +0900 Subject: [PATCH] Refactor ecryptfs structures to C++ style Change-Id: I653ccee054600235117b424ab7ec66ed06ab4599 Signed-off-by: Sungbae Yoo --- volume/ecryptfs.h | 139 ++++++++++++++++++++++++------------------------- volume/key-generator.h | 1 - volume/main.cpp | 49 +++++++---------- 3 files changed, 87 insertions(+), 102 deletions(-) diff --git a/volume/ecryptfs.h b/volume/ecryptfs.h index 9962e34..3bfbb29 100755 --- a/volume/ecryptfs.h +++ b/volume/ecryptfs.h @@ -25,83 +25,80 @@ #define ECRYPTFS_MINOR_VERSION 0x04 #define ECRYPTFS_VERSION ((ECRYPTFS_MAJOR_VERSION << 8) | ECRYPTFS_MINOR_VERSION) -#define ECRYPTFS_MAX_PKI_NAME_BYTES 16 -#define ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET 0x02 - -#define PGP_DIGEST_ALGO_SHA512 10 - -#define ECRYPTFS_FEK_CIPHER "aes" -#define ECRYPTFS_MOUNT_DEVICE "ecryptfs" - -#define ECRYPTFS_MAX_OPTIONS 1024 - -#define ECRYPTFS_MAX_SIG_SIZE 8 -#define ECRYPTFS_MAX_SIG_HEX (ECRYPTFS_MAX_SIG_SIZE*2) -#define ECRYPTFS_PASSWORD_SIG_SIZE ECRYPTFS_MAX_SIG_HEX - -#define ECRYPTFS_MAX_KEY_SIZE 32 -#define ECRYPTFS_MAX_KEY_HEX (ECRYPTFS_MAX_KEY_SIZE * 2) - -#define ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES 512 -#define ECRYPTFS_MAX_PKI_NAME_BYTES 16 - -#define ECRYPTFS_MAX_SALT_SIZE 4 -#define ECRYPTFS_MAX_SALT_HEX 8 - -#define ECRYPTFS_PWD_PAYLOAD_TYPE 0 // password - -struct ecryptfs_session_key { -#define ECRYPTFS_USERSPACE_SHOULD_TRY_TO_DECRYPT 0x00000001 -#define ECRYPTFS_USERSPACE_SHOULD_TRY_TO_ENCRYPT 0x00000002 -#define ECRYPTFS_CONTAINS_DECRYPTED_KEY 0x00000004 -#define ECRYPTFS_CONTAINS_ENCRYPTED_KEY 0x00000008 - int32_t flags; - int32_t encrypted_key_size; - int32_t decrypted_key_size; - u_int8_t encrypted_key[ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES]; - u_int8_t decrypted_key[ECRYPTFS_MAX_KEY_HEX]; +#define ECRYPTFS_SALT_SIZE 8 +#define ECRYPTFS_SIGNATURE_SIZE 16 +#define ECRYPTFS_MAX_KEY_SIZE 64 +#define ECRYPTFS_MAX_KEY_MOD_NAME_SIZE 16 +#define ECRYPTFS_MAX_ENCRYPTED_KEY_SIZE 512 + +struct EcryptfsPassword { + enum Flag { + PersistentPassword = 0x01, + SessionKeyEncryptionKeySet = 0x02 + }; + + int32_t passwordSize; + int32_t hashAlgorithm; + int32_t hashIterations; + int32_t sessionKeyEncryptionKeySize; + uint32_t flags; + uint8_t sessionKeyEncryptionKey[ECRYPTFS_MAX_KEY_SIZE]; + uint8_t signature[ECRYPTFS_SIGNATURE_SIZE + 1]; + uint8_t salt[ECRYPTFS_SALT_SIZE]; }; -struct ecryptfs_password { - int32_t password_bytes; - int32_t hash_algo; - int32_t hash_iterations; - int32_t session_key_encryption_key_bytes; -#define ECRYPTFS_PERSISTENT_PASSWORD 0x01 -#define ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET 0x02 - u_int32_t flags; - /* Iterated-hash concatenation of salt and passphrase */ - u_int8_t session_key_encryption_key[ECRYPTFS_MAX_KEY_HEX]; - u_int8_t signature[ECRYPTFS_PASSWORD_SIG_SIZE + 1]; - /* Always in expanded hex */ - u_int8_t salt[ECRYPTFS_MAX_SALT_SIZE]; +struct EcryptfsPrivateKey { + uint32_t keySize; + uint32_t dataSize; + uint8_t signature[ECRYPTFS_SIGNATURE_SIZE + 1]; + char keyModAlias[ECRYPTFS_MAX_KEY_MOD_NAME_SIZE + 1]; + uint8_t data[]; }; -enum ecryptfs_token_types { - ECRYPTFS_PASSWORD, - ECRYPTFS_PRIVATE_KEY -}; +struct EcryptfsSessionKey { + enum Flag { + UserspaceShouldTryToDecrypt = 0x00000001, + UserspaceShouldTryToEncrypt = 0x00000002, + ContainsDecryptedKey = 0x00000004, + ContainsEncryptedKey = 0x00000008 + }; -struct ecryptfs_private_key { - u_int32_t key_size; - u_int32_t data_len; - u_int8_t signature[ECRYPTFS_PASSWORD_SIG_SIZE + 1]; - char pki_type[ECRYPTFS_MAX_PKI_NAME_BYTES + 1]; - u_int8_t data[]; -}; - -struct ecryptfs_auth_tok { - u_int16_t version; /* 8-bit major and 8-bit minor */ - u_int16_t token_type; -#define ECRYPTFS_ENCRYPT_ONLY 0x00000001 - u_int32_t flags; - struct ecryptfs_session_key session_key; - u_int8_t reserved[32]; + int32_t flags; + int32_t encryptedKeySize; + int32_t decryptedKeySize; + uint8_t encryptedKey[ECRYPTFS_MAX_ENCRYPTED_KEY_SIZE]; + uint8_t decryptedKey[ECRYPTFS_MAX_KEY_SIZE]; + + EcryptfsSessionKey() + : flags(0), encryptedKeySize(0), decryptedKeySize(0), + encryptedKey{0, }, decryptedKey{0, } + {}; +} __attribute__((packed)); + +struct EcryptfsPayload { + enum Type { + PasswordToken, + PrivateKeyToken + }; + enum Flag { + EncryptOnly + }; + + uint16_t version; + uint16_t type; + uint32_t flags; + EcryptfsSessionKey sessionKey; + uint8_t reserved[32]; union { - struct ecryptfs_password password; - struct ecryptfs_private_key private_key; + EcryptfsPassword password; + EcryptfsPrivateKey privateKey; } token; -} __attribute__((packed)); -typedef struct ecryptfs_auth_tok ecryptfs_payload; + EcryptfsPayload(Type type) + : version(ECRYPTFS_VERSION), type(type), flags(0), reserved{0, } + { + ::memset(&token, 0, sizeof(token)); + }; +} __attribute__((packed)); + #endif diff --git a/volume/key-generator.h b/volume/key-generator.h index d6bf6f8..e9ef6cd 100755 --- a/volume/key-generator.h +++ b/volume/key-generator.h @@ -38,7 +38,6 @@ public: static std::string wrapKey(const std::string& decrypted, const std::string& salt, int len); static std::string generateKey(int len); - static void generateToken(char* key, ecryptfs_payload** outToken); private: static void sha1Init(SHA1_CTX* context); diff --git a/volume/main.cpp b/volume/main.cpp index d277009..a05625e 100755 --- a/volume/main.cpp +++ b/volume/main.cpp @@ -44,7 +44,7 @@ int generateKey(const std::string& keyName) try { std::string pass = KeyGenerator::generateKey(ECRYPTFS_MAX_KEY_SIZE); - std::string salt = KeyGenerator::generateKey(ECRYPTFS_MAX_SALT_SIZE); + std::string salt = KeyGenerator::generateKey(ECRYPTFS_SALT_SIZE); std::string wrappedKey = KeyGenerator::wrapKey(pass, salt, ECRYPTFS_MAX_KEY_SIZE); KeyManager::addKey(keyName, wrappedKey); @@ -56,38 +56,26 @@ int generateKey(const std::string& keyName) return 0; } -ecryptfs_payload* generateToken(char* key) +EcryptfsPayload* generateToken(char* key) { - struct ecryptfs_password* tokenKey; + auto *payload = new EcryptfsPayload(EcryptfsPayload::Type::PasswordToken); + payload->token.password.flags = EcryptfsPassword::Flag:: + SessionKeyEncryptionKeySet; + payload->token.password.sessionKeyEncryptionKeySize = ECRYPTFS_MAX_KEY_SIZE; + ::memcpy(payload->token.password.sessionKeyEncryptionKey, key, + payload->token.password.sessionKeyEncryptionKeySize); - unsigned char keyBuffer[ECRYPTFS_MAX_KEY_SIZE+1]; + ::memcpy((char *)payload->token.password.signature, + key, ECRYPTFS_SIGNATURE_SIZE); - ecryptfs_payload* authToken = new ecryptfs_payload(); - if (authToken == NULL) { - return NULL; - } - - ::memset(authToken, 0, sizeof(ecryptfs_payload)); - ::strncpy((char*)keyBuffer, key, ECRYPTFS_MAX_KEY_SIZE); - keyBuffer[ECRYPTFS_MAX_KEY_SIZE] = '\0'; - - tokenKey = &authToken->token.password; - - authToken->version = ECRYPTFS_VERSION; - authToken->token_type = ECRYPTFS_PWD_PAYLOAD_TYPE; - tokenKey->session_key_encryption_key_bytes = ECRYPTFS_MAX_KEY_SIZE; - tokenKey->flags = ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET; - ::memcpy(tokenKey->session_key_encryption_key, keyBuffer, ECRYPTFS_MAX_KEY_SIZE); - ::memcpy(tokenKey->signature, keyBuffer, ECRYPTFS_MAX_SIG_HEX); - - return authToken; + return payload; } int mountEcryptfs(const std::string& src, const std::string& keyName) { int rc; char ecryptfsOpts[1024]; - ecryptfs_payload* authTok = NULL; + EcryptfsPayload* payload = NULL; std::string key; try { @@ -102,12 +90,12 @@ int mountEcryptfs(const std::string& src, const std::string& keyName) return -1; } - if ((authTok = generateToken((char*)key.c_str())) == NULL) { + if ((payload = generateToken((char*)key.c_str())) == NULL) { ERROR("Failed to generate Token"); return -1; } - const char* signature = (const char*)authTok->token.password.signature; + const char* signature = (const char*)payload->token.password.signature; rc = KernelKeyRing::search(KEY_SPEC_USER_KEYRING, "user", signature, @@ -116,18 +104,19 @@ int mountEcryptfs(const std::string& src, const std::string& keyName) if (rc == -1) { if (errno != ENOKEY) { ERROR("Failed to find key"); - delete authTok; + delete payload; return -1; } rc = KernelKeyRing::add("user", signature, - (void*)authTok, - sizeof(ecryptfs_payload), + (void*)payload, + sizeof(*payload), KEY_SPEC_USER_KEYRING); if (rc == -1) { ERROR("Failed to add key"); + delete payload; return -1; } } @@ -140,7 +129,7 @@ int mountEcryptfs(const std::string& src, const std::string& keyName) "smackfsroot=*,smackfsdef=*", ECRYPTFS_MAX_KEY_SIZE, signature); - delete authTok; + delete payload; rc = ::mount(src.c_str(), src.c_str(), "ecryptfs", MS_NODEV, ecryptfsOpts); if (rc != 0) { -- 2.7.4