safexcel: Support multiple nonce lengths for AES-CCM.

Reviewed by:	markj
Sponsored by:	Chelsio Communications, The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D32118

(cherry picked from commit 2ec2e4df09)
This commit is contained in:
John Baldwin 2021-10-06 14:08:48 -07:00
parent 12d5e71fb5
commit cfa1d2c9b9

View file

@ -2,6 +2,10 @@
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2020, 2021 Rubicon Communications, LLC (Netgate)
* Copyright (c) 2021 The FreeBSD Foundation
*
* Portions of this software were developed by Ararat River
* Consulting, LLC under sponsorship of the FreeBSD Foundation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -1689,12 +1693,14 @@ static void
safexcel_instr_ccm(struct safexcel_request *req, struct safexcel_instr *instr,
struct safexcel_cmd_descr *cdesc)
{
const struct crypto_session_params *csp;
struct cryptop *crp;
struct safexcel_instr *start;
uint8_t *a0, *b0, *alenp, L;
int aalign, blen;
crp = req->crp;
csp = crypto_get_params(crp->crp_session);
start = instr;
/*
@ -1703,17 +1709,17 @@ safexcel_instr_ccm(struct safexcel_request *req, struct safexcel_instr *instr,
* descriptor, and B0 is inserted directly into the data stream using
* instructions below.
*
* OCF seems to assume a 12-byte IV, fixing L (the payload length size)
* at 3 bytes due to the layout of B0. This is fine since the driver
* has a maximum of 65535 bytes anyway.
* An explicit check for overflow of the length field is not
* needed since the maximum driver size of 65535 bytes fits in
* the smallest length field used for a 13-byte nonce.
*/
blen = AES_BLOCK_LEN;
L = 3;
L = 15 - csp->csp_ivlen;
a0 = (uint8_t *)&cdesc->control_data.token[0];
memset(a0, 0, blen);
a0[0] = L - 1;
memcpy(&a0[1], req->iv, AES_CCM_IV_LEN);
memcpy(&a0[1], req->iv, csp->csp_ivlen);
/*
* Insert B0 and the AAD length into the input stream.
@ -1731,7 +1737,7 @@ safexcel_instr_ccm(struct safexcel_request *req, struct safexcel_instr *instr,
(L - 1) | /* payload length size */
((CCM_CBC_MAX_DIGEST_LEN - 2) / 2) << 3 /* digest length */ |
(crp->crp_aad_length > 0 ? 1 : 0) << 6 /* AAD present bit */;
memcpy(&b0[1], req->iv, AES_CCM_IV_LEN);
memcpy(&b0[1], req->iv, csp->csp_ivlen);
b0[14] = crp->crp_payload_length >> 8;
b0[15] = crp->crp_payload_length & 0xff;
instr += blen / sizeof(*instr);
@ -2308,7 +2314,8 @@ safexcel_probesession(device_t dev, const struct crypto_session_params *csp)
return (EINVAL);
break;
case CRYPTO_AES_CCM_16:
if (csp->csp_ivlen != AES_CCM_IV_LEN)
if (csp->csp_auth_mlen != 0 &&
csp->csp_auth_mlen != AES_CBC_MAC_HASH_LEN)
return (EINVAL);
break;
default: