M7350v1_en_gpl

This commit is contained in:
T
2024-09-09 08:52:07 +00:00
commit f9cc65cfda
65988 changed files with 26357421 additions and 0 deletions
+46
View File
@@ -0,0 +1,46 @@
#
# Copyright 2010 The Android Open Source Project
#
# Opaque Binary Blob (OBB) Tool
#
# This tool is prebuilt if we're doing an app-only build.
ifeq ($(TARGET_BUILD_APPS),)
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
Main.cpp
LOCAL_CFLAGS := -Wall -Werror
#LOCAL_C_INCLUDES +=
LOCAL_STATIC_LIBRARIES := \
libutils \
libcutils
ifeq ($(HOST_OS),linux)
LOCAL_LDLIBS += -lpthread
endif
LOCAL_MODULE := obbtool
include $(BUILD_HOST_EXECUTABLE)
#####################################################
include $(CLEAR_VARS)
LOCAL_MODULE := pbkdf2gen
LOCAL_MODULE_TAGS := optional
LOCAL_CFLAGS := -Wall -Werror
LOCAL_SRC_FILES := pbkdf2gen.cpp
LOCAL_LDLIBS += -ldl
LOCAL_C_INCLUDES := external/openssl/include $(LOCAL_C_INCLUDES)
LOCAL_STATIC_LIBRARIES := libcrypto_static
include $(BUILD_HOST_EXECUTABLE)
#######################################################
endif # TARGET_BUILD_APPS
+301
View File
@@ -0,0 +1,301 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <utils/ObbFile.h>
#include <utils/String8.h>
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
using namespace android;
static const char* gProgName = "obbtool";
static const char* gProgVersion = "1.0";
static int wantUsage = 0;
static int wantVersion = 0;
#define SALT_LEN 8
#define ADD_OPTS "n:v:os:"
static const struct option longopts[] = {
{"help", no_argument, &wantUsage, 1},
{"version", no_argument, &wantVersion, 1},
/* Args for "add" */
{"name", required_argument, NULL, 'n'},
{"version", required_argument, NULL, 'v'},
{"overlay", optional_argument, NULL, 'o'},
{"salt", required_argument, NULL, 's'},
{NULL, 0, NULL, '\0'}
};
class PackageInfo {
public:
PackageInfo()
: packageName(NULL)
, packageVersion(-1)
, overlay(false)
, salted(false)
{
memset(&salt, 0, sizeof(salt));
}
char* packageName;
int packageVersion;
bool overlay;
bool salted;
unsigned char salt[SALT_LEN];
};
/*
* Print usage info.
*/
void usage(void)
{
fprintf(stderr, "Opaque Binary Blob (OBB) Tool\n\n");
fprintf(stderr, "Usage:\n");
fprintf(stderr,
" %s a[dd] [ OPTIONS ] FILENAME\n"
" Adds an OBB signature to the file.\n\n", gProgName);
fprintf(stderr,
" Options:\n"
" -n <package name> sets the OBB package name (required)\n"
" -v <OBB version> sets the OBB version (required)\n"
" -o sets the OBB overlay flag\n"
" -s <8 byte hex salt> sets the crypto key salt (if encrypted)\n"
"\n");
fprintf(stderr,
" %s r[emove] FILENAME\n"
" Removes the OBB signature from the file.\n\n", gProgName);
fprintf(stderr,
" %s i[nfo] FILENAME\n"
" Prints the OBB signature information of a file.\n\n", gProgName);
}
void doAdd(const char* filename, struct PackageInfo* info) {
ObbFile *obb = new ObbFile();
if (obb->readFrom(filename)) {
fprintf(stderr, "ERROR: %s: OBB signature already present\n", filename);
return;
}
obb->setPackageName(String8(info->packageName));
obb->setVersion(info->packageVersion);
obb->setOverlay(info->overlay);
if (info->salted) {
obb->setSalt(info->salt, SALT_LEN);
}
if (!obb->writeTo(filename)) {
fprintf(stderr, "ERROR: %s: couldn't write OBB signature: %s\n",
filename, strerror(errno));
return;
}
fprintf(stderr, "OBB signature successfully written\n");
}
void doRemove(const char* filename) {
ObbFile *obb = new ObbFile();
if (!obb->readFrom(filename)) {
fprintf(stderr, "ERROR: %s: no OBB signature present\n", filename);
return;
}
if (!obb->removeFrom(filename)) {
fprintf(stderr, "ERROR: %s: couldn't remove OBB signature\n", filename);
return;
}
fprintf(stderr, "OBB signature successfully removed\n");
}
void doInfo(const char* filename) {
ObbFile *obb = new ObbFile();
if (!obb->readFrom(filename)) {
fprintf(stderr, "ERROR: %s: couldn't read OBB signature\n", filename);
return;
}
printf("OBB info for '%s':\n", filename);
printf("Package name: %s\n", obb->getPackageName().string());
printf(" Version: %d\n", obb->getVersion());
printf(" Flags: 0x%08x\n", obb->getFlags());
printf(" Overlay: %s\n", obb->isOverlay() ? "true" : "false");
printf(" Salt: ");
size_t saltLen;
const unsigned char* salt = obb->getSalt(&saltLen);
if (salt != NULL) {
for (int i = 0; i < SALT_LEN; i++) {
printf("%02x", salt[i]);
}
printf("\n");
} else {
printf("<empty>\n");
}
}
bool fromHex(char h, unsigned char *b) {
if (h >= '0' && h <= '9') {
*b = h - '0';
return true;
} else if (h >= 'a' && h <= 'f') {
*b = h - 'a' + 10;
return true;
} else if (h >= 'A' && h <= 'F') {
*b = h - 'A' + 10;
return true;
}
return false;
}
bool hexToByte(char h1, char h2, unsigned char* b) {
unsigned char first, second;
if (!fromHex(h1, &first)) return false;
if (!fromHex(h2, &second)) return false;
*b = (first << 4) | second;
return true;
}
/*
* Parse args.
*/
int main(int argc, char* const argv[])
{
int opt;
int option_index = 0;
struct PackageInfo package_info;
int result = 1; // pessimistically assume an error.
if (argc < 2) {
wantUsage = 1;
goto bail;
}
while ((opt = getopt_long(argc, argv, ADD_OPTS, longopts, &option_index)) != -1) {
switch (opt) {
case 0:
if (longopts[option_index].flag)
break;
fprintf(stderr, "'%s' requires an argument\n", longopts[option_index].name);
wantUsage = 1;
goto bail;
case 'n':
package_info.packageName = optarg;
break;
case 'v': {
char* end;
package_info.packageVersion = strtol(optarg, &end, 10);
if (*optarg == '\0' || *end != '\0') {
fprintf(stderr, "ERROR: invalid version; should be integer!\n\n");
wantUsage = 1;
goto bail;
}
break;
}
case 'o':
package_info.overlay = true;
break;
case 's':
if (strlen(optarg) != SALT_LEN * 2) {
fprintf(stderr, "ERROR: salt must be 8 bytes in hex (e.g., ABCD65031337D00D)\n\n");
wantUsage = 1;
goto bail;
}
package_info.salted = true;
unsigned char b;
for (int i = 0, j = 0; i < SALT_LEN; i++, j+=2) {
if (!hexToByte(optarg[j], optarg[j+1], &b)) {
fprintf(stderr, "ERROR: salt must be in hex (e.g., ABCD65031337D00D)\n");
wantUsage = 1;
goto bail;
}
package_info.salt[i] = b;
}
break;
case '?':
wantUsage = 1;
goto bail;
}
}
if (wantVersion) {
fprintf(stderr, "%s %s\n", gProgName, gProgVersion);
}
if (wantUsage) {
goto bail;
}
#define CHECK_OP(name) \
if (strncmp(op, name, opsize)) { \
fprintf(stderr, "ERROR: unknown function '%s'!\n\n", op); \
wantUsage = 1; \
goto bail; \
}
if (optind < argc) {
const char* op = argv[optind++];
const int opsize = strlen(op);
if (optind >= argc) {
fprintf(stderr, "ERROR: filename required!\n\n");
wantUsage = 1;
goto bail;
}
const char* filename = argv[optind++];
switch (op[0]) {
case 'a':
CHECK_OP("add");
if (package_info.packageName == NULL) {
fprintf(stderr, "ERROR: arguments required 'packageName' and 'version'\n");
goto bail;
}
doAdd(filename, &package_info);
break;
case 'r':
CHECK_OP("remove");
doRemove(filename);
break;
case 'i':
CHECK_OP("info");
doInfo(filename);
break;
default:
fprintf(stderr, "ERROR: unknown command '%s'!\n\n", op);
wantUsage = 1;
goto bail;
}
}
bail:
if (wantUsage) {
usage();
result = 2;
}
return result;
}
+281
View File
@@ -0,0 +1,281 @@
#!/bin/bash
#
# Copyright (C) 2010 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# mkobb.sh - Creates OBB files on Linux machines
# Directory where we should temporarily mount the OBB loopback to copy files
MOUNTDIR=/tmp
# Presets. Changing these will probably break your OBB on the device
CRYPTO=twofish
FS=vfat
MKFS=mkfs.vfat
LOSETUP=losetup
BLOCK_SIZE=512
SLOP=512 # Amount of filesystem slop in ${BLOCK_SIZE} blocks
find_binaries() {
MKFSBIN=`which ${MKFS}`
LOSETUPBIN=`which ${LOSETUP}`
MOUNTBIN=`which mount`
UMOUNTBIN=`which umount`
DDBIN=`which dd`
RSYNCBIN=`which rsync`
PBKDF2GEN=`which pbkdf2gen`
}
check_prereqs() {
if [ "`uname -s`x" != "Linuxx" ]; then \
echo "ERROR: This script only works on Linux!"
exit 1
fi
if ! egrep -q "^cryptoloop " /proc/modules; then \
echo "ERROR: Could not find cryptoloop in the kernel."
echo "Perhaps you need to: modprobe cryptoloop"
exit 1
fi
if ! egrep -q "name\s*:\s*${CRYPTO}$" /proc/crypto; then \
echo "ERROR: Could not find crypto \`${CRYPTO}' in the kernel."
echo "Perhaps you need to: modprobe ${CRYPTO}"
exit 1
fi
if ! egrep -q "^\s*${FS}$" /proc/filesystems; then \
echo "ERROR: Could not find filesystem \`${FS}' in the kernel."
echo "Perhaps you need to: modprobe ${FS}"
exit 1
fi
if [ "${MKFSBIN}x" = "x" ]; then \
echo "ERROR: Could not find ${MKFS} in your path!"
exit 1
elif [ ! -x "${MKFSBIN}" ]; then \
echo "ERROR: ${MKFSBIN} is not executable!"
exit 1
fi
if [ "${LOSETUPBIN}x" = "x" ]; then \
echo "ERROR: Could not find ${LOSETUP} in your path!"
exit 1
elif [ ! -x "${LOSETUPBIN}" ]; then \
echo "ERROR: ${LOSETUPBIN} is not executable!"
exit 1
fi
if [ "${PBKDF2GEN}x" = "x" ]; then \
echo "ERROR: Could not find pbkdf2gen in your path!"
exit 1
fi
}
cleanup() {
if [ "${loopdev}x" != "x" ]; then \
${LOSETUPBIN} -d ${loopdev}
fi
}
hidden_prompt() {
unset output
prompt="$1"
outvar="$2"
while read -s -n 1 -p "$prompt" c; do \
if [ "x$c" = "x" ]; then \
break
fi
prompt='*'
output="${output}${c}"
done
echo
eval $outvar="$output"
unset output
}
read_key() {
hidden_prompt " Encryption key: " key
if [ "${key}x" = "x" ]; then \
echo "ERROR: An empty key is not allowed!"
exit 1
fi
hidden_prompt "Encryption key (again): " key2
if [ "${key}x" != "${key2}x" ]; then \
echo "ERROR: Encryption keys do not match!"
exit 1
fi
}
onexit() {
if [ "x${temp_mount}" != "x" ]; then \
${UMOUNTBIN} ${temp_mount}
rmdir ${temp_mount}
fi
if [ "x${loop_dev}" != "x" ]; then \
if [ ${use_crypto} -eq 1 ]; then \
dmsetup remove -f ${loop_dev}
${LOSETUPBIN} -d ${old_loop_dev}
else \
${LOSETUPBIN} -d ${loop_dev}
fi
fi
if [ "x${tempfile}" != "x" -a -f "${tempfile}" ]; then \
rm -f ${tempfile}
fi
if [ "x${keyfile}" != "x" -a -f "${keyfile}" ]; then \
rm -f ${keyfile}
fi
echo "Fatal error."
exit 1
}
usage() {
echo "mkobb.sh -- Create OBB files for use on Android"
echo ""
echo " -d <directory> Use <directory> as input for OBB files"
echo " -k <key> Use <key> to encrypt OBB file"
echo " -K Prompt for key to encrypt OBB file"
echo " -o <filename> Write OBB file out to <filename>"
echo " -v Verbose mode"
echo " -h Help; this usage screen"
}
find_binaries
check_prereqs
use_crypto=0
args=`getopt -o d:hk:Ko:v -- "$@"`
eval set -- "$args"
while true; do \
case "$1" in
-d) directory=$2; shift 2;;
-h) usage; exit 1;;
-k) key=$2; use_crypto=1; shift 2;;
-K) prompt_key=1; use_crypto=1; shift;;
-v) verbose=1; shift;;
-o) filename=$2; shift 2;;
--) shift; break;;
*) echo "ERROR: Invalid argument in option parsing! Cannot recover. Ever."; exit 1;;
esac
done
if [ "${directory}x" = "x" -o ! -d "${directory}" ]; then \
echo "ERROR: Must specify valid input directory"
echo ""
usage
exit 1;
fi
if [ "${filename}x" = "x" ]; then \
echo "ERROR: Must specify filename"
echo ""
usage
exit 1;
fi
if [ ${use_crypto} -eq 1 -a "${key}x" = "x" -a 0${prompt_key} -eq 0 ]; then \
echo "ERROR: Crypto desired, but no key supplied or requested to prompt for."
exit 1
fi
if [ 0${prompt_key} -eq 1 ]; then \
read_key
fi
outdir=`dirname ${filename}`
if [ ! -d "${outdir}" ]; then \
echo "ERROR: Output directory does not exist: ${outdir}"
exit 1
fi
# Make sure we clean up any stuff we create from here on during error conditions
trap onexit ERR
tempfile=$(tempfile -d ${outdir}) || ( echo "ERROR: couldn't create temporary file in ${outdir}"; exit 1 )
block_count=`du -s --apparent-size --block-size=512 ${directory} | awk '{ print $1; }'`
if [ $? -ne 0 ]; then \
echo "ERROR: Couldn't read size of input directory ${directory}"
exit 1
fi
echo "Creating temporary file..."
${DDBIN} if=/dev/zero of=${tempfile} bs=${BLOCK_SIZE} count=$((${block_count} + ${SLOP})) > /dev/null 2>&1
if [ $? -ne 0 ]; then \
echo "ERROR: creating temporary file: $?"
fi
loop_dev=$(${LOSETUPBIN} -f) || ( echo "ERROR: losetup wouldn't tell us the next unused device"; exit 1 )
${LOSETUPBIN} ${loop_dev} ${tempfile} || ( echo "ERROR: couldn't create loopback device"; exit 1 )
if [ ${use_crypto} -eq 1 ]; then \
eval `${PBKDF2GEN} ${key}`
unique_dm_name=`basename ${tempfile}`
echo "0 `blockdev --getsize ${loop_dev}` crypt ${CRYPTO} ${key} 0 ${loop_dev} 0" | dmsetup create ${unique_dm_name}
old_loop_dev=${loop_dev}
loop_dev=/dev/mapper/${unique_dm_name}
fi
#
# Create the filesystem
#
echo ""
${MKFSBIN} -I ${loop_dev}
echo ""
#
# Make the temporary mount point and mount it
#
temp_mount="${MOUNTDIR}/${RANDOM}"
mkdir ${temp_mount}
${MOUNTBIN} -t ${FS} -o loop ${loop_dev} ${temp_mount}
#
# rsync the files!
#
echo "Copying files:"
${RSYNCBIN} -av --no-owner --no-group ${directory}/ ${temp_mount}/
echo ""
echo "Successfully created \`${filename}'"
if [ ${use_crypto} -eq 1 ]; then \
echo "salt for use with obbtool is:"
echo "${salt}"
fi
#
# Undo all the temporaries
#
umount ${temp_mount}
rmdir ${temp_mount}
if [ ${use_crypto} -eq 1 ]; then \
dmsetup remove -f ${loop_dev}
${LOSETUPBIN} -d ${old_loop_dev}
else \
${LOSETUPBIN} -d ${loop_dev}
fi
mv ${tempfile} ${filename}
trap - ERR
exit 0
+78
View File
@@ -0,0 +1,78 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <openssl/evp.h>
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
/**
* Simple program to generate a key based on PBKDF2 with preset inputs.
*
* Will print out the salt and key in hex.
*/
#define SALT_LEN 8
#define ROUNDS 1024
#define KEY_BITS 128
int main(int argc, char* argv[])
{
if (argc != 2) {
fprintf(stderr, "Usage: %s <password>\n", argv[0]);
exit(1);
}
int fd = open("/dev/urandom", O_RDONLY);
if (fd < 0) {
fprintf(stderr, "Could not open /dev/urandom: %s\n", strerror(errno));
close(fd);
exit(1);
}
unsigned char salt[SALT_LEN];
if (read(fd, &salt, SALT_LEN) != SALT_LEN) {
fprintf(stderr, "Could not read salt from /dev/urandom: %s\n", strerror(errno));
close(fd);
exit(1);
}
close(fd);
unsigned char rawKey[KEY_BITS];
if (PKCS5_PBKDF2_HMAC_SHA1(argv[1], strlen(argv[1]), salt, SALT_LEN,
ROUNDS, KEY_BITS, rawKey) != 1) {
fprintf(stderr, "Could not generate PBKDF2 output: %s\n", strerror(errno));
exit(1);
}
printf("salt=");
for (int i = 0; i < SALT_LEN; i++) {
printf("%02x", salt[i]);
}
printf("\n");
printf("key=");
for (int i = 0; i < (KEY_BITS / 8); i++) {
printf("%02x", rawKey[i]);
}
printf("\n");
}