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}