From 95a68893125105f131ee1b4eaef1dc16da1ef789 Mon Sep 17 00:00:00 2001 From: Kenny Root Date: Wed, 13 Oct 2010 15:00:07 -0700 Subject: [PATCH] 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 --- include/utils/ObbFile.h | 27 +++++++++++++++++++ libs/utils/ObbFile.cpp | 44 +++++++++++++++++++------------ libs/utils/tests/ObbFile_test.cpp | 18 +++++++++++++ 3 files changed, 72 insertions(+), 17 deletions(-) diff --git a/include/utils/ObbFile.h b/include/utils/ObbFile.h index 5243f5005..47559cdd0 100644 --- a/include/utils/ObbFile.h +++ b/include/utils/ObbFile.h @@ -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; diff --git a/libs/utils/ObbFile.cpp b/libs/utils/ObbFile.cpp index e170ab88c..2c3724c0a 100644 --- a/libs/utils/ObbFile.cpp +++ b/libs/utils/ObbFile.cpp @@ -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; } diff --git a/libs/utils/tests/ObbFile_test.cpp b/libs/utils/tests/ObbFile_test.cpp index 29bb70a66..46b30c2a6 100644 --- a/libs/utils/tests/ObbFile_test.cpp +++ b/libs/utils/tests/ObbFile_test.cpp @@ -23,6 +23,7 @@ #include #include +#include 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"; } }