int main(void) { char prop[PROPERTY_VALUE_MAX]; char key_loc[PROPERTY_VALUE_MAX]; char blk_dev[PROPERTY_VALUE_MAX]; char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)]; printf("This tool will gather the build flags needed for decryption support for TWRP.\n"); printf("This tool comes with no warranties whatsoever.\n"); printf("http://teamw.in\n\n"); property_get("ro.crypto.state", prop, "encrypted"); if (strcmp(prop, "encrypted") != 0) printf("Your device is not encrypted, continuing anyway.\n\nTW_INCLUDE_CRYPTO := true\n"); property_get("ro.crypto.fs_type", prop, "ERROR"); printf("TW_CRYPTO_FS_TYPE := \"%s\"\n", prop); property_get("ro.crypto.fs_real_blkdev", prop, "ERROR"); printf("TW_CRYPTO_REAL_BLKDEV := \"%s\"\n", prop); property_get("ro.crypto.fs_mnt_point", prop, "ERROR"); printf("TW_CRYPTO_MNT_POINT := \"%s\"\n", prop); property_get("ro.crypto.fs_options", prop, "ERROR"); printf("TW_CRYPTO_FS_OPTIONS := \"%s\"\n", prop); property_get("ro.crypto.fs_flags", prop, "ERROR"); printf("TW_CRYPTO_FS_FLAGS := \"%s\"\n", prop); property_get("ro.crypto.keyfile.userdata", prop, "footer"); printf("TW_CRYPTO_KEY_LOC := \"%s\"\n", prop); printf("\n*** NEW FOR JELLY BEAN:\n"); strcpy(fstab_filename, FSTAB_PREFIX); property_get("ro.hardware", fstab_filename + sizeof(FSTAB_PREFIX) - 1, ""); fs_mgr_get_crypt_info(fstab_filename, key_loc, blk_dev, sizeof(key_loc)); printf("fstab file location: '%s'\n\nTW_INCLUDE_JB_CRYPTO := true\n", fstab_filename); return 0; }
int get_crypt_ftr_info(char **metadata_fname, off64_t *off) { static int cached_data = 0; static off64_t cached_off = 0; static char cached_metadata_fname[PROPERTY_VALUE_MAX] = ""; int fd; char key_loc[PROPERTY_VALUE_MAX]; char real_blkdev[PROPERTY_VALUE_MAX]; unsigned int nr_sec; int rc = -1; fs_mgr_get_crypt_info(fstab, key_loc, real_blkdev, sizeof(key_loc)); if (!strcmp(key_loc, KEY_IN_FOOTER)) { if ( (fd = open(real_blkdev, O_RDWR)) < 0) { printf("Cannot open real block device %s\n", real_blkdev); return -1; } if ((nr_sec = get_blkdev_size(fd))) { /* If it's an encrypted Android partition, the last 16 Kbytes contain the * encryption info footer and key, and plenty of bytes to spare for future * growth. */ strlcpy(cached_metadata_fname, real_blkdev, sizeof(cached_metadata_fname)); cached_off = ((off64_t)nr_sec * 512) - CRYPT_FOOTER_OFFSET; cached_data = 1; } else { printf("Cannot get size of block device %s\n", real_blkdev); } close(fd); } else { strlcpy(cached_metadata_fname, key_loc, sizeof(cached_metadata_fname)); cached_off = 0; cached_data = 1; } if (cached_data) { if (metadata_fname) { *metadata_fname = cached_metadata_fname; } if (off) { *off = cached_off; } rc = 0; } return rc; }
int fs_mgr_mount_all(struct fstab *fstab) { int i = 0; int encrypted = 0; int ret = -1; int mret; if (!fstab) { return ret; } char key_loc[PROPERTY_VALUE_MAX]; fs_mgr_get_crypt_info(fstab, key_loc, 0, sizeof(key_loc)); for (i = 0; i < fstab->num_entries; i++) { /* Don't mount entries that are managed by vold */ if (fstab->recs[i].fs_mgr_flags & (MF_VOLDMANAGED | MF_RECOVERYONLY)) { continue; } /* Skip swap and raw partition entries such as boot, recovery, etc */ if (!strcmp(fstab->recs[i].fs_type, "swap") || !strcmp(fstab->recs[i].fs_type, "emmc") || !strcmp(fstab->recs[i].fs_type, "mtd")) { continue; } if (fstab->recs[i].fs_mgr_flags & MF_WAIT) { wait_for_file(fstab->recs[i].blk_device, WAIT_TIMEOUT); } if (fstab->recs[i].fs_mgr_flags & MF_CHECK) { check_fs(fstab->recs[i].blk_device, fstab->recs[i].fs_type, fstab->recs[i].mount_point,true, key_loc,fstab->recs[i].fs_mgr_flags & MF_CRYPT); } if (fstab->recs[i].fs_mgr_flags & MF_VERIFY) { if (fs_mgr_setup_verity(&fstab->recs[i]) < 0) { ERROR("Could not set up verified partition, skipping!"); continue; } } mret = __mount(fstab->recs[i].blk_device, fstab->recs[i].mount_point, fstab->recs[i].fs_type, fstab->recs[i].flags, fstab->recs[i].fs_options); if (!mret) { /* Success! Go get the next one */ continue; } /* mount(2) returned an error, check if it's encrypted and deal with it */ if ((fstab->recs[i].fs_mgr_flags & MF_CRYPT) && !partition_wiped(fstab->recs[i].blk_device)) { /* Need to mount a tmpfs at this mountpoint for now, and set * properties that vold will query later for decrypting */ if (mount("tmpfs", fstab->recs[i].mount_point, "tmpfs", MS_NOATIME | MS_NOSUID | MS_NODEV, CRYPTO_TMPFS_OPTIONS) < 0) { ERROR("Cannot mount tmpfs filesystem for encrypted fs at %s\n", fstab->recs[i].mount_point); goto out; } encrypted = 1; } else { ERROR("Cannot mount filesystem on %s at %s\n", fstab->recs[i].blk_device, fstab->recs[i].mount_point); goto out; } } if (encrypted) { ret = 1; } else { ret = 0; } out: return ret; }
int main(void) { char key_loc[PROPERTY_VALUE_MAX]; char blk_dev[PROPERTY_VALUE_MAX]; char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)]; struct stat st; struct crypt_mnt_ftr crypt_ftr; int fdout; printf("This tool comes with no warranties whatsoever.\n"); printf("http://teamw.in\n\n"); strcpy(fstab_filename, FSTAB_PREFIX); property_get("ro.hardware", fstab_filename + sizeof(FSTAB_PREFIX) - 1, ""); if (stat(fstab_filename, &st) != 0) { printf("Cannot locate fstab file '%s'\n", fstab_filename); return -1; } fstab = fs_mgr_read_fstab(fstab_filename); if (!fstab) { printf("failed to open %s\n", fstab_filename); return -1; } fs_mgr_get_crypt_info(fstab, key_loc, blk_dev, sizeof(blk_dev)); if (get_crypt_ftr_and_key(&crypt_ftr)) { printf("Error getting crypt footer and key\n"); return -1; } if ( (fdout = open("/footerfile", O_WRONLY | O_CREAT, 0644)) < 0) { printf("Cannot open output file /footerfile\n"); return -1; } if (write(fdout, (void*) &crypt_ftr, sizeof(struct crypt_mnt_ftr)) != sizeof(struct crypt_mnt_ftr)) { printf("Failed to write footer.\n"); } close(fdout); if (!strcmp(key_loc, KEY_IN_FOOTER)) { unsigned int nr_sec, cnt; off64_t off = 0; char buffer[CRYPT_FOOTER_OFFSET]; int fd; printf("\n\nDumping footer from '%s'...\n", blk_dev); if ( (fd = open(blk_dev, O_RDONLY)) < 0) { printf("Cannot open real block device %s\n", blk_dev); return -1; } if ((nr_sec = get_blkdev_size(fd))) { off = ((off64_t)nr_sec * 512) - CRYPT_FOOTER_OFFSET; } else { printf("Cannot get size of block device %s\n", blk_dev); close(fd); return -1; } printf("Size is %llu, offset is %llu\n", ((off64_t)nr_sec * 512), off); if (lseek64(fd, off, SEEK_SET) == -1) { printf("Cannot seek to real block device footer\n"); close(fd); return -1; } if ( (cnt = read(fd, buffer, sizeof(buffer))) != sizeof(buffer)) { printf("Cannot read real block device footer\n"); close(fd); return -1; } close(fd); if ( (fdout = open("/footerdump", O_WRONLY | O_CREAT, 0644)) < 0) { printf("Cannot open output file /footerdump\n"); return -1; } if (write(fdout, buffer, sizeof(buffer)) != sizeof(buffer)) { printf("Failed to write footer.\n"); } close(fdout); } return 0; }