skf_api/native/
crypto.rs

1//! 密码服务接口
2//! - SKF_GetRandom
3//! - SKF_GenExtRSAKey
4//! - SKF_GenRSAKeyPair
5//! - SKF_ImportRSAKeyPair
6//! - SKF_RSASignData
7//! - SKF_RSAVerify
8//! - SKF_RSAExportSessionKey
9//! - SKF_ExtRSAPubKeyOperation
10//! - SKF_ExtRSAPriKeyOperation
11//! - SKF_GenECCKeyPair
12//! - SKF_ImportECCKeyPair
13//! - SKF_ECCSignData
14//! - SKF_ECCVerify
15//! - SKF_ECCExportSessionKey
16//! - SKF_ExtECCEncrypt
17//! - SKF_ExtECCDecrypt
18//! - SKF_ExtECCSign
19//! - SKF_ExtECCVerify
20//! - SKF_ExportPublicKey
21//! - SKF_ImportSessionKey
22//! - SKF_SetSymmKey
23//! - SKF_EncryptInit
24//! - SKF_Encrypt
25//! - SKF_EncryptUpdate
26//! - SKF_EncryptFinal
27//! - SKF_DecryptInit
28//! - SKF_Decrypt
29//! - SKF_DecryptUpdate
30//! - SKF_DecryptFinal
31//! - SKF_DegistInit
32//! - SKF_Degist
33//! - SKF_DegistUpdate
34//! - SKF_DegistFinal
35//! - SKF_MACInit
36//! - SKF_MAC
37//! - SKF_MACUpdate
38//! - SKF_MACFinal
39//!
40//! see [GM/T 0016-2012](https://github.com/guanzhi/GM-Standards/blob/master/GMT%E5%AF%86%E7%A0%81%E8%A1%8C%E6%A0%87/GMT%200017-2012%20%E6%99%BA%E8%83%BD%E5%AF%86%E7%A0%81%E9%92%A5%E5%8C%99%E5%AF%86%E7%A0%81%E5%BA%94%E7%94%A8%E6%8E%A5%E5%8F%A3%E6%95%B0%E6%8D%AE%E6%A0%BC%E5%BC%8F%E8%A7%84%E8%8C%83.PDF)
41
42use crate::native::types::{
43    BlockCipherParam, ECCCipherBlob, ECCPrivateKeyBlob, ECCPublicKeyBlob, ECCSignatureBlob,
44    EnvelopedKeyBlob, BOOL, BYTE, HANDLE, ULONG,
45};
46
47#[allow(non_camel_case_types)]
48extern "C" {
49
50    /// 产生指定长度的随机数
51    ///
52    /// [device_handle] `[IN]`设备句柄
53    pub fn SKF_GenRandom(device_handle: HANDLE, data: *mut BYTE, len: ULONG) -> ULONG;
54
55    /// 关闭会话密钥、杂凑、消息认证码句柄
56    ///
57    /// [key_handle] `[IN]`密钥句柄
58    pub fn SKF_CloseHandle(key_handle: HANDLE) -> ULONG;
59
60    /// 明文导入会话密钥,返回密钥句柄
61    ///
62    /// **本函数仅用于测试和调试,不建议用于实际的密码服务。**
63    ///
64    /// [device_handle] `[IN]`设备句柄
65    ///
66    /// [key_data] `[IN]`指向会话密钥值的缓冲区
67    ///
68    /// [alg_id] `[IN]`会话密钥的算法标识
69    ///
70    /// [key_handle] `[OUT]`返回会话密钥句柄
71    pub fn SKF_SetSymmKey(
72        device_handle: HANDLE,
73        key_data: *const BYTE,
74        alg_id: ULONG,
75        key_handle: *mut HANDLE,
76    ) -> ULONG;
77
78    /// 数据加密初始化。设置数据加密的算法相关参数。
79    ///
80    /// [key_handle] `[IN]`加密密钥句柄
81    ///
82    /// [encrypt_param] `[IN]`分组密码算法相关参数:算法标识号、密钥长度、初始向量、初始向量长度、填充方法、加密模式、反馈值的位长度
83    pub fn SKF_EncryptInit(key_handle: HANDLE, encrypt_param: BlockCipherParam) -> ULONG;
84
85    /// 单一分组数据的加密操作
86    /// 用指定加密密钥对指定数据进行加密,被加密的数据只包含一个分组,加密后的密文保存到指定的缓冲区中。
87    ///
88    /// [key_handle] `[IN]`加密密钥句柄
89    ///
90    /// [data] `[IN]`待加密数据
91    ///
92    /// [data_len] `[IN]`待加密数据长度
93    ///
94    /// [encrypted_data] `[OUT]`加密后的数据缓冲区指针
95    ///
96    /// [encrypted_len] `[IN,OUT]`输入,给出的缓冲区大小;输出,返回加密后的数据
97    /// ## 注意
98    /// - `SKF_Encrypt`只对单个分组数据进行加密,在调用`SKF_Encrypt`之前,必须调用`SKF_EncryptInit`初始化加密操作。
99    /// - `SKF_Encrypt`等价于先调用`SKF_EncryptUpdate`再调用`SKF_EncryptFinal`。
100    ///
101    /// ## 返回值
102    /// - 成功: `SAR_OK`
103    /// - 失败: `SAR_FAIL`, `SAR_MEMORYERR`, `SAR_UNKNOWNERR`,  `SAR_INVALIDPARAMERR`, `SAR_BUFFER_TOO_SMALL`
104    pub fn SKF_Encrypt(
105        key_handle: HANDLE,
106        data: *const BYTE,
107        data_len: ULONG,
108        encrypted_data: *mut BYTE,
109        encrypted_len: *mut ULONG,
110    ) -> ULONG;
111
112    /// 多个分组数据的加密操作。
113    /// 用指定加密密钥对指定数据进行加密,被加密的数据包含多个分组,加密后的密文保存到指定的缓冲区中。
114    ///
115    /// [key_handle] `[IN]`加密密钥句柄
116    ///
117    /// [data] `[IN]`待加密数据
118    ///
119    /// [data_len] `[IN]`待加密数据长度
120    ///
121    /// [encrypted_data] `[OUT]`加密后的数据缓冲区指针
122    ///
123    /// [encrypted_len] `[OUT]`返回加密后的数据长度
124    /// ## 注意
125    /// - `SKF_EncryptUpdate`对多个分组数据进行加密,在调用`SKF_EncryptUpdate`之前,必须调用`SKF_EncryptInit`初始化加密操作
126    /// - 在调用`SKF_EncryptUpdate`之后,必须调用`SKF_EncryptFinal`结束加密操作
127    pub fn SKF_EncryptUpdate(
128        key_handle: HANDLE,
129        data: *const BYTE,
130        data_len: ULONG,
131        encrypted_data: *mut BYTE,
132        encrypted_len: *mut ULONG,
133    ) -> ULONG;
134
135    /// 结束多个分组数据的加密,返回剩余加密结果。
136    ///
137    /// [key_handle] `[IN]`加密密钥句柄
138    ///
139    /// [data] `[OUT]`加密结果的缓冲区
140    ///
141    /// [data_len] `[OUT]`加密结果的长度
142    /// ## 注意
143    /// - 先调用SKF_EncryptInit初始化加密操作
144    /// - 再调用SKF_EncryptUpdate对多个分组数据进行加密
145    /// - 最后调用SKF_EncryptFinal结束多个分组数据的加密
146    pub fn SKF_EncryptFinal(key_handle: HANDLE, data: *mut BYTE, data_len: *mut ULONG) -> ULONG;
147
148    /// 初始化解密操作
149    ///
150    /// [key_handle] `[IN]`加密密钥句柄
151    ///
152    /// [decrypt_param] `[IN]`分组密码算法相关参数:算法标识号、密钥长度、初始向量、初始向量长度、填充方法、加密模式、反馈值的位长度
153    pub fn SKF_DecryptInit(key_handle: HANDLE, decrypt_param: BlockCipherParam) -> ULONG;
154
155    /// 单个分组数据的解密操作
156    ///
157    /// 用指定解密密钥对指定数据进行解密,被解密的数据只包含一个分组,解密后的明文保存到指定的缓冲区中。
158    ///
159    /// `SKF_Decrypt`只对单个分组数据进行解密,在调用`SKF_Decrypt`之前,必须调用`SKF_DecryptInit`初始化解密操作
160    ///
161    /// `SKF_Decypt`等价于先调用`SKF_DecryptUpdate`再调用`SKF_DecryptFinal`
162    ///
163    /// [key_handle] `[IN]`加密密钥句柄
164    ///
165    /// [encrypted_data] `[IN]`待解密数据
166    ///
167    /// [encrypted_len] `[IN]`待解密数据长度
168    ///
169    /// [data] `[OUT]` 指向解密后的数据缓冲区指针,当为NULL时可获得解密后的数据长度
170    ///
171    /// [data_len] `[IN,OUT]`返回解密后的数据长度
172    pub fn SKF_Decrypt(
173        key_handle: HANDLE,
174        encrypted_data: *const BYTE,
175        encrypted_len: ULONG,
176        data: *mut BYTE,
177        data_len: *mut ULONG,
178    ) -> ULONG;
179
180    /// 多个分组数据的解密操作。
181    /// 用指定解密密钥对指定数据进行解密,被解密的数据包含多个分组,解密后的明文保存到指定的缓冲区中。
182    ///
183    /// `SKF_DecryptUpdate`对多个分组数据进行解密,在调用SKF_DecryptUpdate之前,必须调用SKF_DecryptInit初始化解密操作。
184    ///
185    /// 在调用`SKF_DecryptUpdate`之后,必须调用SKF_DecryptFinal结束解密操作。
186    ///
187    /// [key_handle] `[IN]`加密密钥句柄
188    ///
189    /// [encrypted_data] `[IN]`待解密数据
190    ///
191    /// [encrypted_len] `[IN]`待解密数据长度
192    ///
193    /// [data] `[OUT]`指向解密后的数据缓冲区指针
194    ///
195    /// [data_len] `[IN,OUT]`返回解密后的数据长度
196    pub fn SKF_DecryptUpdate(
197        key_handle: HANDLE,
198        encrypted_data: *const BYTE,
199        encrypted_len: ULONG,
200        data: *mut BYTE,
201        data_len: *mut ULONG,
202    ) -> ULONG;
203
204    /// 结束多个分组数据的解密
205    ///
206    /// [key_handle] `[IN]`加密密钥句柄
207    ///
208    /// [decrypted_data] `[OUT]`解密结果的缓冲区,如果此参数为NULL时,由`decrypted_data_len`返回解密结果的长度
209    ///
210    /// [decrypted_data_len] `[IN,OUT]`调用时表示`decrypted_data`缓冲区的长度,返回解密结果的长度
211    pub fn SKF_DecryptFinal(
212        key_handle: HANDLE,
213        decrypted_data: *mut BYTE,
214        decrypted_data_len: *mut ULONG,
215    ) -> ULONG;
216
217    /// 使用外部传入的ECC公钥对输入数据做加密运算并输出结果
218    ///
219    /// [device_handle] `[IN]`设备句柄
220    ///
221    /// [key_blob] `[IN]`ECC公钥数据结构
222    ///
223    /// [data] `[IN]`待加密的明文数据
224    ///
225    /// [data_len] `[IN]`待加密明文数据的长度
226    ///
227    /// [cipher_blob] `[OUT]`密文数据
228    pub fn SKF_ExtECCEncrypt(
229        device_handle: HANDLE,
230        key_blob: *const ECCPublicKeyBlob,
231        data: *const BYTE,
232        data_len: ULONG,
233        cipher_blob: *mut ECCCipherBlob,
234    ) -> ULONG;
235
236    /// 使用外部传入的ECC私钥对输入数据做解密运算并输出结果
237    ///
238    /// [device_handle] `[IN]`设备句柄
239    ///
240    /// [key_blob] `[IN]`ECC私钥数据结构
241    ///
242    /// [cipher_blob] `[IN]`待解密的密文数据
243    ///
244    /// [data] `[OUT]`返回明文数据,如果该参数为NULL,则由data_len返回明文数据的实际长度
245    ///
246    /// [data_len] `[IN,OUT]`调用前表示data缓冲区的长度,返回明文数据的实际长度
247    pub fn SKF_ExtECCDecrypt(
248        device_handle: HANDLE,
249        key_blob: *const ECCPrivateKeyBlob,
250        cipher_blob: *const ECCCipherBlob,
251        data: *mut BYTE,
252        data_len: *mut ULONG,
253    ) -> ULONG;
254
255    /// 使用外部传入的ECC私钥对输入数据做签名运算并输出结果。
256    ///
257    /// **本函数仅用于测试和调试,不建议用于实际的密码服务。**
258    ///
259    /// [device_handle] `[IN]`设备句柄
260    ///
261    /// [key_blob] `[IN]`ECC私钥数据结构
262    ///
263    /// [data] `[IN]`待签数据的杂凑值。当使用 SM2算法时,该输入数据为待签数据经过`SM2`签名预处理的结果,预处理过程遵循`GM/T 0009`
264    ///
265    /// [data_len] `[IN]`待签名数据的长度
266    ///
267    /// [signature] `[OUT]`签名值
268    pub fn SKF_ExtECCSign(
269        device_handle: HANDLE,
270        key_blob: *const ECCPrivateKeyBlob,
271        data: *const BYTE,
272        data_len: ULONG,
273        signature: *mut ECCSignatureBlob,
274    ) -> ULONG;
275
276    /// 外部使用传入的ECC公钥做签名验证
277    ///
278    /// **本函数仅用于测试和调试,不建议用于实际的密码服务。**
279    ///
280    /// [device_handle] `[IN]`设备句柄
281    ///
282    /// [key_blob] `[IN]`ECC公钥数据结构
283    ///
284    /// [data] 待`[IN]`签数据的杂凑值。当使用 SM2算法时,该输入数据为待签数据经过`SM2`签名预处理的结果,预处理过程遵循`GM/T 0009`
285    ///
286    /// [data_len] `[IN]`待验证数据的长度
287    ///
288    /// [signature] `[IN]`签名值
289    pub fn SKF_ExtECCVerify(
290        device_handle: HANDLE,
291        key_blob: *const ECCPublicKeyBlob,
292        data: *const BYTE,
293        data_len: ULONG,
294        signature: *const ECCSignatureBlob,
295    ) -> ULONG;
296    /// 用ECC公钥对数据进行验签
297    ///
298    /// [device_handle] `[IN]`设备句柄
299    ///
300    /// [key_blob] `[IN]`ECC公钥数据结构
301    ///
302    /// [data] `[IN]`待签数据的杂凑值。当使用 SM2算法时,该输入数据为待签数据经过`SM2`签名预处理的结果,预处理过程遵循`GM/T 0009`
303    ///
304    /// [data_len] `[IN]`数据长度
305    ///
306    /// [signature] `[IN]`待验证的签名值
307    pub fn SKF_ECCVerify(
308        device_handle: HANDLE,
309        key_blob: *const ECCPublicKeyBlob,
310        data: *const BYTE,
311        data_len: ULONG,
312        signature: *const ECCSignatureBlob,
313    ) -> ULONG;
314
315    /// 生成会话密钥并用外部公钥加密输出
316    ///
317    /// [ct_handle] `[IN]`容器句柄
318    ///
319    /// [alg_id] `[IN]`会话密钥的算法标识
320    ///
321    /// [key_blob] `[IN]`外部输入的公钥结构
322    ///
323    /// [cipher_blob] `[OUT]`会话密钥密文
324    ///
325    /// [session_key] `[OUT]`会话密钥句柄
326    pub fn SKF_ECCExportSessionKey(
327        ct_handle: HANDLE,
328        alg_id: ULONG,
329        key_blob: *const ECCPublicKeyBlob,
330        cipher_blob: *mut ECCCipherBlob,
331        session_key: *mut HANDLE,
332    ) -> ULONG;
333
334    /// 生成ECC签名密钥对
335    ///
336    /// [ct_handle] `[IN]`容器句柄
337    ///
338    /// [alg_id] `[IN]`算法标识,只支持`SGD_SM2_1`算法。
339    ///
340    /// [key_blob] `[OUT]`返回ECC公钥数据结构
341    ///
342    /// ## 权限要求
343    /// 需要用户权限
344    pub fn SKF_GenECCKeyPair(
345        ct_handle: HANDLE,
346        alg_id: ULONG,
347        key_blob: *mut ECCPublicKeyBlob,
348    ) -> ULONG;
349
350    /// 导入ECC公私钥对
351    ///
352    /// [ct_handle] `[IN]`容器句柄
353    ///
354    /// [key_blob] `[IN]`ECC公私钥数据结构
355    ///
356    /// ## 权限要求
357    /// 需要用户权限
358    pub fn SKF_ImportECCKeyPair(ct_handle: HANDLE, key_blob: *const EnvelopedKeyBlob) -> ULONG;
359
360    /// 导出容器中的签名公钥或者加密公钥
361    ///
362    /// [ct_handle] `[IN]`容器句柄
363    ///
364    /// [sign_flag] `[IN]`TRUE表示导出签名公钥,FALSE表示导出加密公钥
365    ///
366    /// [data] `[OUT]`指向导出公钥结构的缓冲区,指向 RSA 公钥结构(`RSAPublicKeyBlob`)或者 ECC公钥结构(`ECCPublicKeyBlob`),如果此参数为`NULL`时,由data_len返回长度。
367    ///
368    /// [data_len] `[IN,OUT]`输入时表示导出公钥缓冲区的长度,输出时表示导出公钥结构的大小
369    pub fn SKF_ExportPublicKey(
370        ct_handle: HANDLE,
371        sign_flag: BOOL,
372        data: *mut BYTE,
373        data_len: *mut ULONG,
374    ) -> ULONG;
375
376    /// ECC数字签名,采用 ECC 算法和指定私钥对指定数据进行数字签名,签名后的结果存放到signature中。
377    ///
378    /// [ct_handle] `[IN]`容器句柄
379    ///
380    /// [data] `[IN]`待签名的数据,当使用 SM2算法时,该输入数据为待签数据经过`SM2`签名预处理的结果,预处理过程遵循`GM/T 0009`。
381    ///
382    /// [data_len] `[IN]`待签名数据长度,必须小于密钥模长。
383    ///
384    /// [signature] `[OUT]`签名值
385    /// ## 权限要求
386    /// 需要用户权限
387    pub fn SKF_ECCSignData(
388        ct_handle: HANDLE,
389        data: *const BYTE,
390        data_len: ULONG,
391        signature: *mut ECCSignatureBlob,
392    ) -> ULONG;
393
394    /// 使用ECC密钥协商算法,为计算会话密钥而产生协商参数,返回临时ECC密钥对的公钥及协商句柄
395    ///
396    /// [ct_handle] `[IN]`容器句柄
397    ///
398    /// [alg_id] `[IN]`会话密钥算法标识
399    ///
400    /// [key_blob] `[OUT]`发起方临时ECC公钥
401    ///
402    /// [id_data] `[IN]`发起方的ID
403    ///
404    /// [id_len] `[IN]`发起方ID的长度,不大于32
405    ///
406    /// [key_handle] `[OUT]`返回的密钥协商句柄
407    pub fn SKF_GenerateAgreementDataWithECC(
408        ct_handle: HANDLE,
409        alg_id: ULONG,
410        key_blob: *mut ECCPublicKeyBlob,
411        id_data: *const BYTE,
412        id_len: ULONG,
413        key_handle: *mut HANDLE,
414    ) -> ULONG;
415
416    /// 使用ECC密钥协商算法,产生协商参数并计算会话密钥,输出临时ECC密钥对公钥,并返回产生的密钥句柄
417    ///
418    /// [ct_handle] `[IN]`容器句柄
419    ///
420    /// [alg_id] `[IN]`会话密钥算法标识
421    ///
422    /// [sponsor_key] `[IN]`发起方的ECC公钥
423    ///
424    /// [sponsor_tmp_key] `[IN]`发起方的临时ECC公钥
425    ///
426    /// [key_blob] `[OUT]`响应方的临时ECC公钥
427    ///
428    /// [id] `[IN]`响应方的ID
429    ///
430    /// [id_len] `[IN]`响应方ID的长度,不大于32
431    ///
432    /// [sponsor_id] `[IN]`发起方的ID
433    ///
434    /// [sponsor_id_len] `[IN]`发起方ID的长度,不大于32
435    ///
436    /// [key_handle] `[OUT]` 返回对称算法密钥句柄
437    pub fn SKF_GenerateAgreementDataAndKeyWithECC(
438        ct_handle: HANDLE,
439        alg_id: ULONG,
440        sponsor_key: *const ECCPublicKeyBlob,
441        sponsor_tmp_key: *const ECCPublicKeyBlob,
442        tmp_key: *mut ECCPublicKeyBlob,
443        id: *const BYTE,
444        id_len: ULONG,
445        sponsor_id: *const BYTE,
446        sponsor_id_len: ULONG,
447        key_handle: *mut HANDLE,
448    ) -> ULONG;
449
450    /// 导入会话密钥
451    ///
452    /// [ct_handle] `[IN]`容器句柄
453    ///
454    /// [alg_id] `[IN]`会话密钥的算法标识
455    ///
456    /// [data] `[IN]`要导入的会话密钥密文。当容器为 ECC 类型时,此参数为ECCCipherBlob密文数据,当容器为RSA类型时,此参数为RSA公钥加密后的数据
457    ///
458    /// [data_len] `[IN]`会话密钥密文长度
459    ///
460    /// [key_handle] `[OUT]`返回会话密钥句柄
461    /// ## 权限要求
462    /// 需要用户权限
463    pub fn SKF_ImportSessionKey(
464        ct_handle: HANDLE,
465        alg_id: ULONG,
466        data: *const BYTE,
467        data_len: ULONG,
468        key_handle: *mut HANDLE,
469    ) -> ULONG;
470
471    /// 使用ECC密钥协商算法,使用自身协商句柄和响应方的协商参数计算会话密钥,同时返回会话密钥句柄
472    ///
473    /// [agreement_key] `[IN]`密钥协商句柄
474    ///
475    /// [key_blob] `[IN]`外部输入的响应方ECC公钥
476    ///
477    /// [tmp_key] `[IN]`外部输入的响应方临时ECC公钥
478    ///
479    /// [id] `[IN]`响应方的ID
480    ///
481    /// [id_len] `[IN]`响应方ID的长度,不大于32
482    ///
483    /// [key_handle] `[OUT]`返回的密钥句柄
484    pub fn SKF_GenerateKeyWithECC(
485        agreement_key: HANDLE,
486        key_blob: *const ECCPublicKeyBlob,
487        tmp_key_blob: *const ECCPublicKeyBlob,
488        id: *const BYTE,
489        id_len: ULONG,
490        key_handle: *mut HANDLE,
491    ) -> ULONG;
492}