PDCP u-plane may optionally support integrity as well.
This patch add support for supporting integrity along with
confidentiality.
Signed-off-by: Vakul Garg <vakul.garg@nxp.com>
Acked-by: Akhil Goyal <akhil.goyal@nxp.com>
struct ctxt_priv *priv;
struct dpaa2_sec_dev_private *dev_priv = dev->data->dev_private;
struct alginfo authdata, cipherdata;
+ struct alginfo *p_authdata = NULL;
int bufsize = -1;
struct sec_flow_context *flc;
#if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
goto out;
}
- /* 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 &&
- pdcp_xform->sn_size != RTE_SECURITY_PDCP_SN_SIZE_12) {
- DPAA2_SEC_ERR(
- "PDCP Seq Num size should be 5/12 bits for cmode");
- goto out;
- }
- if (auth_xform) {
- session->auth_key.data = rte_zmalloc(NULL,
- auth_xform->key.length,
- RTE_CACHE_LINE_SIZE);
- if (session->auth_key.data == NULL &&
- auth_xform->key.length > 0) {
- DPAA2_SEC_ERR("No Memory for auth key");
- rte_free(session->cipher_key.data);
- rte_free(priv);
- return -ENOMEM;
- }
- session->auth_key.length = auth_xform->key.length;
- memcpy(session->auth_key.data, auth_xform->key.data,
- auth_xform->key.length);
- session->auth_alg = auth_xform->algo;
- } else {
- session->auth_key.data = NULL;
- session->auth_key.length = 0;
- session->auth_alg = RTE_CRYPTO_AUTH_NULL;
+ if (auth_xform) {
+ session->auth_key.data = rte_zmalloc(NULL,
+ auth_xform->key.length,
+ RTE_CACHE_LINE_SIZE);
+ if (!session->auth_key.data &&
+ auth_xform->key.length > 0) {
+ DPAA2_SEC_ERR("No Memory for auth key");
+ rte_free(session->cipher_key.data);
+ rte_free(priv);
+ return -ENOMEM;
}
- authdata.key = (size_t)session->auth_key.data;
- authdata.keylen = session->auth_key.length;
- authdata.key_enc_flags = 0;
- authdata.key_type = RTA_DATA_IMM;
+ session->auth_key.length = auth_xform->key.length;
+ memcpy(session->auth_key.data, auth_xform->key.data,
+ auth_xform->key.length);
+ session->auth_alg = auth_xform->algo;
+ } else {
+ session->auth_key.data = NULL;
+ session->auth_key.length = 0;
+ session->auth_alg = 0;
+ }
+ authdata.key = (size_t)session->auth_key.data;
+ authdata.keylen = session->auth_key.length;
+ authdata.key_enc_flags = 0;
+ authdata.key_type = RTA_DATA_IMM;
+ if (session->auth_alg) {
switch (session->auth_alg) {
case RTE_CRYPTO_AUTH_SNOW3G_UIA2:
authdata.algtype = PDCP_AUTH_TYPE_SNOW;
goto out;
}
+ p_authdata = &authdata;
+ } else if (pdcp_xform->domain == RTE_SECURITY_PDCP_MODE_CONTROL) {
+ DPAA2_SEC_ERR("Crypto: Integrity must for c-plane");
+ goto out;
+ }
+
+ if (pdcp_xform->domain == RTE_SECURITY_PDCP_MODE_CONTROL) {
if (session->dir == DIR_ENC)
bufsize = cnstr_shdsc_pdcp_c_plane_encap(
priv->flc_desc[0].desc, 1, swap,
pdcp_xform->bearer,
pdcp_xform->pkt_dir,
pdcp_xform->hfn_threshold,
- &cipherdata, 0);
+ &cipherdata, p_authdata, 0);
else if (session->dir == DIR_DEC)
bufsize = cnstr_shdsc_pdcp_u_plane_decap(
priv->flc_desc[0].desc, 1, swap,
pdcp_xform->bearer,
pdcp_xform->pkt_dir,
pdcp_xform->hfn_threshold,
- &cipherdata, 0);
+ &cipherdata, p_authdata, 0);
}
if (bufsize < 0) {
pdcp_insert_uplane_15bit_op(struct program *p,
bool swap __maybe_unused,
struct alginfo *cipherdata,
+ struct alginfo *authdata,
unsigned int dir)
{
int op;
+
+ /* Insert auth key if requested */
+ if (authdata && authdata->algtype)
+ KEY(p, KEY2, authdata->key_enc_flags, authdata->key,
+ authdata->keylen, INLINE_KEY(authdata));
+
/* Insert Cipher Key */
KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
cipherdata->keylen, INLINE_KEY(cipherdata));
unsigned short direction,
uint32_t hfn_threshold,
struct alginfo *cipherdata,
+ struct alginfo *authdata,
unsigned char era_2_sw_hfn_ovrd)
{
struct program prg;
return -EINVAL;
}
+ if (authdata && !authdata->algtype && rta_sec_era < RTA_SEC_ERA_8) {
+ pr_err("Cannot use u-plane auth with era < 8");
+ return -EINVAL;
+ }
+
PROGRAM_CNTXT_INIT(p, descbuf, 0);
if (swap)
PROGRAM_SET_BSWAP(p);
if (err)
return err;
+ /* Insert auth key if requested */
+ if (authdata && authdata->algtype) {
+ KEY(p, KEY2, authdata->key_enc_flags,
+ (uint64_t)authdata->key, authdata->keylen,
+ INLINE_KEY(authdata));
+ }
+
switch (sn_size) {
case PDCP_SN_SIZE_7:
case PDCP_SN_SIZE_12:
pr_err("Invalid era for selected algorithm\n");
return -ENOTSUP;
}
+ /* fallthrough */
case PDCP_CIPHER_TYPE_AES:
case PDCP_CIPHER_TYPE_SNOW:
+ case PDCP_CIPHER_TYPE_NULL:
/* Insert Cipher Key */
KEY(p, KEY1, cipherdata->key_enc_flags,
(uint64_t)cipherdata->key, cipherdata->keylen,
INLINE_KEY(cipherdata));
- PROTOCOL(p, OP_TYPE_ENCAP_PROTOCOL,
- OP_PCLID_LTE_PDCP_USER,
- (uint16_t)cipherdata->algtype);
- break;
- case PDCP_CIPHER_TYPE_NULL:
- insert_copy_frame_op(p,
- cipherdata,
- OP_TYPE_ENCAP_PROTOCOL);
+
+ if (authdata)
+ PROTOCOL(p, OP_TYPE_ENCAP_PROTOCOL,
+ OP_PCLID_LTE_PDCP_USER_RN,
+ ((uint16_t)cipherdata->algtype << 8) |
+ (uint16_t)authdata->algtype);
+ else
+ PROTOCOL(p, OP_TYPE_ENCAP_PROTOCOL,
+ OP_PCLID_LTE_PDCP_USER,
+ (uint16_t)cipherdata->algtype);
break;
default:
pr_err("%s: Invalid encrypt algorithm selected: %d\n",
default:
err = pdcp_insert_uplane_15bit_op(p, swap, cipherdata,
- OP_TYPE_ENCAP_PROTOCOL);
+ authdata, OP_TYPE_ENCAP_PROTOCOL);
if (err)
return err;
break;
unsigned short direction,
uint32_t hfn_threshold,
struct alginfo *cipherdata,
+ struct alginfo *authdata,
unsigned char era_2_sw_hfn_ovrd)
{
struct program prg;
return -EINVAL;
}
+ if (authdata && !authdata->algtype && rta_sec_era < RTA_SEC_ERA_8) {
+ pr_err("Cannot use u-plane auth with era < 8");
+ return -EINVAL;
+ }
+
PROGRAM_CNTXT_INIT(p, descbuf, 0);
if (swap)
PROGRAM_SET_BSWAP(p);
if (err)
return err;
+ /* Insert auth key if requested */
+ if (authdata && authdata->algtype)
+ KEY(p, KEY2, authdata->key_enc_flags,
+ (uint64_t)authdata->key, authdata->keylen,
+ INLINE_KEY(authdata));
+
switch (sn_size) {
case PDCP_SN_SIZE_7:
case PDCP_SN_SIZE_12:
pr_err("Invalid era for selected algorithm\n");
return -ENOTSUP;
}
+ /* fallthrough */
case PDCP_CIPHER_TYPE_AES:
case PDCP_CIPHER_TYPE_SNOW:
+ case PDCP_CIPHER_TYPE_NULL:
/* Insert Cipher Key */
KEY(p, KEY1, cipherdata->key_enc_flags,
cipherdata->key, cipherdata->keylen,
INLINE_KEY(cipherdata));
- PROTOCOL(p, OP_TYPE_DECAP_PROTOCOL,
- OP_PCLID_LTE_PDCP_USER,
- (uint16_t)cipherdata->algtype);
- break;
- case PDCP_CIPHER_TYPE_NULL:
- insert_copy_frame_op(p,
- cipherdata,
- OP_TYPE_DECAP_PROTOCOL);
+ if (authdata)
+ PROTOCOL(p, OP_TYPE_DECAP_PROTOCOL,
+ OP_PCLID_LTE_PDCP_USER_RN,
+ ((uint16_t)cipherdata->algtype << 8) |
+ (uint16_t)authdata->algtype);
+ else
+ PROTOCOL(p, OP_TYPE_DECAP_PROTOCOL,
+ OP_PCLID_LTE_PDCP_USER,
+ (uint16_t)cipherdata->algtype);
break;
default:
pr_err("%s: Invalid encrypt algorithm selected: %d\n",
default:
err = pdcp_insert_uplane_15bit_op(p, swap, cipherdata,
- OP_TYPE_DECAP_PROTOCOL);
+ authdata, OP_TYPE_DECAP_PROTOCOL);
if (err)
return err;
break;
{
struct alginfo authdata = {0}, cipherdata = {0};
struct sec_cdb *cdb = &ses->cdb;
+ struct alginfo *p_authdata = NULL;
int32_t shared_desc_len = 0;
int err;
#if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
cipherdata.key_enc_flags = 0;
cipherdata.key_type = RTA_DATA_IMM;
- if (ses->pdcp.domain == RTE_SECURITY_PDCP_MODE_CONTROL) {
+ cdb->sh_desc[0] = cipherdata.keylen;
+ cdb->sh_desc[1] = 0;
+ cdb->sh_desc[2] = 0;
+
+ if (ses->auth_alg) {
switch (ses->auth_alg) {
case RTE_CRYPTO_AUTH_SNOW3G_UIA2:
authdata.algtype = PDCP_AUTH_TYPE_SNOW;
authdata.key_enc_flags = 0;
authdata.key_type = RTA_DATA_IMM;
- cdb->sh_desc[0] = cipherdata.keylen;
+ p_authdata = &authdata;
+
cdb->sh_desc[1] = authdata.keylen;
- err = rta_inline_query(IPSEC_AUTH_VAR_AES_DEC_BASE_DESC_LEN,
- MIN_JOB_DESC_SIZE,
- (unsigned int *)cdb->sh_desc,
- &cdb->sh_desc[2], 2);
+ }
- if (err < 0) {
- DPAA_SEC_ERR("Crypto: Incorrect key lengths");
- return err;
- }
- if (!(cdb->sh_desc[2] & 1) && cipherdata.keylen) {
- cipherdata.key = (size_t)dpaa_mem_vtop(
- (void *)(size_t)cipherdata.key);
- cipherdata.key_type = RTA_DATA_PTR;
- }
- if (!(cdb->sh_desc[2] & (1<<1)) && authdata.keylen) {
- authdata.key = (size_t)dpaa_mem_vtop(
- (void *)(size_t)authdata.key);
- authdata.key_type = RTA_DATA_PTR;
- }
+ err = rta_inline_query(IPSEC_AUTH_VAR_AES_DEC_BASE_DESC_LEN,
+ MIN_JOB_DESC_SIZE,
+ (unsigned int *)cdb->sh_desc,
+ &cdb->sh_desc[2], 2);
+ if (err < 0) {
+ DPAA_SEC_ERR("Crypto: Incorrect key lengths");
+ return err;
+ }
- cdb->sh_desc[0] = 0;
- cdb->sh_desc[1] = 0;
- cdb->sh_desc[2] = 0;
+ if (!(cdb->sh_desc[2] & 1) && cipherdata.keylen) {
+ cipherdata.key =
+ (size_t)dpaa_mem_vtop((void *)(size_t)cipherdata.key);
+ cipherdata.key_type = RTA_DATA_PTR;
+ }
+ if (!(cdb->sh_desc[2] & (1 << 1)) && authdata.keylen) {
+ authdata.key =
+ (size_t)dpaa_mem_vtop((void *)(size_t)authdata.key);
+ authdata.key_type = RTA_DATA_PTR;
+ }
+ cdb->sh_desc[0] = 0;
+ cdb->sh_desc[1] = 0;
+ cdb->sh_desc[2] = 0;
+
+ if (ses->pdcp.domain == RTE_SECURITY_PDCP_MODE_CONTROL) {
if (ses->dir == DIR_ENC)
shared_desc_len = cnstr_shdsc_pdcp_c_plane_encap(
cdb->sh_desc, 1, swap,
&cipherdata, &authdata,
0);
} else {
- cdb->sh_desc[0] = cipherdata.keylen;
- err = rta_inline_query(IPSEC_AUTH_VAR_AES_DEC_BASE_DESC_LEN,
- MIN_JOB_DESC_SIZE,
- (unsigned int *)cdb->sh_desc,
- &cdb->sh_desc[2], 1);
-
- if (err < 0) {
- DPAA_SEC_ERR("Crypto: Incorrect key lengths");
- return err;
- }
- if (!(cdb->sh_desc[2] & 1) && cipherdata.keylen) {
- cipherdata.key = (size_t)dpaa_mem_vtop(
- (void *)(size_t)cipherdata.key);
- cipherdata.key_type = RTA_DATA_PTR;
- }
- cdb->sh_desc[0] = 0;
- cdb->sh_desc[1] = 0;
- cdb->sh_desc[2] = 0;
-
if (ses->dir == DIR_ENC)
shared_desc_len = cnstr_shdsc_pdcp_u_plane_encap(
cdb->sh_desc, 1, swap,
ses->pdcp.bearer,
ses->pdcp.pkt_dir,
ses->pdcp.hfn_threshold,
- &cipherdata, 0);
+ &cipherdata, p_authdata, 0);
else if (ses->dir == DIR_DEC)
shared_desc_len = cnstr_shdsc_pdcp_u_plane_decap(
cdb->sh_desc, 1, swap,
ses->pdcp.bearer,
ses->pdcp.pkt_dir,
ses->pdcp.hfn_threshold,
- &cipherdata, 0);
+ &cipherdata, p_authdata, 0);
}
return shared_desc_len;
session->dir = DIR_ENC;
}
- /* 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 &&
pdcp_xform->sn_size != RTE_SECURITY_PDCP_SN_SIZE_12) {
"PDCP Seq Num size should be 5/12 bits for cmode");
goto out;
}
- if (auth_xform) {
- session->auth_key.data = rte_zmalloc(NULL,
- auth_xform->key.length,
- RTE_CACHE_LINE_SIZE);
- if (session->auth_key.data == NULL &&
- auth_xform->key.length > 0) {
- DPAA_SEC_ERR("No Memory for auth key");
- rte_free(session->cipher_key.data);
- return -ENOMEM;
- }
- session->auth_key.length = auth_xform->key.length;
- memcpy(session->auth_key.data, auth_xform->key.data,
- auth_xform->key.length);
- session->auth_alg = auth_xform->algo;
- } else {
- session->auth_key.data = NULL;
- session->auth_key.length = 0;
- session->auth_alg = RTE_CRYPTO_AUTH_NULL;
+ }
+
+ if (auth_xform) {
+ session->auth_key.data = rte_zmalloc(NULL,
+ auth_xform->key.length,
+ RTE_CACHE_LINE_SIZE);
+ if (!session->auth_key.data &&
+ auth_xform->key.length > 0) {
+ DPAA_SEC_ERR("No Memory for auth key");
+ rte_free(session->cipher_key.data);
+ return -ENOMEM;
}
+ session->auth_key.length = auth_xform->key.length;
+ memcpy(session->auth_key.data, auth_xform->key.data,
+ auth_xform->key.length);
+ session->auth_alg = auth_xform->algo;
+ } else {
+ session->auth_key.data = NULL;
+ session->auth_key.length = 0;
+ session->auth_alg = 0;
}
session->pdcp.domain = pdcp_xform->domain;
session->pdcp.bearer = pdcp_xform->bearer;