1/*
2 * @file hi_cipher.h
3 *
4 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18/** @defgroup iot_cipher Cipher APIs
19 * @ingroup iot_romboot
20 */
21#ifndef __HI_CIPHER_H__
22#define __HI_CIPHER_H__
23
24#include <hi_types.h>
25#include <hi_boot_err.h>
26
27#ifdef __cplusplus
28#if __cplusplus
29extern "C" {
30#endif
31#endif  /* __cplusplus */
32
33#define PKE_LEN_32_BYTES             32
34#define PKE_LEN_256_BYTES            256
35#define PKE_LEN_384_BYTES            384
36#define PKE_LEN_512_BYTES            512
37#define RSA_KEY_LEN_2048             256
38#define AES_MAX_KEY_IN_WORD          16
39#define AES_IV_LEN_IN_WORD           4
40#define KDF_KEY_LEN_IN_BYTES         32
41
42/**
43* @ingroup iot_cipher
44* Rsa sign and veriry scheme
45*/
46typedef enum {
47    HI_CIPHER_RSA_SIGN_SCHEME_RSASSA_PKCS1_V15_SHA256 = 0x00,   /* PKCS#1 RSASSA_PKCS1_V15_SHA256 signature */
48    HI_CIPHER_RSA_SIGN_SCHEME_RSASSA_PKCS1_PSS_SHA256,          /* PKCS#1 RSASSA_PKCS1_PSS_SHA256 signature */
49    HI_CIPHER_RSA_SIGN_SCHEME_MAX,
50    HI_CIPHER_RSA_SIGN_SCHEME_INVALID = 0xffffffff,
51}hi_cipher_rsa_sign_scheme;
52
53/**
54* @ingroup iot_cipher
55* Aes key from
56*/
57typedef enum {
58    HI_CIPHER_AES_KEY_FROM_CPU = 0x00,
59    HI_CIPHER_AES_KEY_FROM_KDF,
60    HI_CIPHER_AES_KEY_FROM_MAX,
61    HI_CIPHER_AES_KEY_FROM_INVALID = 0xffffffff,
62}hi_cipher_aes_key_from;
63
64/**
65* @ingroup iot_cipher
66* Aes work mode
67*/
68typedef enum {
69    HI_CIPHER_AES_WORK_MODE_ECB = 0x00,    /* Electronic codebook (ECB) mode, ECB has been considered insecure and
70                                               it is recommended not to use it. */
71    HI_CIPHER_AES_WORK_MODE_CBC,            /* Cipher block chaining (CBC) mode. */
72    HI_CIPHER_AES_WORK_MODE_CTR,            /* Counter (CTR) mode. */
73    HI_CIPHER_AES_WORK_MODE_XTS,            /* XTS-AES (XTS) mode. */
74    HI_CIPHER_AES_WORK_MODE_MAX,
75    HI_CIPHER_AES_WORK_MODE_INVALID = 0xffffffff,
76}hi_cipher_aes_work_mode;
77
78/**
79* @ingroup iot_cipher
80* Aes key length
81*/
82typedef enum {
83    HI_CIPHER_AES_KEY_LENGTH_128BIT  = 0x00,
84    HI_CIPHER_AES_KEY_LENGTH_192BIT,
85    HI_CIPHER_AES_KEY_LENGTH_256BIT,
86    HI_CIPHER_AES_KEY_LENGTH_512BIT,             /* 512bit, just used for xts. */
87    HI_CIPHER_AES_KEY_LENGTH_MAX,
88    HI_CIPHER_AES_KEY_LENGTH_INVALID = 0xffffffff,
89}hi_cipher_aes_key_length;
90
91/**
92* @ingroup iot_cipher
93* Rsa public key verify
94*/
95typedef struct {
96    hi_cipher_rsa_sign_scheme scheme;  /* The rsa sign type */
97    hi_u8 *e;                          /* The public exponent */
98    hi_u8 *n;                          /* The modulus */
99    hi_u32 klen;                       /* The key length */
100} hi_cipher_rsa_verify;
101
102/**
103* @ingroup iot_cipher
104* Struct of ecc curves parameters
105*/
106typedef struct {
107    const hi_u8 *p;   /* Finite field: equal to p in case of prime field curves or equal to 2^n in case of binary
108                         field curves. */
109    const hi_u8 *a;   /* Curve parameter a (q-3 in Suite B). */
110    const hi_u8 *b;   /* Curve parameter b. */
111    const hi_u8 *gx;  /* X coordinates of G which is a base point on the curve. */
112    const hi_u8 *gy;  /* Y coordinates of G which is a base point on the curve. */
113    const hi_u8 *n;   /* Prime which is the order of G point. */
114    hi_u32 h;         /* Cofactor, which is the order of the elliptic curve divided by the order of the point G. For
115                         the Suite B curves, h = 1. */
116    hi_u32 ksize;     /* Ecc key size in bytes. It corresponds to the size in bytes of the prime, should be 32bytes. */
117}hi_cipher_ecc_param;
118
119/**
120* @ingroup iot_cipher
121* Struct of ecc verify
122*/
123typedef struct {
124    const hi_u8 *px;   /* Ecdh X coordinates of the generated public key, the caller ensures it is padded with leading
125                          zeros if the effective size of this key is smaller than ecc key size. */
126    const hi_u8 *py;   /* Ecdh Y coordinates of the generated public key, the caller ensures it is padded with leading
127                          zeros if the effective size of this key is smaller than ecc key size. */
128    const hi_u8 *hash; /* Input hash data for ecc verify. */
129    hi_u32 hash_len;   /* The length of hash data, just 32 bytes is valid data. */
130    const hi_u8 *r;    /* Output ecc sign result R, its length is ecc key size. */
131    const hi_u8 *s;    /* Output ecc sign result S, its length is ecc key size. */
132    hi_u8 *out_r;      /* Output verify r data for security. */
133}hi_cipher_ecc_verify;
134
135/**
136* @ingroup iot_cipher
137* Struct of rsa verify
138*/
139typedef struct {
140    hi_u8 *hash;        /* The input hash value will be changed after hi_cipher_rsa_verify_hash execution,
141                           the correct value should be input before each verification */
142    hi_u8 *out_hash;
143    hi_u32 hash_len;
144    const hi_u8 *sign;
145    hi_u32 sign_len;
146} hi_cipher_rsa_data;
147
148/**
149* @ingroup iot_cipher
150* Aes ctrl struct
151*/
152typedef struct {
153    hi_u32 key[AES_MAX_KEY_IN_WORD];     /* Key input. */
154    hi_u32 iv[AES_IV_LEN_IN_WORD];       /* Initialization vector (IV). */
155    hi_bool random_en;                   /* Enable random delay or not. */
156    hi_cipher_aes_key_from key_from;     /* Key from, When using kdf key, no nead to configure the input key. */
157    hi_cipher_aes_work_mode work_mode;   /* Work mode. */
158    hi_cipher_aes_key_length key_len;    /* Key length. aes-ecb/cbc/ctr support 128/192/256 bits key, ccm just support
159                                            128 bits key, xts just support 256/512 bits key. */
160}hi_cipher_aes_ctrl;
161
162/**
163* @ingroup iot_cipher
164* Kdf key type
165*/
166typedef enum {
167    HI_CIPHER_SSS_KDF_KEY_DEVICE  = 0x0, /* kdf device key derivation. */
168    HI_CIPHER_SSS_KDF_KEY_STORAGE,       /* kdf storage key derivation. */
169    HI_CIPHER_SSS_KDF_KEY_MAX,
170    HI_CIPHER_SSS_KDF_KEY_INVALID = 0xFFFFFFFF,
171}hi_cipher_kdf_mode;
172
173/**
174* @ingroup iot_cipher
175* Kdf ctrl struct
176*/
177typedef struct {
178    const hi_u8 *salt;                   /* salt for kdf key derivation. */
179    hi_u32 salt_len;                     /* salt_len should be 16 bytes for kdf device key derivation,
180                                            32 bytes for kdf storage key derivation. */
181    hi_u8 key[KDF_KEY_LEN_IN_BYTES];     /* just used for kdf device key. */
182    hi_cipher_kdf_mode kdf_mode;         /* kdf mode for key derivation. */
183    hi_u32 kdf_cnt;                      /**< kdf cnt for iteration.It is recommended that the number of iterations be
184        not less than 10000 times, if performance requirement, no less than 1000
185        times,  and not more than 0xffff times. */
186    hi_u8 result[KDF_KEY_LEN_IN_BYTES];  /* output for kdf device key derivation. */
187}hi_cipher_kdf_ctrl;
188
189/**
190* @ingroup        iot_cipher
191* @brief          Initializes the Cipher module. CNcomment:Cipher 模块初始化。CNend
192*
193* @par 描述:
194*                 Initializes the Cipher module.
195CNcomment:Cipher模块初始化。CNend
196*
197* @attention      This function must be called before using cipher module.
198CNcomment:使用Cipher模块算法前调用本接口初始化。CNend
199* @param          None
200*
201* @retval #HI_ERR_SUCCESS   Success
202* @retval #Other            Failure. For details, see hi_boot_err.h.
203* @par 依赖:
204*                 @li hi_cipher.h:Describes Cipher module APIs.
205CNcomment:文件用于描述Cipher模块相关接口。CNend
206* @see            hi_cipher_init。
207*/
208hi_u32 hi_cipher_init(hi_void);
209
210/**
211* @ingroup        iot_cipher
212* @brief          Deinitializes the Cipher module. CNcomment:Cipher 模块去初始化。CNend
213*
214* @par 描述:
215*                 Deinitializes the Cipher module, does NOT support multi-tasks.
216CNcomment:Cipher模块去初始化,不支持多任务。CNend
217*
218* @attention      This function could be called after using Cipher module finished.
219CNcomment:结束使用Cipher模块算法后调用本接口去初始化。CNend
220* @param          None
221*
222* @retval #HI_ERR_SUCCESS   Success
223* @retval #Other            Failure. For details, see hi_boot_err.h.
224* @par 依赖:
225*                 @li hi_cipher.h:Describes Cipher module APIs.
226CNcomment:文件用于描述Cipher模块相关接口。CNend
227* @see            hi_cipher_deinit。
228*/
229hi_u32 hi_cipher_deinit(hi_void);
230
231/**
232* @ingroup        iot_cipher
233* @brief          Settings of AES. CNcomment:AES算法参数配置。CNend
234*
235* @par 描述:
236*                 Configure of AES. CNcomment:AES算法参数配置。CNend
237*
238* @attention      None
239* @param          ctrl        [IN]  type #hi_cipher_aes_ctrl *,AES parameters. CNcomment:AES算法参数配置。CNend
240*
241* @retval #HI_ERR_SUCCESS   Success
242* @retval #Other            Failure. For details, see hi_boot_err.h.
243* @par 依赖:
244*                 @li hi_cipher.h:Describes Cipher module APIs.
245CNcomment:文件用于描述Cipher模块相关接口。CNend
246* @see            hi_cipher_aes_config。
247*/
248hi_u32 hi_cipher_aes_config(hi_cipher_aes_ctrl *ctrl);
249
250/**
251* @ingroup        iot_cipher
252* @brief          Encryption/Decryption of AES, if execution fails, hi_cipher_aes_destroy_config must be called to
253release resources.
254CNcomment:AES算法加解密,如果执行失败,必须调用hi_cipher_aes_destroy_config接口释放资源。CNend
255*
256* @par 描述:
257*                 Encryption/Decryption of AES. CNcomment:AES算法加解密。CNend
258*
259* @attention      无。
260* @param          src_addr    [IN]  type #uintptr_t,Input data source address.
261CNcomment:待加密或解密的源数据物理地址,地址要求4对齐。CNend
262* @param          dest_addr   [OUT] type #uintptr_t,output data physical address, the address must be
263aligned in 4 bytes.
264CNcomment:加密或解密结果数据物理地址,地址要求4对齐。CNend
265* @param          length      [IN]  type #hi_u32,data length, ECB/CBC/CTR/XTS must be aligned in 16 bytes.
266CNcomment:数据长度, ECB/CBC/CTR/XTS要求16bytes对齐。CNend
267* @param          encrypt     [IN]  type #hi_bool,options of encryption/decryption, HI_TRUE is for encryption,
268HI_FALSE is for decryption.CNcomment:加解密配置选项,配置HI_TRUE为加密,配置HI_FALSE为解密。CNend
269*
270* @retval #HI_ERR_SUCCESS   Success
271* @retval #Other            Failure. For details, see hi_boot_err.h.
272* @par 依赖:
273*                 @li hi_cipher.h:Describes Cipher module APIs.
274CNcomment:文件用于描述Cipher模块相关接口。CNend
275* @see            hi_cipher_aes_crypto。
276*/
277hi_u32 hi_cipher_aes_crypto(uintptr_t src_addr, uintptr_t dest_addr, hi_u32 length, hi_bool encrypt);
278
279/**
280* @ingroup        iot_cipher
281* @brief          Destory AES configures. CNcomment:AES算法销毁配置的参数CNend
282*
283* @par 描述:
284*                 Destory AES configures. CNcomment:AES算法销毁配置的参数CNend
285*
286* @attention      In pair with hi_cipher_aes_config.CNcomment:与参数配置成对使用CNend
287* @param          None
288
289* @retval #HI_ERR_SUCCESS   Success
290* @retval #Other            Failure. For details, see hi_boot_err.h.
291* @par 依赖:
292*                 @li hi_cipher.h:Describes Cipher module APIs.
293CNcomment:文件用于描述Cipher模块相关接口。CNend
294* @see            hi_cipher_aes_destroy_config。
295*/
296hi_u32 hi_cipher_aes_destroy_config(hi_void);
297
298/**
299* @ingroup        iot_cipher
300* @brief          Settings of HASH.CNcomment:HASH算法参数配置CNend
301*
302* @par 描述:
303*                 Settings of HASH, this function should be called before calculating.
304CNcomment:HASH算法参数配置,HASH计算前调用
305*
306* @attention      None
307* @param  atts    [IN]        type #const hi_cipher_hash_atts *,HASH attribute.CNcomment:HASH算法类型配置。CNend
308
309* @retval #HI_ERR_SUCCESS   Success
310* @retval #Other            Failure. For details, see hi_boot_err.h.
311* @par 依赖:
312*                 @li hi_cipher.h:Describes Cipher module APIs.
313CNcomment:文件用于描述Cipher模块相关接口。CNend
314* @see            hi_cipher_hash_start。
315*/
316hi_u32 hi_cipher_hash_start(hi_void);
317
318/**
319* @ingroup        iot_cipher
320* @brief          Calculating by HASH.CNcomment:HASH计算CNend
321*
322* @par 描述:
323*                 Hash calculation. Multiple segments can be calculated,Maximum 10KB per segment.
324CNcomment:HASH计算,支持多段计算,每段最长10KB。CNend
325*
326* @attention      None
327* @param          src_addr    [IN]  type #uintptr_t,Data address to be calculated by HASH.
328CNcomment:待HASH计算的数据地址。CNend
329* @param          length      [IN]  type #hi_u32,Data length to be calculated by HASH,maximum is 10KB.
330CNcomment:待HASH计算的数据长度,最长10KB。CNend
331*
332* @retval #HI_ERR_SUCCESS   Success
333* @retval #Other            Failure. For details, see hi_boot_err.h.
334* @par 依赖:
335*                 @li hi_cipher.h:Describes Cipher module APIs.
336CNcomment:文件用于描述Cipher模块相关接口。CNend
337* @see            hi_cipher_hash_update。
338*/
339hi_u32 hi_cipher_hash_update(uintptr_t src_addr, hi_u32 length);
340
341/**
342* @ingroup        iot_cipher
343* @brief          HASH calculation finished.CNcomment:HASH计算结束CNend
344*
345* @par 描述:
346*                 Ouput results after HASH finished calculating.CNcomment:HASH计算结束,
347输出计算结果。CNend
348*
349* @attention      None
350*
351* @param          out          [OUT]  type #hi_u8 *,Pointer to the output of the HASH calculation result.
352CNcomment:HASH计算结果输出指针。CNend
353* @param          out_len      [IN]   type #hi_u32,HASH The output pointer of the calculation result points to
354*                              the space length. The output length must be greater than or equal to 32 bytes.
355CNcomment:HASH计算结果输出指针指向空间长度,要求输出长度满足不小于32bytes。CNend
356*
357* @retval #HI_ERR_SUCCESS   Success
358* @retval #Other            Failure. For details, see hi_boot_err.h.
359* @par 依赖:
360*                 @li hi_cipher.h:Describes Cipher module APIs.
361CNcomment:文件用于描述Cipher模块相关接口。CNend
362* @see            hi_cipher_hash_final。
363*/
364hi_u32 hi_cipher_hash_final(hi_u8 *out, hi_u32 out_len);
365
366/**
367* @ingroup        iot_cipher
368* @brief          HASH calculation.CNcomment:HASH计算CNend
369*
370* @par 描述:
371*                 Performs hash calculation on a segment of data and outputs the hash result.
372CNcomment:对一段数据做HASH计算,并输出HASH结果。CNend
373*
374* @attention      None
375*
376* @param          input        [IN]  type #uintptr_t,Enter the data address. The address must be 4-bytes-aligned.
377CNcomment:输入数据地址,地址要求4对齐。CNend
378* @param          input_len    [IN]  type #hi_u32, Input data length.CNcomment:输入数据长度。CNend
379* @param          hash         [OUT] type #hi_u8 *,Output the hash result. The length is 32 bytes.
380CNcomment:输出HASH结果, 长度为 32 bytes。CNend
381* @param          hash_len     [IN]  type #hi_u32, BUF length of the hash result. The value must be greater than or
382*                              equal to 32 bytes.CNcomment:输出HASH结果的BUF长度,需要满足不小于32bytes。CNend
383*
384* @retval #HI_ERR_SUCCESS   Success
385* @retval #Other            Failure. For details, see hi_boot_err.h.
386* @par 依赖:
387*                 @li hi_cipher.h:Describes Cipher module APIs.
388CNcomment:文件用于描述Cipher模块相关接口。CNend
389* @see            hi_cipher_hash_sha256。
390*/
391hi_u32 hi_cipher_hash_sha256(uintptr_t input, hi_u32 input_len, hi_u8 *hash, hi_u32 hash_len);
392
393/**
394* @ingroup        iot_cipher
395* @brief          KDF calculation.CNcomment:KDF算法计算。CNend
396*
397* @par 描述:
398*                 KDF calculation.CNcomment:KDF算法计算。CNend
399*
400* @attention      None
401* @param          ctrl        [IN] type  #hi_cipher_kdf_ctrl*,Poninter to KDF algorithm parameter configuration
402                              control structure.CNcomment:KDF算法参数配置控制结构体。CNend
403*
404* @retval #HI_ERR_SUCCESS   Success
405* @retval #Other            Failure. For details, see hi_boot_err.h.
406* @par 依赖:
407*                 @li hi_cipher.h:Describes Cipher module APIs.
408CNcomment:文件用于描述Cipher模块相关接口。CNend
409* @see            hi_cipher_kdf_key_derive。
410*/
411hi_u32 hi_cipher_kdf_key_derive(hi_cipher_kdf_ctrl *ctrl);
412
413/**
414* @ingroup        iot_cipher
415* @brief          Rsa Signature Verification.CNcomment:Rsa 签名结果校验CNend
416*
417* @par 描述:
418*                 Rsa Signature Verification.CNcomment:Rsa 签名结果校验。CNend
419*
420* @attention      None
421* @param          rsa_verify  [IN]   type #hi_cipher_rsa_verify *,Structure of the Rsa signature result
422*                              verification algorithm.CNcomment:Rsa签名结果校验算法结构体。CNend
423* @param          hash        [IN]   type #const hi_u8 *,Hash data to be checked.
424CNcomment:待校验的HASH数据。CNend
425* @param          hash_len    [IN]   type #hi_u32, Indicates the length of the hash data to be verified.
426*                              The value is 32 bytes valid data.
427CNcomment:待校验的HASH数据的长度,为32bytes有效数据。CNend
428* @param          sign        [IN]   type #const hi_u8 *,Signature input pointer.CNcomment:签名输入指针。CNend
429* @param          sign_len    [IN]   type #hi_u32,Length of the signature result. The length is the same as the
430*                              length of the key.CNcomment:签名结果长度, 长度与key的长度相同。CNend
431*
432* @retval #HI_ERR_SUCCESS   Success
433* @retval #Other            Failure. For details, see hi_boot_err.h.
434* @par 依赖:
435*                 @li hi_cipher.h:Describes Cipher module APIs.
436CNcomment:文件用于描述Cipher模块相关接口。CNend
437* @see            hi_cipher_rsa_verify_hash。
438*/
439hi_u32 hi_cipher_rsa_verify_hash(const hi_cipher_rsa_verify *rsa_verify, hi_cipher_rsa_data *pack);
440
441/**
442* @ingroup        iot_cipher
443* @brief          Ecdsa Signature Verification.CNcomment:Ecdsa 签名结果校验CNend
444*
445* @par 描述:
446*                 Ecdsa Signature Verification.CNcomment:Ecdsa 签名结果校验。CNend
447*
448* @attention      None
449* @param          ecc          [IN]   type #const hi_cipher_ecc_param *,ECC elliptic curve parameter. If the length
450*                              is less than the size of the key, add 0 before the key.
451CNcomment:ECC椭圆曲线参数,长度不足Key的大小,前面补0。CNend
452* @param          verify       [IN]   type #const hi_cipher_ecc_verify *,Pointer to structure of the ECC public key
453*                              verification parameter.CNcomment:ECC公钥验证参数结构体。CNend
454*
455* @retval #HI_ERR_SUCCESS   Success
456* @retval #Other            Failure. For details, see hi_boot_err.h.
457* @par 依赖:
458*                 @li hi_cipher.h:Describes Cipher module APIs.
459CNcomment:文件用于描述Cipher模块相关接口。CNend
460* @see            hi_cipher_ecc_sign_hash。
461*/
462hi_u32 hi_cipher_ecc_verify_hash(hi_cipher_ecc_param *ecc, hi_cipher_ecc_verify *verify);
463
464/**
465* @ingroup        iot_cipher
466* @brief          TRNG Obtain a random number.CNcomment:TRNG获取随机数CNend
467*
468* @par 描述:
469*                 TRNG Obtain a random number. Only one word size can be obtained at a time.
470CNcomment:TRNG获取随机数,每次只能获取一个WORD大小的随机数。CNend
471*
472* @attention      None
473* @param          randnum      [OUT]  type #hi_u32 *,Random number output pointer.
474CNcomment:随机数输出指针。CNend
475*
476* @retval #HI_ERR_SUCCESS   Success
477* @retval #Other            Failure. For details, see hi_boot_err.h.
478* @par 依赖:
479*                 @li hi_cipher.h:Describes Cipher module APIs.
480CNcomment:文件用于描述Cipher模块相关接口。CNend
481* @see            hi_cipher_trng_get_random。
482*/
483hi_u32 hi_cipher_trng_get_random(hi_u32 *randnum);
484
485/**
486* @ingroup        iot_cipher
487* @brief          TRNG Obtain a random number.CNcomment:TRNG获取随机数CNend
488*
489* @par 描述:
490*                 The TRNG obtains the random number and obtains the random number of multiple bytes at a time.
491CNcomment:TRNG获取随机数,每次获取多个byte的随机数。CNend
492*
493* @attention      None
494* @param          randbyte     [OUT]  type #hi_u8 *,Random number output pointer.
495CNcomment:随机数输出指针。CNend
496* @param          size         [IN]   type #hi_u32,Length of the obtained random number.
497CNcomment:获取的随机数长度。CNend
498*
499* @retval #HI_ERR_SUCCESS   Success
500* @retval #Other            Failure. For details, see hi_boot_err.h.
501* @par 依赖:
502*                 @li hi_cipher.h:Describes Cipher module APIs.
503CNcomment:文件用于描述Cipher模块相关接口。CNend
504* @see            hi_cipher_trng_get_random。
505*/
506hi_u32 hi_cipher_trng_get_random_bytes(hi_u8 *randbyte, hi_u32 size);
507
508#ifdef __cplusplus
509#if __cplusplus
510}
511#endif
512#endif  /* __cplusplus */
513
514#endif /* __HI_CIPHER_H__ */
515