ANDROID: Incremental fs: Remove signature checks from kernel

Test: selftests pass
Bug: 133435829
Signed-off-by: Paul Lawrence <paullawrence@google.com>
Change-Id: Ia7e69b1b0176202da4b418ea815b370cbdacd5c2
This commit is contained in:
Paul Lawrence
2020-03-13 12:38:35 -07:00
parent 538096344f
commit 73e7d65693
11 changed files with 306 additions and 870 deletions

View File

@@ -25,8 +25,6 @@
#include "lz4.h"
#include "utils.h"
#define __packed __attribute__((__packed__))
#define TEST_FAILURE 1
#define TEST_SUCCESS 0
#define INCFS_MAX_MTREE_LEVELS 8
@@ -69,101 +67,6 @@ struct linux_dirent64 {
char d_name[0];
} __packed;
/*
* The certificate below and the private key were created by calling:
* openssl req -x509 -newkey rsa:4096 -keyout private.key -out cert.crt
* -days 1000 -sha256 -nodes -outform PEM -subj
* "/C=US/ST=WA/L=Kirkland/O=Example/OU=Org/CN=www.example.com"
*/
char x509_cert[] =
"-----BEGIN CERTIFICATE-----\n"
"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\n"
"-----END CERTIFICATE-----";
char private_key[] =
"-----BEGIN PRIVATE KEY-----\n"
"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\n"
"GyPbW1yZa5vE302a1Cr0Cd7RC4AFAAw=\n"
"-----END PRIVATE KEY-----";
struct test_files_set get_test_files_set(void)
{
static struct test_file files[] = {
@@ -290,7 +193,7 @@ char *bin2hex(char *dst, const void *src, size_t count)
return dst;
}
static char *get_index_filename(char *mnt_dir, incfs_uuid_t id)
static char *get_index_filename(const char *mnt_dir, incfs_uuid_t id)
{
char path[FILENAME_MAX];
char str_id[1 + 2 * sizeof(id)];
@@ -722,8 +625,6 @@ static int build_mtree(struct test_file *file)
int tree_lvl_index[INCFS_MAX_MTREE_LEVELS] = {};
int tree_lvl_count[INCFS_MAX_MTREE_LEVELS] = {};
int levels_count = 0;
char data_to_sign[256] = {};
int sig_data_size;
int i, level;
if (file->size == 0)
@@ -797,19 +698,6 @@ static int build_mtree(struct test_file *file)
sha256(file->mtree[0].data,
INCFS_DATA_FILE_BLOCK_SIZE, file->root_hash);
/* Calculating digital signature */
snprintf(file->sig.add_data, sizeof(file->sig.add_data), "%ld",
file->size);
memcpy(data_to_sign, file->root_hash, SHA256_DIGEST_SIZE);
memcpy(data_to_sign + SHA256_DIGEST_SIZE, file->sig.add_data,
strlen(file->sig.add_data));
sig_data_size = SHA256_DIGEST_SIZE + strlen(file->sig.add_data);
if (!sign_pkcs7(data_to_sign, sig_data_size, private_key, x509_cert,
&file->sig.data, &file->sig.size)) {
ksft_print_msg("Signing failed.\n");
return -EINVAL;
}
return 0;
}
@@ -1873,162 +1761,6 @@ static int multiple_providers_test(char *mount_dir)
return TEST_FAILURE;
}
static int signature_test(char *mount_dir)
{
struct test_files_set test = get_test_files_set();
const int file_num = test.files_count;
int i = 0;
unsigned char sig_buf[INCFS_MAX_SIGNATURE_SIZE];
char *backing_dir;
int cmd_fd = -1;
backing_dir = create_backing_dir(mount_dir);
if (!backing_dir)
goto failure;
/* Mount FS and release the backing file. (10s wait time) */
if (mount_fs(mount_dir, backing_dir, 10000) != 0)
goto failure;
cmd_fd = open_commands_file(mount_dir);
if (cmd_fd < 0)
goto failure;
/* Write hashes and data. */
for (i = 0; i < file_num; i++) {
struct test_file *file = &test.files[i];
int res;
build_mtree(file);
res = crypto_emit_file(cmd_fd, NULL, file->name, &file->id,
file->size, file->root_hash,
file->sig.data, file->sig.size, file->sig.add_data);
if (res) {
ksft_print_msg("Emit failed for %s. error: %s\n",
file->name, strerror(-res));
goto failure;
}
if (emit_test_file_data(mount_dir, file))
goto failure;
res = load_hash_tree(mount_dir, file);
if (res) {
ksft_print_msg("Can't load hashes for %s. error: %s\n",
file->name, strerror(-res));
goto failure;
}
}
/* Validate data */
for (i = 0; i < file_num; i++) {
struct test_file *file = &test.files[i];
int sig_len;
char *path;
int fd;
if (validate_test_file_content(mount_dir, file) < 0)
goto failure;
path = concat_file_name(mount_dir, file->name);
fd = open(path, O_RDWR);
free(path);
if (fd < 0) {
print_error("Can't open file");
goto failure;
}
sig_len = get_file_signature(fd, sig_buf, ARRAY_SIZE(sig_buf));
if (close(fd)) {
print_error("Can't close file");
goto failure;
}
if (sig_len < 0) {
ksft_print_msg("Can't load signature %s. error: %s\n",
file->name, strerror(-sig_len));
goto failure;
}
if (sig_len != file->sig.size ||
memcmp(sig_buf, file->sig.data, sig_len)) {
ksft_print_msg("Signature mismatch %s.\n",
file->name);
goto failure;
}
}
/* Unmount and mount again, to make sure the signature is persistent. */
close(cmd_fd);
cmd_fd = -1;
if (umount(mount_dir) != 0) {
print_error("Can't unmout FS");
goto failure;
}
if (mount_fs(mount_dir, backing_dir, 50) != 0)
goto failure;
cmd_fd = open_commands_file(mount_dir);
if (cmd_fd < 0)
goto failure;
/* Validate data again */
for (i = 0; i < file_num; i++) {
struct test_file *file = &test.files[i];
int sig_len;
char *path;
int fd;
if (validate_test_file_content(mount_dir, file) < 0)
goto failure;
path = concat_file_name(mount_dir, file->name);
fd = open(path, O_RDWR);
free(path);
if (fd < 0) {
print_error("Can't open file");
goto failure;
}
sig_len = get_file_signature(fd, sig_buf, ARRAY_SIZE(sig_buf));
if (close(fd)) {
print_error("Can't close file");
goto failure;
}
if (sig_len < 0) {
ksft_print_msg("Can't load signature %s. error: %s\n",
file->name, strerror(-sig_len));
goto failure;
}
if (sig_len != file->sig.size ||
memcmp(sig_buf, file->sig.data, sig_len)) {
ksft_print_msg("Signature mismatch %s.\n",
file->name);
goto failure;
}
}
/* Final unmount */
close(cmd_fd);
cmd_fd = -1;
if (umount(mount_dir) != 0) {
print_error("Can't unmout FS");
goto failure;
}
return TEST_SUCCESS;
failure:
close(cmd_fd);
free(backing_dir);
umount(mount_dir);
return TEST_FAILURE;
}
static int hash_tree_test(char *mount_dir)
{
char *backing_dir;
@@ -2057,8 +1789,8 @@ static int hash_tree_test(char *mount_dir)
build_mtree(file);
res = crypto_emit_file(cmd_fd, NULL, file->name, &file->id,
file->size, file->root_hash,
file->sig.data, file->sig.size, file->sig.add_data);
file->size, file->root_hash,
file->sig.add_data);
if (i == corrupted_file_idx) {
/* Corrupt third blocks hash */
@@ -2383,7 +2115,6 @@ int main(int argc, char *argv[])
MAKE_TEST(work_after_remount_test),
MAKE_TEST(child_procs_waiting_for_data_test),
MAKE_TEST(multiple_providers_test),
MAKE_TEST(signature_test),
MAKE_TEST(hash_tree_test),
MAKE_TEST(read_log_test),
};

