Files
kunlun/plc/cvg/security/inc/cvg_sec_auth_ca_internal.h

557 lines
19 KiB
C
Raw Normal View History

2024-09-28 14:24:04 +08:00
/****************************************************************************
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
be copied by any method or incorporated into another program without
the express written consent of Aerospace C.Power. This Information or any portion
thereof remains the property of Aerospace C.Power. The Information contained herein
is believed to be accurate and Aerospace C.Power assumes no responsibility or
liability for its use in any way and conveys no license or title under
any patent or copyright and makes no representation or warranty that this
Information is free from patent or copyright infringement.
****************************************************************************/
#ifndef CVG_SEC_AUTH_CA_INTERNAL_H
#define CVG_SEC_AUTH_CA_INTERNAL_H
/* os shim includes */
#include "os_types.h"
#include "os_timer_api.h"
/* public api includes */
#include "plc_fr.h"
/* cvg module internal includes */
#include "cvg_api.h"
#include "cvg.h"
#include "cvg_sec_sign_cache.h"
#ifdef __cplusplus
extern "C" {
#endif
#if (PLC_SUPPORT_AUTH_TYPE == PLC_AUTH_TYPE_CA)
#pragma pack(push) /* save the pack status */
#pragma pack(1) /* 1 byte align */
/* length of identity information */
#define CVG_SEC_AUTH_CA_IDENTITY_INFO_LEN 153
/* length of identity chid id */
#define CVG_SEC_AUTH_CA_CHIP_ID_LEN 24
/* length of encrypted curve */
#define CVG_SEC_AUTH_CA_ENCRYPT_CURVE_LEN 1
/* length of identity public information */
#define CVG_SEC_AUTH_CA_PUB_INFO_LEN 64
/* length of random numbers signature */
#define CVG_SEC_AUTH_CA_RANDOM_SIGN_LEN 64
/* length of encrypted key */
#define CVG_SEC_AUTH_CA_ENCRYPT_KEY_LEN 16
/* length of encrypted iv */
#define CVG_SEC_AUTH_CA_ENCRYPT_IV_LEN 12
/* length of max encrypted iv */
#define CVG_SEC_AUTH_CA_ENCRYPT_IV_MAX_LEN 16
/* length of private key len */
#define CVG_SEC_AUTH_CA_PRI_KEY_LEN 32
/* authorize request result codes */
#define CVG_SEC_AUTH_CA_REQ_SUCC 0
#define CVG_SEC_AUTH_CA_REQ_FAIL 1
/* authorize failure as white list */
#define CVG_SEC_AUTH_CA_REQ_FAIL_AS_WL 0
/* authorize failure as identity information */
#define CVG_SEC_AUTH_CA_REQ_FAIL_AS_IDENT 1
/* authorize failure as unknown reason */
#define CVG_SEC_AUTH_CA_REQ_FAIL_AS_UNKNOWN 2
/* result of communication encryption key conf respond */
#define CVG_SEC_AUTH_CA_CEK_CNF_OK 0
#define CVG_SEC_AUTH_CA_CEK_CNF_FAIL 1
/* certificate authorization sm2 public id info */
typedef struct _cvg_sec_auth_ca_sm2_pub {
/* chip id */
uint8_t chip_id[CVG_SEC_AUTH_CA_CHIP_ID_LEN];
/* sm2 curve type. always 0 */
uint8_t sm2_curve_type;
/* sm2 public key */
uint8_t sm2_key_pub[CVG_SEC_AUTH_CA_PUB_INFO_LEN];
/* sm2 signature */
uint8_t sm2_sign[CVG_SEC_AUTH_CA_RANDOM_SIGN_LEN];
} cvg_sec_auth_ca_sm2_pub_t;
/* certificate authorization ecc public id info */
typedef struct _cvg_sec_auth_ca_ecc_pub {
/* chip id */
uint8_t chip_id[CVG_SEC_AUTH_CA_CHIP_ID_LEN];
/* ecc elliptic curve type. 1 - brainpoolP256r1, others - reserved */
uint8_t ecc_curve_type;
/* ecc public key */
uint8_t ecc_key_pub[CVG_SEC_AUTH_CA_PUB_INFO_LEN];
/* ecc signature */
uint8_t ecc_sign[CVG_SEC_AUTH_CA_RANDOM_SIGN_LEN];
} cvg_sec_auth_ca_ecc_pub_t;
#pragma pack(pop) /* restore the pack status */
/* define max length of authorized key buffer */
#define CVG_SEC_AUTH_CA_KEY_MAX_LEN (16)
/* define max count of cached cek */
#define CVG_SEC_AUTH_CA_KEY_CNT (4)
/* define CEK life time, unit is 1s */
#define CVG_SEC_AUTH_CA_CEK_LIFE_DUR_MIN (1 * 60 * 60)
#define CVG_SEC_AUTH_CA_CEK_LIFE_DUR_MAX (48 * 60 * 60)
#define CVG_SEC_AUTH_CA_CEK_LIFE_DUR_DEFAULT (24 * 60 * 60)
/* define CEK life over hold time, unit is 1s */
#define CVG_SEC_AUTH_CA_CEK_HOLD_DUR (10 * 60)
/* certificate authorization sm2/ecc private key */
typedef struct _cvg_sec_auth_ca_key_pri {
/* sm2 private key */
uint8_t sm2_key_pri[CVG_SEC_AUTH_CA_PRI_KEY_LEN];
/* ecc private key */
uint8_t ecc_key_pri[CVG_SEC_AUTH_CA_PRI_KEY_LEN];
} cvg_sec_auth_ca_key_pri_t;
/* communication encryption key info */
typedef struct _cvg_sec_auth_ca_cek {
/* cek start timestamp, unit is 1s */
uint32_t key_start_ts;
/* cek life time, unit is 1s */
uint32_t key_life_dur;
/* cek */
uint8_t key[CVG_SEC_AUTH_CA_KEY_MAX_LEN];
} cvg_sec_auth_ca_cek_t;
/* certificate authorization id */
typedef struct _cvg_sec_auth_ca_ident {
/* certificate authorization sm2 public info */
cvg_sec_auth_ca_sm2_pub_t sm2_pub;
/* certificate authorization ecc public info */
cvg_sec_auth_ca_ecc_pub_t ecc_pub;
/* certificate authorization sm2/ecc private key */
cvg_sec_auth_ca_key_pri_t key_pri;
} cvg_sec_auth_ca_ident_t;
/* persistent info that won't be cleared when auth reset */
typedef struct _cvg_sec_auth_cco_persist_info {
/* communication encryption key sequence */
uint8_t cek_seq : 2,
/* reserved for future */
rsvd1 : 6;
} cvg_sec_auth_cco_persist_info_t;
/* authorized common info */
typedef struct _cvg_sec_auth {
/* enable flag */
uint8_t enable : 1,
/* encryption compatible mode, see ENCRYP_MODE_XXX */
encrypt_mode : 1,
/* encryption algorithm, see ENCRYPT_ALGO_XXX */
encrypt_algo : 1,
/* selected key suit include international or national encryption,
* see ECDHE_ECDSA_WITH_XXX
*/
selected_key_suit : 1,
/* selected curve, it is valid only when select international
* encryption algorithm. 0 stand for brainpoolP256r1, and other
* value is reserved
*/
selected_curve : 1,
/* reserved for future */
rsvd1 : 3;
/* bitmap of cek valid seq */
uint8_t cek_bm_valid : 4,
/* reserved for future */
rsvd2 : 4;
/* async crypto series number, 0 is invalid */
uint32_t crypto_sn;
/* cek life time, unit is 1s */
uint32_t cek_life_dur;
/* authorized check timer */
timer_id_t auth_timer;
/* communication management key */
uint8_t cmk[CVG_SEC_AUTH_CA_KEY_MAX_LEN];
/* communication encryption key */
cvg_sec_auth_ca_cek_t cek[CVG_SEC_AUTH_CA_KEY_CNT];
/* certificate authorization id */
cvg_sec_auth_ca_ident_t *ca_id;
/* signature list table */
cvg_sec_sign_cache_tab_t *sign;
} cvg_sec_auth_t;
/* cco authorized ca state info */
typedef struct _cvg_sec_auth_cco {
/* persistent info that shall not be clear when auth reset */
cvg_sec_auth_cco_persist_info_t pst_info;
/* timestamp of last broadcast cek */
uint32_t last_bcast_cek_ts;
/* cek broadcast tx retry count */
uint8_t cek_bcast_cnt;
} cvg_sec_auth_cco_t;
/* sta security authorized states */
typedef enum {
/* sta device network authorized initial state */
sta_auth_state_init = 1,
/* sta device is applying for network cmk */
sta_auth_state_cmking,
/* sta device have got nmk, and is applying for network cek */
sta_auth_state_ceking,
/* sta device network authorized completion state */
sta_auth_state_done,
} cvg_sec_auth_sta_state_t;
/* security authorized event definitions */
typedef enum {
/* start event */
sec_auth_event_start = 1,
/* timeout event */
sec_auth_event_timeout,
/* cmk req event */
sec_auth_event_cmk_req,
/* cmk cnf event */
sec_auth_event_cmk_cnf,
/* crypto completed event */
sec_auth_event_crypto_done,
/* cek update event */
sec_auth_event_cek_update,
/* cek cnf event */
sec_auth_event_cek_cnf,
} cvg_sec_auth_event_t;
/* persistent info that won't be cleared when auth reset */
typedef struct _cvg_sec_auth_sta_persist_info {
/* authorized state, sta_auth_state_XXX */
cvg_sec_auth_sta_state_t auth_state;
/* network id */
uint32_t nid : 24,
/* network serial number */
network_sn : 8;
/* time stamp of starting authorization for current network. unit is 1s */
uint32_t auth_ts;
/* mac address of cco */
uint8_t cco_addr[IOT_MAC_ADDR_LEN];
/* auth random number used by sta to verify the cco identity */
uint8_t auth_rand_num[CVG_SEC_AUTH_CA_RANDOM_SIGN_LEN];
} cvg_sec_auth_sta_persist_info_t;
/* sta authorized state info */
typedef struct _cvg_sec_auth_sta {
/* persistent info that shall not be clear when auth reset */
cvg_sec_auth_sta_persist_info_t pst_info;
/* timestamp of last request cek, unit is 1s */
uint32_t last_cek_req_ts;
/* communication encryption key sequence */
uint8_t cek_seq : 2,
/* reserved for future */
rsvd1 : 6;
} cvg_sec_auth_sta_t;
typedef struct _cvg_sec_auth_vdev {
/* authorized common info */
cvg_sec_auth_t auth;
union {
cvg_sec_auth_sta_t *sta;
cvg_sec_auth_cco_t *cco;
} desc;
} cvg_sec_auth_vdev_t;
/* authorization request description */
typedef struct _cvg_sec_auth_req {
/* authorization timeout duration */
uint32_t auth_dur;
/* temp proxy */
uint16_t tmp_pco;
/* link type of temp proxy */
uint8_t tmp_pco_link;
} cvg_sec_auth_req_t;
/* authorization crypto result description */
typedef struct _cvg_sec_auth_crypto {
/* crypto calculate type, see IOT_CRYPTO_CALC_TYPE_XXX */
uint8_t type;
/* crypto result, see CRYPTO_RET_XXX */
uint8_t result;
} cvg_sec_auth_crypto_t;
/* authorization confirm description */
typedef struct _cvg_sec_auth_cnf {
/* authorize result, see CVG_SEC_AUTH_CA_REQ_XXX */
uint8_t auth_ret :1,
/* authorize failure reason, see CVG_SEC_AUTH_CA_REQ_FAIL_AS_XXX */
fail_reason :2,
/* selected key suit include international or national encryption,
* see ECDHE_ECDSA_WITH_XXX
*/
selected_key_suit :1,
/* selected curve, it is valid only when select international
* encryption algorithm. 0 stand for brainpoolP256r1, and other
* value is reserved
*/
selected_curve :1,
/* reserved for future */
rsvd :3;
/* station mac address */
uint8_t mac[IOT_MAC_ADDR_LEN];
/* identity information, come from state grid measurement center */
uint8_t identity_info[CVG_SEC_AUTH_CA_IDENTITY_INFO_LEN];
/* random numbers signature for authorization */
uint8_t random_sign[CVG_SEC_AUTH_CA_RANDOM_SIGN_LEN];
/* cmk encrypted with STA public key */
uint8_t encrypt_cmk[CVG_SEC_AUTH_CA_ENCRYPT_KEY_LEN];
} cvg_sec_auth_cnf_t;
/* communication encryption key confirm MME */
typedef struct _cvg_sec_auth_cek_cnf {
/* cek request result, see CVG_SEC_AUTH_CA_CEK_CNF_XXX */
uint8_t result :1,
/* communication encryption key sequence, reply requesting cek if
* request success, otherwise reply currrent using cek
*/
cek_seq :2,
/* reserved for future */
rsvd :5;
/* countdown of using this cek, unit is 10s */
uint16_t cek_countdown;
/* this cek duration valid time, unit is 10s */
uint16_t cek_dur;
/* iv vector, it is randomly generated by CCO, and using for encrypting CEK
* with CMK
*/
uint8_t iv[CVG_SEC_AUTH_CA_ENCRYPT_IV_MAX_LEN];
/* communication encryption key requested, and encrypted with cmk */
uint8_t cek[CVG_SEC_AUTH_CA_ENCRYPT_KEY_LEN];
} cvg_sec_auth_cek_cnf_t;
/*
* @brief cvg_sec_auth_ca_init() - init authorized ca state info
* @param vdev: pointer to vdev
* @param cfg: pointer of vdev configuration
*
* @return 0 - for success case
* @return otherwise - error code
*/
uint32_t cvg_sec_auth_ca_init(cvg_vdev_t *vdev, cvg_vdev_cfg_t *cfg);
/*
* @brief cvg_sec_auth_ca_deinit() - deinit authorized ca state info
* @param vdev: pointer to vdev
*/
void cvg_sec_auth_ca_deinit(cvg_vdev_t *vdev);
/*
* @brief cvg_sec_auth_ca_reset() - reset authorized ca state info
* @param vdev: pointer to vdev
*/
void cvg_sec_auth_ca_reset(cvg_vdev_t *vdev, cvg_vdev_cfg_t *cfg);
/*
* @brief cvg_sec_auth_ca_get_cek() - get cek by cek_seq
* @param vdev: pointer to vdev
* @param cek_seq: cek_seq
*
* @return pointer to cek
*/
uint8_t *cvg_sec_auth_ca_get_cek(cvg_vdev_t *vdev, uint8_t cek_seq);
/**
* @brief cvg_sec_auth_ca_restart_timer() - restart authorized timer.
* @param vdev: pointer to vdev
* @param dur: duration
*/
void cvg_sec_auth_ca_restart_timer(cvg_vdev_t *vdev, uint32_t dur);
/**
* @brief cvg_sec_auth_ca_stop_timer() - stop authorized timer.
* @param vdev: pointer to vdev
*/
void cvg_sec_auth_ca_stop_timer(cvg_vdev_t *vdev);
/*
* @brief cvg_sec_auth_ca_get_cek_info() - get cek info by cek seq
* @param vdev: pointer to cvg vdev
* @param cek_seq: communication encryption key sequence
* @param key: encryption key for return
* @param key_len: encryption key length
* @param countdown: countdown of the key for return
* @param life_time: life time of the key for return
* @param remain_life_time: remaining life time of the key for return
* return:
* ERR_OK -- for success case
* otherwise -- error code
*/
uint8_t cvg_sec_auth_ca_get_cek_info(cvg_vdev_t *vdev, uint8_t cek_seq,
uint8_t *key, uint32_t key_len, uint32_t *countdown, uint32_t *life_time,
uint32_t *remain_life_time);
/*
* @brief cvg_sec_auth_ca_get_next_seq() - get next seq
* @param cek_seq: key sequence
* return: next key sequence
*/
static inline uint8_t cvg_sec_auth_ca_get_next_seq(uint8_t cek_seq)
{
cek_seq++;
if (cek_seq >= CVG_SEC_AUTH_CA_KEY_CNT) {
cek_seq = 0;
}
return cek_seq;
}
/*
* @brief cvg_sec_auth_ca_share_crypto() - encrypt or decrypt data by share key
* @param vdev: pointer to cvg vdev
* @param indata: input data
* @param indata_len: input data length
* @param outdata: output data
* @param is_encrypt: encrypt flag, 1 - encrypt, 0 - decrypt
* @param iv: iv vector, it is the first 16 bytes of auth_cnf_t
* @param share_key: the share key generated by KDF
* @param key_len: length of share key
* return:
* CRYPTO_RET_OK -- for success case
* otherwise -- error code
*/
uint32_t cvg_sec_auth_ca_share_crypto(cvg_vdev_t *vdev, uint8_t *indata,
uint32_t indata_len, uint8_t *outdata, uint8_t is_encrypt, uint8_t *iv,
uint8_t *share_key, uint16_t key_len);
/**
* @brief cvg_sec_auth_ca_set_cek_to_mac() - set authorized cek to mac
* @param vdev: pointer to cvg vdev
* @param cek_seq1: the cek in order 1
* @param cek_seq2: pointer to the cek in order 2
*/
void cvg_sec_auth_ca_set_cek_to_mac(cvg_vdev_t *vdev, uint8_t cek_seq1,
uint8_t *cek_seq2);
#if (PLC_SUPPORT_CCO_ROLE)
/*
* @brief cvg_sec_auth_ca_cco_stop() - stop authorized ca vdev state
* @param vdev: pointer to vdev
*/
void cvg_sec_auth_ca_cco_stop(cvg_vdev_t *vdev);
/*
* cvg_sec_auth_ca_cco_sm() - ca vdev state machine
* @vdev: vdev pointer of the state machine
* @event: event to be delivered
* @data: data pointer of the event
* @return:
* 0 - restart not required
* otherwise - restart required
*/
uint8_t cvg_sec_auth_ca_cco_sm(cvg_vdev_t *vdev, cvg_sec_auth_event_t event,
void *data);
#else /* PLC_SUPPORT_CCO_ROLE */
#define cvg_sec_auth_ca_cco_stop(vdev)
#define cvg_sec_auth_ca_cco_sm(vdev, event, data) (0)
#endif /* PLC_SUPPORT_CCO_ROLE */
#if (PLC_SUPPORT_STA_ROLE)
/*
* cvg_sec_auth_ca_sta_sm() - ca vdev state machine
* @vdev: vdev pointer of the state machine
* @event: event to be delivered
* @data: data pointer of the event
* @auth_dur: authorization timer duration
* @return:
* 0 - restart not required
* otherwise - restart required
*/
uint8_t cvg_sec_auth_ca_sta_sm(cvg_vdev_t *vdev, cvg_sec_auth_event_t event,
void *data);
/*
* @brief cvg_sec_auth_ca_sta_cmk_req_internal() - sta device cmk request handle
* @param vdev: pointer to cvg vdev
* @param auth_req: authorization request description
*/
void cvg_sec_auth_ca_sta_cmk_req_internal(cvg_vdev_t *vdev,
cvg_sec_auth_req_t *auth_req);
/*
* @brief cvg_sec_auth_ca_sta_cmk_cnf_internal() - sta device cmk rx handle
* @param vdev: pointer to cvg vdev
* @param auth_cnf: pointer to authorization confirm description
*/
void cvg_sec_auth_ca_sta_cmk_cnf_internal(cvg_vdev_t *vdev,
cvg_sec_auth_cnf_t *auth_cnf);
/*
* @brief cvg_sec_auth_ca_sta_cek_cnf_internal() - sta device cek rx handle
* @param vdev: pointer to cvg vdev
* @param cek_cnf: pointer to cek config description
*/
void cvg_sec_auth_ca_sta_cek_cnf_internal(cvg_vdev_t *vdev,
cvg_sec_auth_cek_cnf_t *cek_cnf);
/*
* @brief cvg_sec_auth_ca_sta_cek_update_internal() - sta device cek update rx
* handle
* @param vdev: pointer to cvg vdev
* @param cek_cnf: pointer to cek config description
*/
void cvg_sec_auth_ca_sta_cek_update_internal(cvg_vdev_t *vdev,
cvg_sec_auth_cek_cnf_t *cek_cnf);
#else /* PLC_SUPPORT_STA_ROLE */
#define cvg_sec_auth_ca_sta_sm(vdev, event, data) (0)
#define cvg_sec_auth_ca_sta_cmk_req_internal(vdev, auth_req)
#define cvg_sec_auth_ca_sta_cmk_cnf_internal(vdev, auth_cnf)
#define cvg_sec_auth_ca_sta_cek_cnf_internal(vdev, cek_cnf)
#define cvg_sec_auth_ca_sta_cek_update_internal(vdev, cek_cnf)
#endif /* PLC_SUPPORT_STA_ROLE */
#else /* (PLC_SUPPORT_AUTH_TYPE == PLC_AUTH_TYPE_CA) */
#define cvg_sec_auth_ca_init(vdev, cfg) (0)
#define cvg_sec_auth_ca_deinit(vdev)
#define cvg_sec_auth_ca_reset(vdev, cfg)
#define cvg_sec_auth_ca_cco_stop(vdev)
#define cvg_sec_auth_ca_set_cek_to_mac(vdev, cek_seq1, cek_seq2)
#define cvg_sec_auth_ca_cco_sm(vdev, event, data) (0)
#define cvg_sec_auth_ca_sta_sm(vdev, event, data) (0)
#define cvg_sec_auth_ca_get_cek_info(vdev, cek_seq, key, key_len, countdown, \
life_time, remain_life_time) (ERR_FAIL)
#define cvg_sec_auth_ca_get_next_seq(seq) (seq)
#define cvg_sec_auth_ca_share_crypto(vdev, indata,indata_len, outdata, \
is_encrypt, iv, share_key, key_len) (CRYPTO_RET_NOSUPP)
#endif /* (PLC_SUPPORT_AUTH_TYPE == PLC_AUTH_TYPE_CA) */
#ifdef __cplusplus
}
#endif
#endif /* CVG_SEC_AUTH_CA_INTERNAL_H */