From 759e4b65f6f679a32ea023fbc726b2d444bd3ad9 Mon Sep 17 00:00:00 2001 From: Yilong Wang <2548340423@qq.com> Date: Wed, 21 Aug 2024 20:38:23 +0800 Subject: [PATCH] add SBI_GENERATE_KEY_PAIR_AND_SIGNATURE --- opensbi-1.2/include/sm/attest.h | 2 + opensbi-1.2/include/sm/enclave.h | 2 + opensbi-1.2/include/sm/sm.h | 4 ++ opensbi-1.2/lib/sbi/sbi_ecall_penglai.c | 3 ++ opensbi-1.2/lib/sbi/sm/attest.c | 22 +++++++++- opensbi-1.2/lib/sbi/sm/enclave.c | 55 +++++++++++++++++++++++++ opensbi-1.2/lib/sbi/sm/sm.c | 20 ++++++++- 7 files changed, 106 insertions(+), 2 deletions(-) diff --git a/opensbi-1.2/include/sm/attest.h b/opensbi-1.2/include/sm/attest.h index 84f494988..9d1bebba5 100644 --- a/opensbi-1.2/include/sm/attest.h +++ b/opensbi-1.2/include/sm/attest.h @@ -13,4 +13,6 @@ void sign_enclave(void* signature, unsigned char *message, int len); int verify_enclave(void* signature, unsigned char *message, int len); +void generate_key_pair_and_sigature(void *pri_key_arg, void *pub_key_arg, void *signature_arg); + #endif /* _ATTEST_H */ diff --git a/opensbi-1.2/include/sm/enclave.h b/opensbi-1.2/include/sm/enclave.h index 0d0969ae5..069045b39 100644 --- a/opensbi-1.2/include/sm/enclave.h +++ b/opensbi-1.2/include/sm/enclave.h @@ -109,6 +109,8 @@ uintptr_t enclave_sys_write(uintptr_t *regs); uintptr_t enclave_user_defined_ocall(uintptr_t *regs, uintptr_t ocall_buf_size); uintptr_t enclave_derive_seal_key(uintptr_t* regs, uintptr_t salt_va, uintptr_t salt_len, uintptr_t key_buf_va, uintptr_t key_buf_len); +uintptr_t enclave_generate_key_pair_and_signature(uintptr_t* regs, uintptr_t pri_key_va, + uintptr_t pub_key_va, uintptr_t signature_va); int check_in_enclave_world(); diff --git a/opensbi-1.2/include/sm/sm.h b/opensbi-1.2/include/sm/sm.h index d4f1d8d5b..66ff74d4a 100644 --- a/opensbi-1.2/include/sm/sm.h +++ b/opensbi-1.2/include/sm/sm.h @@ -36,6 +36,7 @@ extern uintptr_t _fw_start[], _fw_end[]; #define SBI_EXIT_ENCLAVE 99 #define SBI_ENCLAVE_OCALL 98 #define SBI_GET_KEY 88 +#define SBI_GENERATE_KEY_PAIR_AND_SIGNATURE 87 //Error code of SBI_ALLOC_ENCLAVE_MEM #define RETRY_SPIN_LOCK -3 @@ -92,6 +93,9 @@ uintptr_t sm_enclave_ocall(uintptr_t *regs, uintptr_t ocall_func_id, uintptr_t a uintptr_t sm_enclave_get_key(uintptr_t* regs, uintptr_t salt_va, uintptr_t salt_len, uintptr_t key_buf_va, uintptr_t key_buf_len); +uintptr_t sm_enclave_generate_key_pair_and_signature(uintptr_t *regs, uintptr_t pri_key_va, + uintptr_t pub_key_va, uintptr_t signature_va); + uintptr_t sm_exit_enclave(uintptr_t *regs, unsigned long retval); uintptr_t sm_do_timer_irq(uintptr_t *regs, uintptr_t mcause, uintptr_t mepc); diff --git a/opensbi-1.2/lib/sbi/sbi_ecall_penglai.c b/opensbi-1.2/lib/sbi/sbi_ecall_penglai.c index 2834e36f0..43d9d79a9 100644 --- a/opensbi-1.2/lib/sbi/sbi_ecall_penglai.c +++ b/opensbi-1.2/lib/sbi/sbi_ecall_penglai.c @@ -101,6 +101,9 @@ static int sbi_ecall_penglai_enclave_handler(unsigned long extid, unsigned long case SBI_GET_KEY://88 ret = sm_enclave_get_key((uintptr_t *)regs, regs->a0, regs->a1, regs->a2, regs->a3); break; + case SBI_GENERATE_KEY_PAIR_AND_SIGNATURE://87 + ret = sm_enclave_generate_key_pair_and_signature((uintptr_t *)regs, regs->a0, regs->a1, regs->a2); + break; default: sbi_printf("[Penglai@Monitor] enclave interface(funcid:%ld) not supported yet\n", funcid); ret = SBI_ENOTSUPP; diff --git a/opensbi-1.2/lib/sbi/sm/attest.c b/opensbi-1.2/lib/sbi/sm/attest.c index 2d959fcd9..7d89e3ff5 100644 --- a/opensbi-1.2/lib/sbi/sm/attest.c +++ b/opensbi-1.2/lib/sbi/sm/attest.c @@ -125,11 +125,31 @@ void attest_init() printm("SM2_KeyGeneration failed with ret value: %d\n", i); } +void generate_key_pair_and_sigature(void *pri_key_arg, void *pub_key_arg, void *signature_arg) +{ + int i; + struct prikey_t *pri_key = (struct prikey_t *)pri_key_arg; + struct pubkey_t *pub_key = (struct pubkey_t *)pub_key_arg; + struct signature_t *signature = (struct signature_t*)signature_arg; + struct prikey_t *sm_prikey = (struct prikey_t *)SM_PRI_KEY; + + i = SM2_Init(); + if(i) + printm("SM2_Init failed with ret value: %d\n", i); + + i = SM2_KeyGeneration(pri_key->dA, pub_key->xA, pub_key->yA); + if(i) + printm("SM2_KeyGeneration failed with ret value: %d\n", i); + + SM2_Sign((void *)pub_key, SIGNATURE_SIZE, sm_prikey->dA, (unsigned char *)(signature->r), + (unsigned char *)(signature->s)); +} + void sign_enclave(void* signature_arg, unsigned char *message, int len) { struct signature_t *signature = (struct signature_t*)signature_arg; struct prikey_t *sm_prikey = (struct prikey_t *)SM_PRI_KEY; - + SM2_Sign(message, len, sm_prikey->dA, (unsigned char *)(signature->r), (unsigned char *)(signature->s)); } diff --git a/opensbi-1.2/lib/sbi/sm/enclave.c b/opensbi-1.2/lib/sbi/sm/enclave.c index b7303151a..af31741d0 100644 --- a/opensbi-1.2/lib/sbi/sm/enclave.c +++ b/opensbi-1.2/lib/sbi/sm/enclave.c @@ -1124,3 +1124,58 @@ uintptr_t resume_from_ocall(uintptr_t* regs, unsigned int eid) retval = resume_enclave(regs, eid); return retval; } + +uintptr_t enclave_generate_key_pair_and_signature(uintptr_t* regs, uintptr_t pri_key_va, uintptr_t pub_key_va, uintptr_t signature_va) +{ + uintptr_t ret = 0; + int eid = get_enclave_id(); + struct enclave_t *enclave = NULL; + + pte_t *enclave_root_pt; + unsigned char pri_key[PRIVATE_KEY_SIZE]; + unsigned char pub_key[PUBLIC_KEY_SIZE]; + unsigned char signature[SIGNATURE_SIZE]; + + if(check_in_enclave_world() < 0) + { + printm_err("[Penglai Monitor@%s] check enclave world is failed\n", __func__); + return -1; + } + + enclave = get_enclave(eid); + + spin_lock(&enclave_metadata_lock); + + if(!enclave || check_enclave_authentication(enclave)!=0 || enclave->state != RUNNING) + { + ret = -1UL; + printm_err("[Penglai Monitor@%s] check enclave authentication is failed\n", __func__); + goto out; + } + + generate_key_pair_and_sigature(pri_key, pub_key, signature); + + enclave_root_pt = (pte_t*)(enclave->thread_context.encl_ptbr << RISCV_PGSHIFT); + ret = copy_to_enclave(enclave_root_pt, (void *)signature_va, signature, SIGNATURE_SIZE); + if(ret != 0){ + ret = -1UL; + printm_err("[Penglai Monitor@%s] unknown error happended when copy to enclave\n", __func__); + goto out; + } + ret = copy_to_enclave(enclave_root_pt, (void *)pri_key_va, pri_key, PRIVATE_KEY_SIZE); + if(ret != 0){ + ret = -1UL; + printm_err("[Penglai Monitor@%s] unknown error happended when copy to enclave\n", __func__); + goto out; + } + ret = copy_to_enclave(enclave_root_pt, (void *)pub_key_va, pub_key, PUBLIC_KEY_SIZE); + if(ret != 0){ + ret = -1UL; + printm_err("[Penglai Monitor@%s] unknown error happended when copy to enclave\n", __func__); + goto out; + } + +out: + spin_unlock(&enclave_metadata_lock); + return ret; +} diff --git a/opensbi-1.2/lib/sbi/sm/sm.c b/opensbi-1.2/lib/sbi/sm/sm.c index dd4b4f2f0..49b63e4b5 100644 --- a/opensbi-1.2/lib/sbi/sm/sm.c +++ b/opensbi-1.2/lib/sbi/sm/sm.c @@ -303,6 +303,24 @@ uintptr_t sm_enclave_get_key(uintptr_t *regs, uintptr_t salt_va, return ret; } +/** + * \brief generate key pair and signed the pub key with sm private key. + * + * \param regs The enclave regs + * \param pri_key_va The private key pointer in enclave address space + * \param pub_key_va The public key pointer in enclave address space + * \param signature_va The signature pointer in enclave address space + */ +uintptr_t sm_enclave_generate_key_pair_and_signature(uintptr_t *regs, + uintptr_t pri_key_va, uintptr_t pub_key_va, uintptr_t signature_va) +{ + uintptr_t ret = 0; + + ret = enclave_generate_key_pair_and_signature(regs, pri_key_va, pub_key_va, signature_va); + + return ret; +} + /** * \brief This transitional function is used to destroy the enclave. * @@ -387,4 +405,4 @@ uintptr_t sm_free_enclave_mem(uintptr_t size_ptr, unsigned long flag) copy_to_host((void *)size_ptr, (void *)(&size), sizeof(unsigned long)); return ret; -} \ No newline at end of file +}