diff --git a/sys/dev/safexcel/safexcel.c b/sys/dev/safexcel/safexcel.c --- a/sys/dev/safexcel/safexcel.c +++ b/sys/dev/safexcel/safexcel.c @@ -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 @@ 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 @@ * 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 @@ (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 @@ 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: