Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/safexcel/safexcel.c
/*- | /*- | ||||
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD | * SPDX-License-Identifier: BSD-2-Clause-FreeBSD | ||||
* | * | ||||
* Copyright (c) 2020, 2021 Rubicon Communications, LLC (Netgate) | * 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 | * Redistribution and use in source and binary forms, with or without | ||||
* modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
* are met: | * are met: | ||||
* 1. Redistributions of source code must retain the above copyright | * 1. Redistributions of source code must retain the above copyright | ||||
* notice, this list of conditions and the following disclaimer. | * notice, this list of conditions and the following disclaimer. | ||||
* 2. Redistributions in binary form must reproduce the above copyright | * 2. Redistributions in binary form must reproduce the above copyright | ||||
* notice, this list of conditions and the following disclaimer in the | * notice, this list of conditions and the following disclaimer in the | ||||
* documentation and/or other materials provided with the distribution. | * documentation and/or other materials provided with the distribution. | ||||
▲ Show 20 Lines • Show All 1,670 Lines • ▼ Show 20 Lines | safexcel_instr_sha_hash(struct safexcel_request *req, | ||||
while (instr != start + SAFEXCEL_MAX_ITOKENS) | while (instr != start + SAFEXCEL_MAX_ITOKENS) | ||||
safexcel_instr_nop(&instr); | safexcel_instr_nop(&instr); | ||||
} | } | ||||
static void | static void | ||||
safexcel_instr_ccm(struct safexcel_request *req, struct safexcel_instr *instr, | safexcel_instr_ccm(struct safexcel_request *req, struct safexcel_instr *instr, | ||||
struct safexcel_cmd_descr *cdesc) | struct safexcel_cmd_descr *cdesc) | ||||
{ | { | ||||
const struct crypto_session_params *csp; | |||||
struct cryptop *crp; | struct cryptop *crp; | ||||
struct safexcel_instr *start; | struct safexcel_instr *start; | ||||
uint8_t *a0, *b0, *alenp, L; | uint8_t *a0, *b0, *alenp, L; | ||||
int aalign, blen; | int aalign, blen; | ||||
crp = req->crp; | crp = req->crp; | ||||
csp = crypto_get_params(crp->crp_session); | |||||
start = instr; | start = instr; | ||||
/* | /* | ||||
* Construct two blocks, A0 and B0, used in encryption and | * Construct two blocks, A0 and B0, used in encryption and | ||||
* authentication, respectively. A0 is embedded in the token | * authentication, respectively. A0 is embedded in the token | ||||
* descriptor, and B0 is inserted directly into the data stream using | * descriptor, and B0 is inserted directly into the data stream using | ||||
* instructions below. | * instructions below. | ||||
* | * | ||||
* OCF seems to assume a 12-byte IV, fixing L (the payload length size) | * An explicit check for overflow of the length field is not | ||||
* at 3 bytes due to the layout of B0. This is fine since the driver | * needed since the maximum driver size of 65535 bytes fits in | ||||
* has a maximum of 65535 bytes anyway. | * the smallest length field used for a 13-byte nonce. | ||||
*/ | */ | ||||
blen = AES_BLOCK_LEN; | blen = AES_BLOCK_LEN; | ||||
L = 3; | L = 15 - csp->csp_ivlen; | ||||
a0 = (uint8_t *)&cdesc->control_data.token[0]; | a0 = (uint8_t *)&cdesc->control_data.token[0]; | ||||
memset(a0, 0, blen); | memset(a0, 0, blen); | ||||
a0[0] = L - 1; | 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. | * Insert B0 and the AAD length into the input stream. | ||||
*/ | */ | ||||
instr->opcode = SAFEXCEL_INSTR_OPCODE_INSERT; | instr->opcode = SAFEXCEL_INSTR_OPCODE_INSERT; | ||||
instr->length = blen + (crp->crp_aad_length > 0 ? 2 : 0); | instr->length = blen + (crp->crp_aad_length > 0 ? 2 : 0); | ||||
instr->status = 0; | instr->status = 0; | ||||
instr->instructions = SAFEXCEL_INSTR_DEST_HASH | | instr->instructions = SAFEXCEL_INSTR_DEST_HASH | | ||||
SAFEXCEL_INSTR_INSERT_IMMEDIATE; | SAFEXCEL_INSTR_INSERT_IMMEDIATE; | ||||
instr++; | instr++; | ||||
b0 = (uint8_t *)instr; | b0 = (uint8_t *)instr; | ||||
memset(b0, 0, blen); | memset(b0, 0, blen); | ||||
b0[0] = | b0[0] = | ||||
(L - 1) | /* payload length size */ | (L - 1) | /* payload length size */ | ||||
((CCM_CBC_MAX_DIGEST_LEN - 2) / 2) << 3 /* digest length */ | | ((CCM_CBC_MAX_DIGEST_LEN - 2) / 2) << 3 /* digest length */ | | ||||
(crp->crp_aad_length > 0 ? 1 : 0) << 6 /* AAD present bit */; | (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[14] = crp->crp_payload_length >> 8; | ||||
b0[15] = crp->crp_payload_length & 0xff; | b0[15] = crp->crp_payload_length & 0xff; | ||||
instr += blen / sizeof(*instr); | instr += blen / sizeof(*instr); | ||||
/* Insert the AAD length and data into the input stream. */ | /* Insert the AAD length and data into the input stream. */ | ||||
if (crp->crp_aad_length > 0) { | if (crp->crp_aad_length > 0) { | ||||
alenp = (uint8_t *)instr; | alenp = (uint8_t *)instr; | ||||
alenp[0] = crp->crp_aad_length >> 8; | alenp[0] = crp->crp_aad_length >> 8; | ||||
▲ Show 20 Lines • Show All 560 Lines • ▼ Show 20 Lines | case CSP_MODE_DIGEST: | ||||
break; | break; | ||||
case CSP_MODE_AEAD: | case CSP_MODE_AEAD: | ||||
switch (csp->csp_cipher_alg) { | switch (csp->csp_cipher_alg) { | ||||
case CRYPTO_AES_NIST_GCM_16: | case CRYPTO_AES_NIST_GCM_16: | ||||
if (csp->csp_ivlen != AES_GCM_IV_LEN) | if (csp->csp_ivlen != AES_GCM_IV_LEN) | ||||
return (EINVAL); | return (EINVAL); | ||||
break; | break; | ||||
case CRYPTO_AES_CCM_16: | 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); | return (EINVAL); | ||||
break; | break; | ||||
default: | default: | ||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
break; | break; | ||||
case CSP_MODE_ETA: | case CSP_MODE_ETA: | ||||
if (!safexcel_probe_cipher(csp)) | if (!safexcel_probe_cipher(csp)) | ||||
▲ Show 20 Lines • Show All 308 Lines • Show Last 20 Lines |