blob: e3672f7735e2cf4fd764c2dc3c3b3075fd79ef30 [file] [log] [blame]
Ken Sumrall8f869aa2010-12-03 03:47:09 -08001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/* TO DO:
18 * 1. Perhaps keep several copies of the encrypted key, in case something
19 * goes horribly wrong?
20 *
21 */
22
23#include <sys/types.h>
24#include <sys/stat.h>
25#include <fcntl.h>
26#include <unistd.h>
27#include <stdio.h>
28#include <sys/ioctl.h>
29#include <linux/dm-ioctl.h>
30#include <libgen.h>
31#include <stdlib.h>
32#include <sys/param.h>
33#include <string.h>
34#include <sys/mount.h>
35#include <openssl/evp.h>
Ken Sumrall8ddbe402011-01-17 15:26:29 -080036#include <openssl/sha.h>
Ken Sumrall8f869aa2010-12-03 03:47:09 -080037#include <errno.h>
Ken Sumrallc290eaf2011-03-07 23:40:35 -080038#include <cutils/android_reboot.h>
Ken Sumrall3ed82362011-01-28 23:31:16 -080039#include <ext4.h>
Ken Sumrall29d8da82011-05-18 17:20:07 -070040#include <linux/kdev_t.h>
Ken Sumrall8f869aa2010-12-03 03:47:09 -080041#include "cryptfs.h"
42#define LOG_TAG "Cryptfs"
43#include "cutils/log.h"
44#include "cutils/properties.h"
Ken Sumrall5d4c68e2011-01-30 19:06:03 -080045#include "hardware_legacy/power.h"
Ken Sumrall29d8da82011-05-18 17:20:07 -070046#include "VolumeManager.h"
Ken Sumrall8f869aa2010-12-03 03:47:09 -080047
48#define DM_CRYPT_BUF_SIZE 4096
Ken Sumrall8ddbe402011-01-17 15:26:29 -080049#define DATA_MNT_POINT "/data"
Ken Sumrall8f869aa2010-12-03 03:47:09 -080050
Jason parks70a4b3f2011-01-28 10:10:47 -060051#define HASH_COUNT 2000
52#define KEY_LEN_BYTES 16
53#define IV_LEN_BYTES 16
54
Ken Sumrall29d8da82011-05-18 17:20:07 -070055#define KEY_LOC_PROP "ro.crypto.keyfile.userdata"
56#define KEY_IN_FOOTER "footer"
57
58#define EXT4_FS 1
59#define FAT_FS 2
60
Ken Sumrall8f869aa2010-12-03 03:47:09 -080061char *me = "cryptfs";
62
Jason parks70a4b3f2011-01-28 10:10:47 -060063static unsigned char saved_master_key[KEY_LEN_BYTES];
Ken Sumrall29d8da82011-05-18 17:20:07 -070064static char *saved_data_blkdev;
Jason parks70a4b3f2011-01-28 10:10:47 -060065static int master_key_saved = 0;
Ken Sumrall8ddbe402011-01-17 15:26:29 -080066
Ken Sumrall8f869aa2010-12-03 03:47:09 -080067static void ioctl_init(struct dm_ioctl *io, size_t dataSize, const char *name, unsigned flags)
68{
69 memset(io, 0, dataSize);
70 io->data_size = dataSize;
71 io->data_start = sizeof(struct dm_ioctl);
72 io->version[0] = 4;
73 io->version[1] = 0;
74 io->version[2] = 0;
75 io->flags = flags;
76 if (name) {
77 strncpy(io->name, name, sizeof(io->name));
78 }
79}
80
Ken Sumrall3ed82362011-01-28 23:31:16 -080081static unsigned int get_fs_size(char *dev)
82{
83 int fd, block_size;
84 struct ext4_super_block sb;
85 off64_t len;
86
87 if ((fd = open(dev, O_RDONLY)) < 0) {
88 SLOGE("Cannot open device to get filesystem size ");
89 return 0;
90 }
91
92 if (lseek64(fd, 1024, SEEK_SET) < 0) {
93 SLOGE("Cannot seek to superblock");
94 return 0;
95 }
96
97 if (read(fd, &sb, sizeof(sb)) != sizeof(sb)) {
98 SLOGE("Cannot read superblock");
99 return 0;
100 }
101
102 close(fd);
103
104 block_size = 1024 << sb.s_log_block_size;
105 /* compute length in bytes */
106 len = ( ((off64_t)sb.s_blocks_count_hi << 32) + sb.s_blocks_count_lo) * block_size;
107
108 /* return length in sectors */
109 return (unsigned int) (len / 512);
110}
111
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800112static unsigned int get_blkdev_size(int fd)
113{
114 unsigned int nr_sec;
115
116 if ( (ioctl(fd, BLKGETSIZE, &nr_sec)) == -1) {
117 nr_sec = 0;
118 }
119
120 return nr_sec;
121}
122
Ken Sumralle8744072011-01-18 22:01:55 -0800123/* key or salt can be NULL, in which case just skip writing that value. Useful to
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800124 * update the failed mount count but not change the key.
125 */
126static int put_crypt_ftr_and_key(char *real_blk_name, struct crypt_mnt_ftr *crypt_ftr,
Ken Sumralle8744072011-01-18 22:01:55 -0800127 unsigned char *key, unsigned char *salt)
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800128{
129 int fd;
130 unsigned int nr_sec, cnt;
131 off64_t off;
132 int rc = -1;
Ken Sumrall29d8da82011-05-18 17:20:07 -0700133 char *fname;
134 char key_loc[PROPERTY_VALUE_MAX];
Ken Sumrall3be890f2011-09-14 16:53:46 -0700135 struct stat statbuf;
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800136
Ken Sumrall29d8da82011-05-18 17:20:07 -0700137 property_get(KEY_LOC_PROP, key_loc, KEY_IN_FOOTER);
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800138
Ken Sumrall29d8da82011-05-18 17:20:07 -0700139 if (!strcmp(key_loc, KEY_IN_FOOTER)) {
140 fname = real_blk_name;
141 if ( (fd = open(fname, O_RDWR)) < 0) {
142 SLOGE("Cannot open real block device %s\n", fname);
143 return -1;
144 }
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800145
Ken Sumrall29d8da82011-05-18 17:20:07 -0700146 if ( (nr_sec = get_blkdev_size(fd)) == 0) {
147 SLOGE("Cannot get size of block device %s\n", fname);
148 goto errout;
149 }
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800150
Ken Sumrall29d8da82011-05-18 17:20:07 -0700151 /* If it's an encrypted Android partition, the last 16 Kbytes contain the
152 * encryption info footer and key, and plenty of bytes to spare for future
153 * growth.
154 */
155 off = ((off64_t)nr_sec * 512) - CRYPT_FOOTER_OFFSET;
156
157 if (lseek64(fd, off, SEEK_SET) == -1) {
158 SLOGE("Cannot seek to real block device footer\n");
159 goto errout;
160 }
161 } else if (key_loc[0] == '/') {
162 fname = key_loc;
163 if ( (fd = open(fname, O_RDWR | O_CREAT, 0600)) < 0) {
164 SLOGE("Cannot open footer file %s\n", fname);
165 return -1;
166 }
167 } else {
168 SLOGE("Unexpected value for" KEY_LOC_PROP "\n");
169 return -1;;
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800170 }
171
172 if ((cnt = write(fd, crypt_ftr, sizeof(struct crypt_mnt_ftr))) != sizeof(struct crypt_mnt_ftr)) {
173 SLOGE("Cannot write real block device footer\n");
174 goto errout;
175 }
176
177 if (key) {
Jason parks70a4b3f2011-01-28 10:10:47 -0600178 if (crypt_ftr->keysize != KEY_LEN_BYTES) {
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800179 SLOGE("Keysize of %d bits not supported for real block device %s\n",
Ken Sumrall29d8da82011-05-18 17:20:07 -0700180 crypt_ftr->keysize*8, fname);
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800181 goto errout;
182 }
183
184 if ( (cnt = write(fd, key, crypt_ftr->keysize)) != crypt_ftr->keysize) {
Ken Sumrall29d8da82011-05-18 17:20:07 -0700185 SLOGE("Cannot write key for real block device %s\n", fname);
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800186 goto errout;
187 }
188 }
189
Ken Sumralle8744072011-01-18 22:01:55 -0800190 if (salt) {
Ken Sumrall29d8da82011-05-18 17:20:07 -0700191 /* Compute the offset from the last write to the salt */
192 off = KEY_TO_SALT_PADDING;
193 if (! key)
194 off += crypt_ftr->keysize;
Ken Sumralle8744072011-01-18 22:01:55 -0800195
Ken Sumrall29d8da82011-05-18 17:20:07 -0700196 if (lseek64(fd, off, SEEK_CUR) == -1) {
Ken Sumralle8744072011-01-18 22:01:55 -0800197 SLOGE("Cannot seek to real block device salt \n");
198 goto errout;
199 }
200
201 if ( (cnt = write(fd, salt, SALT_LEN)) != SALT_LEN) {
Ken Sumrall29d8da82011-05-18 17:20:07 -0700202 SLOGE("Cannot write salt for real block device %s\n", fname);
203 goto errout;
204 }
205 }
206
Ken Sumrall3be890f2011-09-14 16:53:46 -0700207 fstat(fd, &statbuf);
208 /* If the keys are kept on a raw block device, do not try to truncate it. */
209 if (S_ISREG(statbuf.st_mode) && (key_loc[0] == '/')) {
Ken Sumrall29d8da82011-05-18 17:20:07 -0700210 if (ftruncate(fd, 0x4000)) {
Ken Sumrall3be890f2011-09-14 16:53:46 -0700211 SLOGE("Cannot set footer file size\n", fname);
Ken Sumralle8744072011-01-18 22:01:55 -0800212 goto errout;
213 }
214 }
215
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800216 /* Success! */
217 rc = 0;
218
219errout:
220 close(fd);
221 return rc;
222
223}
224
225static int get_crypt_ftr_and_key(char *real_blk_name, struct crypt_mnt_ftr *crypt_ftr,
Ken Sumralle8744072011-01-18 22:01:55 -0800226 unsigned char *key, unsigned char *salt)
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800227{
228 int fd;
229 unsigned int nr_sec, cnt;
230 off64_t off;
231 int rc = -1;
Ken Sumrall29d8da82011-05-18 17:20:07 -0700232 char key_loc[PROPERTY_VALUE_MAX];
233 char *fname;
234 struct stat statbuf;
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800235
Ken Sumrall29d8da82011-05-18 17:20:07 -0700236 property_get(KEY_LOC_PROP, key_loc, KEY_IN_FOOTER);
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800237
Ken Sumrall29d8da82011-05-18 17:20:07 -0700238 if (!strcmp(key_loc, KEY_IN_FOOTER)) {
239 fname = real_blk_name;
240 if ( (fd = open(fname, O_RDONLY)) < 0) {
241 SLOGE("Cannot open real block device %s\n", fname);
242 return -1;
243 }
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800244
Ken Sumrall29d8da82011-05-18 17:20:07 -0700245 if ( (nr_sec = get_blkdev_size(fd)) == 0) {
246 SLOGE("Cannot get size of block device %s\n", fname);
247 goto errout;
248 }
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800249
Ken Sumrall29d8da82011-05-18 17:20:07 -0700250 /* If it's an encrypted Android partition, the last 16 Kbytes contain the
251 * encryption info footer and key, and plenty of bytes to spare for future
252 * growth.
253 */
254 off = ((off64_t)nr_sec * 512) - CRYPT_FOOTER_OFFSET;
255
256 if (lseek64(fd, off, SEEK_SET) == -1) {
257 SLOGE("Cannot seek to real block device footer\n");
258 goto errout;
259 }
260 } else if (key_loc[0] == '/') {
261 fname = key_loc;
262 if ( (fd = open(fname, O_RDONLY)) < 0) {
263 SLOGE("Cannot open footer file %s\n", fname);
264 return -1;
265 }
266
267 /* Make sure it's 16 Kbytes in length */
268 fstat(fd, &statbuf);
Ken Sumrall3be890f2011-09-14 16:53:46 -0700269 if (S_ISREG(statbuf.st_mode) && (statbuf.st_size != 0x4000)) {
Ken Sumrall29d8da82011-05-18 17:20:07 -0700270 SLOGE("footer file %s is not the expected size!\n", fname);
271 goto errout;
272 }
273 } else {
274 SLOGE("Unexpected value for" KEY_LOC_PROP "\n");
275 return -1;;
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800276 }
277
278 if ( (cnt = read(fd, crypt_ftr, sizeof(struct crypt_mnt_ftr))) != sizeof(struct crypt_mnt_ftr)) {
279 SLOGE("Cannot read real block device footer\n");
280 goto errout;
281 }
282
283 if (crypt_ftr->magic != CRYPT_MNT_MAGIC) {
Ken Sumrall29d8da82011-05-18 17:20:07 -0700284 SLOGE("Bad magic for real block device %s\n", fname);
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800285 goto errout;
286 }
287
288 if (crypt_ftr->major_version != 1) {
289 SLOGE("Cannot understand major version %d real block device footer\n",
290 crypt_ftr->major_version);
291 goto errout;
292 }
293
294 if (crypt_ftr->minor_version != 0) {
295 SLOGW("Warning: crypto footer minor version %d, expected 0, continuing...\n",
296 crypt_ftr->minor_version);
297 }
298
299 if (crypt_ftr->ftr_size > sizeof(struct crypt_mnt_ftr)) {
300 /* the footer size is bigger than we expected.
301 * Skip to it's stated end so we can read the key.
302 */
303 if (lseek(fd, crypt_ftr->ftr_size - sizeof(struct crypt_mnt_ftr), SEEK_CUR) == -1) {
304 SLOGE("Cannot seek to start of key\n");
305 goto errout;
306 }
307 }
308
Jason parks70a4b3f2011-01-28 10:10:47 -0600309 if (crypt_ftr->keysize != KEY_LEN_BYTES) {
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800310 SLOGE("Keysize of %d bits not supported for real block device %s\n",
Ken Sumrall29d8da82011-05-18 17:20:07 -0700311 crypt_ftr->keysize * 8, fname);
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800312 goto errout;
313 }
314
315 if ( (cnt = read(fd, key, crypt_ftr->keysize)) != crypt_ftr->keysize) {
Ken Sumrall29d8da82011-05-18 17:20:07 -0700316 SLOGE("Cannot read key for real block device %s\n", fname);
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800317 goto errout;
318 }
319
Ken Sumralle8744072011-01-18 22:01:55 -0800320 if (lseek64(fd, KEY_TO_SALT_PADDING, SEEK_CUR) == -1) {
321 SLOGE("Cannot seek to real block device salt\n");
322 goto errout;
323 }
324
325 if ( (cnt = read(fd, salt, SALT_LEN)) != SALT_LEN) {
Ken Sumrall29d8da82011-05-18 17:20:07 -0700326 SLOGE("Cannot read salt for real block device %s\n", fname);
Ken Sumralle8744072011-01-18 22:01:55 -0800327 goto errout;
328 }
329
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800330 /* Success! */
331 rc = 0;
332
333errout:
334 close(fd);
335 return rc;
336}
337
338/* Convert a binary key of specified length into an ascii hex string equivalent,
339 * without the leading 0x and with null termination
340 */
341void convert_key_to_hex_ascii(unsigned char *master_key, unsigned int keysize,
342 char *master_key_ascii)
343{
344 unsigned int i, a;
345 unsigned char nibble;
346
347 for (i=0, a=0; i<keysize; i++, a+=2) {
348 /* For each byte, write out two ascii hex digits */
349 nibble = (master_key[i] >> 4) & 0xf;
350 master_key_ascii[a] = nibble + (nibble > 9 ? 0x37 : 0x30);
351
352 nibble = master_key[i] & 0xf;
353 master_key_ascii[a+1] = nibble + (nibble > 9 ? 0x37 : 0x30);
354 }
355
356 /* Add the null termination */
357 master_key_ascii[a] = '\0';
358
359}
360
361static int create_crypto_blk_dev(struct crypt_mnt_ftr *crypt_ftr, unsigned char *master_key,
Ken Sumrall29d8da82011-05-18 17:20:07 -0700362 char *real_blk_name, char *crypto_blk_name, const char *name)
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800363{
364 char buffer[DM_CRYPT_BUF_SIZE];
365 char master_key_ascii[129]; /* Large enough to hold 512 bit key and null */
366 char *crypt_params;
367 struct dm_ioctl *io;
368 struct dm_target_spec *tgt;
369 unsigned int minor;
370 int fd;
371 int retval = -1;
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800372
373 if ((fd = open("/dev/device-mapper", O_RDWR)) < 0 ) {
374 SLOGE("Cannot open device-mapper\n");
375 goto errout;
376 }
377
378 io = (struct dm_ioctl *) buffer;
379
380 ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0);
381 if (ioctl(fd, DM_DEV_CREATE, io)) {
382 SLOGE("Cannot create dm-crypt device\n");
383 goto errout;
384 }
385
386 /* Get the device status, in particular, the name of it's device file */
387 ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0);
388 if (ioctl(fd, DM_DEV_STATUS, io)) {
389 SLOGE("Cannot retrieve dm-crypt device status\n");
390 goto errout;
391 }
392 minor = (io->dev & 0xff) | ((io->dev >> 12) & 0xfff00);
393 snprintf(crypto_blk_name, MAXPATHLEN, "/dev/block/dm-%u", minor);
394
395 /* Load the mapping table for this device */
396 tgt = (struct dm_target_spec *) &buffer[sizeof(struct dm_ioctl)];
397
398 ioctl_init(io, 4096, name, 0);
399 io->target_count = 1;
400 tgt->status = 0;
401 tgt->sector_start = 0;
402 tgt->length = crypt_ftr->fs_size;
403 strcpy(tgt->target_type, "crypt");
404
405 crypt_params = buffer + sizeof(struct dm_ioctl) + sizeof(struct dm_target_spec);
406 convert_key_to_hex_ascii(master_key, crypt_ftr->keysize, master_key_ascii);
407 sprintf(crypt_params, "%s %s 0 %s 0", crypt_ftr->crypto_type_name,
408 master_key_ascii, real_blk_name);
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800409 crypt_params += strlen(crypt_params) + 1;
410 crypt_params = (char *) (((unsigned long)crypt_params + 7) & ~8); /* Align to an 8 byte boundary */
411 tgt->next = crypt_params - buffer;
412
413 if (ioctl(fd, DM_TABLE_LOAD, io)) {
414 SLOGE("Cannot load dm-crypt mapping table.\n");
415 goto errout;
416 }
417
418 /* Resume this device to activate it */
419 ioctl_init(io, 4096, name, 0);
420
421 if (ioctl(fd, DM_DEV_SUSPEND, io)) {
422 SLOGE("Cannot resume the dm-crypt device\n");
423 goto errout;
424 }
425
426 /* We made it here with no errors. Woot! */
427 retval = 0;
428
429errout:
430 close(fd); /* If fd is <0 from a failed open call, it's safe to just ignore the close error */
431
432 return retval;
433}
434
Ken Sumrall29d8da82011-05-18 17:20:07 -0700435static int delete_crypto_blk_dev(char *name)
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800436{
437 int fd;
438 char buffer[DM_CRYPT_BUF_SIZE];
439 struct dm_ioctl *io;
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800440 int retval = -1;
441
442 if ((fd = open("/dev/device-mapper", O_RDWR)) < 0 ) {
443 SLOGE("Cannot open device-mapper\n");
444 goto errout;
445 }
446
447 io = (struct dm_ioctl *) buffer;
448
449 ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0);
450 if (ioctl(fd, DM_DEV_REMOVE, io)) {
451 SLOGE("Cannot remove dm-crypt device\n");
452 goto errout;
453 }
454
455 /* We made it here with no errors. Woot! */
456 retval = 0;
457
458errout:
459 close(fd); /* If fd is <0 from a failed open call, it's safe to just ignore the close error */
460
461 return retval;
462
463}
464
Ken Sumralle8744072011-01-18 22:01:55 -0800465static void pbkdf2(char *passwd, unsigned char *salt, unsigned char *ikey)
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800466{
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800467 /* Turn the password into a key and IV that can decrypt the master key */
Ken Sumralle8744072011-01-18 22:01:55 -0800468 PKCS5_PBKDF2_HMAC_SHA1(passwd, strlen(passwd), salt, SALT_LEN,
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800469 HASH_COUNT, KEY_LEN_BYTES+IV_LEN_BYTES, ikey);
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800470}
471
Ken Sumralle8744072011-01-18 22:01:55 -0800472static int encrypt_master_key(char *passwd, unsigned char *salt,
473 unsigned char *decrypted_master_key,
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800474 unsigned char *encrypted_master_key)
475{
476 unsigned char ikey[32+32] = { 0 }; /* Big enough to hold a 256 bit key and 256 bit IV */
477 EVP_CIPHER_CTX e_ctx;
478 int encrypted_len, final_len;
479
480 /* Turn the password into a key and IV that can decrypt the master key */
Ken Sumralle8744072011-01-18 22:01:55 -0800481 pbkdf2(passwd, salt, ikey);
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800482
483 /* Initialize the decryption engine */
484 if (! EVP_EncryptInit(&e_ctx, EVP_aes_128_cbc(), ikey, ikey+KEY_LEN_BYTES)) {
485 SLOGE("EVP_EncryptInit failed\n");
486 return -1;
487 }
488 EVP_CIPHER_CTX_set_padding(&e_ctx, 0); /* Turn off padding as our data is block aligned */
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800489
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800490 /* Encrypt the master key */
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800491 if (! EVP_EncryptUpdate(&e_ctx, encrypted_master_key, &encrypted_len,
492 decrypted_master_key, KEY_LEN_BYTES)) {
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800493 SLOGE("EVP_EncryptUpdate failed\n");
494 return -1;
495 }
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800496 if (! EVP_EncryptFinal(&e_ctx, encrypted_master_key + encrypted_len, &final_len)) {
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800497 SLOGE("EVP_EncryptFinal failed\n");
498 return -1;
499 }
500
501 if (encrypted_len + final_len != KEY_LEN_BYTES) {
502 SLOGE("EVP_Encryption length check failed with %d, %d bytes\n", encrypted_len, final_len);
503 return -1;
504 } else {
505 return 0;
506 }
507}
508
Ken Sumralle8744072011-01-18 22:01:55 -0800509static int decrypt_master_key(char *passwd, unsigned char *salt,
510 unsigned char *encrypted_master_key,
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800511 unsigned char *decrypted_master_key)
512{
513 unsigned char ikey[32+32] = { 0 }; /* Big enough to hold a 256 bit key and 256 bit IV */
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800514 EVP_CIPHER_CTX d_ctx;
515 int decrypted_len, final_len;
516
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800517 /* Turn the password into a key and IV that can decrypt the master key */
Ken Sumralle8744072011-01-18 22:01:55 -0800518 pbkdf2(passwd, salt, ikey);
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800519
520 /* Initialize the decryption engine */
521 if (! EVP_DecryptInit(&d_ctx, EVP_aes_128_cbc(), ikey, ikey+KEY_LEN_BYTES)) {
522 return -1;
523 }
524 EVP_CIPHER_CTX_set_padding(&d_ctx, 0); /* Turn off padding as our data is block aligned */
525 /* Decrypt the master key */
526 if (! EVP_DecryptUpdate(&d_ctx, decrypted_master_key, &decrypted_len,
527 encrypted_master_key, KEY_LEN_BYTES)) {
528 return -1;
529 }
530 if (! EVP_DecryptFinal(&d_ctx, decrypted_master_key + decrypted_len, &final_len)) {
531 return -1;
532 }
533
534 if (decrypted_len + final_len != KEY_LEN_BYTES) {
535 return -1;
536 } else {
537 return 0;
538 }
539}
540
Ken Sumralle8744072011-01-18 22:01:55 -0800541static int create_encrypted_random_key(char *passwd, unsigned char *master_key, unsigned char *salt)
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800542{
543 int fd;
Ken Sumralle8744072011-01-18 22:01:55 -0800544 unsigned char key_buf[KEY_LEN_BYTES];
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800545 EVP_CIPHER_CTX e_ctx;
546 int encrypted_len, final_len;
547
548 /* Get some random bits for a key */
549 fd = open("/dev/urandom", O_RDONLY);
Ken Sumralle8744072011-01-18 22:01:55 -0800550 read(fd, key_buf, sizeof(key_buf));
551 read(fd, salt, SALT_LEN);
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800552 close(fd);
553
554 /* Now encrypt it with the password */
Ken Sumralle8744072011-01-18 22:01:55 -0800555 return encrypt_master_key(passwd, salt, key_buf, master_key);
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800556}
557
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800558static int get_orig_mount_parms(char *mount_point, char *fs_type, char *real_blkdev,
559 unsigned long *mnt_flags, char *fs_options)
560{
Ken Sumrall29d8da82011-05-18 17:20:07 -0700561 char mount_point2[PROPERTY_VALUE_MAX];
562 char fs_flags[PROPERTY_VALUE_MAX];
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800563
564 property_get("ro.crypto.fs_type", fs_type, "");
565 property_get("ro.crypto.fs_real_blkdev", real_blkdev, "");
566 property_get("ro.crypto.fs_mnt_point", mount_point2, "");
567 property_get("ro.crypto.fs_options", fs_options, "");
568 property_get("ro.crypto.fs_flags", fs_flags, "");
569 *mnt_flags = strtol(fs_flags, 0, 0);
570
571 if (strcmp(mount_point, mount_point2)) {
572 /* Consistency check. These should match. If not, something odd happened. */
573 return -1;
574 }
575
576 return 0;
577}
578
579static int wait_and_unmount(char *mountpoint)
580{
581 int i, rc;
Ken Sumrall2eaf7132011-01-14 12:45:48 -0800582#define WAIT_UNMOUNT_COUNT 20
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800583
584 /* Now umount the tmpfs filesystem */
585 for (i=0; i<WAIT_UNMOUNT_COUNT; i++) {
586 if (umount(mountpoint)) {
Ken Sumrall29d8da82011-05-18 17:20:07 -0700587 if (errno == EINVAL) {
588 /* EINVAL is returned if the directory is not a mountpoint,
589 * i.e. there is no filesystem mounted there. So just get out.
590 */
591 break;
592 }
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800593 sleep(1);
594 i++;
595 } else {
596 break;
597 }
598 }
599
600 if (i < WAIT_UNMOUNT_COUNT) {
601 SLOGD("unmounting %s succeeded\n", mountpoint);
602 rc = 0;
603 } else {
604 SLOGE("unmounting %s failed\n", mountpoint);
605 rc = -1;
606 }
607
608 return rc;
609}
610
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800611#define DATA_PREP_TIMEOUT 100
612static int prep_data_fs(void)
613{
614 int i;
615
616 /* Do the prep of the /data filesystem */
617 property_set("vold.post_fs_data_done", "0");
618 property_set("vold.decrypt", "trigger_post_fs_data");
619 SLOGD("Just triggered post_fs_data\n");
620
621 /* Wait a max of 25 seconds, hopefully it takes much less */
622 for (i=0; i<DATA_PREP_TIMEOUT; i++) {
Ken Sumrall29d8da82011-05-18 17:20:07 -0700623 char p[PROPERTY_VALUE_MAX];
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800624
625 property_get("vold.post_fs_data_done", p, "0");
626 if (*p == '1') {
627 break;
628 } else {
629 usleep(250000);
630 }
631 }
632 if (i == DATA_PREP_TIMEOUT) {
633 /* Ugh, we failed to prep /data in time. Bail. */
634 return -1;
635 } else {
636 SLOGD("post_fs_data done\n");
637 return 0;
638 }
639}
640
Ken Sumrall6864b7e2011-01-14 15:20:02 -0800641int cryptfs_restart(void)
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800642{
643 char fs_type[32];
644 char real_blkdev[MAXPATHLEN];
Ken Sumrall6864b7e2011-01-14 15:20:02 -0800645 char crypto_blkdev[MAXPATHLEN];
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800646 char fs_options[256];
647 unsigned long mnt_flags;
648 struct stat statbuf;
649 int rc = -1, i;
Ken Sumrall0cc16632011-01-18 20:32:26 -0800650 static int restart_successful = 0;
651
652 /* Validate that it's OK to call this routine */
Jason parks70a4b3f2011-01-28 10:10:47 -0600653 if (! master_key_saved) {
Ken Sumrall0cc16632011-01-18 20:32:26 -0800654 SLOGE("Encrypted filesystem not validated, aborting");
655 return -1;
656 }
657
658 if (restart_successful) {
659 SLOGE("System already restarted with encrypted disk, aborting");
660 return -1;
661 }
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800662
663 /* Here is where we shut down the framework. The init scripts
664 * start all services in one of three classes: core, main or late_start.
665 * On boot, we start core and main. Now, we stop main, but not core,
666 * as core includes vold and a few other really important things that
667 * we need to keep running. Once main has stopped, we should be able
668 * to umount the tmpfs /data, then mount the encrypted /data.
669 * We then restart the class main, and also the class late_start.
670 * At the moment, I've only put a few things in late_start that I know
671 * are not needed to bring up the framework, and that also cause problems
672 * with unmounting the tmpfs /data, but I hope to add add more services
673 * to the late_start class as we optimize this to decrease the delay
674 * till the user is asked for the password to the filesystem.
675 */
676
677 /* The init files are setup to stop the class main when vold.decrypt is
678 * set to trigger_reset_main.
679 */
680 property_set("vold.decrypt", "trigger_reset_main");
681 SLOGD("Just asked init to shut down class main\n");
682
683 /* Now that the framework is shutdown, we should be able to umount()
684 * the tmpfs filesystem, and mount the real one.
685 */
686
Ken Sumrall6864b7e2011-01-14 15:20:02 -0800687 property_get("ro.crypto.fs_crypto_blkdev", crypto_blkdev, "");
688 if (strlen(crypto_blkdev) == 0) {
689 SLOGE("fs_crypto_blkdev not set\n");
690 return -1;
691 }
692
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800693 if (! get_orig_mount_parms(DATA_MNT_POINT, fs_type, real_blkdev, &mnt_flags, fs_options)) {
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800694 SLOGD("Just got orig mount parms\n");
695
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800696 if (! (rc = wait_and_unmount(DATA_MNT_POINT)) ) {
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800697 /* If that succeeded, then mount the decrypted filesystem */
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800698 mount(crypto_blkdev, DATA_MNT_POINT, fs_type, mnt_flags, fs_options);
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800699
Ken Sumrallad2ac332011-03-08 17:07:06 -0800700 property_set("vold.decrypt", "trigger_load_persist_props");
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800701 /* Create necessary paths on /data */
702 if (prep_data_fs()) {
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800703 return -1;
704 }
705
706 /* startup service classes main and late_start */
707 property_set("vold.decrypt", "trigger_restart_framework");
708 SLOGD("Just triggered restart_framework\n");
709
710 /* Give it a few moments to get started */
711 sleep(1);
712 }
713 }
714
Ken Sumrall0cc16632011-01-18 20:32:26 -0800715 if (rc == 0) {
716 restart_successful = 1;
717 }
718
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800719 return rc;
720}
721
Ken Sumrall7f7dbaa2011-02-01 15:46:41 -0800722static int do_crypto_complete(char *mount_point)
723{
724 struct crypt_mnt_ftr crypt_ftr;
725 unsigned char encrypted_master_key[32];
726 unsigned char salt[SALT_LEN];
727 char real_blkdev[MAXPATHLEN];
Ken Sumrall29d8da82011-05-18 17:20:07 -0700728 char fs_type[PROPERTY_VALUE_MAX];
729 char fs_options[PROPERTY_VALUE_MAX];
Ken Sumrall7f7dbaa2011-02-01 15:46:41 -0800730 unsigned long mnt_flags;
Ken Sumrall29d8da82011-05-18 17:20:07 -0700731 char encrypted_state[PROPERTY_VALUE_MAX];
Ken Sumrall7f7dbaa2011-02-01 15:46:41 -0800732
733 property_get("ro.crypto.state", encrypted_state, "");
734 if (strcmp(encrypted_state, "encrypted") ) {
735 SLOGE("not running with encryption, aborting");
736 return 1;
737 }
738
739 if (get_orig_mount_parms(mount_point, fs_type, real_blkdev, &mnt_flags, fs_options)) {
740 SLOGE("Error reading original mount parms for mount point %s\n", mount_point);
741 return -1;
742 }
743
744 if (get_crypt_ftr_and_key(real_blkdev, &crypt_ftr, encrypted_master_key, salt)) {
745 SLOGE("Error getting crypt footer and key\n");
746 return -1;
747 }
748
749 if (crypt_ftr.flags & CRYPT_ENCRYPTION_IN_PROGRESS) {
750 SLOGE("Encryption process didn't finish successfully\n");
751 return -2; /* -2 is the clue to the UI that there is no usable data on the disk,
752 * and give the user an option to wipe the disk */
753 }
754
755 /* We passed the test! We shall diminish, and return to the west */
756 return 0;
757}
758
Ken Sumrall29d8da82011-05-18 17:20:07 -0700759static int test_mount_encrypted_fs(char *passwd, char *mount_point, char *label)
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800760{
761 struct crypt_mnt_ftr crypt_ftr;
762 /* Allocate enough space for a 256 bit key, but we may use less */
763 unsigned char encrypted_master_key[32], decrypted_master_key[32];
Ken Sumralle8744072011-01-18 22:01:55 -0800764 unsigned char salt[SALT_LEN];
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800765 char crypto_blkdev[MAXPATHLEN];
766 char real_blkdev[MAXPATHLEN];
Ken Sumrall29d8da82011-05-18 17:20:07 -0700767 char fs_type[PROPERTY_VALUE_MAX];
768 char fs_options[PROPERTY_VALUE_MAX];
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800769 char tmp_mount_point[64];
770 unsigned long mnt_flags;
771 unsigned int orig_failed_decrypt_count;
Ken Sumrall29d8da82011-05-18 17:20:07 -0700772 char encrypted_state[PROPERTY_VALUE_MAX];
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800773 int rc;
774
Ken Sumrall0cc16632011-01-18 20:32:26 -0800775 property_get("ro.crypto.state", encrypted_state, "");
Jason parks70a4b3f2011-01-28 10:10:47 -0600776 if ( master_key_saved || strcmp(encrypted_state, "encrypted") ) {
Ken Sumrall0cc16632011-01-18 20:32:26 -0800777 SLOGE("encrypted fs already validated or not running with encryption, aborting");
778 return -1;
779 }
780
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800781 if (get_orig_mount_parms(mount_point, fs_type, real_blkdev, &mnt_flags, fs_options)) {
782 SLOGE("Error reading original mount parms for mount point %s\n", mount_point);
783 return -1;
784 }
785
Ken Sumralle8744072011-01-18 22:01:55 -0800786 if (get_crypt_ftr_and_key(real_blkdev, &crypt_ftr, encrypted_master_key, salt)) {
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800787 SLOGE("Error getting crypt footer and key\n");
788 return -1;
789 }
Ken Sumralld33d4172011-02-01 00:49:13 -0800790
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800791 SLOGD("crypt_ftr->fs_size = %lld\n", crypt_ftr.fs_size);
792 orig_failed_decrypt_count = crypt_ftr.failed_decrypt_count;
793
794 if (! (crypt_ftr.flags & CRYPT_MNT_KEY_UNENCRYPTED) ) {
Ken Sumralle8744072011-01-18 22:01:55 -0800795 decrypt_master_key(passwd, salt, encrypted_master_key, decrypted_master_key);
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800796 }
797
798 if (create_crypto_blk_dev(&crypt_ftr, decrypted_master_key,
Ken Sumrall29d8da82011-05-18 17:20:07 -0700799 real_blkdev, crypto_blkdev, label)) {
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800800 SLOGE("Error creating decrypted block device\n");
801 return -1;
802 }
803
804 /* If init detects an encrypted filesystme, it writes a file for each such
805 * encrypted fs into the tmpfs /data filesystem, and then the framework finds those
806 * files and passes that data to me */
807 /* Create a tmp mount point to try mounting the decryptd fs
808 * Since we're here, the mount_point should be a tmpfs filesystem, so make
809 * a directory in it to test mount the decrypted filesystem.
810 */
811 sprintf(tmp_mount_point, "%s/tmp_mnt", mount_point);
812 mkdir(tmp_mount_point, 0755);
813 if ( mount(crypto_blkdev, tmp_mount_point, "ext4", MS_RDONLY, "") ) {
814 SLOGE("Error temp mounting decrypted block device\n");
Ken Sumrall29d8da82011-05-18 17:20:07 -0700815 delete_crypto_blk_dev(label);
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800816 crypt_ftr.failed_decrypt_count++;
817 } else {
818 /* Success, so just umount and we'll mount it properly when we restart
819 * the framework.
820 */
821 umount(tmp_mount_point);
822 crypt_ftr.failed_decrypt_count = 0;
823 }
824
825 if (orig_failed_decrypt_count != crypt_ftr.failed_decrypt_count) {
Ken Sumralle8744072011-01-18 22:01:55 -0800826 put_crypt_ftr_and_key(real_blkdev, &crypt_ftr, 0, 0);
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800827 }
828
829 if (crypt_ftr.failed_decrypt_count) {
830 /* We failed to mount the device, so return an error */
831 rc = crypt_ftr.failed_decrypt_count;
832
833 } else {
Ken Sumrall6864b7e2011-01-14 15:20:02 -0800834 /* Woot! Success! Save the name of the crypto block device
835 * so we can mount it when restarting the framework.
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800836 */
Ken Sumrall6864b7e2011-01-14 15:20:02 -0800837 property_set("ro.crypto.fs_crypto_blkdev", crypto_blkdev);
Jason parks70a4b3f2011-01-28 10:10:47 -0600838
839 /* Also save a the master key so we can reencrypted the key
840 * the key when we want to change the password on it.
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800841 */
Jason parks70a4b3f2011-01-28 10:10:47 -0600842 memcpy(saved_master_key, decrypted_master_key, KEY_LEN_BYTES);
Ken Sumrall29d8da82011-05-18 17:20:07 -0700843 saved_data_blkdev = strdup(real_blkdev);
Jason parks70a4b3f2011-01-28 10:10:47 -0600844 master_key_saved = 1;
Ken Sumrall6864b7e2011-01-14 15:20:02 -0800845 rc = 0;
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800846 }
847
848 return rc;
849}
850
Ken Sumrall0b8b5972011-08-31 16:14:23 -0700851/* Called by vold when it wants to undo the crypto mapping of a volume it
852 * manages. This is usually in response to a factory reset, when we want
853 * to undo the crypto mapping so the volume is formatted in the clear.
854 */
855int cryptfs_revert_volume(const char *label)
856{
857 return delete_crypto_blk_dev((char *)label);
858}
859
Ken Sumrall29d8da82011-05-18 17:20:07 -0700860/*
861 * Called by vold when it's asked to mount an encrypted, nonremovable volume.
862 * Setup a dm-crypt mapping, use the saved master key from
863 * setting up the /data mapping, and return the new device path.
864 */
865int cryptfs_setup_volume(const char *label, int major, int minor,
866 char *crypto_sys_path, unsigned int max_path,
867 int *new_major, int *new_minor)
868{
869 char real_blkdev[MAXPATHLEN], crypto_blkdev[MAXPATHLEN];
870 struct crypt_mnt_ftr sd_crypt_ftr;
871 unsigned char key[32], salt[32];
872 struct stat statbuf;
873 int nr_sec, fd;
874
875 sprintf(real_blkdev, "/dev/block/vold/%d:%d", major, minor);
876
877 /* Just want the footer, but gotta get it all */
878 get_crypt_ftr_and_key(saved_data_blkdev, &sd_crypt_ftr, key, salt);
879
880 /* Update the fs_size field to be the size of the volume */
881 fd = open(real_blkdev, O_RDONLY);
882 nr_sec = get_blkdev_size(fd);
883 close(fd);
884 if (nr_sec == 0) {
885 SLOGE("Cannot get size of volume %s\n", real_blkdev);
886 return -1;
887 }
888
889 sd_crypt_ftr.fs_size = nr_sec;
890 create_crypto_blk_dev(&sd_crypt_ftr, saved_master_key, real_blkdev,
891 crypto_blkdev, label);
892
893 stat(crypto_blkdev, &statbuf);
894 *new_major = MAJOR(statbuf.st_rdev);
895 *new_minor = MINOR(statbuf.st_rdev);
896
897 /* Create path to sys entry for this block device */
898 snprintf(crypto_sys_path, max_path, "/devices/virtual/block/%s", strrchr(crypto_blkdev, '/')+1);
899
900 return 0;
901}
902
Ken Sumrall7f7dbaa2011-02-01 15:46:41 -0800903int cryptfs_crypto_complete(void)
904{
905 return do_crypto_complete("/data");
906}
907
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800908int cryptfs_check_passwd(char *passwd)
909{
910 int rc = -1;
911
Ken Sumrall29d8da82011-05-18 17:20:07 -0700912 rc = test_mount_encrypted_fs(passwd, DATA_MNT_POINT, "userdata");
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800913
914 return rc;
915}
916
917/* Initialize a crypt_mnt_ftr structure. The keysize is
918 * defaulted to 16 bytes, and the filesystem size to 0.
919 * Presumably, at a minimum, the caller will update the
920 * filesystem size and crypto_type_name after calling this function.
921 */
922static void cryptfs_init_crypt_mnt_ftr(struct crypt_mnt_ftr *ftr)
923{
924 ftr->magic = CRYPT_MNT_MAGIC;
925 ftr->major_version = 1;
926 ftr->minor_version = 0;
927 ftr->ftr_size = sizeof(struct crypt_mnt_ftr);
928 ftr->flags = 0;
Jason parks70a4b3f2011-01-28 10:10:47 -0600929 ftr->keysize = KEY_LEN_BYTES;
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800930 ftr->spare1 = 0;
931 ftr->fs_size = 0;
932 ftr->failed_decrypt_count = 0;
933 ftr->crypto_type_name[0] = '\0';
934}
935
Ken Sumrall29d8da82011-05-18 17:20:07 -0700936static int cryptfs_enable_wipe(char *crypto_blkdev, off64_t size, int type)
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800937{
938 char cmdline[256];
939 int rc = -1;
940
Ken Sumrall29d8da82011-05-18 17:20:07 -0700941 if (type == EXT4_FS) {
942 snprintf(cmdline, sizeof(cmdline), "/system/bin/make_ext4fs -a /data -l %lld %s",
943 size * 512, crypto_blkdev);
944 SLOGI("Making empty filesystem with command %s\n", cmdline);
945 } else if (type== FAT_FS) {
946 snprintf(cmdline, sizeof(cmdline), "/system/bin/newfs_msdos -F 32 -O android -c 8 -s %lld %s",
947 size, crypto_blkdev);
948 SLOGI("Making empty filesystem with command %s\n", cmdline);
949 } else {
950 SLOGE("cryptfs_enable_wipe(): unknown filesystem type %d\n", type);
951 return -1;
952 }
953
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800954 if (system(cmdline)) {
955 SLOGE("Error creating empty filesystem on %s\n", crypto_blkdev);
956 } else {
957 SLOGD("Successfully created empty filesystem on %s\n", crypto_blkdev);
958 rc = 0;
959 }
960
961 return rc;
962}
963
964static inline int unix_read(int fd, void* buff, int len)
965{
966 int ret;
967 do { ret = read(fd, buff, len); } while (ret < 0 && errno == EINTR);
968 return ret;
969}
970
971static inline int unix_write(int fd, const void* buff, int len)
972{
973 int ret;
974 do { ret = write(fd, buff, len); } while (ret < 0 && errno == EINTR);
975 return ret;
976}
977
978#define CRYPT_INPLACE_BUFSIZE 4096
979#define CRYPT_SECTORS_PER_BUFSIZE (CRYPT_INPLACE_BUFSIZE / 512)
Ken Sumrall29d8da82011-05-18 17:20:07 -0700980static int cryptfs_enable_inplace(char *crypto_blkdev, char *real_blkdev, off64_t size,
981 off64_t *size_already_done, off64_t tot_size)
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800982{
983 int realfd, cryptofd;
984 char *buf[CRYPT_INPLACE_BUFSIZE];
985 int rc = -1;
986 off64_t numblocks, i, remainder;
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800987 off64_t one_pct, cur_pct, new_pct;
Ken Sumrall29d8da82011-05-18 17:20:07 -0700988 off64_t blocks_already_done, tot_numblocks;
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800989
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800990 if ( (realfd = open(real_blkdev, O_RDONLY)) < 0) {
991 SLOGE("Error opening real_blkdev %s for inplace encrypt\n", real_blkdev);
992 return -1;
993 }
994
995 if ( (cryptofd = open(crypto_blkdev, O_WRONLY)) < 0) {
996 SLOGE("Error opening crypto_blkdev %s for inplace encrypt\n", crypto_blkdev);
997 close(realfd);
998 return -1;
999 }
1000
1001 /* This is pretty much a simple loop of reading 4K, and writing 4K.
1002 * The size passed in is the number of 512 byte sectors in the filesystem.
1003 * So compute the number of whole 4K blocks we should read/write,
1004 * and the remainder.
1005 */
1006 numblocks = size / CRYPT_SECTORS_PER_BUFSIZE;
1007 remainder = size % CRYPT_SECTORS_PER_BUFSIZE;
Ken Sumrall29d8da82011-05-18 17:20:07 -07001008 tot_numblocks = tot_size / CRYPT_SECTORS_PER_BUFSIZE;
1009 blocks_already_done = *size_already_done / CRYPT_SECTORS_PER_BUFSIZE;
Ken Sumrall8f869aa2010-12-03 03:47:09 -08001010
1011 SLOGE("Encrypting filesystem in place...");
1012
Ken Sumrall29d8da82011-05-18 17:20:07 -07001013 one_pct = tot_numblocks / 100;
Ken Sumrall8ddbe402011-01-17 15:26:29 -08001014 cur_pct = 0;
Ken Sumrall8f869aa2010-12-03 03:47:09 -08001015 /* process the majority of the filesystem in blocks */
1016 for (i=0; i<numblocks; i++) {
Ken Sumrall29d8da82011-05-18 17:20:07 -07001017 new_pct = (i + blocks_already_done) / one_pct;
Ken Sumrall8ddbe402011-01-17 15:26:29 -08001018 if (new_pct > cur_pct) {
1019 char buf[8];
1020
1021 cur_pct = new_pct;
1022 snprintf(buf, sizeof(buf), "%lld", cur_pct);
1023 property_set("vold.encrypt_progress", buf);
1024 }
Ken Sumrall8f869aa2010-12-03 03:47:09 -08001025 if (unix_read(realfd, buf, CRYPT_INPLACE_BUFSIZE) <= 0) {
1026 SLOGE("Error reading real_blkdev %s for inplace encrypt\n", crypto_blkdev);
1027 goto errout;
1028 }
1029 if (unix_write(cryptofd, buf, CRYPT_INPLACE_BUFSIZE) <= 0) {
1030 SLOGE("Error writing crypto_blkdev %s for inplace encrypt\n", crypto_blkdev);
1031 goto errout;
1032 }
1033 }
1034
1035 /* Do any remaining sectors */
1036 for (i=0; i<remainder; i++) {
1037 if (unix_read(realfd, buf, 512) <= 0) {
1038 SLOGE("Error reading rival sectors from real_blkdev %s for inplace encrypt\n", crypto_blkdev);
1039 goto errout;
1040 }
1041 if (unix_write(cryptofd, buf, 512) <= 0) {
1042 SLOGE("Error writing final sectors to crypto_blkdev %s for inplace encrypt\n", crypto_blkdev);
1043 goto errout;
1044 }
1045 }
1046
Ken Sumrall29d8da82011-05-18 17:20:07 -07001047 *size_already_done += size;
Ken Sumrall8f869aa2010-12-03 03:47:09 -08001048 rc = 0;
1049
1050errout:
1051 close(realfd);
1052 close(cryptofd);
1053
1054 return rc;
1055}
1056
1057#define CRYPTO_ENABLE_WIPE 1
1058#define CRYPTO_ENABLE_INPLACE 2
Ken Sumrall8ddbe402011-01-17 15:26:29 -08001059
1060#define FRAMEWORK_BOOT_WAIT 60
1061
Ken Sumrall29d8da82011-05-18 17:20:07 -07001062static inline int should_encrypt(struct volume_info *volume)
1063{
1064 return (volume->flags & (VOL_ENCRYPTABLE | VOL_NONREMOVABLE)) ==
1065 (VOL_ENCRYPTABLE | VOL_NONREMOVABLE);
1066}
1067
Ken Sumrall8f869aa2010-12-03 03:47:09 -08001068int cryptfs_enable(char *howarg, char *passwd)
1069{
1070 int how = 0;
Ken Sumrall29d8da82011-05-18 17:20:07 -07001071 char crypto_blkdev[MAXPATHLEN], real_blkdev[MAXPATHLEN], sd_crypto_blkdev[MAXPATHLEN];
1072 char fs_type[PROPERTY_VALUE_MAX], fs_options[PROPERTY_VALUE_MAX],
1073 mount_point[PROPERTY_VALUE_MAX];
Ken Sumrall8f869aa2010-12-03 03:47:09 -08001074 unsigned long mnt_flags, nr_sec;
Jason parks70a4b3f2011-01-28 10:10:47 -06001075 unsigned char master_key[KEY_LEN_BYTES], decrypted_master_key[KEY_LEN_BYTES];
Ken Sumralle8744072011-01-18 22:01:55 -08001076 unsigned char salt[SALT_LEN];
Ken Sumrall319b1042011-06-14 14:01:55 -07001077 int rc=-1, fd, i, ret;
Ken Sumrall29d8da82011-05-18 17:20:07 -07001078 struct crypt_mnt_ftr crypt_ftr, sd_crypt_ftr;;
1079 char tmpfs_options[PROPERTY_VALUE_MAX];
1080 char encrypted_state[PROPERTY_VALUE_MAX];
Ken Sumrall5d4c68e2011-01-30 19:06:03 -08001081 char lockid[32] = { 0 };
Ken Sumrall29d8da82011-05-18 17:20:07 -07001082 char key_loc[PROPERTY_VALUE_MAX];
1083 char fuse_sdcard[PROPERTY_VALUE_MAX];
1084 char *sd_mnt_point;
1085 char sd_blk_dev[256] = { 0 };
1086 int num_vols;
1087 struct volume_info *vol_list = 0;
1088 off64_t cur_encryption_done=0, tot_encryption_size=0;
Ken Sumrall0cc16632011-01-18 20:32:26 -08001089
1090 property_get("ro.crypto.state", encrypted_state, "");
1091 if (strcmp(encrypted_state, "unencrypted")) {
1092 SLOGE("Device is already running encrypted, aborting");
Ken Sumrall3ed82362011-01-28 23:31:16 -08001093 goto error_unencrypted;
Ken Sumrall0cc16632011-01-18 20:32:26 -08001094 }
Ken Sumrall8f869aa2010-12-03 03:47:09 -08001095
Ken Sumrall29d8da82011-05-18 17:20:07 -07001096 property_get(KEY_LOC_PROP, key_loc, KEY_IN_FOOTER);
1097
Ken Sumrall8f869aa2010-12-03 03:47:09 -08001098 if (!strcmp(howarg, "wipe")) {
1099 how = CRYPTO_ENABLE_WIPE;
1100 } else if (! strcmp(howarg, "inplace")) {
1101 how = CRYPTO_ENABLE_INPLACE;
1102 } else {
1103 /* Shouldn't happen, as CommandListener vets the args */
Ken Sumrall3ed82362011-01-28 23:31:16 -08001104 goto error_unencrypted;
Ken Sumrall8f869aa2010-12-03 03:47:09 -08001105 }
1106
1107 get_orig_mount_parms(mount_point, fs_type, real_blkdev, &mnt_flags, fs_options);
1108
Ken Sumrall3ed82362011-01-28 23:31:16 -08001109 /* Get the size of the real block device */
1110 fd = open(real_blkdev, O_RDONLY);
1111 if ( (nr_sec = get_blkdev_size(fd)) == 0) {
1112 SLOGE("Cannot get size of block device %s\n", real_blkdev);
1113 goto error_unencrypted;
1114 }
1115 close(fd);
1116
1117 /* If doing inplace encryption, make sure the orig fs doesn't include the crypto footer */
Ken Sumrall29d8da82011-05-18 17:20:07 -07001118 if ((how == CRYPTO_ENABLE_INPLACE) && (!strcmp(key_loc, KEY_IN_FOOTER))) {
Ken Sumrall3ed82362011-01-28 23:31:16 -08001119 unsigned int fs_size_sec, max_fs_size_sec;
1120
1121 fs_size_sec = get_fs_size(real_blkdev);
1122 max_fs_size_sec = nr_sec - (CRYPT_FOOTER_OFFSET / 512);
1123
1124 if (fs_size_sec > max_fs_size_sec) {
1125 SLOGE("Orig filesystem overlaps crypto footer region. Cannot encrypt in place.");
1126 goto error_unencrypted;
1127 }
1128 }
1129
Ken Sumrall5d4c68e2011-01-30 19:06:03 -08001130 /* Get a wakelock as this may take a while, and we don't want the
1131 * device to sleep on us. We'll grab a partial wakelock, and if the UI
1132 * wants to keep the screen on, it can grab a full wakelock.
1133 */
Ken Sumrall29d8da82011-05-18 17:20:07 -07001134 snprintf(lockid, sizeof(lockid), "enablecrypto%d", (int) getpid());
Ken Sumrall5d4c68e2011-01-30 19:06:03 -08001135 acquire_wake_lock(PARTIAL_WAKE_LOCK, lockid);
1136
Ken Sumrall29d8da82011-05-18 17:20:07 -07001137 /* Get the sdcard mount point */
1138 sd_mnt_point = getenv("EXTERNAL_STORAGE");
1139 if (! sd_mnt_point) {
1140 sd_mnt_point = "/mnt/sdcard";
1141 }
1142
1143 num_vols=vold_getNumDirectVolumes();
1144 vol_list = malloc(sizeof(struct volume_info) * num_vols);
1145 vold_getDirectVolumeList(vol_list);
1146
1147 for (i=0; i<num_vols; i++) {
1148 if (should_encrypt(&vol_list[i])) {
1149 fd = open(vol_list[i].blk_dev, O_RDONLY);
1150 if ( (vol_list[i].size = get_blkdev_size(fd)) == 0) {
1151 SLOGE("Cannot get size of block device %s\n", vol_list[i].blk_dev);
1152 goto error_unencrypted;
1153 }
1154 close(fd);
1155
Ken Sumrall3b170052011-07-11 15:38:57 -07001156 ret=vold_disableVol(vol_list[i].label);
Ken Sumrall319b1042011-06-14 14:01:55 -07001157 if ((ret < 0) && (ret != UNMOUNT_NOT_MOUNTED_ERR)) {
1158 /* -2 is returned when the device exists but is not currently mounted.
1159 * ignore the error and continue. */
Ken Sumrall29d8da82011-05-18 17:20:07 -07001160 SLOGE("Failed to unmount volume %s\n", vol_list[i].label);
1161 goto error_unencrypted;
1162 }
1163 }
1164 }
1165
Ken Sumrall8f869aa2010-12-03 03:47:09 -08001166 /* The init files are setup to stop the class main and late start when
Ken Sumrall8ddbe402011-01-17 15:26:29 -08001167 * vold sets trigger_shutdown_framework.
Ken Sumrall8f869aa2010-12-03 03:47:09 -08001168 */
1169 property_set("vold.decrypt", "trigger_shutdown_framework");
1170 SLOGD("Just asked init to shut down class main\n");
1171
Ken Sumrall29d8da82011-05-18 17:20:07 -07001172 property_get("ro.crypto.fuse_sdcard", fuse_sdcard, "");
1173 if (!strcmp(fuse_sdcard, "true")) {
1174 /* This is a device using the fuse layer to emulate the sdcard semantics
1175 * on top of the userdata partition. vold does not manage it, it is managed
1176 * by the sdcard service. The sdcard service was killed by the property trigger
1177 * above, so just unmount it now. We must do this _AFTER_ killing the framework,
1178 * unlike the case for vold managed devices above.
1179 */
1180 if (wait_and_unmount(sd_mnt_point)) {
1181 goto error_shutting_down;
1182 }
Ken Sumrall2eaf7132011-01-14 12:45:48 -08001183 }
Ken Sumrall8f869aa2010-12-03 03:47:09 -08001184
1185 /* Now unmount the /data partition. */
Ken Sumrall8ddbe402011-01-17 15:26:29 -08001186 if (wait_and_unmount(DATA_MNT_POINT)) {
Ken Sumrall3ed82362011-01-28 23:31:16 -08001187 goto error_shutting_down;
Ken Sumrall8ddbe402011-01-17 15:26:29 -08001188 }
1189
1190 /* Do extra work for a better UX when doing the long inplace encryption */
1191 if (how == CRYPTO_ENABLE_INPLACE) {
1192 /* Now that /data is unmounted, we need to mount a tmpfs
1193 * /data, set a property saying we're doing inplace encryption,
1194 * and restart the framework.
Ken Sumrall8f869aa2010-12-03 03:47:09 -08001195 */
Ken Sumrall8ddbe402011-01-17 15:26:29 -08001196 property_get("ro.crypto.tmpfs_options", tmpfs_options, "");
1197 if (mount("tmpfs", DATA_MNT_POINT, "tmpfs", MS_NOATIME | MS_NOSUID | MS_NODEV,
1198 tmpfs_options) < 0) {
Ken Sumrall3ed82362011-01-28 23:31:16 -08001199 goto error_shutting_down;
Ken Sumrall8f869aa2010-12-03 03:47:09 -08001200 }
Ken Sumrall8ddbe402011-01-17 15:26:29 -08001201 /* Tells the framework that inplace encryption is starting */
Ken Sumrall7df84122011-01-18 14:04:08 -08001202 property_set("vold.encrypt_progress", "0");
Ken Sumrall8f869aa2010-12-03 03:47:09 -08001203
Ken Sumrall8ddbe402011-01-17 15:26:29 -08001204 /* restart the framework. */
1205 /* Create necessary paths on /data */
1206 if (prep_data_fs()) {
Ken Sumrall3ed82362011-01-28 23:31:16 -08001207 goto error_shutting_down;
Ken Sumrall8f869aa2010-12-03 03:47:09 -08001208 }
1209
Ken Sumrall8ddbe402011-01-17 15:26:29 -08001210 /* startup service classes main and late_start */
1211 property_set("vold.decrypt", "trigger_restart_min_framework");
1212 SLOGD("Just triggered restart_min_framework\n");
Ken Sumrall8f869aa2010-12-03 03:47:09 -08001213
Ken Sumrall7df84122011-01-18 14:04:08 -08001214 /* OK, the framework is restarted and will soon be showing a
1215 * progress bar. Time to setup an encrypted mapping, and
1216 * either write a new filesystem, or encrypt in place updating
1217 * the progress bar as we work.
Ken Sumrall8ddbe402011-01-17 15:26:29 -08001218 */
1219 }
Ken Sumrall8f869aa2010-12-03 03:47:09 -08001220
Ken Sumrall8ddbe402011-01-17 15:26:29 -08001221 /* Start the actual work of making an encrypted filesystem */
Ken Sumrall8ddbe402011-01-17 15:26:29 -08001222 /* Initialize a crypt_mnt_ftr for the partition */
1223 cryptfs_init_crypt_mnt_ftr(&crypt_ftr);
Ken Sumrall29d8da82011-05-18 17:20:07 -07001224 if (!strcmp(key_loc, KEY_IN_FOOTER)) {
1225 crypt_ftr.fs_size = nr_sec - (CRYPT_FOOTER_OFFSET / 512);
1226 } else {
1227 crypt_ftr.fs_size = nr_sec;
1228 }
Ken Sumralld33d4172011-02-01 00:49:13 -08001229 crypt_ftr.flags |= CRYPT_ENCRYPTION_IN_PROGRESS;
Ken Sumrall8ddbe402011-01-17 15:26:29 -08001230 strcpy((char *)crypt_ftr.crypto_type_name, "aes-cbc-essiv:sha256");
1231
1232 /* Make an encrypted master key */
Ken Sumralle8744072011-01-18 22:01:55 -08001233 if (create_encrypted_random_key(passwd, master_key, salt)) {
Ken Sumrall8ddbe402011-01-17 15:26:29 -08001234 SLOGE("Cannot create encrypted master key\n");
Ken Sumrall3ed82362011-01-28 23:31:16 -08001235 goto error_unencrypted;
Ken Sumrall8ddbe402011-01-17 15:26:29 -08001236 }
1237
1238 /* Write the key to the end of the partition */
Ken Sumralle8744072011-01-18 22:01:55 -08001239 put_crypt_ftr_and_key(real_blkdev, &crypt_ftr, master_key, salt);
Ken Sumrall8ddbe402011-01-17 15:26:29 -08001240
Ken Sumralle8744072011-01-18 22:01:55 -08001241 decrypt_master_key(passwd, salt, master_key, decrypted_master_key);
Ken Sumrall29d8da82011-05-18 17:20:07 -07001242 create_crypto_blk_dev(&crypt_ftr, decrypted_master_key, real_blkdev, crypto_blkdev,
1243 "userdata");
1244
Ken Sumrall128626f2011-06-28 18:45:14 -07001245 /* The size of the userdata partition, and add in the vold volumes below */
1246 tot_encryption_size = crypt_ftr.fs_size;
1247
Ken Sumrall29d8da82011-05-18 17:20:07 -07001248 /* setup crypto mapping for all encryptable volumes handled by vold */
1249 for (i=0; i<num_vols; i++) {
1250 if (should_encrypt(&vol_list[i])) {
1251 vol_list[i].crypt_ftr = crypt_ftr; /* gotta love struct assign */
1252 vol_list[i].crypt_ftr.fs_size = vol_list[i].size;
1253 create_crypto_blk_dev(&vol_list[i].crypt_ftr, decrypted_master_key,
1254 vol_list[i].blk_dev, vol_list[i].crypto_blkdev,
1255 vol_list[i].label);
Ken Sumrall128626f2011-06-28 18:45:14 -07001256 tot_encryption_size += vol_list[i].size;
Ken Sumrall29d8da82011-05-18 17:20:07 -07001257 }
1258 }
Ken Sumrall8ddbe402011-01-17 15:26:29 -08001259
1260 if (how == CRYPTO_ENABLE_WIPE) {
Ken Sumrall29d8da82011-05-18 17:20:07 -07001261 rc = cryptfs_enable_wipe(crypto_blkdev, crypt_ftr.fs_size, EXT4_FS);
1262 /* Encrypt all encryptable volumes handled by vold */
1263 if (!rc) {
1264 for (i=0; i<num_vols; i++) {
1265 if (should_encrypt(&vol_list[i])) {
1266 rc = cryptfs_enable_wipe(vol_list[i].crypto_blkdev,
1267 vol_list[i].crypt_ftr.fs_size, FAT_FS);
1268 }
1269 }
1270 }
Ken Sumrall8ddbe402011-01-17 15:26:29 -08001271 } else if (how == CRYPTO_ENABLE_INPLACE) {
Ken Sumrall29d8da82011-05-18 17:20:07 -07001272 rc = cryptfs_enable_inplace(crypto_blkdev, real_blkdev, crypt_ftr.fs_size,
1273 &cur_encryption_done, tot_encryption_size);
1274 /* Encrypt all encryptable volumes handled by vold */
1275 if (!rc) {
1276 for (i=0; i<num_vols; i++) {
1277 if (should_encrypt(&vol_list[i])) {
1278 rc = cryptfs_enable_inplace(vol_list[i].crypto_blkdev,
1279 vol_list[i].blk_dev,
1280 vol_list[i].crypt_ftr.fs_size,
1281 &cur_encryption_done, tot_encryption_size);
1282 }
1283 }
1284 }
1285 if (!rc) {
1286 /* The inplace routine never actually sets the progress to 100%
1287 * due to the round down nature of integer division, so set it here */
1288 property_set("vold.encrypt_progress", "100");
1289 }
Ken Sumrall8f869aa2010-12-03 03:47:09 -08001290 } else {
Ken Sumrall8ddbe402011-01-17 15:26:29 -08001291 /* Shouldn't happen */
1292 SLOGE("cryptfs_enable: internal error, unknown option\n");
Ken Sumrall3ed82362011-01-28 23:31:16 -08001293 goto error_unencrypted;
Ken Sumrall8ddbe402011-01-17 15:26:29 -08001294 }
1295
1296 /* Undo the dm-crypt mapping whether we succeed or not */
Ken Sumrall29d8da82011-05-18 17:20:07 -07001297 delete_crypto_blk_dev("userdata");
1298 for (i=0; i<num_vols; i++) {
1299 if (should_encrypt(&vol_list[i])) {
1300 delete_crypto_blk_dev(vol_list[i].label);
1301 }
1302 }
1303
1304 free(vol_list);
Ken Sumrall8ddbe402011-01-17 15:26:29 -08001305
1306 if (! rc) {
1307 /* Success */
Ken Sumrall7f7dbaa2011-02-01 15:46:41 -08001308
Ken Sumralld33d4172011-02-01 00:49:13 -08001309 /* Clear the encryption in progres flag in the footer */
1310 crypt_ftr.flags &= ~CRYPT_ENCRYPTION_IN_PROGRESS;
1311 put_crypt_ftr_and_key(real_blkdev, &crypt_ftr, 0, 0);
1312
Ken Sumrall29d8da82011-05-18 17:20:07 -07001313 sleep(2); /* Give the UI a chance to show 100% progress */
Ken Sumrallc290eaf2011-03-07 23:40:35 -08001314 android_reboot(ANDROID_RB_RESTART, 0, 0);
Ken Sumrall3ed82362011-01-28 23:31:16 -08001315 } else {
1316 property_set("vold.encrypt_progress", "error_partially_encrypted");
Ken Sumrall5d4c68e2011-01-30 19:06:03 -08001317 release_wake_lock(lockid);
Ken Sumrall3ed82362011-01-28 23:31:16 -08001318 return -1;
Ken Sumrall8ddbe402011-01-17 15:26:29 -08001319 }
1320
Ken Sumrall3ed82362011-01-28 23:31:16 -08001321 /* hrm, the encrypt step claims success, but the reboot failed.
1322 * This should not happen.
1323 * Set the property and return. Hope the framework can deal with it.
1324 */
1325 property_set("vold.encrypt_progress", "error_reboot_failed");
Ken Sumrall5d4c68e2011-01-30 19:06:03 -08001326 release_wake_lock(lockid);
Ken Sumrall8ddbe402011-01-17 15:26:29 -08001327 return rc;
Ken Sumrall3ed82362011-01-28 23:31:16 -08001328
1329error_unencrypted:
Ken Sumrall29d8da82011-05-18 17:20:07 -07001330 free(vol_list);
Ken Sumrall3ed82362011-01-28 23:31:16 -08001331 property_set("vold.encrypt_progress", "error_not_encrypted");
Ken Sumrall5d4c68e2011-01-30 19:06:03 -08001332 if (lockid[0]) {
1333 release_wake_lock(lockid);
1334 }
Ken Sumrall3ed82362011-01-28 23:31:16 -08001335 return -1;
1336
1337error_shutting_down:
1338 /* we failed, and have not encrypted anthing, so the users's data is still intact,
1339 * but the framework is stopped and not restarted to show the error, so it's up to
1340 * vold to restart the system.
1341 */
1342 SLOGE("Error enabling encryption after framework is shutdown, no data changed, restarting system");
Ken Sumrallc290eaf2011-03-07 23:40:35 -08001343 android_reboot(ANDROID_RB_RESTART, 0, 0);
Ken Sumrall3ed82362011-01-28 23:31:16 -08001344
1345 /* shouldn't get here */
1346 property_set("vold.encrypt_progress", "error_shutting_down");
Ken Sumrall29d8da82011-05-18 17:20:07 -07001347 free(vol_list);
Ken Sumrall5d4c68e2011-01-30 19:06:03 -08001348 if (lockid[0]) {
1349 release_wake_lock(lockid);
1350 }
Ken Sumrall3ed82362011-01-28 23:31:16 -08001351 return -1;
Ken Sumrall8ddbe402011-01-17 15:26:29 -08001352}
1353
Jason parks70a4b3f2011-01-28 10:10:47 -06001354int cryptfs_changepw(char *newpw)
Ken Sumrall8ddbe402011-01-17 15:26:29 -08001355{
1356 struct crypt_mnt_ftr crypt_ftr;
Jason parks70a4b3f2011-01-28 10:10:47 -06001357 unsigned char encrypted_master_key[KEY_LEN_BYTES], decrypted_master_key[KEY_LEN_BYTES];
Ken Sumralle8744072011-01-18 22:01:55 -08001358 unsigned char salt[SALT_LEN];
Ken Sumrall8ddbe402011-01-17 15:26:29 -08001359 char real_blkdev[MAXPATHLEN];
1360
1361 /* This is only allowed after we've successfully decrypted the master key */
Jason parks70a4b3f2011-01-28 10:10:47 -06001362 if (! master_key_saved) {
Ken Sumrall0cc16632011-01-18 20:32:26 -08001363 SLOGE("Key not saved, aborting");
Ken Sumrall8ddbe402011-01-17 15:26:29 -08001364 return -1;
1365 }
1366
1367 property_get("ro.crypto.fs_real_blkdev", real_blkdev, "");
1368 if (strlen(real_blkdev) == 0) {
Ken Sumrall57b63e62011-01-17 18:29:19 -08001369 SLOGE("Can't find real blkdev");
Ken Sumrall8ddbe402011-01-17 15:26:29 -08001370 return -1;
1371 }
1372
1373 /* get key */
Ken Sumralle8744072011-01-18 22:01:55 -08001374 if (get_crypt_ftr_and_key(real_blkdev, &crypt_ftr, encrypted_master_key, salt)) {
Ken Sumrall57b63e62011-01-17 18:29:19 -08001375 SLOGE("Error getting crypt footer and key");
Ken Sumrall8ddbe402011-01-17 15:26:29 -08001376 return -1;
1377 }
1378
Jason parks70a4b3f2011-01-28 10:10:47 -06001379 encrypt_master_key(newpw, salt, saved_master_key, encrypted_master_key);
Ken Sumrall8ddbe402011-01-17 15:26:29 -08001380
Jason parks70a4b3f2011-01-28 10:10:47 -06001381 /* save the key */
1382 put_crypt_ftr_and_key(real_blkdev, &crypt_ftr, encrypted_master_key, salt);
Ken Sumrall8f869aa2010-12-03 03:47:09 -08001383
1384 return 0;
1385}