Skip to content

Commit

Permalink
Add prefilled_data argument
Browse files Browse the repository at this point in the history
  • Loading branch information
XuJiandong committed Jan 9, 2024
1 parent 34d1920 commit b4b5bdd
Show file tree
Hide file tree
Showing 8 changed files with 321 additions and 291 deletions.
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ ALL_C_SOURCE := c/always_success.c \
c/auth.c \
c/auth_libecc.c \
c/ckb_hex.h \
c/ripple.h
c/ripple.h \
c/elf_setup.h

fmt:
clang-format -i $(ALL_C_SOURCE)
Expand Down
268 changes: 143 additions & 125 deletions c/auth.c

Large diffs are not rendered by default.

61 changes: 32 additions & 29 deletions c/auth_libecc.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,17 @@

#include "blake2b.h"
#undef CKB_SUCCESS
#include "elf_setup.h"
// clang-format on

int validate_signature_secp256r1(void *prefilled_data, const uint8_t *sig,
size_t sig_len, const uint8_t *msg,
size_t msg_len, uint8_t *output,
size_t *output_len) {
int validate_signature_secp256r1(uint8_t *prefilled_data, uint8_t algorithm_id,
const uint8_t *sig, size_t sig_len,
const uint8_t *msg, size_t msg_len,
uint8_t *out_pubkey_hash,
size_t pubkey_hash_len) {
int err = 0;

if (*output_len < AUTH160_SIZE) {
if (pubkey_hash_len < AUTH160_SIZE) {
return ERROR_INVALID_ARG;
}
CHECK2(msg_len == BLAKE2B_BLOCK_SIZE, ERROR_INVALID_ARG);
Expand All @@ -40,19 +42,20 @@ int validate_signature_secp256r1(void *prefilled_data, const uint8_t *sig,
blake2b_update(&ctx, pub_key_ptr, SECP256R1_PUBKEY_SIZE);
blake2b_final(&ctx, pubkey_hash, sizeof(pubkey_hash));

memcpy(output, pubkey_hash, AUTH160_SIZE);
*output_len = AUTH160_SIZE;
memcpy(out_pubkey_hash, pubkey_hash, AUTH160_SIZE);

exit:
return err;
}

int validate_signature_secp256r1_raw(void *prefilled_data, const uint8_t *sig,
int validate_signature_secp256r1_raw(uint8_t *prefilled_data,
uint8_t algorithm_id, const uint8_t *sig,
size_t sig_len, const uint8_t *msg,
size_t msg_len, uint8_t *output,
size_t *output_len) {
size_t msg_len, uint8_t *out_pubkey_hash,
size_t pubkey_hash_len) {
int err = 0;

if (*output_len < AUTH160_SIZE) {
if (pubkey_hash_len < AUTH160_SIZE) {
return ERROR_INVALID_ARG;
}
CHECK2(msg_len == BLAKE2B_BLOCK_SIZE, ERROR_INVALID_ARG);
Expand All @@ -70,8 +73,7 @@ int validate_signature_secp256r1_raw(void *prefilled_data, const uint8_t *sig,
blake2b_update(&ctx, pub_key_ptr, SECP256R1_PUBKEY_SIZE);
blake2b_final(&ctx, pubkey_hash, sizeof(pubkey_hash));

memcpy(output, pubkey_hash, AUTH160_SIZE);
*output_len = AUTH160_SIZE;
memcpy(out_pubkey_hash, pubkey_hash, AUTH160_SIZE);
exit:
return err;
}
Expand All @@ -84,19 +86,19 @@ int convert_copy(const uint8_t *msg, size_t msg_len, uint8_t *new_msg,
return 0;
}

static int verify(uint8_t *pubkey_hash, const uint8_t *sig, uint32_t sig_len,
const uint8_t *msg, uint32_t msg_len,
validate_signature_t func, convert_msg_t convert) {
static int verify_secp256r1(uint8_t *prefilled_data, uint8_t algorithm_id,
uint8_t *pubkey_hash, const uint8_t *sig,
size_t sig_len, const uint8_t *msg, size_t msg_len,
ckb_auth_validate_t func, convert_msg_t convert) {
int err = 0;
uint8_t new_msg[BLAKE2B_BLOCK_SIZE];

err = convert(msg, msg_len, new_msg, sizeof(new_msg));
CHECK(err);

uint8_t output_pubkey_hash[AUTH160_SIZE];
size_t output_len = AUTH160_SIZE;
err = func(NULL, sig, sig_len, new_msg, sizeof(new_msg), output_pubkey_hash,
&output_len);
err = func(prefilled_data, algorithm_id, sig, sig_len, new_msg,
sizeof(new_msg), output_pubkey_hash, AUTH160_SIZE);
CHECK(err);

int same = memcmp(pubkey_hash, output_pubkey_hash, AUTH160_SIZE);
Expand All @@ -108,23 +110,24 @@ static int verify(uint8_t *pubkey_hash, const uint8_t *sig, uint32_t sig_len,

// dynamic linking entry
__attribute__((visibility("default"))) int ckb_auth_validate(
uint8_t auth_algorithm_id, const uint8_t *signature,
uint32_t signature_size, const uint8_t *message, uint32_t message_size,
uint8_t *pubkey_hash, uint32_t pubkey_hash_size) {
uint8_t *prefilled_data, uint8_t algorithm_id, const uint8_t *signature,
size_t signature_size, const uint8_t *message, size_t message_size,
uint8_t *pubkey_hash, size_t pubkey_hash_size) {
int err = 0;
CHECK2(signature != NULL, ERROR_INVALID_ARG);
CHECK2(message != NULL, ERROR_INVALID_ARG);
CHECK2(message_size > 0, ERROR_INVALID_ARG);
CHECK2(pubkey_hash_size == AUTH160_SIZE, ERROR_INVALID_ARG);

if (auth_algorithm_id == AuthAlgorithmIdSecp256R1) {
err = verify(pubkey_hash, signature, signature_size, message,
message_size, validate_signature_secp256r1, convert_copy);
if (algorithm_id == AuthAlgorithmIdSecp256R1) {
err = verify_secp256r1(prefilled_data, algorithm_id, pubkey_hash,
signature, signature_size, message, message_size,
validate_signature_secp256r1, convert_copy);
CHECK(err);
} else if (auth_algorithm_id == AuthAlgorithmIdSecp256R1Raw) {
err = verify(pubkey_hash, signature, signature_size, message,
message_size, validate_signature_secp256r1_raw,
convert_copy);
} else if (algorithm_id == AuthAlgorithmIdSecp256R1Raw) {
err = verify_secp256r1(prefilled_data, algorithm_id, pubkey_hash,
signature, signature_size, message, message_size,
validate_signature_secp256r1_raw, convert_copy);
CHECK(err);
} else {
CHECK2(false, ERROR_NOT_IMPLEMENTED);
Expand Down
135 changes: 13 additions & 122 deletions c/ckb_auth.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,6 @@
#define AUTH160_SIZE 20
#define BLAKE2B_BLOCK_SIZE 32

#define OFFSETOF(TYPE, ELEMENT) ((size_t) & (((TYPE *)0)->ELEMENT))
#define PT_DYNAMIC 2

/* See https://docs.oracle.com/cd/E23824_01/html/819-0690/chapter6-42444.html
* for details */
#define DT_RELA 7
#define DT_RELACOUNT 0x6ffffff9
#define DT_JMPREL 23
#define DT_PLTRELSZ 2
#define DT_PLTREL 20
#define DT_SYMTAB 6
#define DT_SYMENT 11

enum AuthErrorCodeType {
ERROR_NOT_IMPLEMENTED = 100,
ERROR_MISMATCHED,
Expand Down Expand Up @@ -105,20 +92,13 @@ enum AuthAlgorithmIdType {
AuthAlgorithmIdOwnerLock = 0xFC,
};

typedef int (*validate_signature_t)(void *prefilled_data, const uint8_t *sig,
size_t sig_len, const uint8_t *msg,
size_t msg_len, uint8_t *output,
size_t *output_len);

typedef int (*convert_msg_t)(const uint8_t *msg, size_t msg_len,
uint8_t *new_msg, size_t new_msg_len);

typedef int (*ckb_auth_validate_t)(uint8_t auth_algorithm_id,
const uint8_t *signature,
uint32_t signature_size,
const uint8_t *message,
uint32_t message_size, uint8_t *pubkey_hash,
uint32_t pubkey_hash_size);
typedef int (*ckb_auth_validate_t)(
uint8_t *prefilled_data, uint8_t auth_algorithm_id,
const uint8_t *signature, size_t signature_size, const uint8_t *message,
size_t message_size, uint8_t *out_pubkey_hash, size_t pubkey_hash_size);

#ifndef CKB_AUTH_DISABLE_DYNAMIC_LIB

Expand Down Expand Up @@ -196,8 +176,9 @@ int get_dl_func_by_code_hash(const uint8_t *code_hash, uint8_t hash_type,

#endif // CKB_AUTH_DISABLE_DYNAMIC_LIB

int ckb_auth(CkbEntryType *entry, CkbAuthType *id, const uint8_t *signature,
uint32_t signature_size, const uint8_t *message32) {
int ckb_auth(uint8_t *prefilled_data, CkbEntryType *entry, CkbAuthType *id,
const uint8_t *signature, uint32_t signature_size,
const uint8_t *message32) {
int err = 0;
if (entry->entry_category == EntryCategoryDynamicLibrary) {
#ifdef CKB_AUTH_DISABLE_DYNAMIC_LIB
Expand All @@ -210,8 +191,8 @@ int ckb_auth(CkbEntryType *entry, CkbAuthType *id, const uint8_t *signature,
if (err) {
return err;
}
return func(id->algorithm_id, signature, signature_size, message32,
BLAKE2B_BLOCK_SIZE, id->content, AUTH160_SIZE);
return func(prefilled_data, id->algorithm_id, signature, signature_size,
message32, BLAKE2B_BLOCK_SIZE, id->content, AUTH160_SIZE);
#endif // CKB_AUTH_DISABLE_DYNAMIC_LIB
} else if (entry->entry_category == EntryCategoryExec ||
entry->entry_category == EntryCategorySpawn) {
Expand Down Expand Up @@ -265,98 +246,6 @@ int ckb_auth(CkbEntryType *entry, CkbAuthType *id, const uint8_t *signature,
}
}

int setup_elf() {
// fix error:
// c/auth.c:810:50: error: array subscript 0 is outside array bounds of
// 'uint64_t[0]' {aka 'long unsigned int[]'} [-Werror=array-bounds]
// 810 | Elf64_Phdr *program_headers = (Elf64_Phdr *)(*phoff);
// | ~^~~~~~~
#if defined(__GNUC__) && (__GNUC__ >= 12)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Warray-bounds"
#endif
uint64_t *phoff = (uint64_t *)OFFSETOF(Elf64_Ehdr, e_phoff);
uint16_t *phnum = (uint16_t *)OFFSETOF(Elf64_Ehdr, e_phnum);
Elf64_Phdr *program_headers = (Elf64_Phdr *)(*phoff);

for (int i = 0; i < *phnum; i++) {
Elf64_Phdr *program_header = &program_headers[i];
if (program_header->p_type == PT_DYNAMIC) {
Elf64_Dynamic *d = (Elf64_Dynamic *)program_header->p_vaddr;
uint64_t rela_address = 0;
uint64_t rela_count = 0;
uint64_t jmprel_address = 0;
uint64_t pltrel_size = 0;
uint64_t pltrel = 0;
uint64_t symtab_address = 0;
uint64_t symtab_entry_size = 0;
while (d->type != 0) {
switch (d->type) {
case DT_RELA:
rela_address = d->value;
break;
case DT_RELACOUNT:
rela_count = d->value;
break;
case DT_JMPREL:
jmprel_address = d->value;
break;
case DT_PLTRELSZ:
pltrel_size = d->value;
break;
case DT_PLTREL:
pltrel = d->value;
break;
case DT_SYMTAB:
symtab_address = d->value;
break;
case DT_SYMENT:
symtab_entry_size = d->value;
break;
}
d++;
}
if (rela_address > 0 && rela_count > 0) {
Elf64_Rela *relocations = (Elf64_Rela *)rela_address;
for (int j = 0; j < rela_count; j++) {
Elf64_Rela *relocation = &relocations[j];
if (relocation->r_info != R_RISCV_RELATIVE) {
return ERROR_INVALID_ELF;
}
*((uint64_t *)(relocation->r_offset)) =
(uint64_t)(relocation->r_addend);
}
}
if (jmprel_address > 0 && pltrel_size > 0 && pltrel == DT_RELA &&
symtab_address > 0) {
if (pltrel_size % sizeof(Elf64_Rela) != 0) {
return ERROR_INVALID_ELF;
}
if (symtab_entry_size != sizeof(Elf64_Sym)) {
return ERROR_INVALID_ELF;
}
Elf64_Rela *relocations = (Elf64_Rela *)jmprel_address;
Elf64_Sym *symbols = (Elf64_Sym *)symtab_address;
for (int j = 0; j < pltrel_size / sizeof(Elf64_Rela); j++) {
Elf64_Rela *relocation = &relocations[j];
uint32_t idx = (uint32_t)(relocation->r_info >> 32);
uint32_t t = (uint32_t)relocation->r_info;
if (t != R_RISCV_JUMP_SLOT) {
return ERROR_INVALID_ELF;
}
Elf64_Sym *sym = &symbols[idx];
*((uint64_t *)(relocation->r_offset)) = sym->st_value;
}
}
}
}

return 0;
#if defined(__GNUC__) && (__GNUC__ >= 12)
#pragma GCC diagnostic pop
#endif
}

static int ckb_auth_validate_with_func(int argc, char *argv[],
ckb_auth_validate_t validate_func) {
int err = 0;
Expand Down Expand Up @@ -413,8 +302,10 @@ static int ckb_auth_validate_with_func(int argc, char *argv[],
pubkey_hash_len == AUTH160_SIZE,
ERROR_SPAWN_INVALID_PUBKEY);

err = validate_func(algorithm_id, signature, signature_len, message,
message_len, pubkey_hash, pubkey_hash_len);
// TODO: load prefilled data when in entry of exec/spawn
err = validate_func(NULL, algorithm_id, signature, (size_t)signature_len,
message, (size_t)message_len, pubkey_hash,
(size_t)pubkey_hash_len);
CHECK(err);

exit:
Expand Down
Loading

0 comments on commit b4b5bdd

Please sign in to comment.