1377cd1957172c19ee21baa3d6bda0840f1ce020dPaul Lawrence/* 28d53b9619ba913354ffdb23acf0108f7445bb8bcPaul Crowley * Copyright (C) 2015 The Android Open Source Project 38d53b9619ba913354ffdb23acf0108f7445bb8bcPaul Crowley * 48d53b9619ba913354ffdb23acf0108f7445bb8bcPaul Crowley * Licensed under the Apache License, Version 2.0 (the "License"); 58d53b9619ba913354ffdb23acf0108f7445bb8bcPaul Crowley * you may not use this file except in compliance with the License. 68d53b9619ba913354ffdb23acf0108f7445bb8bcPaul Crowley * You may obtain a copy of the License at 78d53b9619ba913354ffdb23acf0108f7445bb8bcPaul Crowley * 88d53b9619ba913354ffdb23acf0108f7445bb8bcPaul Crowley * http://www.apache.org/licenses/LICENSE-2.0 98d53b9619ba913354ffdb23acf0108f7445bb8bcPaul Crowley * 108d53b9619ba913354ffdb23acf0108f7445bb8bcPaul Crowley * Unless required by applicable law or agreed to in writing, software 118d53b9619ba913354ffdb23acf0108f7445bb8bcPaul Crowley * distributed under the License is distributed on an "AS IS" BASIS, 128d53b9619ba913354ffdb23acf0108f7445bb8bcPaul Crowley * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138d53b9619ba913354ffdb23acf0108f7445bb8bcPaul Crowley * See the License for the specific language governing permissions and 148d53b9619ba913354ffdb23acf0108f7445bb8bcPaul Crowley * limitations under the License. 15377cd1957172c19ee21baa3d6bda0840f1ce020dPaul Lawrence */ 1692da49db65ffbe0bff1771ecef87ad49e94a0626Paul Lawrence 1706ca811e9297e28f43d65f30493df88862ff09c1Tao Bao#include "ext4_utils/ext4_crypt.h" 18af2359fdc4a45fcf482d1a316bae1fff226c425bPaul Lawrence 1906ca811e9297e28f43d65f30493df88862ff09c1Tao Bao#include <asm/ioctl.h> 204818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence#include <dirent.h> 214818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence#include <errno.h> 224818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence#include <fcntl.h> 2306ca811e9297e28f43d65f30493df88862ff09c1Tao Bao#include <string.h> 244818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence#include <sys/syscall.h> 254818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence#include <sys/stat.h> 264818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence#include <sys/types.h> 2706ca811e9297e28f43d65f30493df88862ff09c1Tao Bao#include <unistd.h> 284818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence 29c096c9c65ffd4485f137d1b90cffe280cf96fbc6Paul Lawrence#include <android-base/file.h> 304818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence#include <android-base/logging.h> 318d53b9619ba913354ffdb23acf0108f7445bb8bcPaul Crowley#include <cutils/properties.h> 3292da49db65ffbe0bff1771ecef87ad49e94a0626Paul Lawrence 334818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence#define XATTR_NAME_ENCRYPTION_POLICY "encryption.policy" 344818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence#define EXT4_KEYREF_DELIMITER ((char)'.') 354818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence 364818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence// ext4enc:TODO Include structure from somewhere sensible 374818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence// MUST be in sync with ext4_crypto.c in kernel 384818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence#define EXT4_KEY_DESCRIPTOR_SIZE 8 394818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence#define EXT4_KEY_DESCRIPTOR_SIZE_HEX 17 404818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence 414818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrencestruct ext4_encryption_policy { 425a8ebaacab368cece8fd99c86effcb3c82229586Paul Lawrence uint8_t version; 435a8ebaacab368cece8fd99c86effcb3c82229586Paul Lawrence uint8_t contents_encryption_mode; 445a8ebaacab368cece8fd99c86effcb3c82229586Paul Lawrence uint8_t filenames_encryption_mode; 455a8ebaacab368cece8fd99c86effcb3c82229586Paul Lawrence uint8_t flags; 465a8ebaacab368cece8fd99c86effcb3c82229586Paul Lawrence uint8_t master_key_descriptor[EXT4_KEY_DESCRIPTOR_SIZE]; 474818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence} __attribute__((__packed__)); 484818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence 494818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence#define EXT4_ENCRYPTION_MODE_AES_256_XTS 1 504818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence#define EXT4_ENCRYPTION_MODE_AES_256_CTS 4 51a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers#define EXT4_ENCRYPTION_MODE_AES_256_HEH 126 52c096c9c65ffd4485f137d1b90cffe280cf96fbc6Paul Lawrence#define EXT4_ENCRYPTION_MODE_PRIVATE 127 534818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence 54a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers#define EXT4_POLICY_FLAGS_PAD_4 0x00 55a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers#define EXT4_POLICY_FLAGS_PAD_8 0x01 56a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers#define EXT4_POLICY_FLAGS_PAD_16 0x02 57a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers#define EXT4_POLICY_FLAGS_PAD_32 0x03 58a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers#define EXT4_POLICY_FLAGS_PAD_MASK 0x03 59a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers#define EXT4_POLICY_FLAGS_VALID 0x03 60a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers 614818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence// ext4enc:TODO Get value from somewhere sensible 624818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence#define EXT4_IOC_SET_ENCRYPTION_POLICY _IOR('f', 19, struct ext4_encryption_policy) 634818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence#define EXT4_IOC_GET_ENCRYPTION_POLICY _IOW('f', 21, struct ext4_encryption_policy) 644818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence 654818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence#define HEX_LOOKUP "0123456789abcdef" 664818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence 678d53b9619ba913354ffdb23acf0108f7445bb8bcPaul Crowleybool e4crypt_is_native() { 688d53b9619ba913354ffdb23acf0108f7445bb8bcPaul Crowley char value[PROPERTY_VALUE_MAX]; 698d53b9619ba913354ffdb23acf0108f7445bb8bcPaul Crowley property_get("ro.crypto.type", value, "none"); 708d53b9619ba913354ffdb23acf0108f7445bb8bcPaul Crowley return !strcmp(value, "file"); 718d53b9619ba913354ffdb23acf0108f7445bb8bcPaul Crowley} 724818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence 734818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrencestatic void policy_to_hex(const char* policy, char* hex) { 744818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence for (size_t i = 0, j = 0; i < EXT4_KEY_DESCRIPTOR_SIZE; i++) { 754818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence hex[j++] = HEX_LOOKUP[(policy[i] & 0xF0) >> 4]; 764818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence hex[j++] = HEX_LOOKUP[policy[i] & 0x0F]; 774818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence } 784818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence hex[EXT4_KEY_DESCRIPTOR_SIZE_HEX - 1] = '\0'; 794818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence} 804818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence 814818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrencestatic bool is_dir_empty(const char *dirname, bool *is_empty) 824818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence{ 834818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence int n = 0; 844818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence auto dirp = std::unique_ptr<DIR, int (*)(DIR*)>(opendir(dirname), closedir); 854818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence if (!dirp) { 864818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence PLOG(ERROR) << "Unable to read directory: " << dirname; 874818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence return false; 884818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence } 894818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence for (;;) { 904818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence errno = 0; 914818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence auto entry = readdir(dirp.get()); 924818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence if (!entry) { 934818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence if (errno) { 944818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence PLOG(ERROR) << "Unable to read directory: " << dirname; 954818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence return false; 964818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence } 974818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence break; 984818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence } 994818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence if (strcmp(entry->d_name, "lost+found") != 0) { // Skip lost+found 1004818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence ++n; 1014818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence if (n > 2) { 1024818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence *is_empty = false; 1034818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence return true; 1044818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence } 1054818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence } 1064818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence } 1074818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence *is_empty = true; 1084818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence return true; 1094818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence} 1104818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence 111a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggersstatic uint8_t e4crypt_get_policy_flags(int filenames_encryption_mode) { 112a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers 113a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers // With HEH, pad filenames with zeroes to the next 16-byte boundary. This 114a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers // is not required, but it's more secure (helps hide the length of 115a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers // filenames), makes the inputs evenly divisible into blocks which is more 116a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers // efficient for encryption and decryption, and we had the opportunity to 117a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers // make a breaking change when introducing a new mode anyway. 118a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers if (filenames_encryption_mode == EXT4_ENCRYPTION_MODE_AES_256_HEH) { 119a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers return EXT4_POLICY_FLAGS_PAD_16; 120a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers } 121a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers 122a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers // Default flags (4-byte padding) for CTS 123a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers return EXT4_POLICY_FLAGS_PAD_4; 124a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers} 125a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers 126c096c9c65ffd4485f137d1b90cffe280cf96fbc6Paul Lawrencestatic bool e4crypt_policy_set(const char *directory, const char *policy, 127a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers size_t policy_length, 128a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers int contents_encryption_mode, 129a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers int filenames_encryption_mode) { 1304818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence if (policy_length != EXT4_KEY_DESCRIPTOR_SIZE) { 1314818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence LOG(ERROR) << "Policy wrong length: " << policy_length; 1324818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence return false; 1334818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence } 1344818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence int fd = open(directory, O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC); 1354818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence if (fd == -1) { 1364818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence PLOG(ERROR) << "Failed to open directory " << directory; 1374818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence return false; 1384818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence } 1394818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence 1404818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence ext4_encryption_policy eep; 1414818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence eep.version = 0; 142c096c9c65ffd4485f137d1b90cffe280cf96fbc6Paul Lawrence eep.contents_encryption_mode = contents_encryption_mode; 143a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers eep.filenames_encryption_mode = filenames_encryption_mode; 144a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers eep.flags = e4crypt_get_policy_flags(filenames_encryption_mode); 1454818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence memcpy(eep.master_key_descriptor, policy, EXT4_KEY_DESCRIPTOR_SIZE); 1464818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence if (ioctl(fd, EXT4_IOC_SET_ENCRYPTION_POLICY, &eep)) { 1474818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence PLOG(ERROR) << "Failed to set encryption policy for " << directory; 1484818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence close(fd); 1494818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence return false; 1504818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence } 1514818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence close(fd); 1524818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence 1534818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence char policy_hex[EXT4_KEY_DESCRIPTOR_SIZE_HEX]; 1544818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence policy_to_hex(policy, policy_hex); 1554818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence LOG(INFO) << "Policy for " << directory << " set to " << policy_hex; 1564818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence return true; 1574818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence} 1584818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence 159c096c9c65ffd4485f137d1b90cffe280cf96fbc6Paul Lawrencestatic bool e4crypt_policy_get(const char *directory, char *policy, 160a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers size_t policy_length, 161a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers int contents_encryption_mode, 162a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers int filenames_encryption_mode) { 1634818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence if (policy_length != EXT4_KEY_DESCRIPTOR_SIZE) { 1644818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence LOG(ERROR) << "Policy wrong length: " << policy_length; 1654818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence return false; 1664818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence } 1674818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence 1684818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence int fd = open(directory, O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC); 1694818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence if (fd == -1) { 1704818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence PLOG(ERROR) << "Failed to open directory " << directory; 1714818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence return false; 1724818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence } 1734818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence 1744818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence ext4_encryption_policy eep; 1754818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence memset(&eep, 0, sizeof(ext4_encryption_policy)); 1764818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence if (ioctl(fd, EXT4_IOC_GET_ENCRYPTION_POLICY, &eep) != 0) { 1774818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence PLOG(ERROR) << "Failed to get encryption policy for " << directory; 1784818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence close(fd); 17930b93dd5715abcabd621235733733c0503f9c552Ethan Yonker return false; 1804818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence } 1814818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence close(fd); 1824818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence 1834818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence if ((eep.version != 0) 184c096c9c65ffd4485f137d1b90cffe280cf96fbc6Paul Lawrence || (eep.contents_encryption_mode != contents_encryption_mode) 185a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers || (eep.filenames_encryption_mode != filenames_encryption_mode) 186a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers || (eep.flags != 187a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers e4crypt_get_policy_flags(filenames_encryption_mode))) { 1884818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence LOG(ERROR) << "Failed to find matching encryption policy for " << directory; 1894818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence return false; 1904818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence } 1914818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence memcpy(policy, eep.master_key_descriptor, EXT4_KEY_DESCRIPTOR_SIZE); 1924818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence 1934818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence return true; 1944818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence} 1954818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence 196c096c9c65ffd4485f137d1b90cffe280cf96fbc6Paul Lawrencestatic bool e4crypt_policy_check(const char *directory, const char *policy, 197a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers size_t policy_length, 198a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers int contents_encryption_mode, 199a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers int filenames_encryption_mode) { 2004818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence if (policy_length != EXT4_KEY_DESCRIPTOR_SIZE) { 2014818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence LOG(ERROR) << "Policy wrong length: " << policy_length; 2024818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence return false; 2034818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence } 2044818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence char existing_policy[EXT4_KEY_DESCRIPTOR_SIZE]; 205c096c9c65ffd4485f137d1b90cffe280cf96fbc6Paul Lawrence if (!e4crypt_policy_get(directory, existing_policy, EXT4_KEY_DESCRIPTOR_SIZE, 206a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers contents_encryption_mode, 207a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers filenames_encryption_mode)) return false; 2084818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence char existing_policy_hex[EXT4_KEY_DESCRIPTOR_SIZE_HEX]; 2094818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence 2104818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence policy_to_hex(existing_policy, existing_policy_hex); 2114818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence 2124818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence if (memcmp(policy, existing_policy, EXT4_KEY_DESCRIPTOR_SIZE) != 0) { 2134818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence char policy_hex[EXT4_KEY_DESCRIPTOR_SIZE_HEX]; 2144818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence policy_to_hex(policy, policy_hex); 2154818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence LOG(ERROR) << "Found policy " << existing_policy_hex << " at " << directory 2164818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence << " which doesn't match expected value " << policy_hex; 2174818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence return false; 2184818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence } 2194818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence LOG(INFO) << "Found policy " << existing_policy_hex << " at " << directory 2204818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence << " which matches expected value"; 2214818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence return true; 2224818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence} 2234818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence 224c096c9c65ffd4485f137d1b90cffe280cf96fbc6Paul Lawrenceint e4crypt_policy_ensure(const char *directory, const char *policy, 225a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers size_t policy_length, 226a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers const char *contents_encryption_mode, 227a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers const char *filenames_encryption_mode) { 228a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers int contents_mode = 0; 229a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers int filenames_mode = 0; 230a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers 231a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers if (!strcmp(contents_encryption_mode, "software") || 232a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers !strcmp(contents_encryption_mode, "aes-256-xts")) { 233a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers contents_mode = EXT4_ENCRYPTION_MODE_AES_256_XTS; 234c096c9c65ffd4485f137d1b90cffe280cf96fbc6Paul Lawrence } else if (!strcmp(contents_encryption_mode, "ice")) { 235a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers contents_mode = EXT4_ENCRYPTION_MODE_PRIVATE; 236a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers } else { 237a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers LOG(ERROR) << "Invalid file contents encryption mode: " 238a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers << contents_encryption_mode; 239a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers return -1; 240a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers } 241a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers 242a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers if (!strcmp(filenames_encryption_mode, "aes-256-cts")) { 243a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers filenames_mode = EXT4_ENCRYPTION_MODE_AES_256_CTS; 244a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers } else if (!strcmp(filenames_encryption_mode, "aes-256-heh")) { 245a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers filenames_mode = EXT4_ENCRYPTION_MODE_AES_256_HEH; 246c096c9c65ffd4485f137d1b90cffe280cf96fbc6Paul Lawrence } else { 247a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers LOG(ERROR) << "Invalid file names encryption mode: " 248a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers << filenames_encryption_mode; 249c096c9c65ffd4485f137d1b90cffe280cf96fbc6Paul Lawrence return -1; 250c096c9c65ffd4485f137d1b90cffe280cf96fbc6Paul Lawrence } 251c096c9c65ffd4485f137d1b90cffe280cf96fbc6Paul Lawrence 2524818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence bool is_empty; 2534818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence if (!is_dir_empty(directory, &is_empty)) return -1; 2544818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence if (is_empty) { 255c096c9c65ffd4485f137d1b90cffe280cf96fbc6Paul Lawrence if (!e4crypt_policy_set(directory, policy, policy_length, 256a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers contents_mode, filenames_mode)) return -1; 2574818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence } else { 258c096c9c65ffd4485f137d1b90cffe280cf96fbc6Paul Lawrence if (!e4crypt_policy_check(directory, policy, policy_length, 259a9fa60514da82a4bb2d420771b696b4a6d53c024Eric Biggers contents_mode, filenames_mode)) return -1; 2604818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence } 2614818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence return 0; 2624818b73cf845e05c6b14afb07e38da0b6720865aPaul Lawrence} 263