/*
* Copyright (C) 2010 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.
*/
/* TO DO:
* 1. Perhaps keep several copies of the encrypted key, in case something
* goes horribly wrong?
*
*/
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <linux/dm-ioctl.h>
#include <libgen.h>
#include <stdlib.h>
#include <sys/param.h>
#include <string.h>
#include <sys/mount.h>
#include <openssl/evp.h>
#include <openssl/sha.h>
#include <errno.h>
#include <ext4.h>
#include <linux/kdev_t.h>
#include <fs_mgr.h>
#include "cryptfs.h"
#define LOG_TAG "Cryptfs"
#include "cutils/log.h"
#include "cutils/properties.h"
#include "cutils/android_reboot.h"
#include "hardware_legacy/power.h"
#include <logwrap/logwrap.h>
#include "VolumeManager.h"
#include "VoldUtil.h"
#include "crypto_scrypt.h"
#define DM_CRYPT_BUF_SIZE 4096
#define DATA_MNT_POINT "/data"
#define HASH_COUNT 2000
#define KEY_LEN_BYTES 16
#define IV_LEN_BYTES 16
#define KEY_IN_FOOTER "footer"
#define EXT4_FS 1
#define FAT_FS 2
#define TABLE_LOAD_RETRIES 10
char *me = "cryptfs";
static unsigned char saved_master_key[KEY_LEN_BYTES];
static char *saved_mount_point;
static int master_key_saved = 0;
static struct crypt_persist_data *persist_data = NULL;
extern struct fstab *fstab;
static void cryptfs_reboot(int recovery)
{
if (recovery) {
property_set(ANDROID_RB_PROPERTY, "reboot,recovery");
} else {
property_set(ANDROID_RB_PROPERTY, "reboot");
}
sleep(20);
/* Shouldn't get here, reboot should happen before sleep times out */
return;
}
static void ioctl_init(struct dm_ioctl *io, size_t dataSize, const char *name, unsigned flags)
{
memset(io, 0, dataSize);
io->data_size = dataSize;
io->data_start = sizeof(struct dm_ioctl);
io->version[0] = 4;
io->version[1] = 0;
io->version[2] = 0;
io->flags = flags;
if (name) {
strncpy(io->name, name, sizeof(io->name));
}
}
/**
* Gets the default device scrypt parameters for key derivation time tuning.
* The parameters should lead to about one second derivation time for the
* given device.
*/
static void get_device_scrypt_params(struct crypt_mnt_ftr *ftr) {
const int default_params[] = SCRYPT_DEFAULTS;
int params[] = SCRYPT_DEFAULTS;
char paramstr[PROPERTY_VALUE_MAX];
char *token;
char *saveptr;
int i;
property_get(SCRYPT_PROP, paramstr, "");
if (paramstr[0] != '\0') {
/*
* The token we're looking for should be three integers separated by
* colons (e.g., "12:8:1"). Scan the property to make sure it matches.
*/
for (i = 0, token = strtok_r(paramstr, ":", &saveptr);
token != NULL && i < 3;
i++, token = strtok_r(NULL, ":", &saveptr)) {
char *endptr;
params[i] = strtol(token, &endptr, 10);
/*
* Check that there was a valid number and it's 8-bit. If not,
* break out and the end check will take the default values.
*/
if ((*token == '\0') || (*endptr != '\0') || params[i] < 0 || params[i] > 255) {
break;
}
}
/*
* If there were not enough tokens or a token was malformed (not an
* integer), it will end up here and the default parameters can be
* taken.
*/
if ((i != 3) || (token != NULL)) {
SLOGW("bad scrypt parameters '%s' should be like '12:8:1'; using defaults", paramstr);
memcpy(params, default_params, sizeof(params));
}
}
ftr->N_factor = params[0];
ftr->r_factor = params[1];
ftr->p_factor = params[2];
}
static unsigned int get_fs_size(char *dev)
{
int fd, block_size;
struct ext4_super_block sb;
off64_t len;
if ((fd = open(dev, O_RDONLY)) < 0) {
SLOGE("Cannot open device to get filesystem size ");
return 0;
}
if (lseek64(fd, 1024, SEEK_SET) < 0) {
SLOGE("Cannot seek to superblock");
return 0;
}
if (read(fd, &sb, sizeof(sb)) != sizeof(sb)) {
SLOGE("Cannot read superblock");
return 0;
}
close(fd);
block_size = 1024 << sb.s_log_block_size;
/* compute length in bytes */
len = ( ((off64_t)sb.s_blocks_count_hi << 32) + sb.s_blocks_count_lo) * block_size;
/* return length in sectors */
return (unsigned int) (len / 512);
}
static int get_crypt_ftr_info(char **metadata_fname, off64_t *off)
{
static int cached_data = 0;
static off64_t cached_off = 0;
static char cached_metadata_fname[PROPERTY_VALUE_MAX] = "";
int fd;
char key_loc[PROPERTY_VALUE_MAX];
char real_blkdev[PROPERTY_VALUE_MAX];
unsigned int nr_sec;
int rc = -1;
if (!cached_data) {
fs_mgr_get_crypt_info(fstab, key_loc, real_blkdev, sizeof(key_loc));
if (!strcmp(key_loc, KEY_IN_FOOTER)) {
if ( (fd = open(real_blkdev, O_RDWR)) < 0) {
SLOGE("Cannot open real block device %s\n", real_blkdev);
return -1;
}
if ((nr_sec = get_blkdev_size(fd))) {
/* If it's an encrypted Android partition, the last 16 Kbytes contain the
* encryption info footer and key, and plenty of bytes to spare for future
* growth.
*/
strlcpy(cached_metadata_fname, real_blkdev, sizeof(cached_metadata_fname));
cached_off = ((off64_t)nr_sec * 512) - CRYPT_FOOTER_OFFSET;
cached_data = 1;
} else {
SLOGE("Cannot get size of block device %s\n", real_blkdev);
}
close(fd);
} else {
strlcpy(cached_metadata_fname, key_loc, sizeof(cached_metadata_fname));
cached_off = 0;
cached_data = 1;
}
}
if (cached_data) {
if (metadata_fname) {
*metadata_fname = cached_metadata_fname;
}
if (off) {
*off = cached_off;
}
rc = 0;
}
return rc;
}
/* key or salt can be NULL, in which case just skip writing that value. Useful to
* update the failed mount count but not change the key.
*/
static int put_crypt_ftr_and_key(struct crypt_mnt_ftr *crypt_ftr)
{
int fd;
unsigned int nr_sec, cnt;
/* starting_off is set to the SEEK_SET offset
* where the crypto structure starts
*/
off64_t starting_off;
int rc = -1;
char *fname = NULL;
struct stat statbuf;
if (get_crypt_ftr_info(&fname, &starting_off)) {
SLOGE("Unable to get crypt_ftr_info\n");
return -1;
}
if (fname[0] != '/') {
SLOGE("Unexpected value for crypto key location\n");
return -1;
}
if ( (fd = open(fname, O_RDWR | O_CREAT, 0600)) < 0) {
SLOGE("Cannot open footer file %s for put\n", fname);
return -1;
}
/* Seek to the start of the crypt footer */
if (lseek64(fd, starting_off, SEEK_SET) == -1) {
SLOGE("Cannot seek to real block device footer\n");
goto errout;
}
if ((cnt = write(fd, crypt_ftr, sizeof(struct crypt_mnt_ftr))) != sizeof(struct crypt_mnt_ftr)) {
SLOGE("Cannot write real block device footer\n");
goto errout;
}
fstat(fd, &statbuf);
/* If the keys are kept on a raw block device, do not try to truncate it. */
if (S_ISREG(statbuf.st_mode)) {
if (ftruncate(fd, 0x4000)) {
SLOGE("Cannot set footer file size\n", fname);
goto errout;
}
}
/* Success! */
rc = 0;
errout:
close(fd);
return rc;
}
static inline int unix_read(int fd,
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
Android vold 多U盘多分区挂载实现 (153个子文件)
03bf8a7ab9dcee8897f275c75adfcdb20e0fdc 266B
0668855addac1bc22af3a4ea01ac2db20209ac 1KB
0a1d66585fb44f59d913d3417422486ef10225 284B
1e1b9565b3598967a52e19c03495251fbb6a02 11KB
1fceb5517d4a85da9a9197cd14cd1d5dabbedf 215B
24576834b3c9740052732371bb7e5d359bbe86 1KB
2dcf905abd3dc76738fd864e3979bd6e5ce183 260B
android-4.4 532B
android-4.4 41B
4ccd58813e9ac7f59fd9782e7c8aede3efd110 11KB
4cf54129f5916fc42a771d14934987bc9dbb21 1KB
5d705c797b9571af1b405f978d3ce114e03900 464B
5d99ce39b5edd0b78c47a93563aed6b3d56356 297B
6080530455cfda14017f7067dd9b249b30cfa3 19KB
68f54bb96e1e792b817efef60a8977e59918bf 10KB
6932df89756f796c3a1f04f748db39a0564561 279B
707dae0d89fe72c55a20be1473a329d6f3e53d 1KB
770dcf6ffe2baba16cbb290aba16f735c51962 252B
79cdb85ced77da6d3782db41d107418fab2785 558B
96c50d4185eca2e0b72ad5aeda91989551f2f7 2KB
a1dc1a8af0fd4fd5e3d59e55a84361b665e140 1KB
ab611925aea29fc4088b5c3de7c8c77d956b8b 273B
4.4-BOX-RkExplorer.apk 998KB
b62aff7b3a21d6de7eda7fb245d856b073af85 1KB
b84bffc0a181d51363662a6abcdc389495c1d8 1KB
cryptfs.c 64KB
cryptfs.c 64KB
fstrim.c 5KB
fstrim.c 5KB
vdc.c 4KB
vdc.c 4KB
VoldUtil.c 819B
VoldUtil.c 819B
cc8957470f16100140110ddf494128d1adc553 174B
config 207B
VolumeManager.cpp 48KB
VolumeManager.cpp 48KB
Volume.cpp 44KB
Volume.cpp 30KB
DirectVolume.cpp 28KB
CommandListener.cpp 23KB
CommandListener.cpp 23KB
DirectVolume.cpp 18KB
Devmapper.cpp 8KB
Devmapper.cpp 8KB
Fat.cpp 7KB
Fat.cpp 7KB
Loop.cpp 7KB
Loop.cpp 7KB
Process.cpp 6KB
Process.cpp 6KB
main.cpp 6KB
main.cpp 6KB
G3Dev.cpp 6KB
G3Dev.cpp 6KB
Ntfs.cpp 5KB
Ntfs.cpp 4KB
Ext4.cpp 3KB
Ext4.cpp 3KB
NetlinkManager.cpp 3KB
NetlinkManager.cpp 3KB
VolumeManager_test.cpp 2KB
VolumeManager_test.cpp 2KB
Xwarp.cpp 2KB
Xwarp.cpp 2KB
MiscManager.cpp 2KB
MiscManager.cpp 2KB
NetlinkHandler.cpp 2KB
NetlinkHandler.cpp 2KB
Misc.cpp 1KB
Misc.cpp 1KB
ResponseCode.cpp 1KB
ResponseCode.cpp 1KB
VoldCommand.cpp 732B
VoldCommand.cpp 732B
d4e556e35f05633efce4e5473f49b072be318f 12KB
description 73B
e110df1adbb885d31b9441d62025904ef6f857 1KB
e7c05848ebe80e9283f4d531ca2b83892f8e88 1KB
e7c61102611ccd5df1ca48cb733bf037512c6b 335B
edff7fbb9a1d65ae3deedf58ad9b4d53722847 1KB
exclude 240B
f05b15b76b91aa07182e86a730d7552b23130c 291B
f2b13fcd72ddd1c90df6ab49bbe83022af3dfe 11KB
fff871a7e1ee070eba591d452b5a4fab80b1fa 2KB
Volume.h 6KB
cryptfs.h 6KB
cryptfs.h 6KB
VolumeManager.h 5KB
VolumeManager.h 5KB
Volume.h 4KB
DirectVolume.h 3KB
ResponseCode.h 3KB
ResponseCode.h 3KB
DirectVolume.h 3KB
hash.h 2KB
hash.h 2KB
CommandListener.h 2KB
CommandListener.h 2KB
Process.h 1KB
共 153 条
- 1
- 2
N_E_M_O_C艹
- 粉丝: 134
- 资源: 24
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
- 1
- 2
- 3
前往页