staticunsignedint aes_disable;
module_param(aes_disable, uint, 0444);
MODULE_PARM_DESC(aes_disable, "Disable use of AES - any non-zero value");
staticunsignedint sha_disable;
module_param(sha_disable, uint, 0444);
MODULE_PARM_DESC(sha_disable, "Disable use of SHA - any non-zero value");
staticunsignedint des3_disable;
module_param(des3_disable, uint, 0444);
MODULE_PARM_DESC(des3_disable, "Disable use of 3DES - any non-zero value");
staticunsignedint rsa_disable;
module_param(rsa_disable, uint, 0444);
MODULE_PARM_DESC(rsa_disable, "Disable use of RSA - any non-zero value");
/* List heads for the supported algorithms */ static LIST_HEAD(hash_algs); static LIST_HEAD(skcipher_algs); static LIST_HEAD(aead_algs); static LIST_HEAD(akcipher_algs);
/* For any tfm, requests for that tfm must be returned on the order * received. With multiple queues available, the CCP can process more * than one cmd at a time. Therefore we must maintain a cmd list to insure * the proper ordering of requests on a given tfm.
*/ struct ccp_crypto_queue { struct list_head cmds; struct list_head *backlog; unsignedint cmd_count;
};
/* Save the crypto_tfm and crypto_async_request addresses * separately to avoid any reference to a possibly invalid * crypto_async_request structure after invoking the request * callback
*/ struct crypto_async_request *req; struct crypto_tfm *tfm;
/* Used for held command processing to determine state */ int ret;
};
/* Held cmds will be after the current cmd in the queue so start * searching for a cmd with a matching tfm for submission.
*/
tmp = crypto_cmd;
list_for_each_entry_continue(tmp, &req_queue.cmds, entry) { if (crypto_cmd->tfm != tmp->tfm) continue;
held = tmp; break;
}
/* Process the backlog: * Because cmds can be executed from any point in the cmd list * special precautions have to be taken when handling the backlog.
*/ if (req_queue.backlog != &req_queue.cmds) { /* Skip over this cmd if it is the next backlog cmd */ if (req_queue.backlog == &crypto_cmd->entry)
req_queue.backlog = crypto_cmd->entry.next;
if (err == -EINPROGRESS) { /* Only propagate the -EINPROGRESS if necessary */ if (crypto_cmd->ret == -EBUSY) {
crypto_cmd->ret = -EINPROGRESS;
crypto_request_complete(req, -EINPROGRESS);
}
return;
}
/* Operation has completed - update the queue before invoking * the completion callbacks and retrieve the next cmd (cmd with * a matching tfm) that can be submitted to the CCP.
*/
held = ccp_crypto_cmd_complete(crypto_cmd, &backlog); if (backlog) {
backlog->ret = -EINPROGRESS;
crypto_request_complete(backlog->req, -EINPROGRESS);
}
/* Transition the state from -EBUSY to -EINPROGRESS first */ if (crypto_cmd->ret == -EBUSY)
crypto_request_complete(req, -EINPROGRESS);
/* Completion callbacks */
ret = err; if (ctx->complete)
ret = ctx->complete(req, ret);
crypto_request_complete(req, ret);
/* Submit the next cmd */ while (held) { /* Since we have already queued the cmd, we must indicate that * we can backlog so as not to "lose" this request.
*/
held->cmd->flags |= CCP_CMD_MAY_BACKLOG;
ret = ccp_enqueue_cmd(held->cmd); if (ccp_crypto_success(ret)) break;
/* Error occurred, report it and get the next entry */
ctx = crypto_tfm_ctx_dma(held->req->tfm); if (ctx->complete)
ret = ctx->complete(held->req, ret);
crypto_request_complete(held->req, ret);
next = ccp_crypto_cmd_complete(held, &backlog); if (backlog) {
backlog->ret = -EINPROGRESS;
crypto_request_complete(backlog->req, -EINPROGRESS);
}
/* Check if the cmd can/should be queued */ if (req_queue.cmd_count >= CCP_CRYPTO_MAX_QLEN) { if (!(crypto_cmd->cmd->flags & CCP_CMD_MAY_BACKLOG)) {
ret = -ENOSPC; goto e_lock;
}
}
/* Look for an entry with the same tfm. If there is a cmd * with the same tfm in the list then the current cmd cannot * be submitted to the CCP yet.
*/
list_for_each_entry(tmp, &req_queue.cmds, entry) { if (crypto_cmd->tfm != tmp->tfm) continue;
active = tmp; break;
}
ret = -EINPROGRESS; if (!active) {
ret = ccp_enqueue_cmd(crypto_cmd->cmd); if (!ccp_crypto_success(ret)) goto e_lock; /* Error, don't queue it */
}
if (req_queue.cmd_count >= CCP_CRYPTO_MAX_QLEN) {
ret = -EBUSY; if (req_queue.backlog == &req_queue.cmds)
req_queue.backlog = &crypto_cmd->entry;
}
crypto_cmd->ret = ret;
/** * ccp_crypto_enqueue_request - queue an crypto async request for processing * by the CCP * * @req: crypto_async_request struct to be processed * @cmd: ccp_cmd struct to be sent to the CCP
*/ int ccp_crypto_enqueue_request(struct crypto_async_request *req, struct ccp_cmd *cmd)
{ struct ccp_crypto_cmd *crypto_cmd;
gfp_t gfp;
crypto_cmd = kzalloc(sizeof(*crypto_cmd), gfp); if (!crypto_cmd) return -ENOMEM;
/* The tfm pointer must be saved and not referenced from the * crypto_async_request (req) pointer because it is used after * completion callback for the request and the req pointer * might not be valid anymore.
*/
crypto_cmd->cmd = cmd;
crypto_cmd->req = req;
crypto_cmd->tfm = req->tfm;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.