View File

@@ -23,7 +23,8 @@
#include "utils.h"
int mount_fs(char *mount_dir, char *backing_dir, int read_timeout_ms)
int mount_fs(const char *mount_dir, const char *backing_dir,
int read_timeout_ms)
{
static const char fs_name[] = INCFS_NAME;
char mount_options[512];
@@ -39,7 +40,8 @@ int mount_fs(char *mount_dir, char *backing_dir, int read_timeout_ms)
return result;
}
int mount_fs_opt(char *mount_dir, char *backing_dir, char *opt)
int mount_fs_opt(const char *mount_dir, const char *backing_dir,
const char *opt)
{
static const char fs_name[] = INCFS_NAME;
int result;
@@ -50,179 +52,94 @@ int mount_fs_opt(char *mount_dir, char *backing_dir, char *opt)
return result;
}
int unlink_node(int fd, int parent_ino, char *filename)
struct hash_section {
uint32_t algorithm;
uint8_t log2_blocksize;
uint32_t salt_size;
/* no salt */
uint32_t hash_size;
uint8_t hash[SHA256_DIGEST_SIZE];
} __packed;
struct signature_blob {
uint32_t version;
uint32_t hash_section_size;
struct hash_section hash_section;
uint32_t signing_section_size;
uint8_t signing_section[];
} __packed;
size_t format_signature(void **buf, const char *root_hash, const char *add_data)
{
return 0;
size_t size = sizeof(struct signature_blob) + strlen(add_data) + 1;
struct signature_blob *sb = malloc(size);
*sb = (struct signature_blob){
.version = INCFS_SIGNATURE_VERSION,
.hash_section_size = sizeof(struct hash_section),
.hash_section =
(struct hash_section){
.algorithm = INCFS_HASH_TREE_SHA256,
.log2_blocksize = 12,
.salt_size = 0,
.hash_size = SHA256_DIGEST_SIZE,
},
.signing_section_size = sizeof(uint32_t) + strlen(add_data) + 1,
};
memcpy(sb->hash_section.hash, root_hash, SHA256_DIGEST_SIZE);
memcpy((char *)sb->signing_section, add_data, strlen(add_data) + 1);
*buf = sb;
return size;
}
static EVP_PKEY *deserialize_private_key(const char *pem_key)
{
BIO *bio = NULL;
EVP_PKEY *pkey = NULL;
int len = strlen(pem_key);
bio = BIO_new_mem_buf(pem_key, len);
if (!bio)
return NULL;
pkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
BIO_free(bio);
return pkey;
}
static X509 *deserialize_cert(const char *pem_cert)
{
BIO *bio = NULL;
X509 *cert = NULL;
int len = strlen(pem_cert);
bio = BIO_new_mem_buf(pem_cert, len);
if (!bio)
return NULL;
cert = PEM_read_bio_X509(bio, NULL, NULL, NULL);
BIO_free(bio);
return cert;
}
bool sign_pkcs7(const void *data_to_sign, size_t data_size,
char *pkey_pem, char *cert_pem,
void **sig_ret, size_t *sig_size_ret)
{
/*
* PKCS#7 signing flags:
*
* - PKCS7_BINARY signing binary data, so skip MIME translation
*
* - PKCS7_NOATTR omit extra authenticated attributes, such as
* SMIMECapabilities
*
* - PKCS7_PARTIAL PKCS7_sign() creates a handle only, then
* PKCS7_sign_add_signer() can add a signer later.
* This is necessary to change the message digest
* algorithm from the default of SHA-1. Requires
* OpenSSL 1.0.0 or later.
*/
int pkcs7_flags = PKCS7_BINARY | PKCS7_NOATTR | PKCS7_PARTIAL;
void *sig;
size_t sig_size;
BIO *bio = NULL;
PKCS7 *p7 = NULL;
EVP_PKEY *pkey = NULL;
X509 *cert = NULL;
bool ok = false;
const EVP_MD *md = EVP_sha256();
pkey = deserialize_private_key(pkey_pem);
if (!pkey) {
printf("deserialize_private_key failed\n");
goto out;
}
cert = deserialize_cert(cert_pem);
if (!cert) {
printf("deserialize_cert failed\n");
goto out;
}
bio = BIO_new_mem_buf(data_to_sign, data_size);
if (!bio)
goto out;
p7 = PKCS7_sign(NULL, NULL, NULL, bio, pkcs7_flags);
if (!p7) {
printf("failed to initialize PKCS#7 signature object\n");
goto out;
}
if (!PKCS7_sign_add_signer(p7, cert, pkey, md, pkcs7_flags)) {
printf("failed to add signer to PKCS#7 signature object\n");
goto out;
}
if (PKCS7_final(p7, bio, pkcs7_flags) != 1) {
printf("failed to finalize PKCS#7 signature\n");
goto out;
}
BIO_free(bio);
bio = BIO_new(BIO_s_mem());
if (!bio) {
printf("out of memory\n");
goto out;
}
if (i2d_PKCS7_bio(bio, p7) != 1) {
printf("failed to DER-encode PKCS#7 signature object\n");
goto out;
}
sig_size = BIO_get_mem_data(bio, &sig);
*sig_ret = malloc(sig_size);
memcpy(*sig_ret, sig, sig_size);
*sig_size_ret = sig_size;
ok = true;
out:
PKCS7_free(p7);
BIO_free(bio);
return ok;
}
int crypto_emit_file(int fd, char *dir, char *filename, incfs_uuid_t *id_out,
size_t size, const char *root_hash, char *sig, size_t sig_size,
char *add_data)
int crypto_emit_file(int fd, const char *dir, const char *filename,
incfs_uuid_t *id_out, size_t size, const char *root_hash,
const char *add_data)
{
int mode = __S_IFREG | 0555;
struct incfs_file_signature_info sig_info = {
.hash_tree_alg = root_hash
? INCFS_HASH_TREE_SHA256
: 0,
.root_hash = ptr_to_u64(root_hash),
.additional_data = ptr_to_u64(add_data),
.additional_data_size = strlen(add_data),
.signature = ptr_to_u64(sig),
.signature_size = sig_size,
};
void *signature;
int error = 0;
struct incfs_new_file_args args = {
.size = size,
.mode = mode,
.file_name = ptr_to_u64(filename),
.directory_path = ptr_to_u64(dir),
.signature_info = ptr_to_u64(&sig_info),
.file_attr = 0,
.file_attr_len = 0
};
args.signature_size = format_signature(&signature, root_hash, add_data);
args.signature_info = ptr_to_u64(signature);
md5(filename, strlen(filename), (char *)args.file_id.bytes);
if (ioctl(fd, INCFS_IOC_CREATE_FILE, &args) != 0)
return -errno;
if (ioctl(fd, INCFS_IOC_CREATE_FILE, &args) != 0) {
error = -errno;
goto out;
}
*id_out = args.file_id;
return 0;
out:
free(signature);
return error;
}
int emit_file(int fd, char *dir, char *filename, incfs_uuid_t *id_out,
size_t size, char *attr)
int emit_file(int fd, const char *dir, const char *filename,
incfs_uuid_t *id_out, size_t size, const char *attr)
{
int mode = __S_IFREG | 0555;
struct incfs_file_signature_info sig_info = {
.hash_tree_alg = 0,
.root_hash = ptr_to_u64(NULL)
};
struct incfs_new_file_args args = {
.size = size,
.mode = mode,
.file_name = ptr_to_u64(filename),
.directory_path = ptr_to_u64(dir),
.signature_info = ptr_to_u64(&sig_info),
.file_attr = ptr_to_u64(attr),
.file_attr_len = attr ? strlen(attr) : 0
};
struct incfs_new_file_args args = { .size = size,
.mode = mode,
.file_name = ptr_to_u64(filename),
.directory_path = ptr_to_u64(dir),
.signature_info = ptr_to_u64(NULL),
.signature_size = 0,
.file_attr = ptr_to_u64(attr),
.file_attr_len =
attr ? strlen(attr) : 0 };
md5(filename, strlen(filename), (char *)args.file_id.bytes);
@@ -250,7 +167,7 @@ int get_file_signature(int fd, unsigned char *buf, int buf_size)
return -errno;
}
loff_t get_file_size(char *name)
loff_t get_file_size(const char *name)
{
struct stat st;
@@ -259,7 +176,7 @@ loff_t get_file_size(char *name)
return -ENOENT;
}
int open_commands_file(char *mount_dir)
int open_commands_file(const char *mount_dir)
{
char cmd_file[255];
int cmd_fd;
@@ -273,7 +190,7 @@ int open_commands_file(char *mount_dir)
return cmd_fd;
}
int open_log_file(char *mount_dir)
int open_log_file(const char *mount_dir)
{
char cmd_file[255];
int cmd_fd;
@@ -358,7 +275,7 @@ int delete_dir_tree(const char *dir_path)
return result;
}
void sha256(char *data, size_t dsize, char *hash)
void sha256(const char *data, size_t dsize, char *hash)
{
SHA256_CTX ctx;
@@ -367,7 +284,7 @@ void sha256(char *data, size_t dsize, char *hash)
SHA256_Final((unsigned char *)hash, &ctx);
}
void md5(char *data, size_t dsize, char *hash)
void md5(const char *data, size_t dsize, char *hash)
{
MD5_CTX ctx;

View File

@@ -9,6 +9,8 @@
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
#define __packed __attribute__((__packed__))
#ifdef __LP64__
#define ptr_to_u64(p) ((__u64)p)
#else
@@ -17,9 +19,11 @@
#define SHA256_DIGEST_SIZE 32
int mount_fs(char *mount_dir, char *backing_dir, int read_timeout_ms);
int mount_fs(const char *mount_dir, const char *backing_dir,
int read_timeout_ms);
int mount_fs_opt(char *mount_dir, char *backing_dir, char *opt);
int mount_fs_opt(const char *mount_dir, const char *backing_dir,
const char *opt);
int get_file_bmap(int cmd_fd, int ino, unsigned char *buf, int buf_size);
@@ -28,32 +32,26 @@ int get_file_signature(int fd, unsigned char *buf, int buf_size);
int emit_node(int fd, char *filename, int *ino_out, int parent_ino,
size_t size, mode_t mode, char *attr);
int emit_file(int fd, char *dir, char *filename, incfs_uuid_t *id_out,
size_t size, char *attr);
int emit_file(int fd, const char *dir, const char *filename,
incfs_uuid_t *id_out, size_t size, const char *attr);
int crypto_emit_file(int fd, char *dir, char *filename, incfs_uuid_t *id_out,
size_t size, const char *root_hash, char *sig, size_t sig_size,
char *add_data);
int crypto_emit_file(int fd, const char *dir, const char *filename,
incfs_uuid_t *id_out, size_t size, const char *root_hash,
const char *add_data);
int unlink_node(int fd, int parent_ino, char *filename);
loff_t get_file_size(const char *name);
loff_t get_file_size(char *name);
int open_commands_file(const char *mount_dir);
int open_commands_file(char *mount_dir);
int open_log_file(char *mount_dir);
int open_log_file(const char *mount_dir);
int wait_for_pending_reads(int fd, int timeout_ms,
struct incfs_pending_read_info *prs, int prs_count);
char *concat_file_name(const char *dir, char *file);
void sha256(char *data, size_t dsize, char *hash);
void sha256(const char *data, size_t dsize, char *hash);
void md5(char *data, size_t dsize, char *hash);
bool sign_pkcs7(const void *data_to_sign, size_t data_size,
char *pkey_pem, char *cert_pem,
void **sig_ret, size_t *sig_size_ret);
void md5(const char *data, size_t dsize, char *hash);
int delete_dir_tree(const char *path);