diff --git a/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c b/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c index f162eeed29..fae2168252 100644 --- a/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c +++ b/drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c @@ -2695,9 +2695,10 @@ dpaa2_sec_set_pdcp_session(struct rte_cryptodev *dev, /* Auth is only applicable for control mode operation. */ if (pdcp_xform->domain == RTE_SECURITY_PDCP_MODE_CONTROL) { - if (pdcp_xform->sn_size != RTE_SECURITY_PDCP_SN_SIZE_5) { + if (pdcp_xform->sn_size != RTE_SECURITY_PDCP_SN_SIZE_5 && + pdcp_xform->sn_size != RTE_SECURITY_PDCP_SN_SIZE_12) { DPAA2_SEC_ERR( - "PDCP Seq Num size should be 5 bits for cmode"); + "PDCP Seq Num size should be 5/12 bits for cmode"); goto out; } if (auth_xform) { @@ -2748,6 +2749,7 @@ dpaa2_sec_set_pdcp_session(struct rte_cryptodev *dev, bufsize = cnstr_shdsc_pdcp_c_plane_encap( priv->flc_desc[0].desc, 1, swap, pdcp_xform->hfn, + session->pdcp.sn_size, pdcp_xform->bearer, pdcp_xform->pkt_dir, pdcp_xform->hfn_threshold, @@ -2757,6 +2759,7 @@ dpaa2_sec_set_pdcp_session(struct rte_cryptodev *dev, bufsize = cnstr_shdsc_pdcp_c_plane_decap( priv->flc_desc[0].desc, 1, swap, pdcp_xform->hfn, + session->pdcp.sn_size, pdcp_xform->bearer, pdcp_xform->pkt_dir, pdcp_xform->hfn_threshold, @@ -2766,7 +2769,7 @@ dpaa2_sec_set_pdcp_session(struct rte_cryptodev *dev, if (session->dir == DIR_ENC) bufsize = cnstr_shdsc_pdcp_u_plane_encap( priv->flc_desc[0].desc, 1, swap, - (enum pdcp_sn_size)pdcp_xform->sn_size, + session->pdcp.sn_size, pdcp_xform->hfn, pdcp_xform->bearer, pdcp_xform->pkt_dir, @@ -2775,7 +2778,7 @@ dpaa2_sec_set_pdcp_session(struct rte_cryptodev *dev, else if (session->dir == DIR_DEC) bufsize = cnstr_shdsc_pdcp_u_plane_decap( priv->flc_desc[0].desc, 1, swap, - (enum pdcp_sn_size)pdcp_xform->sn_size, + session->pdcp.sn_size, pdcp_xform->hfn, pdcp_xform->bearer, pdcp_xform->pkt_dir, diff --git a/drivers/crypto/dpaa2_sec/hw/desc.h b/drivers/crypto/dpaa2_sec/hw/desc.h index 5d99dd8af6..e12c3db2fd 100644 --- a/drivers/crypto/dpaa2_sec/hw/desc.h +++ b/drivers/crypto/dpaa2_sec/hw/desc.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0) * * Copyright 2008-2016 Freescale Semiconductor Inc. - * Copyright 2016 NXP + * Copyright 2016, 2019 NXP * */ @@ -621,6 +621,7 @@ #define OP_PCLID_LTE_PDCP_USER (0x42 << OP_PCLID_SHIFT) #define OP_PCLID_LTE_PDCP_CTRL (0x43 << OP_PCLID_SHIFT) #define OP_PCLID_LTE_PDCP_CTRL_MIXED (0x44 << OP_PCLID_SHIFT) +#define OP_PCLID_LTE_PDCP_USER_RN (0x45 << OP_PCLID_SHIFT) /* * ProtocolInfo selectors diff --git a/drivers/crypto/dpaa2_sec/hw/desc/pdcp.h b/drivers/crypto/dpaa2_sec/hw/desc/pdcp.h index fee8441005..607c587e20 100644 --- a/drivers/crypto/dpaa2_sec/hw/desc/pdcp.h +++ b/drivers/crypto/dpaa2_sec/hw/desc/pdcp.h @@ -253,6 +253,7 @@ pdcp_insert_cplane_null_op(struct program *p, struct alginfo *cipherdata __maybe_unused, struct alginfo *authdata __maybe_unused, unsigned int dir, + enum pdcp_sn_size sn_size __maybe_unused, unsigned char era_2_sw_hfn_ovrd __maybe_unused) { LABEL(local_offset); @@ -413,8 +414,18 @@ pdcp_insert_cplane_int_only_op(struct program *p, bool swap __maybe_unused, struct alginfo *cipherdata __maybe_unused, struct alginfo *authdata, unsigned int dir, + enum pdcp_sn_size sn_size, unsigned char era_2_sw_hfn_ovrd) { + if (rta_sec_era >= RTA_SEC_ERA_8 && sn_size == PDCP_SN_SIZE_12) { + KEY(p, KEY2, authdata->key_enc_flags, authdata->key, + authdata->keylen, INLINE_KEY(authdata)); + + PROTOCOL(p, dir, OP_PCLID_LTE_PDCP_USER_RN, + (uint16_t)authdata->algtype); + return 0; + } + LABEL(local_offset); REFERENCE(move_cmd_read_descbuf); REFERENCE(move_cmd_write_descbuf); @@ -720,6 +731,7 @@ pdcp_insert_cplane_enc_only_op(struct program *p, struct alginfo *cipherdata, struct alginfo *authdata __maybe_unused, unsigned int dir, + enum pdcp_sn_size sn_size, unsigned char era_2_sw_hfn_ovrd __maybe_unused) { /* Insert Cipher Key */ @@ -727,8 +739,12 @@ pdcp_insert_cplane_enc_only_op(struct program *p, cipherdata->keylen, INLINE_KEY(cipherdata)); if (rta_sec_era >= RTA_SEC_ERA_8) { - PROTOCOL(p, dir, OP_PCLID_LTE_PDCP_CTRL_MIXED, - (uint16_t)cipherdata->algtype << 8); + if (sn_size == PDCP_SN_SIZE_5) + PROTOCOL(p, dir, OP_PCLID_LTE_PDCP_CTRL_MIXED, + (uint16_t)cipherdata->algtype << 8); + else + PROTOCOL(p, dir, OP_PCLID_LTE_PDCP_USER_RN, + (uint16_t)cipherdata->algtype << 8); return 0; } @@ -742,12 +758,12 @@ pdcp_insert_cplane_enc_only_op(struct program *p, IFB | IMMED2); SEQSTORE(p, MATH0, 7, 1, 0); MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0); - MOVE(p, DESCBUF, 8, MATH2, 0, 8, WAITCOMP | IMMED); + MOVEB(p, DESCBUF, 8, MATH2, 0, 8, WAITCOMP | IMMED); MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0); switch (cipherdata->algtype) { case PDCP_CIPHER_TYPE_SNOW: - MOVE(p, MATH2, 0, CONTEXT1, 0, 8, WAITCOMP | IMMED); + MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, WAITCOMP | IMMED); if (rta_sec_era > RTA_SEC_ERA_2) { MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0); @@ -771,7 +787,7 @@ pdcp_insert_cplane_enc_only_op(struct program *p, break; case PDCP_CIPHER_TYPE_AES: - MOVE(p, MATH2, 0, CONTEXT1, 0x10, 0x10, WAITCOMP | IMMED); + MOVEB(p, MATH2, 0, CONTEXT1, 0x10, 0x10, WAITCOMP | IMMED); if (rta_sec_era > RTA_SEC_ERA_2) { MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0); @@ -802,8 +818,8 @@ pdcp_insert_cplane_enc_only_op(struct program *p, return -ENOTSUP; } - MOVE(p, MATH2, 0, CONTEXT1, 0, 0x08, IMMED); - MOVE(p, MATH2, 0, CONTEXT1, 0x08, 0x08, WAITCOMP | IMMED); + MOVEB(p, MATH2, 0, CONTEXT1, 0, 0x08, IMMED); + MOVEB(p, MATH2, 0, CONTEXT1, 0x08, 0x08, WAITCOMP | IMMED); MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0); if (dir == OP_TYPE_ENCAP_PROTOCOL) MATHB(p, SEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, @@ -848,6 +864,7 @@ pdcp_insert_cplane_acc_op(struct program *p, struct alginfo *cipherdata, struct alginfo *authdata, unsigned int dir, + enum pdcp_sn_size sn_size, unsigned char era_2_hfn_ovrd __maybe_unused) { /* Insert Auth Key */ @@ -857,7 +874,14 @@ pdcp_insert_cplane_acc_op(struct program *p, /* Insert Cipher Key */ KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key, cipherdata->keylen, INLINE_KEY(cipherdata)); - PROTOCOL(p, dir, OP_PCLID_LTE_PDCP_CTRL, (uint16_t)cipherdata->algtype); + + if (sn_size == PDCP_SN_SIZE_5) + PROTOCOL(p, dir, OP_PCLID_LTE_PDCP_CTRL, + (uint16_t)cipherdata->algtype); + else + PROTOCOL(p, dir, OP_PCLID_LTE_PDCP_USER_RN, + ((uint16_t)cipherdata->algtype << 8) | + (uint16_t)authdata->algtype); return 0; } @@ -868,6 +892,7 @@ pdcp_insert_cplane_snow_aes_op(struct program *p, struct alginfo *cipherdata, struct alginfo *authdata, unsigned int dir, + enum pdcp_sn_size sn_size, unsigned char era_2_sw_hfn_ovrd) { LABEL(back_to_sd_offset); @@ -887,9 +912,14 @@ pdcp_insert_cplane_snow_aes_op(struct program *p, KEY(p, KEY2, authdata->key_enc_flags, authdata->key, authdata->keylen, INLINE_KEY(authdata)); - PROTOCOL(p, dir, OP_PCLID_LTE_PDCP_CTRL_MIXED, - ((uint16_t)cipherdata->algtype << 8) | - (uint16_t)authdata->algtype); + if (sn_size == PDCP_SN_SIZE_5) + PROTOCOL(p, dir, OP_PCLID_LTE_PDCP_CTRL_MIXED, + ((uint16_t)cipherdata->algtype << 8) | + (uint16_t)authdata->algtype); + else + PROTOCOL(p, dir, OP_PCLID_LTE_PDCP_USER_RN, + ((uint16_t)cipherdata->algtype << 8) | + (uint16_t)authdata->algtype); return 0; } @@ -1174,6 +1204,7 @@ pdcp_insert_cplane_aes_snow_op(struct program *p, struct alginfo *cipherdata, struct alginfo *authdata, unsigned int dir, + enum pdcp_sn_size sn_size, unsigned char era_2_sw_hfn_ovrd __maybe_unused) { KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key, @@ -1182,7 +1213,14 @@ pdcp_insert_cplane_aes_snow_op(struct program *p, INLINE_KEY(authdata)); if (rta_sec_era >= RTA_SEC_ERA_8) { - PROTOCOL(p, dir, OP_PCLID_LTE_PDCP_CTRL_MIXED, + int pclid; + + if (sn_size == PDCP_SN_SIZE_5) + pclid = OP_PCLID_LTE_PDCP_CTRL_MIXED; + else + pclid = OP_PCLID_LTE_PDCP_USER_RN; + + PROTOCOL(p, dir, pclid, ((uint16_t)cipherdata->algtype << 8) | (uint16_t)authdata->algtype); @@ -1281,6 +1319,7 @@ pdcp_insert_cplane_snow_zuc_op(struct program *p, struct alginfo *cipherdata, struct alginfo *authdata, unsigned int dir, + enum pdcp_sn_size sn_size, unsigned char era_2_sw_hfn_ovrd __maybe_unused) { LABEL(keyjump); @@ -1300,7 +1339,14 @@ pdcp_insert_cplane_snow_zuc_op(struct program *p, SET_LABEL(p, keyjump); if (rta_sec_era >= RTA_SEC_ERA_8) { - PROTOCOL(p, dir, OP_PCLID_LTE_PDCP_CTRL_MIXED, + int pclid; + + if (sn_size == PDCP_SN_SIZE_5) + pclid = OP_PCLID_LTE_PDCP_CTRL_MIXED; + else + pclid = OP_PCLID_LTE_PDCP_USER_RN; + + PROTOCOL(p, dir, pclid, ((uint16_t)cipherdata->algtype << 8) | (uint16_t)authdata->algtype); return 0; @@ -1376,6 +1422,7 @@ pdcp_insert_cplane_aes_zuc_op(struct program *p, struct alginfo *cipherdata, struct alginfo *authdata, unsigned int dir, + enum pdcp_sn_size sn_size, unsigned char era_2_sw_hfn_ovrd __maybe_unused) { LABEL(keyjump); @@ -1393,7 +1440,14 @@ pdcp_insert_cplane_aes_zuc_op(struct program *p, INLINE_KEY(authdata)); if (rta_sec_era >= RTA_SEC_ERA_8) { - PROTOCOL(p, dir, OP_PCLID_LTE_PDCP_CTRL_MIXED, + int pclid; + + if (sn_size == PDCP_SN_SIZE_5) + pclid = OP_PCLID_LTE_PDCP_CTRL_MIXED; + else + pclid = OP_PCLID_LTE_PDCP_USER_RN; + + PROTOCOL(p, dir, pclid, ((uint16_t)cipherdata->algtype << 8) | (uint16_t)authdata->algtype); @@ -1474,6 +1528,7 @@ pdcp_insert_cplane_zuc_snow_op(struct program *p, struct alginfo *cipherdata, struct alginfo *authdata, unsigned int dir, + enum pdcp_sn_size sn_size, unsigned char era_2_sw_hfn_ovrd __maybe_unused) { LABEL(keyjump); @@ -1491,7 +1546,14 @@ pdcp_insert_cplane_zuc_snow_op(struct program *p, INLINE_KEY(authdata)); if (rta_sec_era >= RTA_SEC_ERA_8) { - PROTOCOL(p, dir, OP_PCLID_LTE_PDCP_CTRL_MIXED, + int pclid; + + if (sn_size == PDCP_SN_SIZE_5) + pclid = OP_PCLID_LTE_PDCP_CTRL_MIXED; + else + pclid = OP_PCLID_LTE_PDCP_USER_RN; + + PROTOCOL(p, dir, pclid, ((uint16_t)cipherdata->algtype << 8) | (uint16_t)authdata->algtype); @@ -1594,6 +1656,7 @@ pdcp_insert_cplane_zuc_aes_op(struct program *p, struct alginfo *cipherdata, struct alginfo *authdata, unsigned int dir, + enum pdcp_sn_size sn_size, unsigned char era_2_sw_hfn_ovrd __maybe_unused) { if (rta_sec_era < RTA_SEC_ERA_5) { @@ -1602,12 +1665,19 @@ pdcp_insert_cplane_zuc_aes_op(struct program *p, } if (rta_sec_era >= RTA_SEC_ERA_8) { + int pclid; + KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key, cipherdata->keylen, INLINE_KEY(cipherdata)); KEY(p, KEY2, authdata->key_enc_flags, authdata->key, authdata->keylen, INLINE_KEY(authdata)); - PROTOCOL(p, dir, OP_PCLID_LTE_PDCP_CTRL_MIXED, + if (sn_size == PDCP_SN_SIZE_5) + pclid = OP_PCLID_LTE_PDCP_CTRL_MIXED; + else + pclid = OP_PCLID_LTE_PDCP_USER_RN; + + PROTOCOL(p, dir, pclid, ((uint16_t)cipherdata->algtype << 8) | (uint16_t)authdata->algtype); return 0; @@ -1754,7 +1824,7 @@ pdcp_insert_uplane_15bit_op(struct program *p, IFB | IMMED2); SEQSTORE(p, MATH0, 6, 2, 0); MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0); - MOVE(p, DESCBUF, 8, MATH2, 0, 8, WAITCOMP | IMMED); + MOVEB(p, DESCBUF, 8, MATH2, 0, 8, WAITCOMP | IMMED); MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0); MATHB(p, SEQINSZ, SUB, MATH3, VSEQINSZ, 4, 0); @@ -1765,7 +1835,7 @@ pdcp_insert_uplane_15bit_op(struct program *p, op = dir == OP_TYPE_ENCAP_PROTOCOL ? DIR_ENC : DIR_DEC; switch (cipherdata->algtype) { case PDCP_CIPHER_TYPE_SNOW: - MOVE(p, MATH2, 0, CONTEXT1, 0, 8, WAITCOMP | IMMED); + MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, WAITCOMP | IMMED); ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F8, OP_ALG_AAI_F8, OP_ALG_AS_INITFINAL, @@ -1774,7 +1844,7 @@ pdcp_insert_uplane_15bit_op(struct program *p, break; case PDCP_CIPHER_TYPE_AES: - MOVE(p, MATH2, 0, CONTEXT1, 0x10, 0x10, WAITCOMP | IMMED); + MOVEB(p, MATH2, 0, CONTEXT1, 0x10, 0x10, WAITCOMP | IMMED); ALG_OPERATION(p, OP_ALG_ALGSEL_AES, OP_ALG_AAI_CTR, OP_ALG_AS_INITFINAL, @@ -1787,8 +1857,8 @@ pdcp_insert_uplane_15bit_op(struct program *p, pr_err("Invalid era for selected algorithm\n"); return -ENOTSUP; } - MOVE(p, MATH2, 0, CONTEXT1, 0, 0x08, IMMED); - MOVE(p, MATH2, 0, CONTEXT1, 0x08, 0x08, WAITCOMP | IMMED); + MOVEB(p, MATH2, 0, CONTEXT1, 0, 0x08, IMMED); + MOVEB(p, MATH2, 0, CONTEXT1, 0x08, 0x08, WAITCOMP | IMMED); ALG_OPERATION(p, OP_ALG_ALGSEL_ZUCE, OP_ALG_AAI_F8, @@ -1885,6 +1955,7 @@ insert_hfn_ov_op(struct program *p, static inline enum pdb_type_e cnstr_pdcp_c_plane_pdb(struct program *p, uint32_t hfn, + enum pdcp_sn_size sn_size, unsigned char bearer, unsigned char direction, uint32_t hfn_threshold, @@ -1923,18 +1994,36 @@ cnstr_pdcp_c_plane_pdb(struct program *p, if (rta_sec_era >= RTA_SEC_ERA_8) { memset(&pdb, 0x00, sizeof(struct pdcp_pdb)); - /* This is a HW issue. Bit 2 should be set to zero, - * but it does not work this way. Override here. + /* To support 12-bit seq numbers, we use u-plane opt in pdb. + * SEC supports 5-bit only with c-plane opt in pdb. */ - pdb.opt_res.rsvd = 0x00000002; + if (sn_size == PDCP_SN_SIZE_12) { + pdb.hfn_res = hfn << PDCP_U_PLANE_PDB_LONG_SN_HFN_SHIFT; + pdb.bearer_dir_res = (uint32_t) + ((bearer << PDCP_U_PLANE_PDB_BEARER_SHIFT) | + (direction << PDCP_U_PLANE_PDB_DIR_SHIFT)); - /* Copy relevant information from user to PDB */ - pdb.hfn_res = hfn << PDCP_C_PLANE_PDB_HFN_SHIFT; - pdb.bearer_dir_res = (uint32_t) + pdb.hfn_thr_res = + hfn_threshold << PDCP_U_PLANE_PDB_LONG_SN_HFN_THR_SHIFT; + + } else { + /* This means 5-bit c-plane. + * Here we use c-plane opt in pdb + */ + + /* This is a HW issue. Bit 2 should be set to zero, + * but it does not work this way. Override here. + */ + pdb.opt_res.rsvd = 0x00000002; + + /* Copy relevant information from user to PDB */ + pdb.hfn_res = hfn << PDCP_C_PLANE_PDB_HFN_SHIFT; + pdb.bearer_dir_res = (uint32_t) ((bearer << PDCP_C_PLANE_PDB_BEARER_SHIFT) | - (direction << PDCP_C_PLANE_PDB_DIR_SHIFT)); - pdb.hfn_thr_res = - hfn_threshold << PDCP_C_PLANE_PDB_HFN_THR_SHIFT; + (direction << PDCP_C_PLANE_PDB_DIR_SHIFT)); + pdb.hfn_thr_res = + hfn_threshold << PDCP_C_PLANE_PDB_HFN_THR_SHIFT; + } /* copy PDB in descriptor*/ __rta_out32(p, pdb.opt_res.opt); @@ -2053,6 +2142,7 @@ cnstr_pdcp_u_plane_pdb(struct program *p, * @swap: must be true when core endianness doesn't match SEC endianness * @hfn: starting Hyper Frame Number to be used together with the SN from the * PDCP frames. + * @sn_size: size of sequence numbers, only 5/12 bit sequence numbers are valid * @bearer: radio bearer ID * @direction: the direction of the PDCP frame (UL/DL) * @hfn_threshold: HFN value that once reached triggers a warning from SEC that @@ -2077,6 +2167,7 @@ cnstr_shdsc_pdcp_c_plane_encap(uint32_t *descbuf, bool ps, bool swap, uint32_t hfn, + enum pdcp_sn_size sn_size, unsigned char bearer, unsigned char direction, uint32_t hfn_threshold, @@ -2087,7 +2178,7 @@ cnstr_shdsc_pdcp_c_plane_encap(uint32_t *descbuf, static int (*pdcp_cp_fp[PDCP_CIPHER_TYPE_INVALID][PDCP_AUTH_TYPE_INVALID]) (struct program*, bool swap, struct alginfo *, - struct alginfo *, unsigned int, + struct alginfo *, unsigned int, enum pdcp_sn_size, unsigned char __maybe_unused) = { { /* NULL */ pdcp_insert_cplane_null_op, /* NULL */ @@ -2152,6 +2243,11 @@ cnstr_shdsc_pdcp_c_plane_encap(uint32_t *descbuf, return -EINVAL; } + if (sn_size != PDCP_SN_SIZE_12 && sn_size != PDCP_SN_SIZE_5) { + pr_err("C-plane supports only 5-bit and 12-bit sequence numbers\n"); + return -EINVAL; + } + PROGRAM_CNTXT_INIT(p, descbuf, 0); if (swap) PROGRAM_SET_BSWAP(p); @@ -2162,6 +2258,7 @@ cnstr_shdsc_pdcp_c_plane_encap(uint32_t *descbuf, pdb_type = cnstr_pdcp_c_plane_pdb(p, hfn, + sn_size, bearer, direction, hfn_threshold, @@ -2170,7 +2267,7 @@ cnstr_shdsc_pdcp_c_plane_encap(uint32_t *descbuf, SET_LABEL(p, pdb_end); - err = insert_hfn_ov_op(p, PDCP_SN_SIZE_5, pdb_type, + err = insert_hfn_ov_op(p, sn_size, pdb_type, era_2_sw_hfn_ovrd); if (err) return err; @@ -2180,6 +2277,7 @@ cnstr_shdsc_pdcp_c_plane_encap(uint32_t *descbuf, cipherdata, authdata, OP_TYPE_ENCAP_PROTOCOL, + sn_size, era_2_sw_hfn_ovrd); if (err) return err; @@ -2197,6 +2295,7 @@ cnstr_shdsc_pdcp_c_plane_encap(uint32_t *descbuf, * @swap: must be true when core endianness doesn't match SEC endianness * @hfn: starting Hyper Frame Number to be used together with the SN from the * PDCP frames. + * @sn_size: size of sequence numbers, only 5/12 bit sequence numbers are valid * @bearer: radio bearer ID * @direction: the direction of the PDCP frame (UL/DL) * @hfn_threshold: HFN value that once reached triggers a warning from SEC that @@ -2222,6 +2321,7 @@ cnstr_shdsc_pdcp_c_plane_decap(uint32_t *descbuf, bool ps, bool swap, uint32_t hfn, + enum pdcp_sn_size sn_size, unsigned char bearer, unsigned char direction, uint32_t hfn_threshold, @@ -2232,7 +2332,8 @@ cnstr_shdsc_pdcp_c_plane_decap(uint32_t *descbuf, static int (*pdcp_cp_fp[PDCP_CIPHER_TYPE_INVALID][PDCP_AUTH_TYPE_INVALID]) (struct program*, bool swap, struct alginfo *, - struct alginfo *, unsigned int, unsigned char) = { + struct alginfo *, unsigned int, enum pdcp_sn_size, + unsigned char) = { { /* NULL */ pdcp_insert_cplane_null_op, /* NULL */ pdcp_insert_cplane_int_only_op, /* SNOW f9 */ @@ -2296,6 +2397,11 @@ cnstr_shdsc_pdcp_c_plane_decap(uint32_t *descbuf, return -EINVAL; } + if (sn_size != PDCP_SN_SIZE_12 && sn_size != PDCP_SN_SIZE_5) { + pr_err("C-plane supports only 5-bit and 12-bit sequence numbers\n"); + return -EINVAL; + } + PROGRAM_CNTXT_INIT(p, descbuf, 0); if (swap) PROGRAM_SET_BSWAP(p); @@ -2306,6 +2412,7 @@ cnstr_shdsc_pdcp_c_plane_decap(uint32_t *descbuf, pdb_type = cnstr_pdcp_c_plane_pdb(p, hfn, + sn_size, bearer, direction, hfn_threshold, @@ -2314,7 +2421,7 @@ cnstr_shdsc_pdcp_c_plane_decap(uint32_t *descbuf, SET_LABEL(p, pdb_end); - err = insert_hfn_ov_op(p, PDCP_SN_SIZE_5, pdb_type, + err = insert_hfn_ov_op(p, sn_size, pdb_type, era_2_sw_hfn_ovrd); if (err) return err; @@ -2324,6 +2431,7 @@ cnstr_shdsc_pdcp_c_plane_decap(uint32_t *descbuf, cipherdata, authdata, OP_TYPE_DECAP_PROTOCOL, + sn_size, era_2_sw_hfn_ovrd); if (err) return err; diff --git a/drivers/crypto/dpaa2_sec/hw/rta/protocol_cmd.h b/drivers/crypto/dpaa2_sec/hw/rta/protocol_cmd.h index cf8dfb910c..82581edf5b 100644 --- a/drivers/crypto/dpaa2_sec/hw/rta/protocol_cmd.h +++ b/drivers/crypto/dpaa2_sec/hw/rta/protocol_cmd.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0) * * Copyright 2008-2016 Freescale Semiconductor Inc. - * Copyright 2016 NXP + * Copyright 2016, 2019 NXP * */ @@ -596,13 +596,15 @@ static const struct proto_map proto_table[] = { /*38*/ {OP_TYPE_DECAP_PROTOCOL, OP_PCLID_LTE_PDCP_CTRL_MIXED, __rta_lte_pdcp_mixed_proto}, {OP_TYPE_DECAP_PROTOCOL, OP_PCLID_IPSEC_NEW, __rta_ipsec_proto}, +/*40*/ {OP_TYPE_DECAP_PROTOCOL, OP_PCLID_LTE_PDCP_USER_RN, + __rta_lte_pdcp_mixed_proto}, }; /* * Allowed OPERATION protocols for each SEC Era. * Values represent the number of entries from proto_table[] that are supported. */ -static const unsigned int proto_table_sz[] = {21, 29, 29, 29, 29, 35, 37, 39}; +static const unsigned int proto_table_sz[] = {21, 29, 29, 29, 29, 35, 37, 40}; static inline int rta_proto_operation(struct program *program, uint32_t optype, diff --git a/drivers/crypto/dpaa_sec/dpaa_sec.c b/drivers/crypto/dpaa_sec/dpaa_sec.c index 758f893205..d29e563051 100644 --- a/drivers/crypto/dpaa_sec/dpaa_sec.c +++ b/drivers/crypto/dpaa_sec/dpaa_sec.c @@ -473,6 +473,7 @@ dpaa_sec_prep_pdcp_cdb(dpaa_sec_session *ses) shared_desc_len = cnstr_shdsc_pdcp_c_plane_encap( cdb->sh_desc, 1, swap, ses->pdcp.hfn, + ses->pdcp.sn_size, ses->pdcp.bearer, ses->pdcp.pkt_dir, ses->pdcp.hfn_threshold, @@ -482,6 +483,7 @@ dpaa_sec_prep_pdcp_cdb(dpaa_sec_session *ses) shared_desc_len = cnstr_shdsc_pdcp_c_plane_decap( cdb->sh_desc, 1, swap, ses->pdcp.hfn, + ses->pdcp.sn_size, ses->pdcp.bearer, ses->pdcp.pkt_dir, ses->pdcp.hfn_threshold, @@ -2389,9 +2391,10 @@ dpaa_sec_set_pdcp_session(struct rte_cryptodev *dev, /* Auth is only applicable for control mode operation. */ if (pdcp_xform->domain == RTE_SECURITY_PDCP_MODE_CONTROL) { - if (pdcp_xform->sn_size != RTE_SECURITY_PDCP_SN_SIZE_5) { + if (pdcp_xform->sn_size != RTE_SECURITY_PDCP_SN_SIZE_5 && + pdcp_xform->sn_size != RTE_SECURITY_PDCP_SN_SIZE_12) { DPAA_SEC_ERR( - "PDCP Seq Num size should be 5 bits for cmode"); + "PDCP Seq Num size should be 5/12 bits for cmode"); goto out; } if (auth_xform) {