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:
Kenny Root 2010-10-13 15:00:07 -07:00
parent 91a2e55166
commit 95a6889312
3 changed files with 72 additions and 17 deletions

View File

@ -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;

View File

@ -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;
}

View File

@ -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";
}
}