OBB: use PBKDF2 for key generation.
Switch to using PBKDF2 for the key generation for OBBs. Any previously generated OBBs will stop being read correctly. A small pbkdf2gen program is available to allow generation of appropriate keys with the salts. Bug: 3059950 Change-Id: If4305c989fd692fd1150eb270dbf751e09c37295
This commit is contained in:
parent
91a2e55166
commit
95a6889312
@ -27,6 +27,7 @@ namespace android {
|
||||
|
||||
// OBB flags (bit 0)
|
||||
#define OBB_OVERLAY (1 << 0)
|
||||
#define OBB_SALTED (1 << 1)
|
||||
|
||||
class ObbFile : public RefBase {
|
||||
protected:
|
||||
@ -70,6 +71,26 @@ public:
|
||||
mFlags = flags;
|
||||
}
|
||||
|
||||
const unsigned char* getSalt(size_t* length) const {
|
||||
if ((mFlags & OBB_SALTED) == 0) {
|
||||
*length = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*length = sizeof(mSalt);
|
||||
return mSalt;
|
||||
}
|
||||
|
||||
bool setSalt(const unsigned char* salt, size_t length) {
|
||||
if (length != sizeof(mSalt)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(mSalt, salt, sizeof(mSalt));
|
||||
mFlags |= OBB_SALTED;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isOverlay() {
|
||||
return (mFlags & OBB_OVERLAY) == OBB_OVERLAY;
|
||||
}
|
||||
@ -103,6 +124,12 @@ private:
|
||||
/* Flags for this OBB type. */
|
||||
int32_t mFlags;
|
||||
|
||||
/* Whether the file is salted. */
|
||||
bool mSalted;
|
||||
|
||||
/* The encryption salt. */
|
||||
unsigned char mSalt[8];
|
||||
|
||||
const char* mFileName;
|
||||
|
||||
size_t mFileSize;
|
||||
|
@ -29,10 +29,11 @@
|
||||
|
||||
#define kFooterTagSize 8 /* last two 32-bit integers */
|
||||
|
||||
#define kFooterMinSize 25 /* 32-bit signature version (4 bytes)
|
||||
#define kFooterMinSize 33 /* 32-bit signature version (4 bytes)
|
||||
* 32-bit package version (4 bytes)
|
||||
* 32-bit flags (4 bytes)
|
||||
* 32-bit package name size (4-bytes)
|
||||
* 64-bit salt (8 bytes)
|
||||
* 32-bit package name size (4 bytes)
|
||||
* >=1-character package name (1 byte)
|
||||
* 32-bit footer size (4 bytes)
|
||||
* 32-bit footer marker (4 bytes)
|
||||
@ -47,8 +48,9 @@
|
||||
/* offsets in version 1 of the header */
|
||||
#define kPackageVersionOffset 4
|
||||
#define kFlagsOffset 8
|
||||
#define kPackageNameLenOffset 12
|
||||
#define kPackageNameOffset 16
|
||||
#define kSaltOffset 12
|
||||
#define kPackageNameLenOffset 20
|
||||
#define kPackageNameOffset 24
|
||||
|
||||
/*
|
||||
* TEMP_FAILURE_RETRY is defined by some, but not all, versions of
|
||||
@ -79,11 +81,12 @@ typedef off64_t my_off64_t;
|
||||
|
||||
namespace android {
|
||||
|
||||
ObbFile::ObbFile() :
|
||||
mPackageName(""),
|
||||
mVersion(-1),
|
||||
mFlags(0)
|
||||
ObbFile::ObbFile()
|
||||
: mPackageName("")
|
||||
, mVersion(-1)
|
||||
, mFlags(0)
|
||||
{
|
||||
memset(mSalt, 0, sizeof(mSalt));
|
||||
}
|
||||
|
||||
ObbFile::~ObbFile() {
|
||||
@ -192,7 +195,7 @@ bool ObbFile::parseObbFile(int fd)
|
||||
|
||||
#ifdef DEBUG
|
||||
for (int i = 0; i < footerSize; ++i) {
|
||||
LOGI("char: 0x%02x", scanBuf[i]);
|
||||
LOGI("char: 0x%02x\n", scanBuf[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -206,6 +209,8 @@ bool ObbFile::parseObbFile(int fd)
|
||||
mVersion = (int32_t) get4LE((unsigned char*)scanBuf + kPackageVersionOffset);
|
||||
mFlags = (int32_t) get4LE((unsigned char*)scanBuf + kFlagsOffset);
|
||||
|
||||
memcpy(&mSalt, (unsigned char*)scanBuf + kSaltOffset, sizeof(mSalt));
|
||||
|
||||
uint32_t packageNameLen = get4LE((unsigned char*)scanBuf + kPackageNameLenOffset);
|
||||
if (packageNameLen <= 0
|
||||
|| packageNameLen > (footerSize - kPackageNameOffset)) {
|
||||
@ -255,7 +260,7 @@ bool ObbFile::writeTo(int fd)
|
||||
my_lseek64(fd, 0, SEEK_END);
|
||||
|
||||
if (mPackageName.size() == 0 || mVersion == -1) {
|
||||
LOGW("tried to write uninitialized ObbFile data");
|
||||
LOGW("tried to write uninitialized ObbFile data\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -264,43 +269,48 @@ bool ObbFile::writeTo(int fd)
|
||||
|
||||
put4LE(intBuf, kSigVersion);
|
||||
if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
|
||||
LOGW("couldn't write signature version: %s", strerror(errno));
|
||||
LOGW("couldn't write signature version: %s\n", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
put4LE(intBuf, mVersion);
|
||||
if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
|
||||
LOGW("couldn't write package version");
|
||||
LOGW("couldn't write package version\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
put4LE(intBuf, mFlags);
|
||||
if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
|
||||
LOGW("couldn't write package version");
|
||||
LOGW("couldn't write package version\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (write(fd, mSalt, sizeof(mSalt)) != (ssize_t)sizeof(mSalt)) {
|
||||
LOGW("couldn't write salt: %s\n", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t packageNameLen = mPackageName.size();
|
||||
put4LE(intBuf, packageNameLen);
|
||||
if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
|
||||
LOGW("couldn't write package name length: %s", strerror(errno));
|
||||
LOGW("couldn't write package name length: %s\n", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (write(fd, mPackageName.string(), packageNameLen) != (ssize_t)packageNameLen) {
|
||||
LOGW("couldn't write package name: %s", strerror(errno));
|
||||
LOGW("couldn't write package name: %s\n", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
put4LE(intBuf, kPackageNameOffset + packageNameLen);
|
||||
if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
|
||||
LOGW("couldn't write footer size: %s", strerror(errno));
|
||||
LOGW("couldn't write footer size: %s\n", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
put4LE(intBuf, kSignature);
|
||||
if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
|
||||
LOGW("couldn't write footer magic signature: %s", strerror(errno));
|
||||
LOGW("couldn't write footer magic signature: %s\n", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
@ -63,6 +64,10 @@ TEST_F(ObbFileTest, WriteThenRead) {
|
||||
|
||||
mObbFile->setPackageName(String8(packageName));
|
||||
mObbFile->setVersion(versionNum);
|
||||
#define SALT_SIZE 8
|
||||
unsigned char salt[SALT_SIZE] = {0x01, 0x10, 0x55, 0xAA, 0xFF, 0x00, 0x5A, 0xA5};
|
||||
EXPECT_TRUE(mObbFile->setSalt(salt, SALT_SIZE))
|
||||
<< "Salt should be successfully set";
|
||||
|
||||
EXPECT_TRUE(mObbFile->writeTo(mFileName))
|
||||
<< "couldn't write to fake .obb file";
|
||||
@ -77,6 +82,19 @@ TEST_F(ObbFileTest, WriteThenRead) {
|
||||
const char* currentPackageName = mObbFile->getPackageName().string();
|
||||
EXPECT_STREQ(packageName, currentPackageName)
|
||||
<< "package name didn't come out the same as it went in";
|
||||
|
||||
size_t saltLen;
|
||||
const unsigned char* newSalt = mObbFile->getSalt(&saltLen);
|
||||
|
||||
EXPECT_EQ(sizeof(salt), saltLen)
|
||||
<< "salt sizes were not the same";
|
||||
|
||||
for (int i = 0; i < sizeof(salt); i++) {
|
||||
EXPECT_EQ(salt[i], newSalt[i])
|
||||
<< "salt character " << i << " should be equal";
|
||||
}
|
||||
EXPECT_TRUE(memcmp(newSalt, salt, sizeof(salt)) == 0)
|
||||
<< "salts should be the same";
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user