blob: 72ffc2470cd2347d1b180fc71c4350649c6543a0 [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>
38#include <sys/reboot.h>
39#include "cryptfs.h"
40#define LOG_TAG "Cryptfs"
41#include "cutils/log.h"
42#include "cutils/properties.h"
43
44#define DM_CRYPT_BUF_SIZE 4096
Ken Sumrall8ddbe402011-01-17 15:26:29 -080045#define DATA_MNT_POINT "/data"
Ken Sumrall8f869aa2010-12-03 03:47:09 -080046
47char *me = "cryptfs";
48
Ken Sumrall8ddbe402011-01-17 15:26:29 -080049static unsigned char saved_key_sha1[20] = { '\0' };
50static int key_sha1_saved = 0;
51
Ken Sumrall8f869aa2010-12-03 03:47:09 -080052static void ioctl_init(struct dm_ioctl *io, size_t dataSize, const char *name, unsigned flags)
53{
54 memset(io, 0, dataSize);
55 io->data_size = dataSize;
56 io->data_start = sizeof(struct dm_ioctl);
57 io->version[0] = 4;
58 io->version[1] = 0;
59 io->version[2] = 0;
60 io->flags = flags;
61 if (name) {
62 strncpy(io->name, name, sizeof(io->name));
63 }
64}
65
66static unsigned int get_blkdev_size(int fd)
67{
68 unsigned int nr_sec;
69
70 if ( (ioctl(fd, BLKGETSIZE, &nr_sec)) == -1) {
71 nr_sec = 0;
72 }
73
74 return nr_sec;
75}
76
77/* key can be NULL, in which case just write out the footer. Useful to
78 * update the failed mount count but not change the key.
79 */
80static int put_crypt_ftr_and_key(char *real_blk_name, struct crypt_mnt_ftr *crypt_ftr,
81 unsigned char *key)
82{
83 int fd;
84 unsigned int nr_sec, cnt;
85 off64_t off;
86 int rc = -1;
87
88 if ( (fd = open(real_blk_name, O_RDWR)) < 0) {
89 SLOGE("Cannot open real block device %s\n", real_blk_name);
90 return -1;
91 }
92
93 if ( (nr_sec = get_blkdev_size(fd)) == 0) {
94 SLOGE("Cannot get size of block device %s\n", real_blk_name);
95 goto errout;
96 }
97
98 /* If it's an encrypted Android partition, the last 16 Kbytes contain the
99 * encryption info footer and key, and plenty of bytes to spare for future
100 * growth.
101 */
102 off = ((off64_t)nr_sec * 512) - CRYPT_FOOTER_OFFSET;
103
104 if (lseek64(fd, off, SEEK_SET) == -1) {
105 SLOGE("Cannot seek to real block device footer\n");
106 goto errout;
107 }
108
109 if ((cnt = write(fd, crypt_ftr, sizeof(struct crypt_mnt_ftr))) != sizeof(struct crypt_mnt_ftr)) {
110 SLOGE("Cannot write real block device footer\n");
111 goto errout;
112 }
113
114 if (key) {
115 if (crypt_ftr->keysize != 16) {
116 SLOGE("Keysize of %d bits not supported for real block device %s\n",
117 crypt_ftr->keysize * 8, real_blk_name);
118 goto errout;
119 }
120
121 if ( (cnt = write(fd, key, crypt_ftr->keysize)) != crypt_ftr->keysize) {
122 SLOGE("Cannot write key for real block device %s\n", real_blk_name);
123 goto errout;
124 }
125 }
126
127 /* Success! */
128 rc = 0;
129
130errout:
131 close(fd);
132 return rc;
133
134}
135
136static int get_crypt_ftr_and_key(char *real_blk_name, struct crypt_mnt_ftr *crypt_ftr,
137 unsigned char *key)
138{
139 int fd;
140 unsigned int nr_sec, cnt;
141 off64_t off;
142 int rc = -1;
143
144 if ( (fd = open(real_blk_name, O_RDWR)) < 0) {
145 SLOGE("Cannot open real block device %s\n", real_blk_name);
146 return -1;
147 }
148
149 if ( (nr_sec = get_blkdev_size(fd)) == 0) {
150 SLOGE("Cannot get size of block device %s\n", real_blk_name);
151 goto errout;
152 }
153
154 /* If it's an encrypted Android partition, the last 16 Kbytes contain the
155 * encryption info footer and key, and plenty of bytes to spare for future
156 * growth.
157 */
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800158 off = ((off64_t)nr_sec * 512) - CRYPT_FOOTER_OFFSET;
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800159
160 if (lseek64(fd, off, SEEK_SET) == -1) {
161 SLOGE("Cannot seek to real block device footer\n");
162 goto errout;
163 }
164
165 if ( (cnt = read(fd, crypt_ftr, sizeof(struct crypt_mnt_ftr))) != sizeof(struct crypt_mnt_ftr)) {
166 SLOGE("Cannot read real block device footer\n");
167 goto errout;
168 }
169
170 if (crypt_ftr->magic != CRYPT_MNT_MAGIC) {
171 SLOGE("Bad magic for real block device %s\n", real_blk_name);
172 goto errout;
173 }
174
175 if (crypt_ftr->major_version != 1) {
176 SLOGE("Cannot understand major version %d real block device footer\n",
177 crypt_ftr->major_version);
178 goto errout;
179 }
180
181 if (crypt_ftr->minor_version != 0) {
182 SLOGW("Warning: crypto footer minor version %d, expected 0, continuing...\n",
183 crypt_ftr->minor_version);
184 }
185
186 if (crypt_ftr->ftr_size > sizeof(struct crypt_mnt_ftr)) {
187 /* the footer size is bigger than we expected.
188 * Skip to it's stated end so we can read the key.
189 */
190 if (lseek(fd, crypt_ftr->ftr_size - sizeof(struct crypt_mnt_ftr), SEEK_CUR) == -1) {
191 SLOGE("Cannot seek to start of key\n");
192 goto errout;
193 }
194 }
195
196 if (crypt_ftr->keysize != 16) {
197 SLOGE("Keysize of %d bits not supported for real block device %s\n",
198 crypt_ftr->keysize * 8, real_blk_name);
199 goto errout;
200 }
201
202 if ( (cnt = read(fd, key, crypt_ftr->keysize)) != crypt_ftr->keysize) {
203 SLOGE("Cannot read key for real block device %s\n", real_blk_name);
204 goto errout;
205 }
206
207 /* Success! */
208 rc = 0;
209
210errout:
211 close(fd);
212 return rc;
213}
214
215/* Convert a binary key of specified length into an ascii hex string equivalent,
216 * without the leading 0x and with null termination
217 */
218void convert_key_to_hex_ascii(unsigned char *master_key, unsigned int keysize,
219 char *master_key_ascii)
220{
221 unsigned int i, a;
222 unsigned char nibble;
223
224 for (i=0, a=0; i<keysize; i++, a+=2) {
225 /* For each byte, write out two ascii hex digits */
226 nibble = (master_key[i] >> 4) & 0xf;
227 master_key_ascii[a] = nibble + (nibble > 9 ? 0x37 : 0x30);
228
229 nibble = master_key[i] & 0xf;
230 master_key_ascii[a+1] = nibble + (nibble > 9 ? 0x37 : 0x30);
231 }
232
233 /* Add the null termination */
234 master_key_ascii[a] = '\0';
235
236}
237
238static int create_crypto_blk_dev(struct crypt_mnt_ftr *crypt_ftr, unsigned char *master_key,
239 char *real_blk_name, char *crypto_blk_name)
240{
241 char buffer[DM_CRYPT_BUF_SIZE];
242 char master_key_ascii[129]; /* Large enough to hold 512 bit key and null */
243 char *crypt_params;
244 struct dm_ioctl *io;
245 struct dm_target_spec *tgt;
246 unsigned int minor;
247 int fd;
248 int retval = -1;
249 char *name ="datadev"; /* FIX ME: Make me a parameter */
250
251 if ((fd = open("/dev/device-mapper", O_RDWR)) < 0 ) {
252 SLOGE("Cannot open device-mapper\n");
253 goto errout;
254 }
255
256 io = (struct dm_ioctl *) buffer;
257
258 ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0);
259 if (ioctl(fd, DM_DEV_CREATE, io)) {
260 SLOGE("Cannot create dm-crypt device\n");
261 goto errout;
262 }
263
264 /* Get the device status, in particular, the name of it's device file */
265 ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0);
266 if (ioctl(fd, DM_DEV_STATUS, io)) {
267 SLOGE("Cannot retrieve dm-crypt device status\n");
268 goto errout;
269 }
270 minor = (io->dev & 0xff) | ((io->dev >> 12) & 0xfff00);
271 snprintf(crypto_blk_name, MAXPATHLEN, "/dev/block/dm-%u", minor);
272
273 /* Load the mapping table for this device */
274 tgt = (struct dm_target_spec *) &buffer[sizeof(struct dm_ioctl)];
275
276 ioctl_init(io, 4096, name, 0);
277 io->target_count = 1;
278 tgt->status = 0;
279 tgt->sector_start = 0;
280 tgt->length = crypt_ftr->fs_size;
281 strcpy(tgt->target_type, "crypt");
282
283 crypt_params = buffer + sizeof(struct dm_ioctl) + sizeof(struct dm_target_spec);
284 convert_key_to_hex_ascii(master_key, crypt_ftr->keysize, master_key_ascii);
285 sprintf(crypt_params, "%s %s 0 %s 0", crypt_ftr->crypto_type_name,
286 master_key_ascii, real_blk_name);
Ken Sumrall2eaf7132011-01-14 12:45:48 -0800287 //SLOGD("crypt_params = %s\n", crypt_params); // Only for debugging, prints the master key!
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800288 crypt_params += strlen(crypt_params) + 1;
289 crypt_params = (char *) (((unsigned long)crypt_params + 7) & ~8); /* Align to an 8 byte boundary */
290 tgt->next = crypt_params - buffer;
291
292 if (ioctl(fd, DM_TABLE_LOAD, io)) {
293 SLOGE("Cannot load dm-crypt mapping table.\n");
294 goto errout;
295 }
296
297 /* Resume this device to activate it */
298 ioctl_init(io, 4096, name, 0);
299
300 if (ioctl(fd, DM_DEV_SUSPEND, io)) {
301 SLOGE("Cannot resume the dm-crypt device\n");
302 goto errout;
303 }
304
305 /* We made it here with no errors. Woot! */
306 retval = 0;
307
308errout:
309 close(fd); /* If fd is <0 from a failed open call, it's safe to just ignore the close error */
310
311 return retval;
312}
313
314static int delete_crypto_blk_dev(char *crypto_blkdev)
315{
316 int fd;
317 char buffer[DM_CRYPT_BUF_SIZE];
318 struct dm_ioctl *io;
319 char *name ="datadev"; /* FIX ME: Make me a paraameter */
320 int retval = -1;
321
322 if ((fd = open("/dev/device-mapper", O_RDWR)) < 0 ) {
323 SLOGE("Cannot open device-mapper\n");
324 goto errout;
325 }
326
327 io = (struct dm_ioctl *) buffer;
328
329 ioctl_init(io, DM_CRYPT_BUF_SIZE, name, 0);
330 if (ioctl(fd, DM_DEV_REMOVE, io)) {
331 SLOGE("Cannot remove dm-crypt device\n");
332 goto errout;
333 }
334
335 /* We made it here with no errors. Woot! */
336 retval = 0;
337
338errout:
339 close(fd); /* If fd is <0 from a failed open call, it's safe to just ignore the close error */
340
341 return retval;
342
343}
344
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800345#define HASH_COUNT 2000
346#define KEY_LEN_BYTES 16
347#define IV_LEN_BYTES 16
348
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800349static void pbkdf2(char *passwd, unsigned char *ikey)
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800350{
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800351 unsigned char salt[32] = { 0 };
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800352
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800353 /* To Do: Make a salt based on some immutable data about this device.
354 * IMEI, or MEID, or CPU serial number, or whatever we can find
355 */
356 /* Turn the password into a key and IV that can decrypt the master key */
357 PKCS5_PBKDF2_HMAC_SHA1(passwd, strlen(passwd), salt, sizeof(salt),
358 HASH_COUNT, KEY_LEN_BYTES+IV_LEN_BYTES, ikey);
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800359}
360
361static int encrypt_master_key(char *passwd, unsigned char *decrypted_master_key,
362 unsigned char *encrypted_master_key)
363{
364 unsigned char ikey[32+32] = { 0 }; /* Big enough to hold a 256 bit key and 256 bit IV */
365 EVP_CIPHER_CTX e_ctx;
366 int encrypted_len, final_len;
367
368 /* Turn the password into a key and IV that can decrypt the master key */
369 pbkdf2(passwd, ikey);
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800370
371 /* Initialize the decryption engine */
372 if (! EVP_EncryptInit(&e_ctx, EVP_aes_128_cbc(), ikey, ikey+KEY_LEN_BYTES)) {
373 SLOGE("EVP_EncryptInit failed\n");
374 return -1;
375 }
376 EVP_CIPHER_CTX_set_padding(&e_ctx, 0); /* Turn off padding as our data is block aligned */
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800377
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800378 /* Encrypt the master key */
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800379 if (! EVP_EncryptUpdate(&e_ctx, encrypted_master_key, &encrypted_len,
380 decrypted_master_key, KEY_LEN_BYTES)) {
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800381 SLOGE("EVP_EncryptUpdate failed\n");
382 return -1;
383 }
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800384 if (! EVP_EncryptFinal(&e_ctx, encrypted_master_key + encrypted_len, &final_len)) {
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800385 SLOGE("EVP_EncryptFinal failed\n");
386 return -1;
387 }
388
389 if (encrypted_len + final_len != KEY_LEN_BYTES) {
390 SLOGE("EVP_Encryption length check failed with %d, %d bytes\n", encrypted_len, final_len);
391 return -1;
392 } else {
393 return 0;
394 }
395}
396
397static int decrypt_master_key(char *passwd, unsigned char *encrypted_master_key,
398 unsigned char *decrypted_master_key)
399{
400 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 -0800401 EVP_CIPHER_CTX d_ctx;
402 int decrypted_len, final_len;
403
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800404 /* Turn the password into a key and IV that can decrypt the master key */
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800405 pbkdf2(passwd, ikey);
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800406
407 /* Initialize the decryption engine */
408 if (! EVP_DecryptInit(&d_ctx, EVP_aes_128_cbc(), ikey, ikey+KEY_LEN_BYTES)) {
409 return -1;
410 }
411 EVP_CIPHER_CTX_set_padding(&d_ctx, 0); /* Turn off padding as our data is block aligned */
412 /* Decrypt the master key */
413 if (! EVP_DecryptUpdate(&d_ctx, decrypted_master_key, &decrypted_len,
414 encrypted_master_key, KEY_LEN_BYTES)) {
415 return -1;
416 }
417 if (! EVP_DecryptFinal(&d_ctx, decrypted_master_key + decrypted_len, &final_len)) {
418 return -1;
419 }
420
421 if (decrypted_len + final_len != KEY_LEN_BYTES) {
422 return -1;
423 } else {
424 return 0;
425 }
426}
427
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800428static int create_encrypted_random_key(char *passwd, unsigned char *master_key)
429{
430 int fd;
431 unsigned char buf[KEY_LEN_BYTES];
432 unsigned char ikey[32+32] = { 0 }; /* Big enough to hold a 256 bit key and 256 bit IV */
433 unsigned char salt[32] = { 0 };
434 EVP_CIPHER_CTX e_ctx;
435 int encrypted_len, final_len;
436
437 /* Get some random bits for a key */
438 fd = open("/dev/urandom", O_RDONLY);
439 read(fd, buf, sizeof(buf));
440 close(fd);
441
442 /* Now encrypt it with the password */
443 return encrypt_master_key(passwd, buf, master_key);
444}
445
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800446static int get_orig_mount_parms(char *mount_point, char *fs_type, char *real_blkdev,
447 unsigned long *mnt_flags, char *fs_options)
448{
449 char mount_point2[32];
450 char fs_flags[32];
451
452 property_get("ro.crypto.fs_type", fs_type, "");
453 property_get("ro.crypto.fs_real_blkdev", real_blkdev, "");
454 property_get("ro.crypto.fs_mnt_point", mount_point2, "");
455 property_get("ro.crypto.fs_options", fs_options, "");
456 property_get("ro.crypto.fs_flags", fs_flags, "");
457 *mnt_flags = strtol(fs_flags, 0, 0);
458
459 if (strcmp(mount_point, mount_point2)) {
460 /* Consistency check. These should match. If not, something odd happened. */
461 return -1;
462 }
463
464 return 0;
465}
466
467static int wait_and_unmount(char *mountpoint)
468{
469 int i, rc;
Ken Sumrall2eaf7132011-01-14 12:45:48 -0800470#define WAIT_UNMOUNT_COUNT 20
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800471
472 /* Now umount the tmpfs filesystem */
473 for (i=0; i<WAIT_UNMOUNT_COUNT; i++) {
474 if (umount(mountpoint)) {
475 sleep(1);
476 i++;
477 } else {
478 break;
479 }
480 }
481
482 if (i < WAIT_UNMOUNT_COUNT) {
483 SLOGD("unmounting %s succeeded\n", mountpoint);
484 rc = 0;
485 } else {
486 SLOGE("unmounting %s failed\n", mountpoint);
487 rc = -1;
488 }
489
490 return rc;
491}
492
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800493#define DATA_PREP_TIMEOUT 100
494static int prep_data_fs(void)
495{
496 int i;
497
498 /* Do the prep of the /data filesystem */
499 property_set("vold.post_fs_data_done", "0");
500 property_set("vold.decrypt", "trigger_post_fs_data");
501 SLOGD("Just triggered post_fs_data\n");
502
503 /* Wait a max of 25 seconds, hopefully it takes much less */
504 for (i=0; i<DATA_PREP_TIMEOUT; i++) {
505 char p[16];;
506
507 property_get("vold.post_fs_data_done", p, "0");
508 if (*p == '1') {
509 break;
510 } else {
511 usleep(250000);
512 }
513 }
514 if (i == DATA_PREP_TIMEOUT) {
515 /* Ugh, we failed to prep /data in time. Bail. */
516 return -1;
517 } else {
518 SLOGD("post_fs_data done\n");
519 return 0;
520 }
521}
522
Ken Sumrall6864b7e2011-01-14 15:20:02 -0800523int cryptfs_restart(void)
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800524{
525 char fs_type[32];
526 char real_blkdev[MAXPATHLEN];
Ken Sumrall6864b7e2011-01-14 15:20:02 -0800527 char crypto_blkdev[MAXPATHLEN];
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800528 char fs_options[256];
529 unsigned long mnt_flags;
530 struct stat statbuf;
531 int rc = -1, i;
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800532
533 /* Here is where we shut down the framework. The init scripts
534 * start all services in one of three classes: core, main or late_start.
535 * On boot, we start core and main. Now, we stop main, but not core,
536 * as core includes vold and a few other really important things that
537 * we need to keep running. Once main has stopped, we should be able
538 * to umount the tmpfs /data, then mount the encrypted /data.
539 * We then restart the class main, and also the class late_start.
540 * At the moment, I've only put a few things in late_start that I know
541 * are not needed to bring up the framework, and that also cause problems
542 * with unmounting the tmpfs /data, but I hope to add add more services
543 * to the late_start class as we optimize this to decrease the delay
544 * till the user is asked for the password to the filesystem.
545 */
546
547 /* The init files are setup to stop the class main when vold.decrypt is
548 * set to trigger_reset_main.
549 */
550 property_set("vold.decrypt", "trigger_reset_main");
551 SLOGD("Just asked init to shut down class main\n");
552
553 /* Now that the framework is shutdown, we should be able to umount()
554 * the tmpfs filesystem, and mount the real one.
555 */
556
Ken Sumrall6864b7e2011-01-14 15:20:02 -0800557 property_get("ro.crypto.fs_crypto_blkdev", crypto_blkdev, "");
558 if (strlen(crypto_blkdev) == 0) {
559 SLOGE("fs_crypto_blkdev not set\n");
560 return -1;
561 }
562
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800563 if (! get_orig_mount_parms(DATA_MNT_POINT, fs_type, real_blkdev, &mnt_flags, fs_options)) {
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800564 SLOGD("Just got orig mount parms\n");
565
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800566 if (! (rc = wait_and_unmount(DATA_MNT_POINT)) ) {
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800567 /* If that succeeded, then mount the decrypted filesystem */
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800568 mount(crypto_blkdev, DATA_MNT_POINT, fs_type, mnt_flags, fs_options);
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800569
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800570 /* Create necessary paths on /data */
571 if (prep_data_fs()) {
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800572 return -1;
573 }
574
575 /* startup service classes main and late_start */
576 property_set("vold.decrypt", "trigger_restart_framework");
577 SLOGD("Just triggered restart_framework\n");
578
579 /* Give it a few moments to get started */
580 sleep(1);
581 }
582 }
583
584 return rc;
585}
586
587static int test_mount_encrypted_fs(char *passwd, char *mount_point)
588{
589 struct crypt_mnt_ftr crypt_ftr;
590 /* Allocate enough space for a 256 bit key, but we may use less */
591 unsigned char encrypted_master_key[32], decrypted_master_key[32];
592 char crypto_blkdev[MAXPATHLEN];
593 char real_blkdev[MAXPATHLEN];
594 char fs_type[32];
595 char fs_options[256];
596 char tmp_mount_point[64];
597 unsigned long mnt_flags;
598 unsigned int orig_failed_decrypt_count;
599 int rc;
600
601 if (get_orig_mount_parms(mount_point, fs_type, real_blkdev, &mnt_flags, fs_options)) {
602 SLOGE("Error reading original mount parms for mount point %s\n", mount_point);
603 return -1;
604 }
605
606 if (get_crypt_ftr_and_key(real_blkdev, &crypt_ftr, encrypted_master_key)) {
607 SLOGE("Error getting crypt footer and key\n");
608 return -1;
609 }
610 SLOGD("crypt_ftr->fs_size = %lld\n", crypt_ftr.fs_size);
611 orig_failed_decrypt_count = crypt_ftr.failed_decrypt_count;
612
613 if (! (crypt_ftr.flags & CRYPT_MNT_KEY_UNENCRYPTED) ) {
614 decrypt_master_key(passwd, encrypted_master_key, decrypted_master_key);
615 }
616
617 if (create_crypto_blk_dev(&crypt_ftr, decrypted_master_key,
618 real_blkdev, crypto_blkdev)) {
619 SLOGE("Error creating decrypted block device\n");
620 return -1;
621 }
622
623 /* If init detects an encrypted filesystme, it writes a file for each such
624 * encrypted fs into the tmpfs /data filesystem, and then the framework finds those
625 * files and passes that data to me */
626 /* Create a tmp mount point to try mounting the decryptd fs
627 * Since we're here, the mount_point should be a tmpfs filesystem, so make
628 * a directory in it to test mount the decrypted filesystem.
629 */
630 sprintf(tmp_mount_point, "%s/tmp_mnt", mount_point);
631 mkdir(tmp_mount_point, 0755);
632 if ( mount(crypto_blkdev, tmp_mount_point, "ext4", MS_RDONLY, "") ) {
633 SLOGE("Error temp mounting decrypted block device\n");
634 delete_crypto_blk_dev(crypto_blkdev);
635 crypt_ftr.failed_decrypt_count++;
636 } else {
637 /* Success, so just umount and we'll mount it properly when we restart
638 * the framework.
639 */
640 umount(tmp_mount_point);
641 crypt_ftr.failed_decrypt_count = 0;
642 }
643
644 if (orig_failed_decrypt_count != crypt_ftr.failed_decrypt_count) {
645 put_crypt_ftr_and_key(real_blkdev, &crypt_ftr, 0);
646 }
647
648 if (crypt_ftr.failed_decrypt_count) {
649 /* We failed to mount the device, so return an error */
650 rc = crypt_ftr.failed_decrypt_count;
651
652 } else {
Ken Sumrall6864b7e2011-01-14 15:20:02 -0800653 /* Woot! Success! Save the name of the crypto block device
654 * so we can mount it when restarting the framework.
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800655 */
Ken Sumrall6864b7e2011-01-14 15:20:02 -0800656 property_set("ro.crypto.fs_crypto_blkdev", crypto_blkdev);
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800657 /* Also save a SHA1 of the master key so we can know if we
658 * successfully decrypted the key when we want to change the
659 * password on it.
660 */
661 SHA1(decrypted_master_key, KEY_LEN_BYTES, saved_key_sha1);
662 key_sha1_saved = 1;
Ken Sumrall6864b7e2011-01-14 15:20:02 -0800663 rc = 0;
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800664 }
665
666 return rc;
667}
668
669int cryptfs_check_passwd(char *passwd)
670{
671 int rc = -1;
672
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800673 rc = test_mount_encrypted_fs(passwd, DATA_MNT_POINT);
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800674
675 return rc;
676}
677
678/* Initialize a crypt_mnt_ftr structure. The keysize is
679 * defaulted to 16 bytes, and the filesystem size to 0.
680 * Presumably, at a minimum, the caller will update the
681 * filesystem size and crypto_type_name after calling this function.
682 */
683static void cryptfs_init_crypt_mnt_ftr(struct crypt_mnt_ftr *ftr)
684{
685 ftr->magic = CRYPT_MNT_MAGIC;
686 ftr->major_version = 1;
687 ftr->minor_version = 0;
688 ftr->ftr_size = sizeof(struct crypt_mnt_ftr);
689 ftr->flags = 0;
690 ftr->keysize = 16;
691 ftr->spare1 = 0;
692 ftr->fs_size = 0;
693 ftr->failed_decrypt_count = 0;
694 ftr->crypto_type_name[0] = '\0';
695}
696
697static int cryptfs_enable_wipe(char *crypto_blkdev, off64_t size)
698{
699 char cmdline[256];
700 int rc = -1;
701
702 snprintf(cmdline, sizeof(cmdline), "/system/bin/make_ext4fs -a /data -l %lld %s",
703 size * 512, crypto_blkdev);
704 SLOGI("Making empty filesystem with command %s\n", cmdline);
705 if (system(cmdline)) {
706 SLOGE("Error creating empty filesystem on %s\n", crypto_blkdev);
707 } else {
708 SLOGD("Successfully created empty filesystem on %s\n", crypto_blkdev);
709 rc = 0;
710 }
711
712 return rc;
713}
714
715static inline int unix_read(int fd, void* buff, int len)
716{
717 int ret;
718 do { ret = read(fd, buff, len); } while (ret < 0 && errno == EINTR);
719 return ret;
720}
721
722static inline int unix_write(int fd, const void* buff, int len)
723{
724 int ret;
725 do { ret = write(fd, buff, len); } while (ret < 0 && errno == EINTR);
726 return ret;
727}
728
729#define CRYPT_INPLACE_BUFSIZE 4096
730#define CRYPT_SECTORS_PER_BUFSIZE (CRYPT_INPLACE_BUFSIZE / 512)
731static int cryptfs_enable_inplace(char *crypto_blkdev, char *real_blkdev, off64_t size)
732{
733 int realfd, cryptofd;
734 char *buf[CRYPT_INPLACE_BUFSIZE];
735 int rc = -1;
736 off64_t numblocks, i, remainder;
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800737 off64_t one_pct, cur_pct, new_pct;
738
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800739 if ( (realfd = open(real_blkdev, O_RDONLY)) < 0) {
740 SLOGE("Error opening real_blkdev %s for inplace encrypt\n", real_blkdev);
741 return -1;
742 }
743
744 if ( (cryptofd = open(crypto_blkdev, O_WRONLY)) < 0) {
745 SLOGE("Error opening crypto_blkdev %s for inplace encrypt\n", crypto_blkdev);
746 close(realfd);
747 return -1;
748 }
749
750 /* This is pretty much a simple loop of reading 4K, and writing 4K.
751 * The size passed in is the number of 512 byte sectors in the filesystem.
752 * So compute the number of whole 4K blocks we should read/write,
753 * and the remainder.
754 */
755 numblocks = size / CRYPT_SECTORS_PER_BUFSIZE;
756 remainder = size % CRYPT_SECTORS_PER_BUFSIZE;
757
758 SLOGE("Encrypting filesystem in place...");
759
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800760 one_pct = numblocks / 100;
761 cur_pct = 0;
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800762 /* process the majority of the filesystem in blocks */
763 for (i=0; i<numblocks; i++) {
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800764 new_pct = i / one_pct;
765 if (new_pct > cur_pct) {
766 char buf[8];
767
768 cur_pct = new_pct;
769 snprintf(buf, sizeof(buf), "%lld", cur_pct);
770 property_set("vold.encrypt_progress", buf);
771 }
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800772 if (unix_read(realfd, buf, CRYPT_INPLACE_BUFSIZE) <= 0) {
773 SLOGE("Error reading real_blkdev %s for inplace encrypt\n", crypto_blkdev);
774 goto errout;
775 }
776 if (unix_write(cryptofd, buf, CRYPT_INPLACE_BUFSIZE) <= 0) {
777 SLOGE("Error writing crypto_blkdev %s for inplace encrypt\n", crypto_blkdev);
778 goto errout;
779 }
780 }
781
782 /* Do any remaining sectors */
783 for (i=0; i<remainder; i++) {
784 if (unix_read(realfd, buf, 512) <= 0) {
785 SLOGE("Error reading rival sectors from real_blkdev %s for inplace encrypt\n", crypto_blkdev);
786 goto errout;
787 }
788 if (unix_write(cryptofd, buf, 512) <= 0) {
789 SLOGE("Error writing final sectors to crypto_blkdev %s for inplace encrypt\n", crypto_blkdev);
790 goto errout;
791 }
792 }
793
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800794 property_set("vold.encrypt_progress", "100");
795
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800796 rc = 0;
797
798errout:
799 close(realfd);
800 close(cryptofd);
801
802 return rc;
803}
804
805#define CRYPTO_ENABLE_WIPE 1
806#define CRYPTO_ENABLE_INPLACE 2
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800807
808#define FRAMEWORK_BOOT_WAIT 60
809
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800810int cryptfs_enable(char *howarg, char *passwd)
811{
812 int how = 0;
813 char crypto_blkdev[MAXPATHLEN], real_blkdev[MAXPATHLEN];
814 char fs_type[32], fs_options[256], mount_point[32];
815 unsigned long mnt_flags, nr_sec;
816 unsigned char master_key[16], decrypted_master_key[16];
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800817 int rc=-1, fd, i;
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800818 struct crypt_mnt_ftr crypt_ftr;
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800819 char tmpfs_options[80];
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800820
821 if (!strcmp(howarg, "wipe")) {
822 how = CRYPTO_ENABLE_WIPE;
823 } else if (! strcmp(howarg, "inplace")) {
824 how = CRYPTO_ENABLE_INPLACE;
825 } else {
826 /* Shouldn't happen, as CommandListener vets the args */
827 return -1;
828 }
829
830 get_orig_mount_parms(mount_point, fs_type, real_blkdev, &mnt_flags, fs_options);
831
832 /* The init files are setup to stop the class main and late start when
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800833 * vold sets trigger_shutdown_framework.
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800834 */
835 property_set("vold.decrypt", "trigger_shutdown_framework");
836 SLOGD("Just asked init to shut down class main\n");
837
Ken Sumrall2eaf7132011-01-14 12:45:48 -0800838 if (wait_and_unmount("/mnt/sdcard")) {
839 return -1;
840 }
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800841
842 /* Now unmount the /data partition. */
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800843 if (wait_and_unmount(DATA_MNT_POINT)) {
844 return -1;
845 }
846
847 /* Do extra work for a better UX when doing the long inplace encryption */
848 if (how == CRYPTO_ENABLE_INPLACE) {
849 /* Now that /data is unmounted, we need to mount a tmpfs
850 * /data, set a property saying we're doing inplace encryption,
851 * and restart the framework.
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800852 */
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800853 property_get("ro.crypto.tmpfs_options", tmpfs_options, "");
854 if (mount("tmpfs", DATA_MNT_POINT, "tmpfs", MS_NOATIME | MS_NOSUID | MS_NODEV,
855 tmpfs_options) < 0) {
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800856 return -1;
857 }
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800858 /* Tells the framework that inplace encryption is starting */
859 property_set("vold.encrypt_progress", "startup");
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800860
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800861 /* restart the framework. */
862 /* Create necessary paths on /data */
863 if (prep_data_fs()) {
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800864 return -1;
865 }
866
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800867 /* startup service classes main and late_start */
868 property_set("vold.decrypt", "trigger_restart_min_framework");
869 SLOGD("Just triggered restart_min_framework\n");
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800870
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800871 /* Wait till the framework is ready */
872 for (i=0; i<FRAMEWORK_BOOT_WAIT; i++) {
873 char progress_state[32];
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800874
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800875 sleep(1);
876 property_get("vold.encrypt_progress", progress_state, "");
877 if (! strcmp(progress_state, "ready")) {
878 break;
879 }
880 }
881 if (i == FRAMEWORK_BOOT_WAIT) {
882 /* The framework never rebooted, so abort */
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800883 return -1;
884 }
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800885 /* OK, the framework is restarted and displaying a progress bar,
886 * time to setup an encrypted mapping, and either write a new
887 * filesystem or encrypt in place, updating the progress bar
888 * as we work.
889 */
890 }
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800891
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800892 /* Start the actual work of making an encrypted filesystem */
893 fd = open(real_blkdev, O_RDONLY);
894 if ( (nr_sec = get_blkdev_size(fd)) == 0) {
895 SLOGE("Cannot get size of block device %s\n", real_blkdev);
896 return -1;
897 }
898 close(fd);
899
900 /* Initialize a crypt_mnt_ftr for the partition */
901 cryptfs_init_crypt_mnt_ftr(&crypt_ftr);
902 crypt_ftr.fs_size = nr_sec - (CRYPT_FOOTER_OFFSET / 512);
903 strcpy((char *)crypt_ftr.crypto_type_name, "aes-cbc-essiv:sha256");
904
905 /* Make an encrypted master key */
906 if (create_encrypted_random_key(passwd, master_key)) {
907 SLOGE("Cannot create encrypted master key\n");
908 return -1;
909 }
910
911 /* Write the key to the end of the partition */
912 put_crypt_ftr_and_key(real_blkdev, &crypt_ftr, master_key);
913
914 decrypt_master_key(passwd, master_key, decrypted_master_key);
915 create_crypto_blk_dev(&crypt_ftr, decrypted_master_key, real_blkdev, crypto_blkdev);
916
917 if (how == CRYPTO_ENABLE_WIPE) {
918 rc = cryptfs_enable_wipe(crypto_blkdev, crypt_ftr.fs_size);
919 } else if (how == CRYPTO_ENABLE_INPLACE) {
920 rc = cryptfs_enable_inplace(crypto_blkdev, real_blkdev, crypt_ftr.fs_size);
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800921 } else {
Ken Sumrall8ddbe402011-01-17 15:26:29 -0800922 /* Shouldn't happen */
923 SLOGE("cryptfs_enable: internal error, unknown option\n");
924 return -1;
925 }
926
927 /* Undo the dm-crypt mapping whether we succeed or not */
928 delete_crypto_blk_dev(crypto_blkdev);
929
930 if (! rc) {
931 /* Success */
932 sleep(2); /* Give the UI a change to show 100% progress */
933 sync();
934 reboot(LINUX_REBOOT_CMD_RESTART);
935 }
936
937 /* Only returns on error */
938 return rc;
939}
940
941int cryptfs_changepw(char *oldpw, char *newpw)
942{
943 struct crypt_mnt_ftr crypt_ftr;
944 unsigned char encrypted_master_key[32], decrypted_master_key[32];
945 unsigned char new_key_sha1[20];
946 char real_blkdev[MAXPATHLEN];
947
948 /* This is only allowed after we've successfully decrypted the master key */
949 if (! key_sha1_saved) {
950 return -1;
951 }
952
953 property_get("ro.crypto.fs_real_blkdev", real_blkdev, "");
954 if (strlen(real_blkdev) == 0) {
955 return -1;
956 }
957
958 /* get key */
959 if (get_crypt_ftr_and_key(real_blkdev, &crypt_ftr, encrypted_master_key)) {
960 SLOGE("Error getting crypt footer and key\n");
961 return -1;
962 }
963
964 /* decrypt key with old passwd */
965 decrypt_master_key(oldpw, encrypted_master_key, decrypted_master_key);
966
967 /* compute sha1 of decrypted key */
968 SHA1(decrypted_master_key, KEY_LEN_BYTES, new_key_sha1);
969
970 /* If computed sha1 and saved sha1 match, encrypt key with new passwd */
971 if (! memcmp(saved_key_sha1, new_key_sha1, sizeof(saved_key_sha1))) {
972 /* they match, it's safe to re-encrypt the key */
973 encrypt_master_key(newpw, decrypted_master_key, encrypted_master_key);
974
975 /* save the key */
976 put_crypt_ftr_and_key(real_blkdev, &crypt_ftr, encrypted_master_key);
977 } else {
978 SLOGE("SHA1 mismatch");
Ken Sumrall8f869aa2010-12-03 03:47:09 -0800979 return -1;
980 }
981
982 return 0;
983}
984