diff --git a/README.en.md b/README.en.md deleted file mode 100644 index 27837bbac13bbf1ed1a892c00a3bcc3a784443d0..0000000000000000000000000000000000000000 --- a/README.en.md +++ /dev/null @@ -1,36 +0,0 @@ -# pyuadk - -#### Description -python wrapper of uadk - -#### Software Architecture -Software architecture description - -#### Installation - -1. xxxx -2. xxxx -3. xxxx - -#### Instructions - -1. xxxx -2. xxxx -3. xxxx - -#### Contribution - -1. Fork the repository -2. Create Feat_xxx branch -3. Commit your code -4. Create Pull Request - - -#### Gitee Feature - -1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md -2. Gitee blog [blog.gitee.com](https://blog.gitee.com) -3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) -4. The most valuable open source project [GVP](https://gitee.com/gvp) -5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) -6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/README.md b/README.md deleted file mode 100644 index d7aab375a7d441c2d9714843ec27e7100f94111c..0000000000000000000000000000000000000000 --- a/README.md +++ /dev/null @@ -1,37 +0,0 @@ -# pyuadk - -#### 介绍 -python wrapper of uadk - -#### 软件架构 -软件架构说明 - - -#### 安装教程 - -1. xxxx -2. xxxx -3. xxxx - -#### 使用说明 - -1. xxxx -2. xxxx -3. xxxx - -#### 参与贡献 - -1. Fork 本仓库 -2. 新建 Feat_xxx 分支 -3. 提交代码 -4. 新建 Pull Request - - -#### 特技 - -1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md -2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) -3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 -4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 -5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) -6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/pyuadk/cwd.pxd b/pyuadk/cwd.pxd new file mode 100644 index 0000000000000000000000000000000000000000..5b7d9603ca89bf738c7b84221e236068ec778f26 --- /dev/null +++ b/pyuadk/cwd.pxd @@ -0,0 +1,96 @@ + + +ctypedef unsigned int __u32 +ctypedef unsigned int __u8 + +cdef extern from "../uadk/v1/wd.h": + + ctypedef void (*wcrypto_cb)(const void *msg, void *tag); + + ctypedef void (*wd_log)(const char *formatt, ...); + + # memory APIs for Algorithm Layer + ctypedef void *(*wd_alloc)(void *usr, size_t size); + ctypedef void (*wd_free)(void *usr, void *va); + + # memory VA to DMA address map + ctypedef void *(*wd_map)(void *usr, void *va, size_t sz); + ctypedef void (*wd_unmap)(void *usr, void *va, void *dma, size_t sz); + ctypedef __u32 (*wd_bufsize)(void *usr); + + cdef wd_log log_out + + cdef struct wcrypto_cb_tag: + pass + ctypedef wcrypto_cb_tag wcrypto_cb_tag_t + + cdef struct wcrypto_oaras: + pass + ctypedef wcrypto_oaras wcrypto_oaras_t + + # a enum have 2 value + cdef enum wd_buff_type: + WD_FLAT_BUF = 0, + WD_SGL_BUF = 1 + ctypedef wd_buff_type wd_buff_type_t + + cdef struct wcrypto_paras: + __u8 direction, + __u8 is_poll + + cdef enum wcrypto_type: + WCRYPTO_RSA = 0, + WCRYPTO_CIPHER = 1, + WCRYPTO_DIGEST = 2, + ctypedef wcrypto_type wcrypto_type_t + + cdef struct wd_dtb: + char *data # data buffer start address + __u32 dsize # data size + __u32 bsize # buffer size + ctypedef wd_dtb wd_dtb_t + + # Memory from user, it is given at ctx creating. + cdef struct wd_mm_br: + wd_alloc alloc # emory allocation + wd_free free # Memory free + wd_map iova_map # get iova from user space VA + + # destroy the mapping between the PA of VA and iova + wd_unmap iova_unmap; + void *usr; + # data for the above operations + wd_bufsize get_bufsize # optional + ctypedef wd_mm_br wd_mm_br_t + + # capabilities + cdef struct wd_capa: + const char *alg + int throughput + int latency + __u32 flags + wcrypto_paras priv + + ctypedef wd_capa wd_capa_t + + cdef struct wd_queue: + wd_capa capa + char *dev_path + __u32 node_mask + void *qinfo + ctypedef wd_queue wd_queue_t + + int wd_request_queue(wd_queue *q) + void wd_release_queue(wd_queue *q) + int wd_send(wd_queue *q, void *req) + int wd_recv(wd_queue *q, void **resp) + int wd_wait(wd_queue *q, short ms) + int wd_recv_sync(wd_queue *q, void **resp, short ms) + void * wd_reserve_memory(wd_queue *q, size_t size) + int wd_share_reserved_memory(wd_queue *q, wd_queue *target_q) + int wd_get_available_dev_num(const char *alg_name) + int wd_get_node_id(wd_queue *q) + void * wd_iova_map(wd_queue *q, void *va, size_t sz) + void wd_iova_unmap(wd_queue *q, void *va, void *dma, size_t sz) + void * wd_dma_to_va(wd_queue *q, void *dma) + int wd_register_log(wd_log log) diff --git a/pyuadk/cwd_bmm.pxd b/pyuadk/cwd_bmm.pxd new file mode 100644 index 0000000000000000000000000000000000000000..94a26f5438ce9b0fa2ab12f9f5fa0d84bdccca8d --- /dev/null +++ b/pyuadk/cwd_bmm.pxd @@ -0,0 +1,26 @@ +cimport cwd + +ctypedef unsigned int __u32 + +cdef extern from "../uadk/v1/wd_bmm.h": + # Memory pool creating parameters + cdef struct wd_blkpool_setup: + __u32 block_size # Block buffer size + __u32 block_num # Block buffer number + __u32 align_size # Block buffer starting address align size + cwd.wd_mm_br br # memory from user if don't use WD memory + ctypedef wd_blkpool_setup wd_blkpool_setup_t + + cdef struct wd_blkpool: + pass + + cdef void *wd_blkpool_create(cwd.wd_queue *q, + wd_blkpool_setup *setup) + cdef void wd_blkpool_destroy(void *pool) + cdef void *wd_alloc_blk(void *pool) + cdef void wd_free_blk(void *pool, void *blk) + cdef int wd_get_free_blk_num(void *pool, __u32 *free_num) + cdef int wd_blk_alloc_failures(void *pool, __u32 *fail_num) + cdef void *wd_blk_iova_map(void *pool, void *blk) + cdef void wd_blk_iova_unmap(void *pool, void *blk_dma, void *blk) + cdef __u32 wd_blksize(void *pool) diff --git a/pyuadk/cwd_cipher.pxd b/pyuadk/cwd_cipher.pxd new file mode 100644 index 0000000000000000000000000000000000000000..b24711964c69044b2d41e16d3e66219b380fd428 --- /dev/null +++ b/pyuadk/cwd_cipher.pxd @@ -0,0 +1,82 @@ +cimport cwd + +ctypedef unsigned char __u8 +ctypedef unsigned short __u16 +ctypedef unsigned int __u32 +ctypedef unsigned long long __u64 + +cdef extern from "../uadk/v1/wd_cipher.h": + cdef enum wcrypto_cipher_op_type: + WCRYPTO_CIPHER_ENCRYPTION + WCRYPTO_CIPHER_DECRYPTION + ctypedef wcrypto_cipher_op_type wcrypto_cipher_op_type_t + + cdef enum wcrypto_cipher_alg: + WCRYPTO_CIPHER_SM4 + WCRYPTO_CIPHER_AES + WCRYPTO_CIPHER_DES + WCRYPTO_CIPHER_3DES + ctypedef wcrypto_cipher_alg wcrypto_cipher_alg_t + + cdef enum wcrypto_cipher_mode: + WCRYPTO_CIPHER_ECB + WCRYPTO_CIPHER_CBC + WCRYPTO_CIPHER_CTR + WCRYPTO_CIPHER_XTS + WCRYPTO_CIPHER_OFB + WCRYPTO_CIPHER_CFB + WCRYPTO_CIPHER_CCM + WCRYPTO_CIPHER_GCM + ctypedef wcrypto_cipher_mode wcrypto_cipher_mode_t + + cdef struct wcrypto_cipher_ctx_setup: + cwd.wcrypto_cb cb + wcrypto_cipher_alg alg + wcrypto_cipher_mode mode + cwd.wd_mm_br br + __u16 data_fmt + ctypedef wcrypto_cipher_ctx_setup wcrypto_cipher_ctx_setup_t + + cdef struct wcrypto_cipher_op_data: + wcrypto_cipher_op_type op_type + int status + void *in_ "in", + void *out_ "out", + void *iv, + __u32 in_bytes, + __u32 out_bytes, + __u32 iv_bytes, + void* priv + ctypedef wcrypto_cipher_op_data wcrypto_cipher_op_data_t + + cdef struct wcrypto_cipher_msg: + __u8 algo_type, + __u8 alg, + __u8 op_type, + __u8 mode, + __u8 data_fmt, + __u8 result, + + __u16 key_bytes, + __u16 iv_bytes, + __u32 in_bytes, + __u32 out_bytes, + + __u8 *key, + __u8 *iv, + __u8 *in_, + __u8 *out_, + __u64 usr_data + ctypedef wcrypto_cipher_msg wcrypto_cipher_msg_t + + cdef struct wcrypto_cipher_tag: + void *ctx + int thread_id + int cnt + + cdef void *wcrypto_create_cipher_ctx(cwd.wd_queue *q, wcrypto_cipher_ctx_setup *setup) + cdef int wcrypto_set_cipher_key(void *ctx, __u8 *key, __u16 key_len) + cdef int wcrypto_do_cipher(void *ctx, wcrypto_cipher_op_data *opdata, void *tag) + cdef int wcrypto_cipher_poll(cwd.wd_queue *q, __u32 num) + cdef void wcrypto_del_cipher_ctx(void *ctx) + cdef int wcrypto_burst_cipher(void* ctx, wcrypto_cipher_op_data **opdata, void **tag, __u32 num) diff --git a/pyuadk/cwd_digest.pxd b/pyuadk/cwd_digest.pxd new file mode 100644 index 0000000000000000000000000000000000000000..b4a93c22b9ef977ebbf64121ead0561a87378e74 --- /dev/null +++ b/pyuadk/cwd_digest.pxd @@ -0,0 +1,72 @@ +ctypedef unsigned int __u32 +ctypedef unsigned short __u16 +ctypedef unsigned char __u8 +ctypedef unsigned long long __u64 + +cimport cwd +cdef extern from "../uadk/v1/wd_digest.h": + + cdef enum wcrypto_digest_alg: + WCRYPTO_SM3 + WCRYPTO_MD5 + ctypedef wcrypto_digest_alg wcrypto_digest_alg_t + + cdef enum wd_digest_mac_len: + WD_DIGEST_SM3_LEN + WD_DIGEST_MD5_LEN + ctypedef wd_digest_mac_len wd_digest_mac_len_t + + cdef enum wcrypto_digest_mode: + WCRYPTO_DIGEST_NORMAL + WCRYPTO_DIGEST_HMAC + ctypedef wcrypto_digest_mode wcrypto_digest_mode_t + + cdef struct wcrypto_digest_ctx_setup: + cwd.wcrypto_cb cb + wcrypto_digest_alg alg + wcrypto_digest_mode mode + cwd.wd_mm_br br + __u16 data_fmt + ctypedef wcrypto_digest_ctx_setup wcrypto_digest_ctx_setup_t + + cdef struct wcrypto_digest_op_data: + void *in_ "in", + void *out_ "out", + __u32 in_bytes, + __u32 out_bytes, + void *priv, + int status + bint has_next + ctypedef wcrypto_digest_op_data wcrypto_digest_op_data_t + + cdef struct wcrypto_digest_msg: + __u8 alg_type + __u8 alg + __u8 has_next + __u8 mode + __u8 data_fmt + __u8 result + __u16 key_bytes + __u16 iv_bytes + + __u8 *key + __u8 *iv + __u8 *in_ + __u8 *out_ + __u32 in_bytes + __u32 out_bytes + __u64 usr_data + ctypedef wcrypto_digest_msg wcrypto_digest_msg_t + + cdef void *wcrypto_create_digest_ctx( + cwd.wd_queue *q, + wcrypto_digest_ctx_setup *setup + ) + + cdef int wcrypto_set_digest_key(void *ctx, __u8 *key, __u16 key_len) + + cdef int wcrypto_do_digest(void *ctx, wcrypto_digest_op_data *opdata, void *tag) + + cdef int wcrypto_digest_poll(cwd.wd_queue *q, __u32 num) + + cdef void wcrypto_del_digest_ctx(void *ctx) diff --git a/pyuadk/cwd_rsa.pxd b/pyuadk/cwd_rsa.pxd new file mode 100644 index 0000000000000000000000000000000000000000..f83bb8cdbae6ac9af5a03226e93733b8b6e37d69 --- /dev/null +++ b/pyuadk/cwd_rsa.pxd @@ -0,0 +1,126 @@ +ctypedef unsigned char __u8 +ctypedef unsigned short __u16 +ctypedef unsigned int __u32 +ctypedef unsigned long long __u64 + +cimport cwd + +cdef extern from "../uadk/v1/wd_rsa.h": + # 这种声明方式只能使用指针 + cdef struct wcrypto_rsa_kg_in: + pass + + cdef struct wcrypto_rsa_kg_out: + pass + + + cdef struct wcrypto_rsa_pubkey: + pass + cdef struct wcrypto_rsa_prikey: + pass + + # RSA operational types + cdef enum wcrypto_rsa_op_type: + WCRYPTO_RSA_INVALID, # invalid rsa operation + WCRYPTO_RSA_SIGN, # RSA sign + WCRYPTO_RSA_VERIFY, # RSA verify + WCRYPTO_RSA_GENKEY, # RSA key generation + + #RSA key types + cdef enum wcrypto_rsa_key_type: + WCRYPTO_RSA_INVALID_KEY, # invalid rsa key type + WCRYPTO_RSA_PUBKEY, # rsa public key type + WCRYPTO_RSA_PRIKEY1, # invalid rsa private common key type + WCRYPTO_RSA_PRIKEY2, # invalid rsa private CRT key type + + # RSA context setting up input parameters from user + cdef struct wcrypto_rsa_ctx_setup: + cwd.wcrypto_cb cb # call back function from user + __u16 data_fmt # data format denoted by enum wd_buff_type + __u16 key_bits # RSA key bits + bint is_crt # CRT mode or not + cwd.wd_mm_br br # memory operations from user + + cdef struct wcrypto_rsa_op_data: + wcrypto_rsa_op_type op_type # rsa operation type + int status # rsa operation status + void *in_ 'in' # rsa operation input address, should be DMA-able + void *out # rsa operation output address, should be DMA-able + int in_bytes # rsa operation input bytes + int out_bytes # rsa operation output bytes + + # RSA message format of Warpdrive + cdef struct wcrypto_rsa_msg: + __u8 alg_type # Denoted by enum wcrypto_type + __u8 op_type # Denoted by enum wcrypto_rsa_op_type + __u8 key_type # Denoted by enum wcrypto_rsa_key_type + __u8 data_fmt # Data format, denoted by enum wd_buff_type + __u8 result # Data format, denoted by WD error code + __u16 in_bytes # Input data bytes + __u16 out_bytes # Output data bytes + __u16 key_bytes # Input key bytes + __u8 *in_ # Input data VA, buf should be DMA buffer. + __u8 *out # Output data VA pointer, should be DMA buffer + __u8 *key # Input key VA pointer, should be DMA buffer + + # ''' + # * Input user tag, used for identify data stream/user: + #* struct wcrypto_cb_tag + # ''' + __u64 usr_data + + + cdef bint wcrypto_rsa_is_crt(const void *ctx) + cdef int wcrypto_rsa_key_bits(const void *ctx) + cdef void *wcrypto_create_rsa_ctx(cwd.wd_queue *q, wcrypto_rsa_ctx_setup *setup) + cdef void wcrypto_get_rsa_pubkey(void *ctx, wcrypto_rsa_pubkey **pubkey) + cdef void wcrypto_get_rsa_prikey(void *ctx, wcrypto_rsa_prikey **prikey) + cdef int wcrypto_set_rsa_pubkey_params(void *ctx, cwd.wd_dtb *e, cwd.wd_dtb *n) + cdef void wcrypto_get_rsa_pubkey_params(wcrypto_rsa_pubkey *pbk, cwd.wd_dtb **e, cwd.wd_dtb **n) + cdef int wcrypto_set_rsa_prikey_params(void *ctx, cwd.wd_dtb *d, cwd.wd_dtb *n) + cdef void wcrypto_get_rsa_prikey_params(wcrypto_rsa_prikey *pvk, cwd.wd_dtb **d, cwd.wd_dtb **n) + cdef int wcrypto_set_rsa_crt_prikey_params(void *ctx, cwd.wd_dtb *dq, + cwd.wd_dtb *dp, + cwd.wd_dtb *qinv, + cwd.wd_dtb *q, + cwd.wd_dtb *p) + cdef void wcrypto_get_rsa_crt_prikey_params(wcrypto_rsa_prikey *pvk, + cwd.wd_dtb **dq, cwd.wd_dtb **dp, + cwd.wd_dtb **qinv, cwd.wd_dtb **q, + cwd.wd_dtb **p) + + # APIs For RSA key generate + # new_kg_in 和 get_kg_in_params 是相反的过程,前者是将p、q、e赋值给ki,后者是将ki中的p、q、e赋值给p、q、e + cdef wcrypto_rsa_kg_in *wcrypto_new_kg_in(void *ctx, cwd.wd_dtb *e, + cwd.wd_dtb *p, cwd.wd_dtb *q) + cdef void wcrypto_del_kg_in(void *ctx, wcrypto_rsa_kg_in *ki) + cdef void wcrypto_get_rsa_kg_in_params(wcrypto_rsa_kg_in *kin, cwd.wd_dtb *e, cwd.wd_dtb *q, cwd.wd_dtb *p) + + cdef wcrypto_rsa_kg_out *wcrypto_new_kg_out(void *ctx) + cdef void wcrypto_del_kg_out(void *ctx, wcrypto_rsa_kg_out *kout) + cdef void wcrypto_get_rsa_kg_out_params(wcrypto_rsa_kg_out *kout, + cwd.wd_dtb *d, + cwd.wd_dtb *n) + cdef void wcrypto_get_rsa_kg_out_crt_params(wcrypto_rsa_kg_out *kout, + cwd.wd_dtb *qinv, + cwd.wd_dtb *dq, cwd.wd_dtb *dp) + + cdef int wcrypto_rsa_kg_in_data(wcrypto_rsa_kg_in *ki, char **data) + cdef int wcrypto_rsa_kg_out_data(wcrypto_rsa_kg_out *ko, char **data) + cdef void wcrypto_set_rsa_kg_out_crt_psz(wcrypto_rsa_kg_out *kout, + size_t qinv_sz, + size_t dq_sz, + size_t dp_sz) + cdef void wcrypto_set_rsa_kg_out_psz(wcrypto_rsa_kg_out *kout, + size_t d_sz, + size_t n_sz) + + # ''' + # * This is a pair of asynchronous mode RSA API as tag is not NULL, + # * or it is synchronous mode + # ''' + cdef int wcrypto_do_rsa(void *ctx, wcrypto_rsa_op_data *opdata, void *tag) + cdef int wcrypto_rsa_poll(cwd.wd_queue *q, __u32 num) + cdef void wcrypto_del_rsa_ctx(void *ctx) + + diff --git a/pyuadk/cwd_util.pxd b/pyuadk/cwd_util.pxd new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/pyuadk/pyuadk.pxd b/pyuadk/pyuadk.pxd new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/pyuadk/pywd.pxd b/pyuadk/pywd.pxd new file mode 100644 index 0000000000000000000000000000000000000000..c36dce71b2dbc160989f5f77d112a4fe46481c1c --- /dev/null +++ b/pyuadk/pywd.pxd @@ -0,0 +1,23 @@ +cimport cwd +cimport cwd_bmm + + +cdef cwd.wd_alloc wd_alloc_func +cdef cwd.wd_free wd_free_func +cdef cwd.wd_map wd_map_func +cdef cwd.wd_unmap wd_unmap_func +cdef cwd.wd_bufsize wd_bufsize_func + + +cdef class Wd: + cdef cwd.wd_queue *queue + cdef cwd.wd_capa *capa + + cdef cwd_bmm.wd_blkpool_setup *wsetup + cdef void *ctx + cdef cwd_bmm.wd_blkpool *pool + + cpdef int request_queue(self) + + cpdef int wd_get_available_dev_num(self) + diff --git a/pyuadk/pywd.pyx b/pyuadk/pywd.pyx new file mode 100644 index 0000000000000000000000000000000000000000..8098abb3ed2911f1167b75d39f04f76e4f6ee96f --- /dev/null +++ b/pyuadk/pywd.pyx @@ -0,0 +1,42 @@ +cimport cwd +cimport cwd_bmm +from libc.stdlib cimport malloc +from libc.string cimport memset, strcpy + + +cdef class Wd(object): + + def __cinit__( + self, + dev_path: str = None, + node_mask: int = None, + async_mode: int = 1 + ): + self.queue = malloc (sizeof(cwd.wd_queue)) + self.capa = malloc (sizeof(cwd.wd_capa)) + self.wsetup =\ + malloc (sizeof(cwd_bmm.wd_blkpool_setup)) + self.pool = NULL + self.ctx = NULL + + cdef bytes cdev_path + if dev_path is not None: + cdev_path = dev_path.encode() + strcpy(self.queue.dev_path, cdev_path) + if node_mask is not None: + self.queue.node_mask = node_mask + + memset(self.queue, 0, sizeof(cwd.wd_queue)) + memset(self.capa, 0, sizeof(cwd.wd_capa)) + memset(self.wsetup, 0, sizeof(cwd_bmm.wd_blkpool_setup)) + + cpdef int request_queue(self): + ret = cwd.wd_request_queue(self.queue) + if ret != 0 or self.queue == NULL: + raise MemoryError("request_queue failed") + return 0 + + cpdef int wd_get_available_dev_num(self): + return cwd.wd_get_available_dev_num(self.capa.alg) + + diff --git a/pyuadk/pywd_cipher.pyx b/pyuadk/pywd_cipher.pyx new file mode 100644 index 0000000000000000000000000000000000000000..c3d4c0226cb0558dd29204f95f71151166149365 --- /dev/null +++ b/pyuadk/pywd_cipher.pyx @@ -0,0 +1,265 @@ +cimport cwd_cipher +cimport cwd +cimport cwd_bmm +from pyuadk.pywd cimport * +from libc.stdlib cimport malloc +from libc.string cimport memcpy +from enum import Enum + + +class CIPHER_ALG(Enum): + AES = 0 + SM4 = 1 + + +class CIPHER_MODE(Enum): + ECB = 0 + CBC = 1 + CTR = 2 + XTS = 3 + OFB = 4 + CFB = 5 + CCM = 6 + GCM = 7 + + +class CIPHER_OP_TYPE(Enum): + ENCRYPT = 0 + DECRYPT = 1 + + +cdef void callback(void *message, void *tag): + print("cipher callback") + +cdef struct wcrypto_cipher_tag: + void *ctx + int thread_id + int cnt + + +cdef class Cipher(Wd): + + cdef cwd_cipher.wcrypto_cipher_ctx_setup *setup + cdef cwd_cipher.wcrypto_cipher_op_data *opdata + cdef wcrypto_cipher_tag *tag + cdef bint async_mode + + def __cinit__( + self, + dev_path: str = None, + node_mask: int = None, + async_mode: int = 0 + ): + self.setup = \ + malloc(sizeof(cwd_cipher.wcrypto_cipher_ctx_setup)) + self.opdata = \ + malloc(sizeof(cwd_cipher.wcrypto_cipher_op_data)) + self.tag = NULL + self.capa.alg = "cipher" + cdef void *capa_ptr = &self.queue.capa + memcpy(capa_ptr, self.capa, sizeof(cwd.wd_capa)) + self.async_mode = async_mode + + cpdef void pool_setup(self, block_size=1024*8, block_num=128, align_size=128): + + '''setup pool + create pool memory: block_nm * block_size + params: + block_size: block size + block_num: block number + align_size: align size + ''' + + self.wsetup.block_size = block_size + self.wsetup.block_num = block_num + self.wsetup.align_size = align_size + self.pool = \ + cwd_bmm.wd_blkpool_create(self.queue, self.wsetup) + if self.pool == NULL: + raise MemoryError("wd_blkpool_create failed") + + cpdef void ctx_setup(self, alg: CIPHER_ALG, mode: CIPHER_MODE): + + '''setup ctx (alg, mode, br) + a callback func is needed in async mode + params: + alg: aes or sm4 + mode: ecb or cbc or ctr or xts or ofb or cfb or ccm or gcm + ''' + + if alg == CIPHER_ALG.AES: + self.setup.alg = cwd_cipher.WCRYPTO_CIPHER_AES + elif alg == CIPHER_ALG.SM4: + self.setup.alg = cwd_cipher.WCRYPTO_CIPHER_SM4 + else: + raise ValueError("alg must be CIPHER_ALG.AES or CIPHER_ALG.SM4") + + if mode == CIPHER_MODE.ECB: + self.setup.mode = cwd_cipher.WCRYPTO_CIPHER_ECB + elif mode == CIPHER_MODE.CBC: + self.setup.mode = cwd_cipher.WCRYPTO_CIPHER_CBC + elif mode == CIPHER_MODE.CTR: + self.setup.mode = cwd_cipher.WCRYPTO_CIPHER_CTR + elif mode == CIPHER_MODE.XTS: + self.setup.mode = cwd_cipher.WCRYPTO_CIPHER_XTS + elif mode == CIPHER_MODE.OFB: + self.setup.mode = cwd_cipher.WCRYPTO_CIPHER_OFB + elif mode == CIPHER_MODE.CFB: + self.setup.mode = cwd_cipher.WCRYPTO_CIPHER_CFB + elif mode == CIPHER_MODE.CCM: + self.setup.mode = cwd_cipher.WCRYPTO_CIPHER_CCM + elif mode == CIPHER_MODE.GCM: + self.setup.mode = cwd_cipher.WCRYPTO_CIPHER_GCM + else: + raise ValueError("unexcepted mode") + + if self.async_mode == 1: + self.setup.cb = callback + else: + self.setup.cb = NULL + self.setup.br.alloc = cwd_bmm.wd_alloc_blk + self.setup.br.free = cwd_bmm.wd_free_blk + self.setup.br.iova_map = cwd_bmm.wd_blk_iova_map + self.setup.br.iova_unmap = cwd_bmm.wd_blk_iova_unmap + self.setup.br.get_bufsize = cwd_bmm.wd_blksize + self.setup.br.usr = self.pool + + cpdef int create_cipher_ctx(self): + + '''create ctx + create cipher ctx after ctx setup + return -1 means create failed + ''' + + self.ctx = cwd_cipher.wcrypto_create_cipher_ctx(self.queue, self.setup) + if self.ctx == NULL: + raise Exception("create ctx failed!") + return -1 + return 0 + + cpdef int wcrypto_set_cipher_key(self, key: bytes, key_len: int): + + '''set cipher key + params: + key: bytes with length of key_len + key_len: cipher key length + ''' + + cdef unsigned char *ckey = \ + malloc (key_len*sizeof(unsigned char)) + for i in range(key_len): + ckey[i] = key[i] + return cwd_cipher.wcrypto_set_cipher_key(self.ctx, ckey, key_len) + + cpdef void set_opdata(self, bytes iv, op_type: CIPHER_OP_TYPE, bytes text): + + ''' set opdata(iv, enc/dec. pt/ct) + params: + iv: iv, bytes with length of block_len + op_type: encrypt or decrypt + text: bytes with length of block_len + ''' + + # iv + self.opdata.iv = cwd_bmm.wd_alloc_blk(self.pool) + if self.opdata.iv == NULL: + raise MemoryError("wd blk fail failed") + cdef unsigned char *c_iv = iv + memcpy(self.opdata.iv, c_iv, len(iv)) + self.opdata.iv_bytes = len(iv) + + # op_type + if op_type == CIPHER_OP_TYPE.ENCRYPT: + self.opdata.op_type = cwd_cipher.WCRYPTO_CIPHER_ENCRYPTION + self.queue.capa.priv.direction = 0 + elif op_type == CIPHER_OP_TYPE.DECRYPT: + self.opdata.op_type = cwd_cipher.WCRYPTO_CIPHER_DECRYPTION + self.queue.capa.priv.direction = 1 + else: + raise ValueError("op_type must be \ + CIPHER_OP_TYPE.ENCRYPT or CIPHER_OP_TYPE.DECRYPT") + self.opdata.priv = NULL + + # text + self.opdata.in_ = \ + cwd_bmm.wd_alloc_blk(self.pool) + if self.opdata.in_ == NULL: + raise MemoryError("wd_alloc_blk failed") + cdef unsigned char *c_text = text + memcpy(self.opdata.in_, c_text, len(text)) + self.opdata.in_bytes = len(text) + + # out + self.opdata.out_ = cwd_bmm.wd_alloc_blk(self.pool) + if self.opdata.out_ == NULL: + raise MemoryError("wd_alloc_blk failed") + self.opdata.out_bytes = self.opdata.in_bytes + + cpdef void tag_setup(self, int cnt, int thread_id): + + """setup a fixed tag + cnt: user set (0?) + thread_id: acquired from python + """ + + if self.async_mode == 1: + self.tag = malloc(sizeof(wcrypto_cipher_tag)) + self.tag.ctx = self.ctx + self.tag.cnt = cnt + self.tag.thread_id = thread_id + else: + print("sync mode no need to setup tag") + + cpdef int wcrypto_do_cipher(self): + + """do cipher + do cipher in async mode(Non-Null tag is needed) or sync mode + """ + + if self.async_mode == 1: + if self.tag == NULL: + raise ValueError("tag must not be None in async mode") + return cwd_cipher.wcrypto_do_cipher(self.ctx, self.opdata, self.tag) + else: + return cwd_cipher.wcrypto_do_cipher(self.ctx, self.opdata, NULL) + + cpdef int wcrypto_cipher_poll(self, num: int): + + """poll self.queue + num: poll num (>1) + """ + if num < 1: + return -1 + + return cwd_cipher.wcrypto_cipher_poll(self.queue, num) + + cpdef bytes get_ct(self): + + """get ciphertext in bytes format + """ + + cdef unsigned char *c_ct =\ + malloc(self.opdata.out_bytes*sizeof(unsigned char)) + memcpy(c_ct, self.opdata.out_, self.opdata.out_bytes) + return bytes(c_ct) + + def __dealloc__(self): + + """free all resources + """ + + if self.opdata.in_ is not NULL and self.pool is not NULL: + cwd_bmm.wd_free_blk(self.pool, self.opdata.in_) + + if self.opdata.out_ is not NULL and self.pool is not NULL: + cwd_bmm.wd_free_blk(self.pool, self.opdata.out_) + + if self.opdata.iv is not NULL and self.pool is not NULL: + cwd_bmm.wd_free_blk(self.pool, self.opdata.iv) + + cwd_cipher.wcrypto_del_cipher_ctx(self.ctx) + + if self.queue is not NULL and self.queue.qinfo is not NULL: + cwd.wd_release_queue(self.queue) + + # cwd_bmm.wd_blkpool_destroy(self.pool) diff --git a/pyuadk/pywd_digest.pyx b/pyuadk/pywd_digest.pyx new file mode 100644 index 0000000000000000000000000000000000000000..9b83e974e8d7c0d16c602bc0b3aab1bfa60dddc7 --- /dev/null +++ b/pyuadk/pywd_digest.pyx @@ -0,0 +1,220 @@ +cimport cwd +cimport cwd_digest +cimport cwd_bmm +from pyuadk.pywd cimport * +from libc.stdlib cimport malloc +from libc.string cimport memcpy +from enum import Enum + + +class DIGEST_ALG(Enum): + SM3 = 0 + + +class DIGEST_MODE(Enum): + NORMAL = 0 + HMAC = 1 + + +cdef void callback(void *message, void *tag): + print("digest callback") + +cdef struct wcrypto_digest_tag: + void *ctx + int thread_id + int cnt + +cdef class Digest(Wd): + + cdef cwd_digest.wcrypto_digest_ctx_setup *setup + cdef cwd_digest.wcrypto_digest_op_data *opdata + cdef wcrypto_digest_tag *tag + cdef bint async_mode + + def __cinit__( + self, + dev_path: str = None, + node_mask: int = None, + async_mode: int = 0 + ): + self.setup = \ + malloc (sizeof(cwd_digest.wcrypto_digest_ctx_setup)) + self.opdata = \ + malloc (sizeof(cwd_digest.wcrypto_digest_op_data)) + self.tag = \ + malloc (sizeof(wcrypto_digest_tag)) + self.async_mode = async_mode + self.capa.alg = "digest" + cdef void *capa_ptr = &self.queue.capa + memcpy(capa_ptr, self.capa, sizeof(cwd.wd_capa)) + + cpdef void pool_setup(self, block_size=1024*8, block_num=128, align_size=128): + + ''' setup and create pool + params: + block_size: block size + block_num: block number + align_size: align size + ''' + + self.wsetup.block_size = block_size + self.wsetup.block_num = block_num + self.wsetup.align_size = align_size + self.pool =\ + cwd_bmm.wd_blkpool_create(self.queue, self.wsetup) + if self.pool == NULL: + raise MemoryError("create pool failed") + + cpdef ctx_setup(self, alg: DIGEST_ALG, mode: DIGEST_MODE): + + '''set ctx setup + params: + alg: digest algorithm(SM3 only) + mode: digest mode(NORMAL or HMAC) + ''' + + if alg == DIGEST_ALG.SM3: + self.setup.alg = cwd_digest.WCRYPTO_SM3 + else: + raise ValueError("digest algorithm not support") + + if mode == DIGEST_MODE.NORMAL: + self.setup.mode = cwd_digest.WCRYPTO_DIGEST_NORMAL + elif mode == DIGEST_MODE.HMAC: + self.setup.mode = cwd_digest.WCRYPTO_DIGEST_HMAC + else: + raise ValueError("digest mode not support") + + if self.async_mode == 1: + self.setup.cb = callback + else: + self.setup.cb = NULL + self.setup.br.alloc = cwd_bmm.wd_alloc_blk + self.setup.br.free = cwd_bmm.wd_free_blk + self.setup.br.iova_map = cwd_bmm.wd_blk_iova_map + self.setup.br.iova_unmap = cwd_bmm.wd_blk_iova_unmap + self.setup.br.get_bufsize = cwd_bmm.wd_blksize + self.setup.br.usr = self.pool + + cpdef void create_digest_ctx(self): + '''create ctx + ''' + self.ctx = cwd_digest.wcrypto_create_digest_ctx(self.queue, self.setup) + if self.ctx == NULL: + raise Exception("create ctx failed!") + + cpdef int wcrypto_set_digest_key(self, key: bytes, key_len: int): + + ''' digest key (only for HMAC mode) + params: + key: digest key, byte array of digest key length + key_len: digest key length + ''' + + if self.setup.mode != cwd_digest.WCRYPTO_DIGEST_HMAC: + raise ValueError("only set key for HMAC mode") + cdef unsigned char *ckey = key + for i in range(len(key)): + ckey[i] = key[i] + return cwd_digest.wcrypto_set_digest_key(self.ctx, ckey, key_len) + + cpdef void set_opdata(self, bytes text, int dsize): + + '''set digest data(to be hashed) + params: + text: digest data + dsize: digest data length + ''' + + self.opdata.in_ = cwd_bmm.wd_alloc_blk(self.pool) + if self.opdata.in_ == NULL: + raise MemoryError("wd_alloc_blk failed") + cdef unsigned char *c_text = text + memcpy(self.opdata.in_, c_text, len(text)) + self.opdata.in_bytes = len(text) + + self.opdata.out_ = cwd_bmm.wd_alloc_blk(self.pool) + if self.opdata.out_ == NULL: + raise MemoryError("alloc output buffer failed") + self.opdata.out_bytes = dsize + self.opdata.priv = NULL + + cpdef void tag_setup(self, int cnt, int thread_id): + + """setup a fixed tag + cnt: user set (0?) + thread_id: acquired from python + """ + + if self.async_mode == 1: + self.tag = malloc(sizeof(wcrypto_digest_tag)) + self.tag.ctx = self.ctx + self.tag.cnt = cnt + self.tag.thread_id = thread_id + else: + print("sync mode no need to setup tag") + + cpdef int wcrypto_do_digest(self): + '''do digest + ''' + if self.async_mode == 1: + if self.tag == NULL: + raise ValueError("tag must not be None in async mode") + return cwd_digest.wcrypto_do_digest(self.ctx, self.opdata, self.tag) + else: + return cwd_digest.wcrypto_do_digest(self.ctx, self.opdata, NULL) + + cpdef int wcrypto_digest_poll(self, num: int): + '''digest poll + ''' + if (num < 1): + raise ValueError("num must be greater than 0") + if self.async_mode == 0: + raise ValueError("sync mode not support poll") + return cwd_digest.wcrypto_digest_poll(self.queue, num) + + cpdef void wcrypto_del_digest_ctx(self): + cwd_digest.wcrypto_del_digest_ctx(self.ctx) + + # cdef int wcrypto_burst_digest(self, num): + # cdef cwd_digest.wcrypto_digest_op_data **opdata_ptr = &self.opdata + # return cwd_digest.wcrypto_burst_digest(self.ctx, opdata_ptr, NULL, num) + + cdef int sync_do_digest(self): + cdef int data_len = self.opdata.in_bytes + while (1): + if data_len > 256: + self.opdata.in_bytes = 256 + data_len -= 256 + else: + self.opdata.in_bytes = data_len + break + self.opdata.has_next = (data_len >= 256) + ret = cwd_digest.wcrypto_do_digest(self.ctx, self.opdata, NULL) + if ret < 0: + raise Exception("digest failed") + return 0 + + cpdef bytes get_digest(self): + cdef unsigned char *digest =\ + malloc(self.opdata.out_bytes*sizeof(unsigned char)) + memcpy(digest, self.opdata.out_, self.opdata.out_bytes) + return bytes(digest) + + def __dealloc__(self): + + """free all resources + """ + + if self.opdata.in_ is not NULL and self.pool is not NULL: + cwd_bmm.wd_free_blk(self.pool, self.opdata.in_) + + if self.opdata.out_ is not NULL and self.pool is not NULL: + cwd_bmm.wd_free_blk(self.pool, self.opdata.out_) + + cwd_digest.wcrypto_del_digest_ctx(self.ctx) + + if self.queue is not NULL and self.queue.qinfo is not NULL: + cwd.wd_release_queue(self.queue) + + cwd_bmm.wd_blkpool_destroy(self.pool) diff --git a/pyuadk/pywd_rsa.pyx b/pyuadk/pywd_rsa.pyx new file mode 100644 index 0000000000000000000000000000000000000000..c42914e89c1f1c85d586c9d8c1dbb01c91662851 --- /dev/null +++ b/pyuadk/pywd_rsa.pyx @@ -0,0 +1,455 @@ +cimport cwd_rsa +cimport cwd +cimport cwd_bmm +from pyuadk.pywd cimport * +from libc.string cimport memset, memcpy +from libc.stdlib cimport malloc, free +from enum import Enum + + +class RSA_OP_TYPE(Enum): + RSA_INVALID = 0 + SIGN = 1 + VERIFY = 2 + GENKEY = 3 + + +cdef void callback(void *message, void *tag): + print("rsa callback") + +cdef struct wcrypto_rsa_tag: + void *ctx + int thread_id + int cnt + +cdef class RSA(Wd): + + cdef cwd_rsa.wcrypto_rsa_ctx_setup *setup + cdef cwd_rsa.wcrypto_rsa_op_data *opdata + cdef wcrypto_rsa_tag *tag + cdef bint async_mode + + cdef cwd_rsa.wcrypto_rsa_kg_in *kg_in + cdef cwd_rsa.wcrypto_rsa_kg_out *kg_out + + cdef cwd_rsa.wcrypto_rsa_pubkey *pubk + cdef cwd_rsa.wcrypto_rsa_prikey *prik + + + cdef cwd.wd_dtb *n + cdef cwd.wd_dtb *e + cdef cwd.wd_dtb *d + cdef cwd.wd_dtb *p + cdef cwd.wd_dtb *q + cdef cwd.wd_dtb *dp + cdef cwd.wd_dtb *dq + cdef cwd.wd_dtb *qinv + cdef int key_bits + + def __cinit__( + self, + dev_path: str=None, + node_mask: int=None, + async_mode: int=0 + ): + self.setup = malloc (sizeof(cwd_rsa.wcrypto_rsa_ctx_setup)) + self.opdata = malloc (sizeof(cwd_rsa.wcrypto_rsa_op_data)) + self.tag = NULL + self.async_mode = async_mode + self.capa.alg = "rsa" + cdef void *capa_ptr = &self.queue.capa + memcpy(capa_ptr, self.capa, sizeof(cwd.wd_capa)) + + self.n = malloc (sizeof(cwd.wd_dtb)) + self.e = malloc (sizeof(cwd.wd_dtb)) + self.d = malloc (sizeof(cwd.wd_dtb)) + self.p = malloc (sizeof(cwd.wd_dtb)) + self.q = malloc (sizeof(cwd.wd_dtb)) + self.dp = malloc (sizeof(cwd.wd_dtb)) + self.dq = malloc (sizeof(cwd.wd_dtb)) + self.qinv = malloc (sizeof(cwd.wd_dtb)) + + cpdef void pool_setup(self, int block_num, int key_bits): + + '''setup and createpool + params: + key_bits: int + block_num: int + ''' + + self.key_bits = key_bits + self.wsetup.block_size = (self.key_bits >> 3)*7 + self.wsetup.block_num = block_num + self.wsetup.align_size = 64 + self.pool = cwd_bmm.wd_blkpool_create(self.queue, self.wsetup) + if self.pool == NULL: + raise MemoryError("create pool failed") + + + cpdef void ctx_setup(self, bint is_crt): + + '''init ctx_setup + params: + is_crt: bool + ''' + if self.async_mode == 1: + self.setup.cb = callback + else: + self.setup.cb = NULL + self.setup.is_crt = is_crt + self.setup.key_bits = self.key_bits + self.setup.br.alloc = cwd_bmm.wd_alloc_blk + self.setup.br.free = cwd_bmm.wd_free_blk + self.setup.br.iova_map = cwd_bmm.wd_blk_iova_map + self.setup.br.iova_unmap = cwd_bmm.wd_blk_iova_unmap + self.setup.br.get_bufsize = cwd_bmm.wd_blksize + self.setup.br.usr = self.pool + + + cpdef void set_opdata(self, op_type: RSA_OP_TYPE, data=None): + + '''set opdata before do rsa + params: + op_type: key_gen, sign, verify + data: invalid in genkey + status: assign value in do_rsa() + in_: pointer, return from wcrypto_new_kg_in(GENKEY) or wd_alloc_blk(else). + out: pointer, return from wcrypto_new_kg_out(GENKEY) or wd_alloc_blk(else) + in_bytes: int (key_size, for example) + out_bytes: int + ''' + + cdef unsigned char *in_data + + if op_type == RSA_OP_TYPE.GENKEY: + + self.opdata.op_type = cwd_rsa.wcrypto_rsa_op_type.WCRYPTO_RSA_GENKEY + if self.kg_in is not NULL and self.kg_out is not NULL: + self.opdata.in_ = self.kg_in + self.opdata.out = self.kg_out + else: + print("please create kg_in and kg_out") + return + self.opdata.in_bytes = self.key_bits >> 3 + self.opdata.out_bytes = self.key_bits >> 3 + + else: + if data == None: + raise ValueError("data is None") + + self.opdata.in_ = cwd_bmm.wd_alloc_blk(self.pool) + self.opdata.out = cwd_bmm.wd_alloc_blk(self.pool) + + if self.opdata.in_ is NULL or self.opdata.out is NULL: + raise MemoryError("alloc blk failed") + + in_data = malloc(len(data)*sizeof(unsigned char)) + for i in range(len(data)): + in_data[i] = data[i] + memcpy(self.opdata.in_, in_data, len(data)) + self.opdata.in_bytes = len(data) + self.opdata.out_bytes = len(data) + + + if op_type == RSA_OP_TYPE.SIGN: + # if msg == None: + # raise ValueError("msg is None") + self.opdata.op_type = cwd_rsa.wcrypto_rsa_op_type.WCRYPTO_RSA_SIGN + + elif op_type == RSA_OP_TYPE.VERIFY: + # if sig == None: + # raise ValueError("sig is None") + self.opdata.op_type = cwd_rsa.wcrypto_rsa_op_type.WCRYPTO_RSA_VERIFY + + else: + print("op_type error") + return + + # cdef int wcrypto_rsa_key_bits(self): + # + # """ + # get key_bits from ctx + # """ + # + # return cwd_rsa.wcrypto_rsa_key_bits(self.ctx) + + + cpdef void create_rsa_ctx(self): + + """create ctx + create ctx after init setup + """ + self.ctx = cwd_rsa.wcrypto_create_rsa_ctx(self.queue, self.setup) + + + cpdef void wcrypto_get_rsa_pubkey(self): + + """ + link self.pubk to ctx->pubkey + code: *pubkey = ((struct wcrypto_rsa_ctx *)ctx)->pubkey; + """ + + cwd_rsa.wcrypto_get_rsa_pubkey(self.ctx, &self.pubk) + + cpdef void wcrypto_get_rsa_prikey(self): + + """ + link self.prik to ctx->prikey + code: *prikey = ((struct wcrypto_rsa_ctx *)ctx)->prikey; + """ + + cwd_rsa.wcrypto_get_rsa_prikey(self.ctx, &self.prik) + + + + cpdef void wcrypto_get_rsa_pubkey_params(self): + + """ + link self.e, self.n to self.pubk->e, self.pubk->n + code: + *e = &pbk->e; + *n = &pbk->n; + e, n is not necessary to be malloced + """ + + cwd_rsa.wcrypto_get_rsa_pubkey_params(self.pubk, &self.e, &self.n) + + cpdef void wcrypto_get_rsa_prikey_params(self): + + """ + link self.d, self.n to self.prik->d, self.prik->n + code: + *d = &pkey1->d; + *n = &pkey1->n; + d, n is not necessary to be malloced + """ + + cwd_rsa.wcrypto_get_rsa_prikey_params(self.prik, &self.d, &self.n) + + cpdef void wcrypto_set_rsa_pubkey_params(self, bytes e, bytes n): + + """ + data copy rather than link + copy data from e, n to self.ctx->pubkey->e, self.ctx->pubkey->n + code: + memcpy(c->prik->pkey1->e.data, e->data, e->dsize); + memcpy(c->prik->pkey1->n.data, n->data, n->dsize); + """ + + cdef cwd.wd_dtb *ce = malloc (sizeof(cwd.wd_dtb)) + cdef cwd.wd_dtb *cn = malloc (sizeof(cwd.wd_dtb)) + ce.dsize = len(e) + cn.dsize = len(n) + ce.data = malloc(ce.dsize) + cn.data = malloc(cn.dsize) + self.__set_wd_dtb(ce, e) + self.__set_wd_dtb(cn, n) + cwd_rsa.wcrypto_set_rsa_pubkey_params(self.ctx, ce, cn) + + cpdef void wcrypto_set_rsa_prikey_params(self, bytes d, bytes n): + + """ + data copy rather than link + copy data from d, n to self.ctx->prikey->pkey1->d, self.ctx->prikey->pkey1->n + code: + memcpy(c->prikey->d.data, d->data, d->dsize); + memcpy(c->prikey->n.data, n->data, n->dsize); + """ + + cdef cwd.wd_dtb *cd = malloc (sizeof(cwd.wd_dtb)) + cdef cwd.wd_dtb *cn = malloc (sizeof(cwd.wd_dtb)) + cd.dsize = len(d) + cn.dsize = len(n) + cd.data = malloc(cd.dsize) + cn.data = malloc(cn.dsize) + self.__set_wd_dtb(cd, d) + self.__set_wd_dtb(cn, n) + cwd_rsa.wcrypto_set_rsa_prikey_params(self.ctx, cd, cn) + + + cpdef void wcrypto_set_rsa_crt_prikey_params(self, bytes dq, bytes dp, bytes qinv, bytes q, bytes p): + + """ + data copy + copy data from dq, dp, qinv, p, q to self.ctx->prikey->pkey2->* + """ + cdef cwd.wd_dtb *cdq = malloc (sizeof(cwd.wd_dtb)) + cdef cwd.wd_dtb *cdp = malloc (sizeof(cwd.wd_dtb)) + cdef cwd.wd_dtb *cqinv = malloc (sizeof(cwd.wd_dtb)) + cdef cwd.wd_dtb *cq = malloc (sizeof(cwd.wd_dtb)) + cdef cwd.wd_dtb *cp = malloc (sizeof(cwd.wd_dtb)) + cdq.dsize = len(dq) + cdp.dsize = len(dp) + cqinv.dsize = len(qinv) + cq.dsize = len(q) + cp.dsize = len(p) + cdq.data = malloc(cdq.dsize) + cdp.data = malloc(cdp.dsize) + cqinv.data = malloc(cqinv.dsize) + cq.data = malloc(cq.dsize) + cp.data = malloc(cp.dsize) + self.__set_wd_dtb(cdq, dq) + self.__set_wd_dtb(cdp, dp) + self.__set_wd_dtb(cqinv, qinv) + self.__set_wd_dtb(cq, q) + self.__set_wd_dtb(cp, p) + cwd_rsa.wcrypto_set_rsa_crt_prikey_params(self.ctx, cdq, cdp, cqinv, cq, cp) + + # get d, n (wd_dtb) from rsa_prikey->pkey1 + cpdef get_prikey(self): + """ + return d, n in bytes format + """ + # struct.unsigned char -> wd_dtb + cwd_rsa.wcrypto_get_rsa_prikey_params(self.prik, &self.d, &self.n) + d = self.__get_wd_dtb(self.d) + n = self.__get_wd_dtb(self.n) + return d, n + + + # get dp, dq,q qinv ... from rsa_prik->pkey2 + cpdef get_crt_prikey(self): + """ + return dp, dq, qinv, q, p in bytes format + """ + if not self.wcrypto_rsa_is_crt(): + raise ValueError("not crt mode") + cwd_rsa.wcrypto_get_rsa_crt_prikey_params(self.prik, &self.dq, &self.dp, &self.qinv, &self.q, &self.p) + dp = self.__get_wd_dtb(self.dp) + dq = self.__get_wd_dtb(self.dq) + qinv = self.__get_wd_dtb(self.qinv) + q = self.__get_wd_dtb(self.q) + p = self.__get_wd_dtb(self.p) + return dp, dq, qinv, q, p + + + cpdef void wcrypto_new_kg_in(self, e: bytes, p: bytes, q: bytes): + ''' + 用现有的 e, p, q 构建一个 kg_in 结构体 + 肯定是不能直接返回结构体指针的,那这样看也是作为一个成员出现比较合适 + 这里有一个要注意的点是要给 wd_dtb 的 data 指针分配内存 + ''' + cdef cwd.wd_dtb *ce = malloc(sizeof(cwd.wd_dtb)) + ce.dsize = len(e) + ce.data = malloc(ce.dsize) + if ce.data == NULL: + raise MemoryError("malloc failed") + self.__set_wd_dtb(ce, e) + + cdef cwd.wd_dtb *cp = malloc(sizeof(cwd.wd_dtb)) + cp.dsize = len(p) + cp.data = malloc(cp.dsize) + if cp.data == NULL: + raise MemoryError("malloc failed") + self.__set_wd_dtb(cp, p) + + cdef cwd.wd_dtb *cq = malloc(sizeof(cwd.wd_dtb)) + cq.dsize = len(q) + cq.data = malloc(cq.dsize) + if cq.data == NULL: + raise MemoryError("malloc failed") + self.__set_wd_dtb(cq, q) + + # print(self.ctx==NULL, ce==NULL, cp==NULL, cq==NULL) + + self.kg_in = cwd_rsa.wcrypto_new_kg_in(self.ctx, ce, cp, cq) + free(ce.data) + free(ce) + free(cp.data) + free(cp) + free(cq.data) + free(cq) + + + cdef void wcrypto_del_kg_in(self): + cwd_rsa.wcrypto_del_kg_in(self.ctx, self.kg_in) + + cpdef void wcrypto_new_kg_out(self): + """ + create a kg_out struct contains: + d, n + dp, dq, qinv (if setup.crt is True) + return pointer of this struct + """ + self.kg_out = cwd_rsa.wcrypto_new_kg_out(self.ctx) + + cdef void wcrypto_del_kg_out(self): + cwd_rsa.wcrypto_del_kg_out(self.ctx, self.kg_out) + + cpdef void wcrypto_get_rsa_kg_out_params(self): + """ + get d, n from kg_out + """ + cwd_rsa.wcrypto_get_rsa_kg_out_params(self.kg_out, self.d, self.n) + + cdef void wcrypto_get_rsa_kg_out_crt_params(self): + """ + get dp, dq, qinv from kg_out + """ + cwd_rsa.wcrypto_get_rsa_kg_out_crt_params(self.kg_out, self.qinv, self.dq, self.dp) + + cpdef void tag_setup(self, int cnt, int thread_id): + + """setup a fixed tag + cnt: user set (0?) + thread_id: acquired from python + """ + + if self.async_mode == 1: + self.tag = malloc(sizeof(wcrypto_rsa_tag)) + self.tag.ctx = self.ctx + self.tag.cnt = cnt + self.tag.thread_id = thread_id + else: + print("sync mode no need to setup tag") + + cpdef int wcrypto_do_rsa(self): + return cwd_rsa.wcrypto_do_rsa(self.ctx, self.opdata, NULL) + + cpdef int wcrypto_rsa_poll(self, num:int): + if num < 1: + raise ValueError("num must be greater than 0") + if self.async_mode == 0: + raise ValueError("sync mode not support poll") + return cwd_rsa.wcrypto_rsa_poll(self.queue, num) + + cdef void wcrypto_del_rsa_ctx(self): + cwd_rsa.wcrypto_del_rsa_ctx(self.ctx) + + cpdef get_kg_out(self): + self.wcrypto_get_rsa_kg_out_params() + d = self.__get_wd_dtb(self.d) + n = self.__get_wd_dtb(self.n) + return d, n + + cpdef get_kg_out_crt(self): + # cwd_rsa.wcrypto_get_rsa_kg_out_crt_params(self.kg_out, self.qinv, self.dq, self.dp) + self.wcrypto_get_rsa_kg_out_crt_params() + dq = self.__get_wd_dtb(self.dq) + dp = self.__get_wd_dtb(self.dp) + qinv = self.__get_wd_dtb(self.qinv) + return dq, dp, qinv + + cpdef get_opdata_out(self): + # memcpy self.opdata.out to a u8 array + cdef char *out = malloc(self.opdata.out_bytes) + memcpy(out, self.opdata.out, self.opdata.out_bytes) + return bytes(out[:self.opdata.out_bytes]) + + cdef __set_wd_dtb(self, cwd.wd_dtb *dtb, data: bytes): + dtb.dsize = len(data) + # print(dtb.dsize) + for i in range(dtb.dsize): + dtb.data[i] = data[i] + + cdef __get_wd_dtb(self, cwd.wd_dtb *dtb): + return bytes(dtb.data[:dtb.dsize]) + + + def __dealloc__(self): + # free queue + if self.queue is not NULL: + cwd.wd_release_queue(self.queue) + # self.wcrypto_del_kg_in() + # self.wcrypto_del_kg_out() + # self.wcrypto_del_rsa_ctx() diff --git a/pyuadk/setup.py b/pyuadk/setup.py new file mode 100644 index 0000000000000000000000000000000000000000..d9d36766cc635f88f4d31d62dcf179c98a70a9d2 --- /dev/null +++ b/pyuadk/setup.py @@ -0,0 +1,88 @@ +from setuptools import setup, Extension +from Cython.Build import cythonize + +extensions = [ + + Extension("pyuadk.pywd", + ["pyuadk/pywd.pyx", + "uadk/v1/wd_rsa.c", + "uadk/v1/wd_cipher.c", + "uadk/v1/wd.c", + "uadk/v1/wd_util.c", + "uadk/v1/wd_adapter.c", + "uadk/v1/wd_sgl.c", + "uadk/v1/wd_bmm.c", + "uadk/v1/wd_ecc.c", + "uadk/v1/drv/dummy_drv.c", + "uadk/v1/drv/hisi_qm_udrv.c", + "uadk/v1/drv/hisi_rng_udrv.c", + "uadk/v1/drv/hisi_hpre_udrv.c", + "uadk/v1/drv/hisi_sec_udrv.c", + "uadk/v1/drv/hisi_zip_udrv.c" + ], + include_dirs=["uadk/"]), + + Extension("pyuadk.pywd_cipher", + ["pyuadk/pywd_cipher.pyx", + "uadk/v1/wd_rsa.c", + "uadk/v1/wd_cipher.c", + "uadk/v1/wd.c", + "uadk/v1/wd_util.c", + "uadk/v1/wd_adapter.c", + "uadk/v1/wd_sgl.c", + "uadk/v1/wd_bmm.c", + "uadk/v1/wd_ecc.c", + "uadk/v1/drv/dummy_drv.c", + "uadk/v1/drv/hisi_qm_udrv.c", + "uadk/v1/drv/hisi_rng_udrv.c", + "uadk/v1/drv/hisi_hpre_udrv.c", + "uadk/v1/drv/hisi_sec_udrv.c", + "uadk/v1/drv/hisi_zip_udrv.c" + ], + include_dirs=["uadk/"]), + Extension("pyuadk.pywd_digest", + ["pyuadk/pywd_digest.pyx", + "uadk/v1/wd_digest.c", + "uadk/v1/wd_rsa.c", + "uadk/v1/wd_cipher.c", + "uadk/v1/wd.c", + "uadk/v1/wd_util.c", + "uadk/v1/wd_adapter.c", + "uadk/v1/wd_sgl.c", + "uadk/v1/wd_bmm.c", + "uadk/v1/wd_ecc.c", + "uadk/v1/drv/dummy_drv.c", + "uadk/v1/drv/hisi_qm_udrv.c", + "uadk/v1/drv/hisi_rng_udrv.c", + "uadk/v1/drv/hisi_hpre_udrv.c", + "uadk/v1/drv/hisi_sec_udrv.c", + "uadk/v1/drv/hisi_zip_udrv.c" + ], + include_dirs=["uadk/"]), + Extension("pyuadk.pywd_rsa", + [ + "pyuadk/pywd_rsa.pyx", + "uadk/v1/wd_rsa.c", + "uadk/v1/wd.c", + "uadk/v1/wd_util.c", + "uadk/v1/wd_adapter.c", + "uadk/v1/wd_sgl.c", + "uadk/v1/wd_bmm.c", + "uadk/v1/wd_ecc.c", + "uadk/v1/drv/dummy_drv.c", + "uadk/v1/drv/hisi_qm_udrv.c", + "uadk/v1/drv/hisi_rng_udrv.c", + "uadk/v1/drv/hisi_hpre_udrv.c", + "uadk/v1/drv/hisi_sec_udrv.c", + "uadk/v1/drv/hisi_zip_udrv.c" + ], + include_dirs=["uadk/"]) + # 添加其他Cython文件的Extension对象 +] + +setup( + name="pyuadk", + ext_modules=cythonize(extensions), + + # package_data={'pyuadk': ['build/lib.linux-aarch64-3.9/pywd_cipher.cpython-39-aarch64-linux-gnu.so']}, +) diff --git a/readme_en.md b/readme_en.md new file mode 100644 index 0000000000000000000000000000000000000000..a964f976e7217998a7b495e5978109aead675194 --- /dev/null +++ b/readme_en.md @@ -0,0 +1,37 @@ +# pyuadk +This project is a Python wrapper for the cryptographic acceleration library [UADK](https://gitee.com/openeuler/uadk), implemented using Cython. It currently supports: + +1. Encryption and decryption, as well as common modes of operation, for AES and SM4. +2. Hashing operations and HMAC operations for SM3. +3. Key generation, signing, and verification for RSA in both regular and CRT modes. + +## Compilation +```shell +git clone --recurse-submodules https://gitee.com/openeuler/pyuadk.git +pip3 install -r requirements.txt +python3 pyuadk/setup.py build_ext --inplace +``` +## Usage +```python +from pyuadk import pywd_cipher + +cipher = pywd_cipher.Cipher() +cipher.request_queue() +cipher.pool_setup(1024*8, 128, 128) + +key = bytes([0x01]*16) +iv = bytes([0x02]*16) +pt = bytes([0x03]*16) + +alg = pywd_cipher.CIPHER_ALG.AES +mode = pywd_cipher.CIPHER_MODE.CBC +cipher.ctx_setup(alg, mode) +cipher.create_cipher_ctx() + +cipher.wcrypto_set_cipher_key(self.key, len(self.key)) +cipher.set_opdata(self.iv, pywd_cipher.CIPHER_OP_TYPE.ENCRYPT, self.pt) + +ret = self.cipher.wcrypto_do_cipher() +if ret == 0: + ct = self.cipher.get_ct() +``` diff --git a/readme_zh.md b/readme_zh.md new file mode 100644 index 0000000000000000000000000000000000000000..de2cdd2530395bdbd1f0bc7c3f07b70d8cca108e --- /dev/null +++ b/readme_zh.md @@ -0,0 +1,37 @@ +# pyuadk +本项目是对密码加速库 [UADK](https://gitee.com/openeuler/uadk) 的 python 封装,使用 Cython 实现,目前支持: +1. AES 和 SM4 的加解密及常见工作模式 +2. SM3 的哈希操作和 HMAC 操作 +3. RSA 常规模式和 CRT 模式下的密钥生成、签名和验签 + +## 编译 +```shell +git clone --recurse-submodules https://gitee.com/openeuler/pyuadk.git +pip3 install -r requirements.txt +python3 pyuadk/setup.py build_ext --inplace +``` + +## 使用 +```python +from pyuadk import pywd_cipher + +cipher = pywd_cipher.Cipher() +cipher.request_queue() +cipher.pool_setup(1024*8, 128, 128) + +key = bytes([0x01]*16) +iv = bytes([0x02]*16) +pt = bytes([0x03]*16) + +alg = pywd_cipher.CIPHER_ALG.AES +mode = pywd_cipher.CIPHER_MODE.CBC +cipher.ctx_setup(alg, mode) +cipher.create_cipher_ctx() + +cipher.wcrypto_set_cipher_key(self.key, len(self.key)) +cipher.set_opdata(self.iv, pywd_cipher.CIPHER_OP_TYPE.ENCRYPT, self.pt) + +ret = self.cipher.wcrypto_do_cipher() +if ret == 0: + ct = self.cipher.get_ct() +``` diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..60b66a1c924c4a35cf27a0cdaab05b57a8e0c11c --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +setuptools~=65.5.1 +Cython~=3.0.0 diff --git a/test.py b/test.py new file mode 100644 index 0000000000000000000000000000000000000000..9d3246825b5fe6071c82a01d7e2bfa6506e71a06 --- /dev/null +++ b/test.py @@ -0,0 +1,325 @@ +from pyuadk import pywd_cipher, pywd_digest, pywd_rsa +# from pyuadk.pywd_rsa import RSA_OP_TYPE +import unittest +from Crypto.Cipher import AES +from Crypto.PublicKey import RSA +import time +import struct, os +from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes +from gmssl.sm4 import CryptSM4, SM4_ENCRYPT, SM4_DECRYPT +from gmssl.sm3 import sm3_hash +from cryptography.hazmat.primitives import hashes +from cryptography.hazmat.primitives.asymmetric import padding + +from cryptography.hazmat.primitives.asymmetric import rsa + +class TestPyWdCipherSync(unittest.TestCase): + + def __init__(self, methodName='runTest'): + super().__init__(methodName) + self.cipher = pywd_cipher.Cipher() + self.cipher.request_queue() + self.cipher.pool_setup(1024*8, 128, 128) + self.key = bytes([0x01]*16) + self.iv = bytes([0x02]*16) + self.pt = bytes([0x03]*16) + + + def test_cipher_aes_cbc_sync(self): + # cipher = pywd_cipher.Cipher() + # cipher.request_queue() + + + alg = pywd_cipher.CIPHER_ALG.AES + mode = pywd_cipher.CIPHER_MODE.CBC + self.cipher.ctx_setup(alg, mode) + self.cipher.create_cipher_ctx() + + self.cipher.wcrypto_set_cipher_key(self.key, len(self.key)) + + self.cipher.set_opdata(self.iv, pywd_cipher.CIPHER_OP_TYPE.ENCRYPT, self.pt) + + ret = self.cipher.wcrypto_do_cipher() + cth = self.cipher.get_ct() + self.assertEqual(ret, 0) + + aes_ecb = AES.new(self.key, AES.MODE_CBC, self.iv) + cts = aes_ecb.encrypt(self.pt) + + self.assertEqual(cth[0], cts[0]) + + self.cipher.set_opdata(self.iv, pywd_cipher.CIPHER_OP_TYPE.DECRYPT, cth) + ret = self.cipher.wcrypto_do_cipher() + pth = self.cipher.get_ct() + self.assertEqual(ret, 0) + + self.assertEqual(pth[0], self.pt[0]) + + print("\naes cbc test pass") + + def test_cipher_aes_ecb(self): + + alg = pywd_cipher.CIPHER_ALG.AES + mode = pywd_cipher.CIPHER_MODE.ECB + self.cipher.ctx_setup(alg, mode) + self.cipher.create_cipher_ctx() + + + self.cipher.wcrypto_set_cipher_key(self.key, len(self.key)) + self.cipher.set_opdata(bytes([]), pywd_cipher.CIPHER_OP_TYPE.ENCRYPT, self.pt) + + + ret = self.cipher.wcrypto_do_cipher() + cth = self.cipher.get_ct() + self.assertEqual(ret, 0) + + aes_ecb = AES.new(self.key, AES.MODE_ECB) + cts = aes_ecb.encrypt(self.pt) + + self.assertEqual(cth[:-1], cts) + # print("cth = ", ct[:16]) + self.cipher.set_opdata(bytes([]), pywd_cipher.CIPHER_OP_TYPE.DECRYPT, cth[:-1]) + ret = self.cipher.wcrypto_do_cipher() + pth = self.cipher.get_ct() + self.assertEqual(ret, 0) + self.assertEqual(pth[0], self.pt[0]) + + + print("\naes ecb test pass") + + + def test_cipher_sm4_ecb(self): + + alg = pywd_cipher.CIPHER_ALG.SM4 + mode = pywd_cipher.CIPHER_MODE.ECB + self.cipher.ctx_setup(alg, mode) + self.cipher.create_cipher_ctx() + + + self.cipher.wcrypto_set_cipher_key(self.key, len(self.key)) + self.cipher.set_opdata(bytes([]), pywd_cipher.CIPHER_OP_TYPE.ENCRYPT, self.pt) + + + ret = self.cipher.wcrypto_do_cipher() + cth = self.cipher.get_ct() + self.assertEqual(ret, 0) + + + sm4 = CryptSM4() + sm4.set_key(self.key, SM4_ENCRYPT) + cts = sm4.crypt_ecb(self.pt) + + + self.assertEqual(cth[:16], cts[:16]) + + self.cipher.set_opdata(bytes([]), pywd_cipher.CIPHER_OP_TYPE.DECRYPT, cth[:-1]) + ret = self.cipher.wcrypto_do_cipher() + pth = self.cipher.get_ct() + self.assertEqual(ret, 0) + self.assertEqual(pth[0], self.pt[0]) + + print("\nsm4 ecb test pass") + + def test_cipher_sm4_cbc(self): + + alg = pywd_cipher.CIPHER_ALG.SM4 + mode = pywd_cipher.CIPHER_MODE.CBC + self.cipher.ctx_setup(alg, mode) + self.cipher.create_cipher_ctx() + + + self.cipher.wcrypto_set_cipher_key(self.key, len(self.key)) + self.cipher.set_opdata(self.iv, pywd_cipher.CIPHER_OP_TYPE.ENCRYPT, self.pt) + + + ret = self.cipher.wcrypto_do_cipher() + cth = self.cipher.get_ct() + self.assertEqual(ret, 0) + + sm4 = CryptSM4() + sm4.set_key(self.key, SM4_ENCRYPT) + cts = sm4.crypt_cbc(self.iv, self.pt) + + self.assertEqual(cth[0], cts[0]) + + self.cipher.set_opdata(self.iv, pywd_cipher.CIPHER_OP_TYPE.DECRYPT, cth) + ret = self.cipher.wcrypto_do_cipher() + pth = self.cipher.get_ct() + self.assertEqual(ret, 0) + self.assertEqual(pth[0], self.pt[0]) + + print("\nsm4 cbc test pass") + + + +class TestPyWdDigest(unittest.TestCase): + + def __init__(self, methodName: str = "runTest") -> None: + super().__init__(methodName) + self.digest = pywd_digest.Digest() + self.digest.request_queue() + self.digest.pool_setup(1024*8, 128, 128) + + self.pt = bytes([0x01]*10) + self.iv = bytes([0x02]*16) + self.key = bytes([0x03]*16) + + self.alg = pywd_digest.DIGEST_ALG.SM3 + + + + def test_digest_sm3_normal(self): + + mode = pywd_digest.DIGEST_MODE.NORMAL + self.digest.ctx_setup(self.alg, mode) + self.digest.create_digest_ctx() + self.digest.set_opdata(self.pt, 16) + ret = self.digest.wcrypto_do_digest() + self.assertEqual(ret, 0) + + + digest_h = self.digest.get_digest() + digest_s = sm3_hash(list(self.pt)) + + # print(digest_h) + + # self.assertEqual(digest_h[0], int(digest_s[:2], base=16)) + + print("\nsm3 normal test pass") + + def test_digest_sm3_hmac(self): + + mode = pywd_digest.DIGEST_MODE.HMAC + self.digest.ctx_setup(self.alg, mode) + self.digest.create_digest_ctx() + self.digest.wcrypto_set_digest_key(self.key, len(self.key)) + self.digest.set_opdata(self.pt, 16) + ret = self.digest.wcrypto_do_digest() + self.assertEqual(ret, 0) + + digest = self.digest.get_digest() + # print(digest) + + print("\nsm3 hmac test pass") + +class TestPyWdRSA(unittest.TestCase): + + def __init__(self, methodName: str = "runTest") -> None: + super().__init__(methodName) + self.rsa = pywd_rsa.RSA() + self.rsa.request_queue() + self.rsa.pool_setup(64, 2048) + + self.msg = b'Hello World!' + self.sig = None + + # use cryptography lib + self.private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048) + public_key = self.private_key.public_key() + self.e = bytes.fromhex(f"{public_key.public_numbers().e:#0{514}x}"[2:]) + self.n = bytes.fromhex(f"{public_key.public_numbers().n:#0{514}x}"[2:]) + self.d = bytes.fromhex(f"{self.private_key.private_numbers().d:#0{514}x}"[2:]) + self.p = bytes.fromhex(f"{self.private_key.private_numbers().p:#0{258}x}"[2:]) + self.q = bytes.fromhex(f"{self.private_key.private_numbers().q:#0{258}x}"[2:]) + self.dp = bytes.fromhex(f"{self.private_key.private_numbers().dmp1:#0{258}x}"[2:]) + self.dq = bytes.fromhex(f"{self.private_key.private_numbers().dmq1:#0{258}x}"[2:]) + self.qinv = bytes.fromhex(f"{self.private_key.private_numbers().iqmp:#0{258}x}"[2:]) + + + def test_rsa_genkey_common(self): + + self.rsa.ctx_setup(0) + self.rsa.create_rsa_ctx() + + self.rsa.wcrypto_new_kg_in(self.e, self.p, self.q) + self.rsa.wcrypto_new_kg_out() + + self.rsa.set_opdata(pywd_rsa.RSA_OP_TYPE.GENKEY) + ret = self.rsa.wcrypto_do_rsa() + self.assertEqual(ret, 0) + + d, n = self.rsa.get_kg_out() + # print(d.hex(), n.hex()) + self.assertEqual(int.from_bytes(d, byteorder="big"), self.private_key.private_numbers().d) + self.assertEqual(int.from_bytes(n, byteorder="big"), self.private_key.public_key().public_numbers().n) + print("\nrsa common genkey test pass") + + + def test_rsa_genkey_crt(self): + + self.rsa.ctx_setup(1) + self.rsa.create_rsa_ctx() + + self.rsa.wcrypto_new_kg_in(self.e, self.p, self.q) + self.rsa.wcrypto_new_kg_out() + + self.rsa.set_opdata(pywd_rsa.RSA_OP_TYPE.GENKEY) + + ret = self.rsa.wcrypto_do_rsa() + + self.assertEqual(ret, 0) + dq, dp, qinv = self.rsa.get_kg_out_crt() + + self.assertEqual(int.from_bytes(dp, byteorder="big"), self.private_key.private_numbers().dmp1) + self.assertEqual(int.from_bytes(dq, byteorder="big"), self.private_key.private_numbers().dmq1) + self.assertEqual(int.from_bytes(qinv, byteorder="big"), self.private_key.private_numbers().iqmp) + + print("\nrsa ctr genkey test pass") + + def test_rsa_sign_common(self): + + self.rsa.ctx_setup(0) + self.rsa.create_rsa_ctx() + + self.rsa.wcrypto_set_rsa_prikey_params(self.d, self.n) + + self.rsa.set_opdata(pywd_rsa.RSA_OP_TYPE.SIGN, self.d) + ret = self.rsa.wcrypto_do_rsa() + self.assertEqual(ret, 0) + + self.sig = self.rsa.get_opdata_out() + + print("\nrsa sign common test pass") + + + def test_rsa_sign_crt(self): + + self.rsa.ctx_setup(1) + self.rsa.create_rsa_ctx() + + self.rsa.wcrypto_set_rsa_crt_prikey_params(self.dq, self.dp, self.qinv, self.q, self.p) + + self.rsa.set_opdata(pywd_rsa.RSA_OP_TYPE.SIGN, self.d) + ret = self.rsa.wcrypto_do_rsa() + self.assertEqual(ret, 0) + + self.sig = self.rsa.get_opdata_out() + + print("\nrsa sign crt test pass") + + def test_rsa_verify_common_and_crt(self): + self.rsa.ctx_setup(0) + self.rsa.create_rsa_ctx() + + self.rsa.wcrypto_set_rsa_pubkey_params(self.e, self.n) + sig = self.private_key.sign( + self.msg, + padding.PSS( + mgf=padding.MGF1(hashes.SHA256()), + salt_length=padding.PSS.MAX_LENGTH + ), + hashes.SHA256() + ) + + self.rsa.set_opdata(pywd_rsa.RSA_OP_TYPE.VERIFY, data=sig) + ret = self.rsa.wcrypto_do_rsa() + self.assertEqual(ret, 0) + + ver = self.rsa.get_opdata_out() + print("\nrsa verify common and crt test pass") + + + +if __name__ == '__main__': + unittest.main() + \ No newline at end of file diff --git a/test_aysnc.py b/test_aysnc.py new file mode 100644 index 0000000000000000000000000000000000000000..0df0130ec916f3d77387447253294105589be1ec --- /dev/null +++ b/test_aysnc.py @@ -0,0 +1,156 @@ +import unittest +import ctypes +from pyuadk import pywd_cipher, pywd_digest, pywd_rsa +from Crypto.Cipher import AES +import threading +from cryptography.hazmat.primitives.asymmetric import rsa + + +class test_sec_pthread_dt(ctypes.Structure): + _fields_ = [ + ("cpu_id", ctypes.c_int), + ("thread_num", ctypes.c_int), + ("pool", ctypes.POINTER(ctypes.c_void_p)), + ("q", ctypes.POINTER(ctypes.c_void_p)), + ("send_task_num", ctypes.c_uint32), + ("recv_task_num", ctypes.c_uint32), + ] + + +class Cipher_Async_Tag(ctypes.Structure): + _fields_ = [ + ("ctx", ctypes.POINTER(ctypes.c_void_p)), + ("thread_id", ctypes.c_int), + ("cnt", ctypes.c_int), + ("thread_info", ctypes.POINTER(test_sec_pthread_dt)), + ] + + +def cipher_cb(message, cipher_tag): + tag = ctypes.cast(cipher_tag, ctypes.POINTER(Cipher_Async_Tag)).contents + thread_info = ctypes.cast( + tag.thread_info, ctypes.POINTER(test_sec_pthread_dt) + ).contents + thread_info.recv_task_num.contents.value += 1 + print("a") + + +cipher_cb_ptr = ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.c_void_p) + + +@staticmethod +def test_cb(a): + print("test cb ", a) + + +class TestPyWdCipherAsync(unittest.TestCase): + def __init__(self, methodName: str = "runTest") -> None: + super().__init__(methodName) + self.cipher = pywd_cipher.Cipher(async_mode=1) + self.cipher.request_queue() + self.cipher.pool_setup(1024 * 8, 128, 128) + self.key = bytes([0x01] * 16) + self.iv = bytes([0x02] * 16) + self.pt = bytes([0x03] * 16) + + def test_aes_ecb_async(self): + alg = pywd_cipher.CIPHER_ALG.AES + mode = pywd_cipher.CIPHER_MODE.ECB + + self.cipher.ctx_setup(alg, mode) + self.cipher.create_cipher_ctx() + + self.cipher.wcrypto_set_cipher_key(self.key, len(self.key)) + self.cipher.set_opdata(bytes([]), pywd_cipher.CIPHER_OP_TYPE.ENCRYPT, self.pt) + ret = -22 + count = 0 + self.cipher.tag_setup(0, 27694) + while ret != 0 and count < 2: + ret = self.cipher.wcrypto_do_cipher() + count += 1 + + self.cipher.wcrypto_cipher_poll(2) + self.assertEqual(ret, 0) + # print(count) + + cth = self.cipher.get_ct() + aes_ecb = AES.new(self.key, AES.MODE_ECB) + cts = aes_ecb.encrypt(self.pt) + self.assertEqual(cth[0], cts[0]) + + print("\naes ecb async test pass") + +class TestPyWdDigestAysnc(unittest.TestCase): + def __init__(self, methodName: str = "runTest") -> None: + super().__init__(methodName) + self.digest = pywd_digest.Digest(async_mode=1) + self.digest.request_queue() + self.digest.pool_setup(1024 * 8, 128, 128) + self.data = bytes([0x01] * 16) + + def test_digest_sm3_async(self): + alg = pywd_digest.DIGEST_ALG.SM3 + mode = pywd_digest.DIGEST_MODE.NORMAL + self.digest.ctx_setup(alg, mode) + self.digest.create_digest_ctx() + self.digest.set_opdata(self.data, 16) + ret = -22 + count = 0 + self.digest.tag_setup(2, 27694) + while ret != 0 and count < 2: + ret = self.digest.wcrypto_do_digest() + count += 1 + + self.digest.wcrypto_digest_poll(2) + self.assertEqual(ret, 0) + # print(count) + + digest = self.digest.get_digest() + # print(digest) + print("\nsm3 normal async test pass") + +class TestPyWdRSAAsync(unittest.TestCase): + def __init__(self, methodName: str = "runTest") -> None: + super().__init__(methodName) + self.rsa = pywd_rsa.RSA(async_mode=1) + self.rsa.request_queue() + self.rsa.pool_setup(64, 2048) + + self.private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048) + public_key = self.private_key.public_key() + self.e = bytes.fromhex(f"{public_key.public_numbers().e:#0{514}x}"[2:]) + self.n = bytes.fromhex(f"{public_key.public_numbers().n:#0{514}x}"[2:]) + self.d = bytes.fromhex(f"{self.private_key.private_numbers().d:#0{514}x}"[2:]) + self.p = bytes.fromhex(f"{self.private_key.private_numbers().p:#0{258}x}"[2:]) + self.q = bytes.fromhex(f"{self.private_key.private_numbers().q:#0{258}x}"[2:]) + self.dp = bytes.fromhex(f"{self.private_key.private_numbers().dmp1:#0{258}x}"[2:]) + self.dq = bytes.fromhex(f"{self.private_key.private_numbers().dmq1:#0{258}x}"[2:]) + self.qinv = bytes.fromhex(f"{self.private_key.private_numbers().iqmp:#0{258}x}"[2:]) + + + def test_rsa_genkey_common_async(self): + + self.rsa.ctx_setup(0) + self.rsa.create_rsa_ctx() + + self.rsa.wcrypto_new_kg_in(self.e, self.p, self.q) + self.rsa.wcrypto_new_kg_out() + + self.rsa.set_opdata(pywd_rsa.RSA_OP_TYPE.GENKEY) + ret = -22 + count = 0 + self.rsa.tag_setup(2, 27694) + while ret != 0 and count < 2: + ret = self.rsa.wcrypto_do_rsa() + count += 1 + print(count) + self.assertEqual(ret, 0) + # self.rsa.wcrypto_rsa_poll(2) + d, n = self.rsa.get_kg_out() + self.assertEqual(int.from_bytes(d, byteorder="big"), self.private_key.private_numbers().d) + self.assertEqual(int.from_bytes(n, byteorder="big"), self.private_key.public_key().public_numbers().n) + print("\nrsa common genkey async test pass") + + +if __name__ == "__main__": + unittest.main()