From 253368a0726120efa57664cdd1d088af099a3d81 Mon Sep 17 00:00:00 2001 From: Ethan Yonker Date: Tue, 25 Nov 2014 15:00:52 -0600 Subject: Reduce libs needed for decrypt and clean up old decypt files Trim cryptfs.c to remove functions that TWRP does not use for decrypt and remove the need for libfs_mgr from cryptfs.c by passing some items to cryptfs.c from the partition manager. Add support for new fstab flags: encryptable and forceencrypt=/path/to/cryptokey For example: flags=forceencrypt=/dev/block/platform/sdhci-tegra.3/by-name/MD1 Note that "footer" is the default, so you do not need to set this flag on devices that use the footer for the crypto key. Also add mounttodecrypt if you need to mount a partition during the decrypt cycle for firmware of proprietary libs. Clean up decrypt and only support one version Android 5.0 lollipop decrypt should be backwards compatible with older versions so we will only support one version, 1.3 that came with 5.0 lollipop. Remove support for Samsung TouchWiz decrypt. It does not work with the latest versions of Samsung encryption anyway and it has not been updated to work with any AOSP decryption higher than 1.1 Change-Id: I2d9c6e31df50268c91ee642c2fa090f901d9d5c9 --- crypto/fs_mgr/fs_mgr_verity.c | 410 ------------------------------------------ 1 file changed, 410 deletions(-) delete mode 100644 crypto/fs_mgr/fs_mgr_verity.c (limited to 'crypto/fs_mgr/fs_mgr_verity.c') diff --git a/crypto/fs_mgr/fs_mgr_verity.c b/crypto/fs_mgr/fs_mgr_verity.c deleted file mode 100644 index 969eab2a0..000000000 --- a/crypto/fs_mgr/fs_mgr_verity.c +++ /dev/null @@ -1,410 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "mincrypt/rsa.h" -#include "mincrypt/sha.h" -#include "mincrypt/sha256.h" - -#include "ext4_utils.h" -#include "ext4.h" - -#include "fs_mgr_priv.h" -#include "fs_mgr_priv_verity.h" - -#define VERITY_METADATA_SIZE 32768 -#define VERITY_METADATA_MAGIC_NUMBER 0xb001b001 -#define VERITY_TABLE_RSA_KEY "/verity_key" - -extern struct fs_info info; - -static RSAPublicKey *load_key(char *path) -{ - FILE *f; - RSAPublicKey *key; - - key = malloc(sizeof(RSAPublicKey)); - if (!key) { - ERROR("Can't malloc key\n"); - return NULL; - } - - f = fopen(path, "r"); - if (!f) { - ERROR("Can't open '%s'\n", path); - free(key); - return NULL; - } - - if (!fread(key, sizeof(*key), 1, f)) { - ERROR("Could not read key!"); - fclose(f); - free(key); - return NULL; - } - - if (key->len != RSANUMWORDS) { - ERROR("Invalid key length %d\n", key->len); - fclose(f); - free(key); - return NULL; - } - - fclose(f); - return key; -} - -static int verify_table(char *signature, char *table, int table_length) -{ - int fd; - RSAPublicKey *key; - uint8_t hash_buf[SHA_DIGEST_SIZE]; - int retval = -1; - - // Hash the table - SHA_hash((uint8_t*)table, table_length, hash_buf); - - // Now get the public key from the keyfile - key = load_key(VERITY_TABLE_RSA_KEY); - if (!key) { - ERROR("Couldn't load verity keys"); - goto out; - } - - // verify the result - if (!RSA_verify(key, - (uint8_t*) signature, - RSANUMBYTES, - (uint8_t*) hash_buf, - SHA_DIGEST_SIZE)) { - ERROR("Couldn't verify table."); - goto out; - } - - retval = 0; - -out: - free(key); - return retval; -} - -static int get_target_device_size(char *blk_device, uint64_t *device_size) -{ - int data_device; - struct ext4_super_block sb; - - data_device = open(blk_device, O_RDONLY); - if (data_device < 0) { - ERROR("Error opening block device (%s)", strerror(errno)); - return -1; - } - - if (lseek64(data_device, 1024, SEEK_SET) < 0) { - ERROR("Error seeking to superblock"); - close(data_device); - return -1; - } - - if (read(data_device, &sb, sizeof(sb)) != sizeof(sb)) { - ERROR("Error reading superblock"); - close(data_device); - return -1; - } - - ext4_parse_sb(&sb); - *device_size = info.len; - - close(data_device); - return 0; -} - -static int read_verity_metadata(char *block_device, char **signature, char **table) -{ - unsigned magic_number; - unsigned table_length; - uint64_t device_length; - int protocol_version; - FILE *device; - int retval = -1; - - device = fopen(block_device, "r"); - if (!device) { - ERROR("Could not open block device %s (%s).\n", block_device, strerror(errno)); - goto out; - } - - // find the start of the verity metadata - if (get_target_device_size(block_device, &device_length) < 0) { - ERROR("Could not get target device size.\n"); - goto out; - } - if (fseek(device, device_length, SEEK_SET) < 0) { - ERROR("Could not seek to start of verity metadata block.\n"); - goto out; - } - - // check the magic number - if (!fread(&magic_number, sizeof(int), 1, device)) { - ERROR("Couldn't read magic number!\n"); - goto out; - } - if (magic_number != VERITY_METADATA_MAGIC_NUMBER) { - ERROR("Couldn't find verity metadata at offset %llu!\n", device_length); - goto out; - } - - // check the protocol version - if (!fread(&protocol_version, sizeof(int), 1, device)) { - ERROR("Couldn't read verity metadata protocol version!\n"); - goto out; - } - if (protocol_version != 0) { - ERROR("Got unknown verity metadata protocol version %d!\n", protocol_version); - goto out; - } - - // get the signature - *signature = (char*) malloc(RSANUMBYTES * sizeof(char)); - if (!*signature) { - ERROR("Couldn't allocate memory for signature!\n"); - goto out; - } - if (!fread(*signature, RSANUMBYTES, 1, device)) { - ERROR("Couldn't read signature from verity metadata!\n"); - free(*signature); - goto out; - } - - // get the size of the table - if (!fread(&table_length, sizeof(int), 1, device)) { - ERROR("Couldn't get the size of the verity table from metadata!\n"); - free(*signature); - goto out; - } - - // get the table + null terminator - table_length += 1; - *table = malloc(table_length); - if(!*table) { - ERROR("Couldn't allocate memory for verity table!\n"); - goto out; - } - if (!fgets(*table, table_length, device)) { - ERROR("Couldn't read the verity table from metadata!\n"); - free(*table); - free(*signature); - goto out; - } - - retval = 0; - -out: - if (device) - fclose(device); - return retval; -} - -static void verity_ioctl_init(struct dm_ioctl *io, char *name, unsigned flags) -{ - memset(io, 0, DM_BUF_SIZE); - io->data_size = DM_BUF_SIZE; - io->data_start = sizeof(struct dm_ioctl); - io->version[0] = 4; - io->version[1] = 0; - io->version[2] = 0; - io->flags = flags | DM_READONLY_FLAG; - if (name) { - strlcpy(io->name, name, sizeof(io->name)); - } -} - -static int create_verity_device(struct dm_ioctl *io, char *name, int fd) -{ - verity_ioctl_init(io, name, 1); - if (ioctl(fd, DM_DEV_CREATE, io)) { - ERROR("Error creating device mapping (%s)", strerror(errno)); - return -1; - } - return 0; -} - -static int get_verity_device_name(struct dm_ioctl *io, char *name, int fd, char **dev_name) -{ - verity_ioctl_init(io, name, 0); - if (ioctl(fd, DM_DEV_STATUS, io)) { - ERROR("Error fetching verity device number (%s)", strerror(errno)); - return -1; - } - int dev_num = (io->dev & 0xff) | ((io->dev >> 12) & 0xfff00); - if (asprintf(dev_name, "/dev/block/dm-%u", dev_num) < 0) { - ERROR("Error getting verity block device name (%s)", strerror(errno)); - return -1; - } - return 0; -} - -static int load_verity_table(struct dm_ioctl *io, char *name, char *blockdev, int fd, char *table) -{ - char *verity_params; - char *buffer = (char*) io; - uint64_t device_size = 0; - - if (get_target_device_size(blockdev, &device_size) < 0) { - return -1; - } - - verity_ioctl_init(io, name, DM_STATUS_TABLE_FLAG); - - struct dm_target_spec *tgt = (struct dm_target_spec *) &buffer[sizeof(struct dm_ioctl)]; - - // set tgt arguments here - io->target_count = 1; - tgt->status=0; - tgt->sector_start=0; - tgt->length=device_size/512; - strcpy(tgt->target_type, "verity"); - - // build the verity params here - verity_params = buffer + sizeof(struct dm_ioctl) + sizeof(struct dm_target_spec); - if (sprintf(verity_params, "%s", table) < 0) { - return -1; - } - - // set next target boundary - verity_params += strlen(verity_params) + 1; - verity_params = (char*) (((unsigned long)verity_params + 7) & ~8); - tgt->next = verity_params - buffer; - - // send the ioctl to load the verity table - if (ioctl(fd, DM_TABLE_LOAD, io)) { - ERROR("Error loading verity table (%s)", strerror(errno)); - return -1; - } - - return 0; -} - -static int resume_verity_table(struct dm_ioctl *io, char *name, int fd) -{ - verity_ioctl_init(io, name, 0); - if (ioctl(fd, DM_DEV_SUSPEND, io)) { - ERROR("Error activating verity device (%s)", strerror(errno)); - return -1; - } - return 0; -} - -static int test_access(char *device) { - int tries = 25; - while (tries--) { - if (!access(device, F_OK) || errno != ENOENT) { - return 0; - } - usleep(40 * 1000); - } - return -1; -} - -int fs_mgr_setup_verity(struct fstab_rec *fstab) { - - int retval = -1; - - char *verity_blk_name; - char *verity_table; - char *verity_table_signature; - - char buffer[DM_BUF_SIZE]; - struct dm_ioctl *io = (struct dm_ioctl *) buffer; - char *mount_point = basename(fstab->mount_point); - - // set the dm_ioctl flags - io->flags |= 1; - io->target_count = 1; - - // get the device mapper fd - int fd; - if ((fd = open("/dev/device-mapper", O_RDWR)) < 0) { - ERROR("Error opening device mapper (%s)", strerror(errno)); - return retval; - } - - // create the device - if (create_verity_device(io, mount_point, fd) < 0) { - ERROR("Couldn't create verity device!"); - goto out; - } - - // get the name of the device file - if (get_verity_device_name(io, mount_point, fd, &verity_blk_name) < 0) { - ERROR("Couldn't get verity device number!"); - goto out; - } - - // read the verity block at the end of the block device - if (read_verity_metadata(fstab->blk_device, - &verity_table_signature, - &verity_table) < 0) { - goto out; - } - - // verify the signature on the table - if (verify_table(verity_table_signature, - verity_table, - strlen(verity_table)) < 0) { - goto out; - } - - // load the verity mapping table - if (load_verity_table(io, mount_point, fstab->blk_device, fd, verity_table) < 0) { - goto out; - } - - // activate the device - if (resume_verity_table(io, mount_point, fd) < 0) { - goto out; - } - - // assign the new verity block device as the block device - free(fstab->blk_device); - fstab->blk_device = verity_blk_name; - - // make sure we've set everything up properly - if (test_access(fstab->blk_device) < 0) { - goto out; - } - - retval = 0; - -out: - close(fd); - return retval; -} -- cgit v1.2.3