kernel: Refactor manager apk check method
- When we have multiple apk sign keys available, just add to `apk_sign_keys`. - Check all apk sign keys in one open file without opening the file repeatedly.
This commit is contained in:
@@ -17,13 +17,24 @@
|
|||||||
#include "apk_sign.h"
|
#include "apk_sign.h"
|
||||||
#include "klog.h" // IWYU pragma: keep
|
#include "klog.h" // IWYU pragma: keep
|
||||||
#include "kernel_compat.h"
|
#include "kernel_compat.h"
|
||||||
|
#include "manager_sign.h"
|
||||||
|
|
||||||
struct sdesc {
|
struct sdesc {
|
||||||
struct shash_desc shash;
|
struct shash_desc shash;
|
||||||
char ctx[];
|
char ctx[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct apk_sign_key {
|
||||||
|
unsigned size;
|
||||||
|
const char *sha256;
|
||||||
|
} apk_sign_keys[] = {
|
||||||
|
{EXPECTED_SIZE, EXPECTED_HASH}, // Official
|
||||||
|
{EXPECTED_SIZE_RSUNTK, EXPECTED_HASH_RSUNTK}, // RKSU
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)
|
||||||
|
{EXPECTED_SIZE_5EC1CFF, EXPECTED_HASH_5EC1CFF}, // MKSU
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
static struct sdesc *init_sdesc(struct crypto_shash *alg)
|
static struct sdesc *init_sdesc(struct crypto_shash *alg)
|
||||||
{
|
{
|
||||||
struct sdesc *sdesc;
|
struct sdesc *sdesc;
|
||||||
@@ -71,9 +82,11 @@ static int ksu_sha256(const unsigned char *data, unsigned int datalen,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool check_block(struct file *fp, u32 *size4, loff_t *pos, u32 *offset,
|
static bool check_block(struct file *fp, u32 *size4, loff_t *pos, u32 *offset)
|
||||||
unsigned expected_size, const char *expected_sha256)
|
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
struct apk_sign_key sign_key;
|
||||||
|
|
||||||
ksu_kernel_read_compat(fp, size4, 0x4, pos); // signer-sequence length
|
ksu_kernel_read_compat(fp, size4, 0x4, pos); // signer-sequence length
|
||||||
ksu_kernel_read_compat(fp, size4, 0x4, pos); // signer length
|
ksu_kernel_read_compat(fp, size4, 0x4, pos); // signer length
|
||||||
ksu_kernel_read_compat(fp, size4, 0x4, pos); // signed data length
|
ksu_kernel_read_compat(fp, size4, 0x4, pos); // signed data length
|
||||||
@@ -89,7 +102,11 @@ static bool check_block(struct file *fp, u32 *size4, loff_t *pos, u32 *offset,
|
|||||||
ksu_kernel_read_compat(fp, size4, 0x4, pos); // certificate length
|
ksu_kernel_read_compat(fp, size4, 0x4, pos); // certificate length
|
||||||
*offset += 0x4 * 2;
|
*offset += 0x4 * 2;
|
||||||
|
|
||||||
if (*size4 == expected_size) {
|
for (i = 0; i < ARRAY_SIZE(apk_sign_keys); i++) {
|
||||||
|
sign_key = apk_sign_keys[i];
|
||||||
|
|
||||||
|
if (*size4 != sign_key.size)
|
||||||
|
continue;
|
||||||
*offset += *size4;
|
*offset += *size4;
|
||||||
|
|
||||||
#define CERT_MAX_LENGTH 1024
|
#define CERT_MAX_LENGTH 1024
|
||||||
@@ -110,8 +127,8 @@ static bool check_block(struct file *fp, u32 *size4, loff_t *pos, u32 *offset,
|
|||||||
|
|
||||||
bin2hex(hash_str, digest, SHA256_DIGEST_SIZE);
|
bin2hex(hash_str, digest, SHA256_DIGEST_SIZE);
|
||||||
pr_info("sha256: %s, expected: %s\n", hash_str,
|
pr_info("sha256: %s, expected: %s\n", hash_str,
|
||||||
expected_sha256);
|
sign_key.sha256);
|
||||||
if (strcmp(expected_sha256, hash_str) == 0) {
|
if (strcmp(sign_key.sha256, hash_str) == 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -171,9 +188,7 @@ static bool has_v1_signature_file(struct file *fp)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __always_inline bool check_v2_signature(char *path,
|
static __always_inline bool check_v2_signature(char *path)
|
||||||
unsigned expected_size,
|
|
||||||
const char *expected_sha256)
|
|
||||||
{
|
{
|
||||||
unsigned char buffer[0x11] = { 0 };
|
unsigned char buffer[0x11] = { 0 };
|
||||||
u32 size4;
|
u32 size4;
|
||||||
@@ -244,9 +259,7 @@ static __always_inline bool check_v2_signature(char *path,
|
|||||||
offset = 4;
|
offset = 4;
|
||||||
if (id == 0x7109871au) {
|
if (id == 0x7109871au) {
|
||||||
v2_signing_blocks++;
|
v2_signing_blocks++;
|
||||||
v2_signing_valid =
|
v2_signing_valid = check_block(fp, &size4, &pos, &offset);
|
||||||
check_block(fp, &size4, &pos, &offset,
|
|
||||||
expected_size, expected_sha256);
|
|
||||||
} else if (id == 0xf05368c0u) {
|
} else if (id == 0xf05368c0u) {
|
||||||
// http://aospxref.com/android-14.0.0_r2/xref/frameworks/base/core/java/android/util/apk/ApkSignatureSchemeV3Verifier.java#73
|
// http://aospxref.com/android-14.0.0_r2/xref/frameworks/base/core/java/android/util/apk/ApkSignatureSchemeV3Verifier.java#73
|
||||||
v3_signing_exist = true;
|
v3_signing_exist = true;
|
||||||
|
|||||||
Reference in New Issue
Block a user