Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
Pull crypto fixes from Herbert Xu: "This fixes the following issues: API: - A large number of bug fixes for the af_alg interface, credit goes to Dmitry Vyukov for discovering and reporting these issues. Algorithms: - sw842 needs to select crc32. - The soft dependency on crc32c is now in the correct spot. Drivers: - The atmel AES driver needs HAS_DMA. - The atmel AES driver was a missing break statement, fortunately it's only a debug function. - A number of bug fixes for the Intel qat driver" * 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6: (24 commits) crypto: algif_skcipher - sendmsg SG marking is off by one crypto: crc32c - Fix crc32c soft dependency crypto: algif_skcipher - Load TX SG list after waiting crypto: atmel-aes - Add missing break to atmel_aes_reg_name crypto: algif_skcipher - Fix race condition in skcipher_check_key crypto: algif_hash - Fix race condition in hash_check_key crypto: CRYPTO_DEV_ATMEL_AES should depend on HAS_DMA lib: sw842: select crc32 crypto: af_alg - Forbid bind(2) when nokey child sockets are present crypto: algif_skcipher - Remove custom release parent function crypto: algif_hash - Remove custom release parent function crypto: af_alg - Allow af_af_alg_release_parent to be called on nokey path crypto: qat - update init_esram for C3xxx dev type crypto: qat - fix timeout issues crypto: qat - remove to call get_sram_bar_id for qat_c3xxx crypto: algif_skcipher - Add key check exception for cipher_null crypto: skcipher - Add crypto_skcipher_has_setkey crypto: algif_hash - Require setkey before accept(2) crypto: hash - Add crypto_ahash_has_setkey crypto: algif_skcipher - Add nokey compatibility path ...
This commit is contained in:
commit
48162a203e
|
@ -76,6 +76,8 @@ int af_alg_register_type(const struct af_alg_type *type)
|
|||
goto unlock;
|
||||
|
||||
type->ops->owner = THIS_MODULE;
|
||||
if (type->ops_nokey)
|
||||
type->ops_nokey->owner = THIS_MODULE;
|
||||
node->type = type;
|
||||
list_add(&node->list, &alg_types);
|
||||
err = 0;
|
||||
|
@ -125,6 +127,26 @@ int af_alg_release(struct socket *sock)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(af_alg_release);
|
||||
|
||||
void af_alg_release_parent(struct sock *sk)
|
||||
{
|
||||
struct alg_sock *ask = alg_sk(sk);
|
||||
unsigned int nokey = ask->nokey_refcnt;
|
||||
bool last = nokey && !ask->refcnt;
|
||||
|
||||
sk = ask->parent;
|
||||
ask = alg_sk(sk);
|
||||
|
||||
lock_sock(sk);
|
||||
ask->nokey_refcnt -= nokey;
|
||||
if (!last)
|
||||
last = !--ask->refcnt;
|
||||
release_sock(sk);
|
||||
|
||||
if (last)
|
||||
sock_put(sk);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(af_alg_release_parent);
|
||||
|
||||
static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
|
||||
{
|
||||
const u32 forbidden = CRYPTO_ALG_INTERNAL;
|
||||
|
@ -133,6 +155,7 @@ static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
|
|||
struct sockaddr_alg *sa = (void *)uaddr;
|
||||
const struct af_alg_type *type;
|
||||
void *private;
|
||||
int err;
|
||||
|
||||
if (sock->state == SS_CONNECTED)
|
||||
return -EINVAL;
|
||||
|
@ -160,16 +183,22 @@ static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
|
|||
return PTR_ERR(private);
|
||||
}
|
||||
|
||||
err = -EBUSY;
|
||||
lock_sock(sk);
|
||||
if (ask->refcnt | ask->nokey_refcnt)
|
||||
goto unlock;
|
||||
|
||||
swap(ask->type, type);
|
||||
swap(ask->private, private);
|
||||
|
||||
err = 0;
|
||||
|
||||
unlock:
|
||||
release_sock(sk);
|
||||
|
||||
alg_do_release(type, private);
|
||||
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
static int alg_setkey(struct sock *sk, char __user *ukey,
|
||||
|
@ -202,11 +231,15 @@ static int alg_setsockopt(struct socket *sock, int level, int optname,
|
|||
struct sock *sk = sock->sk;
|
||||
struct alg_sock *ask = alg_sk(sk);
|
||||
const struct af_alg_type *type;
|
||||
int err = -ENOPROTOOPT;
|
||||
int err = -EBUSY;
|
||||
|
||||
lock_sock(sk);
|
||||
if (ask->refcnt)
|
||||
goto unlock;
|
||||
|
||||
type = ask->type;
|
||||
|
||||
err = -ENOPROTOOPT;
|
||||
if (level != SOL_ALG || !type)
|
||||
goto unlock;
|
||||
|
||||
|
@ -238,6 +271,7 @@ int af_alg_accept(struct sock *sk, struct socket *newsock)
|
|||
struct alg_sock *ask = alg_sk(sk);
|
||||
const struct af_alg_type *type;
|
||||
struct sock *sk2;
|
||||
unsigned int nokey;
|
||||
int err;
|
||||
|
||||
lock_sock(sk);
|
||||
|
@ -257,20 +291,29 @@ int af_alg_accept(struct sock *sk, struct socket *newsock)
|
|||
security_sk_clone(sk, sk2);
|
||||
|
||||
err = type->accept(ask->private, sk2);
|
||||
if (err) {
|
||||
sk_free(sk2);
|
||||
|
||||
nokey = err == -ENOKEY;
|
||||
if (nokey && type->accept_nokey)
|
||||
err = type->accept_nokey(ask->private, sk2);
|
||||
|
||||
if (err)
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
sk2->sk_family = PF_ALG;
|
||||
|
||||
sock_hold(sk);
|
||||
if (nokey || !ask->refcnt++)
|
||||
sock_hold(sk);
|
||||
ask->nokey_refcnt += nokey;
|
||||
alg_sk(sk2)->parent = sk;
|
||||
alg_sk(sk2)->type = type;
|
||||
alg_sk(sk2)->nokey_refcnt = nokey;
|
||||
|
||||
newsock->ops = type->ops;
|
||||
newsock->state = SS_CONNECTED;
|
||||
|
||||
if (nokey)
|
||||
newsock->ops = type->ops_nokey;
|
||||
|
||||
err = 0;
|
||||
|
||||
unlock:
|
||||
|
|
|
@ -451,6 +451,7 @@ static int crypto_ahash_init_tfm(struct crypto_tfm *tfm)
|
|||
struct ahash_alg *alg = crypto_ahash_alg(hash);
|
||||
|
||||
hash->setkey = ahash_nosetkey;
|
||||
hash->has_setkey = false;
|
||||
hash->export = ahash_no_export;
|
||||
hash->import = ahash_no_import;
|
||||
|
||||
|
@ -463,8 +464,10 @@ static int crypto_ahash_init_tfm(struct crypto_tfm *tfm)
|
|||
hash->finup = alg->finup ?: ahash_def_finup;
|
||||
hash->digest = alg->digest;
|
||||
|
||||
if (alg->setkey)
|
||||
if (alg->setkey) {
|
||||
hash->setkey = alg->setkey;
|
||||
hash->has_setkey = true;
|
||||
}
|
||||
if (alg->export)
|
||||
hash->export = alg->export;
|
||||
if (alg->import)
|
||||
|
|
|
@ -34,6 +34,11 @@ struct hash_ctx {
|
|||
struct ahash_request req;
|
||||
};
|
||||
|
||||
struct algif_hash_tfm {
|
||||
struct crypto_ahash *hash;
|
||||
bool has_key;
|
||||
};
|
||||
|
||||
static int hash_sendmsg(struct socket *sock, struct msghdr *msg,
|
||||
size_t ignored)
|
||||
{
|
||||
|
@ -235,19 +240,151 @@ static struct proto_ops algif_hash_ops = {
|
|||
.accept = hash_accept,
|
||||
};
|
||||
|
||||
static int hash_check_key(struct socket *sock)
|
||||
{
|
||||
int err = 0;
|
||||
struct sock *psk;
|
||||
struct alg_sock *pask;
|
||||
struct algif_hash_tfm *tfm;
|
||||
struct sock *sk = sock->sk;
|
||||
struct alg_sock *ask = alg_sk(sk);
|
||||
|
||||
lock_sock(sk);
|
||||
if (ask->refcnt)
|
||||
goto unlock_child;
|
||||
|
||||
psk = ask->parent;
|
||||
pask = alg_sk(ask->parent);
|
||||
tfm = pask->private;
|
||||
|
||||
err = -ENOKEY;
|
||||
lock_sock_nested(psk, SINGLE_DEPTH_NESTING);
|
||||
if (!tfm->has_key)
|
||||
goto unlock;
|
||||
|
||||
if (!pask->refcnt++)
|
||||
sock_hold(psk);
|
||||
|
||||
ask->refcnt = 1;
|
||||
sock_put(psk);
|
||||
|
||||
err = 0;
|
||||
|
||||
unlock:
|
||||
release_sock(psk);
|
||||
unlock_child:
|
||||
release_sock(sk);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int hash_sendmsg_nokey(struct socket *sock, struct msghdr *msg,
|
||||
size_t size)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = hash_check_key(sock);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return hash_sendmsg(sock, msg, size);
|
||||
}
|
||||
|
||||
static ssize_t hash_sendpage_nokey(struct socket *sock, struct page *page,
|
||||
int offset, size_t size, int flags)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = hash_check_key(sock);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return hash_sendpage(sock, page, offset, size, flags);
|
||||
}
|
||||
|
||||
static int hash_recvmsg_nokey(struct socket *sock, struct msghdr *msg,
|
||||
size_t ignored, int flags)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = hash_check_key(sock);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return hash_recvmsg(sock, msg, ignored, flags);
|
||||
}
|
||||
|
||||
static int hash_accept_nokey(struct socket *sock, struct socket *newsock,
|
||||
int flags)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = hash_check_key(sock);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return hash_accept(sock, newsock, flags);
|
||||
}
|
||||
|
||||
static struct proto_ops algif_hash_ops_nokey = {
|
||||
.family = PF_ALG,
|
||||
|
||||
.connect = sock_no_connect,
|
||||
.socketpair = sock_no_socketpair,
|
||||
.getname = sock_no_getname,
|
||||
.ioctl = sock_no_ioctl,
|
||||
.listen = sock_no_listen,
|
||||
.shutdown = sock_no_shutdown,
|
||||
.getsockopt = sock_no_getsockopt,
|
||||
.mmap = sock_no_mmap,
|
||||
.bind = sock_no_bind,
|
||||
.setsockopt = sock_no_setsockopt,
|
||||
.poll = sock_no_poll,
|
||||
|
||||
.release = af_alg_release,
|
||||
.sendmsg = hash_sendmsg_nokey,
|
||||
.sendpage = hash_sendpage_nokey,
|
||||
.recvmsg = hash_recvmsg_nokey,
|
||||
.accept = hash_accept_nokey,
|
||||
};
|
||||
|
||||
static void *hash_bind(const char *name, u32 type, u32 mask)
|
||||
{
|
||||
return crypto_alloc_ahash(name, type, mask);
|
||||
struct algif_hash_tfm *tfm;
|
||||
struct crypto_ahash *hash;
|
||||
|
||||
tfm = kzalloc(sizeof(*tfm), GFP_KERNEL);
|
||||
if (!tfm)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
hash = crypto_alloc_ahash(name, type, mask);
|
||||
if (IS_ERR(hash)) {
|
||||
kfree(tfm);
|
||||
return ERR_CAST(hash);
|
||||
}
|
||||
|
||||
tfm->hash = hash;
|
||||
|
||||
return tfm;
|
||||
}
|
||||
|
||||
static void hash_release(void *private)
|
||||
{
|
||||
crypto_free_ahash(private);
|
||||
struct algif_hash_tfm *tfm = private;
|
||||
|
||||
crypto_free_ahash(tfm->hash);
|
||||
kfree(tfm);
|
||||
}
|
||||
|
||||
static int hash_setkey(void *private, const u8 *key, unsigned int keylen)
|
||||
{
|
||||
return crypto_ahash_setkey(private, key, keylen);
|
||||
struct algif_hash_tfm *tfm = private;
|
||||
int err;
|
||||
|
||||
err = crypto_ahash_setkey(tfm->hash, key, keylen);
|
||||
tfm->has_key = !err;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void hash_sock_destruct(struct sock *sk)
|
||||
|
@ -261,12 +398,14 @@ static void hash_sock_destruct(struct sock *sk)
|
|||
af_alg_release_parent(sk);
|
||||
}
|
||||
|
||||
static int hash_accept_parent(void *private, struct sock *sk)
|
||||
static int hash_accept_parent_nokey(void *private, struct sock *sk)
|
||||
{
|
||||
struct hash_ctx *ctx;
|
||||
struct alg_sock *ask = alg_sk(sk);
|
||||
unsigned len = sizeof(*ctx) + crypto_ahash_reqsize(private);
|
||||
unsigned ds = crypto_ahash_digestsize(private);
|
||||
struct algif_hash_tfm *tfm = private;
|
||||
struct crypto_ahash *hash = tfm->hash;
|
||||
unsigned len = sizeof(*ctx) + crypto_ahash_reqsize(hash);
|
||||
unsigned ds = crypto_ahash_digestsize(hash);
|
||||
|
||||
ctx = sock_kmalloc(sk, len, GFP_KERNEL);
|
||||
if (!ctx)
|
||||
|
@ -286,7 +425,7 @@ static int hash_accept_parent(void *private, struct sock *sk)
|
|||
|
||||
ask->private = ctx;
|
||||
|
||||
ahash_request_set_tfm(&ctx->req, private);
|
||||
ahash_request_set_tfm(&ctx->req, hash);
|
||||
ahash_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_BACKLOG,
|
||||
af_alg_complete, &ctx->completion);
|
||||
|
||||
|
@ -295,12 +434,24 @@ static int hash_accept_parent(void *private, struct sock *sk)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int hash_accept_parent(void *private, struct sock *sk)
|
||||
{
|
||||
struct algif_hash_tfm *tfm = private;
|
||||
|
||||
if (!tfm->has_key && crypto_ahash_has_setkey(tfm->hash))
|
||||
return -ENOKEY;
|
||||
|
||||
return hash_accept_parent_nokey(private, sk);
|
||||
}
|
||||
|
||||
static const struct af_alg_type algif_type_hash = {
|
||||
.bind = hash_bind,
|
||||
.release = hash_release,
|
||||
.setkey = hash_setkey,
|
||||
.accept = hash_accept_parent,
|
||||
.accept_nokey = hash_accept_parent_nokey,
|
||||
.ops = &algif_hash_ops,
|
||||
.ops_nokey = &algif_hash_ops_nokey,
|
||||
.name = "hash",
|
||||
.owner = THIS_MODULE
|
||||
};
|
||||
|
|
|
@ -31,6 +31,11 @@ struct skcipher_sg_list {
|
|||
struct scatterlist sg[0];
|
||||
};
|
||||
|
||||
struct skcipher_tfm {
|
||||
struct crypto_skcipher *skcipher;
|
||||
bool has_key;
|
||||
};
|
||||
|
||||
struct skcipher_ctx {
|
||||
struct list_head tsgl;
|
||||
struct af_alg_sgl rsgl;
|
||||
|
@ -387,7 +392,8 @@ static int skcipher_sendmsg(struct socket *sock, struct msghdr *msg,
|
|||
|
||||
sgl = list_entry(ctx->tsgl.prev, struct skcipher_sg_list, list);
|
||||
sg = sgl->sg;
|
||||
sg_unmark_end(sg + sgl->cur);
|
||||
if (sgl->cur)
|
||||
sg_unmark_end(sg + sgl->cur - 1);
|
||||
do {
|
||||
i = sgl->cur;
|
||||
plen = min_t(size_t, len, PAGE_SIZE);
|
||||
|
@ -642,13 +648,6 @@ static int skcipher_recvmsg_sync(struct socket *sock, struct msghdr *msg,
|
|||
|
||||
lock_sock(sk);
|
||||
while (msg_data_left(msg)) {
|
||||
sgl = list_first_entry(&ctx->tsgl,
|
||||
struct skcipher_sg_list, list);
|
||||
sg = sgl->sg;
|
||||
|
||||
while (!sg->length)
|
||||
sg++;
|
||||
|
||||
if (!ctx->used) {
|
||||
err = skcipher_wait_for_data(sk, flags);
|
||||
if (err)
|
||||
|
@ -669,6 +668,13 @@ static int skcipher_recvmsg_sync(struct socket *sock, struct msghdr *msg,
|
|||
if (!used)
|
||||
goto free;
|
||||
|
||||
sgl = list_first_entry(&ctx->tsgl,
|
||||
struct skcipher_sg_list, list);
|
||||
sg = sgl->sg;
|
||||
|
||||
while (!sg->length)
|
||||
sg++;
|
||||
|
||||
skcipher_request_set_crypt(&ctx->req, sg, ctx->rsgl.sg, used,
|
||||
ctx->iv);
|
||||
|
||||
|
@ -748,19 +754,139 @@ static struct proto_ops algif_skcipher_ops = {
|
|||
.poll = skcipher_poll,
|
||||
};
|
||||
|
||||
static int skcipher_check_key(struct socket *sock)
|
||||
{
|
||||
int err = 0;
|
||||
struct sock *psk;
|
||||
struct alg_sock *pask;
|
||||
struct skcipher_tfm *tfm;
|
||||
struct sock *sk = sock->sk;
|
||||
struct alg_sock *ask = alg_sk(sk);
|
||||
|
||||
lock_sock(sk);
|
||||
if (ask->refcnt)
|
||||
goto unlock_child;
|
||||
|
||||
psk = ask->parent;
|
||||
pask = alg_sk(ask->parent);
|
||||
tfm = pask->private;
|
||||
|
||||
err = -ENOKEY;
|
||||
lock_sock_nested(psk, SINGLE_DEPTH_NESTING);
|
||||
if (!tfm->has_key)
|
||||
goto unlock;
|
||||
|
||||
if (!pask->refcnt++)
|
||||
sock_hold(psk);
|
||||
|
||||
ask->refcnt = 1;
|
||||
sock_put(psk);
|
||||
|
||||
err = 0;
|
||||
|
||||
unlock:
|
||||
release_sock(psk);
|
||||
unlock_child:
|
||||
release_sock(sk);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int skcipher_sendmsg_nokey(struct socket *sock, struct msghdr *msg,
|
||||
size_t size)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = skcipher_check_key(sock);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return skcipher_sendmsg(sock, msg, size);
|
||||
}
|
||||
|
||||
static ssize_t skcipher_sendpage_nokey(struct socket *sock, struct page *page,
|
||||
int offset, size_t size, int flags)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = skcipher_check_key(sock);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return skcipher_sendpage(sock, page, offset, size, flags);
|
||||
}
|
||||
|
||||
static int skcipher_recvmsg_nokey(struct socket *sock, struct msghdr *msg,
|
||||
size_t ignored, int flags)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = skcipher_check_key(sock);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return skcipher_recvmsg(sock, msg, ignored, flags);
|
||||
}
|
||||
|
||||
static struct proto_ops algif_skcipher_ops_nokey = {
|
||||
.family = PF_ALG,
|
||||
|
||||
.connect = sock_no_connect,
|
||||
.socketpair = sock_no_socketpair,
|
||||
.getname = sock_no_getname,
|
||||
.ioctl = sock_no_ioctl,
|
||||
.listen = sock_no_listen,
|
||||
.shutdown = sock_no_shutdown,
|
||||
.getsockopt = sock_no_getsockopt,
|
||||
.mmap = sock_no_mmap,
|
||||
.bind = sock_no_bind,
|
||||
.accept = sock_no_accept,
|
||||
.setsockopt = sock_no_setsockopt,
|
||||
|
||||
.release = af_alg_release,
|
||||
.sendmsg = skcipher_sendmsg_nokey,
|
||||
.sendpage = skcipher_sendpage_nokey,
|
||||
.recvmsg = skcipher_recvmsg_nokey,
|
||||
.poll = skcipher_poll,
|
||||
};
|
||||
|
||||
static void *skcipher_bind(const char *name, u32 type, u32 mask)
|
||||
{
|
||||
return crypto_alloc_skcipher(name, type, mask);
|
||||
struct skcipher_tfm *tfm;
|
||||
struct crypto_skcipher *skcipher;
|
||||
|
||||
tfm = kzalloc(sizeof(*tfm), GFP_KERNEL);
|
||||
if (!tfm)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
skcipher = crypto_alloc_skcipher(name, type, mask);
|
||||
if (IS_ERR(skcipher)) {
|
||||
kfree(tfm);
|
||||
return ERR_CAST(skcipher);
|
||||
}
|
||||
|
||||
tfm->skcipher = skcipher;
|
||||
|
||||
return tfm;
|
||||
}
|
||||
|
||||
static void skcipher_release(void *private)
|
||||
{
|
||||
crypto_free_skcipher(private);
|
||||
struct skcipher_tfm *tfm = private;
|
||||
|
||||
crypto_free_skcipher(tfm->skcipher);
|
||||
kfree(tfm);
|
||||
}
|
||||
|
||||
static int skcipher_setkey(void *private, const u8 *key, unsigned int keylen)
|
||||
{
|
||||
return crypto_skcipher_setkey(private, key, keylen);
|
||||
struct skcipher_tfm *tfm = private;
|
||||
int err;
|
||||
|
||||
err = crypto_skcipher_setkey(tfm->skcipher, key, keylen);
|
||||
tfm->has_key = !err;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static void skcipher_wait(struct sock *sk)
|
||||
|
@ -788,24 +914,26 @@ static void skcipher_sock_destruct(struct sock *sk)
|
|||
af_alg_release_parent(sk);
|
||||
}
|
||||
|
||||
static int skcipher_accept_parent(void *private, struct sock *sk)
|
||||
static int skcipher_accept_parent_nokey(void *private, struct sock *sk)
|
||||
{
|
||||
struct skcipher_ctx *ctx;
|
||||
struct alg_sock *ask = alg_sk(sk);
|
||||
unsigned int len = sizeof(*ctx) + crypto_skcipher_reqsize(private);
|
||||
struct skcipher_tfm *tfm = private;
|
||||
struct crypto_skcipher *skcipher = tfm->skcipher;
|
||||
unsigned int len = sizeof(*ctx) + crypto_skcipher_reqsize(skcipher);
|
||||
|
||||
ctx = sock_kmalloc(sk, len, GFP_KERNEL);
|
||||
if (!ctx)
|
||||
return -ENOMEM;
|
||||
|
||||
ctx->iv = sock_kmalloc(sk, crypto_skcipher_ivsize(private),
|
||||
ctx->iv = sock_kmalloc(sk, crypto_skcipher_ivsize(skcipher),
|
||||
GFP_KERNEL);
|
||||
if (!ctx->iv) {
|
||||
sock_kfree_s(sk, ctx, len);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset(ctx->iv, 0, crypto_skcipher_ivsize(private));
|
||||
memset(ctx->iv, 0, crypto_skcipher_ivsize(skcipher));
|
||||
|
||||
INIT_LIST_HEAD(&ctx->tsgl);
|
||||
ctx->len = len;
|
||||
|
@ -818,7 +946,7 @@ static int skcipher_accept_parent(void *private, struct sock *sk)
|
|||
|
||||
ask->private = ctx;
|
||||
|
||||
skcipher_request_set_tfm(&ctx->req, private);
|
||||
skcipher_request_set_tfm(&ctx->req, skcipher);
|
||||
skcipher_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_BACKLOG,
|
||||
af_alg_complete, &ctx->completion);
|
||||
|
||||
|
@ -827,12 +955,24 @@ static int skcipher_accept_parent(void *private, struct sock *sk)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int skcipher_accept_parent(void *private, struct sock *sk)
|
||||
{
|
||||
struct skcipher_tfm *tfm = private;
|
||||
|
||||
if (!tfm->has_key && crypto_skcipher_has_setkey(tfm->skcipher))
|
||||
return -ENOKEY;
|
||||
|
||||
return skcipher_accept_parent_nokey(private, sk);
|
||||
}
|
||||
|
||||
static const struct af_alg_type algif_type_skcipher = {
|
||||
.bind = skcipher_bind,
|
||||
.release = skcipher_release,
|
||||
.setkey = skcipher_setkey,
|
||||
.accept = skcipher_accept_parent,
|
||||
.accept_nokey = skcipher_accept_parent_nokey,
|
||||
.ops = &algif_skcipher_ops,
|
||||
.ops_nokey = &algif_skcipher_ops_nokey,
|
||||
.name = "skcipher",
|
||||
.owner = THIS_MODULE
|
||||
};
|
||||
|
|
|
@ -172,4 +172,3 @@ MODULE_DESCRIPTION("CRC32c (Castagnoli) calculations wrapper for lib/crc32c");
|
|||
MODULE_LICENSE("GPL");
|
||||
MODULE_ALIAS_CRYPTO("crc32c");
|
||||
MODULE_ALIAS_CRYPTO("crc32c-generic");
|
||||
MODULE_SOFTDEP("pre: crc32c");
|
||||
|
|
|
@ -355,8 +355,10 @@ int crypto_init_shash_ops_async(struct crypto_tfm *tfm)
|
|||
crt->finup = shash_async_finup;
|
||||
crt->digest = shash_async_digest;
|
||||
|
||||
if (alg->setkey)
|
||||
if (alg->setkey) {
|
||||
crt->setkey = shash_async_setkey;
|
||||
crt->has_setkey = true;
|
||||
}
|
||||
if (alg->export)
|
||||
crt->export = shash_async_export;
|
||||
if (alg->import)
|
||||
|
|
|
@ -118,6 +118,7 @@ static int crypto_init_skcipher_ops_blkcipher(struct crypto_tfm *tfm)
|
|||
skcipher->decrypt = skcipher_decrypt_blkcipher;
|
||||
|
||||
skcipher->ivsize = crypto_blkcipher_ivsize(blkcipher);
|
||||
skcipher->has_setkey = calg->cra_blkcipher.max_keysize;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -210,6 +211,7 @@ static int crypto_init_skcipher_ops_ablkcipher(struct crypto_tfm *tfm)
|
|||
skcipher->ivsize = crypto_ablkcipher_ivsize(ablkcipher);
|
||||
skcipher->reqsize = crypto_ablkcipher_reqsize(ablkcipher) +
|
||||
sizeof(struct ablkcipher_request);
|
||||
skcipher->has_setkey = calg->cra_ablkcipher.max_keysize;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -381,6 +381,7 @@ config CRYPTO_DEV_BFIN_CRC
|
|||
|
||||
config CRYPTO_DEV_ATMEL_AES
|
||||
tristate "Support for Atmel AES hw accelerator"
|
||||
depends on HAS_DMA
|
||||
depends on AT_XDMAC || AT_HDMAC || COMPILE_TEST
|
||||
select CRYPTO_AES
|
||||
select CRYPTO_AEAD
|
||||
|
|
|
@ -280,6 +280,7 @@ static const char *atmel_aes_reg_name(u32 offset, char *tmp, size_t sz)
|
|||
case AES_GCMHR(2):
|
||||
case AES_GCMHR(3):
|
||||
snprintf(tmp, sz, "GCMHR[%u]", (offset - AES_GCMHR(0)) >> 2);
|
||||
break;
|
||||
|
||||
default:
|
||||
snprintf(tmp, sz, "0x%02x", offset);
|
||||
|
|
|
@ -389,7 +389,7 @@ static int qat_hal_check_ae_alive(struct icp_qat_fw_loader_handle *handle)
|
|||
{
|
||||
unsigned int base_cnt, cur_cnt;
|
||||
unsigned char ae;
|
||||
unsigned int times = MAX_RETRY_TIMES;
|
||||
int times = MAX_RETRY_TIMES;
|
||||
|
||||
for (ae = 0; ae < handle->hal_handle->ae_max_num; ae++) {
|
||||
qat_hal_rd_ae_csr(handle, ae, PROFILE_COUNT,
|
||||
|
@ -402,7 +402,7 @@ static int qat_hal_check_ae_alive(struct icp_qat_fw_loader_handle *handle)
|
|||
cur_cnt &= 0xffff;
|
||||
} while (times-- && (cur_cnt == base_cnt));
|
||||
|
||||
if (!times) {
|
||||
if (times < 0) {
|
||||
pr_err("QAT: AE%d is inactive!!\n", ae);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
@ -453,7 +453,11 @@ static int qat_hal_init_esram(struct icp_qat_fw_loader_handle *handle)
|
|||
void __iomem *csr_addr =
|
||||
(void __iomem *)((uintptr_t)handle->hal_ep_csr_addr_v +
|
||||
ESRAM_AUTO_INIT_CSR_OFFSET);
|
||||
unsigned int csr_val, times = 30;
|
||||
unsigned int csr_val;
|
||||
int times = 30;
|
||||
|
||||
if (handle->pci_dev->device == ADF_C3XXX_PCI_DEVICE_ID)
|
||||
return 0;
|
||||
|
||||
csr_val = ADF_CSR_RD(csr_addr, 0);
|
||||
if ((csr_val & ESRAM_AUTO_TINIT) && (csr_val & ESRAM_AUTO_TINIT_DONE))
|
||||
|
@ -467,7 +471,7 @@ static int qat_hal_init_esram(struct icp_qat_fw_loader_handle *handle)
|
|||
qat_hal_wait_cycles(handle, 0, ESRAM_AUTO_INIT_USED_CYCLES, 0);
|
||||
csr_val = ADF_CSR_RD(csr_addr, 0);
|
||||
} while (!(csr_val & ESRAM_AUTO_TINIT_DONE) && times--);
|
||||
if ((!times)) {
|
||||
if ((times < 0)) {
|
||||
pr_err("QAT: Fail to init eSram!\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
@ -658,7 +662,7 @@ static int qat_hal_clear_gpr(struct icp_qat_fw_loader_handle *handle)
|
|||
ret = qat_hal_wait_cycles(handle, ae, 20, 1);
|
||||
} while (ret && times--);
|
||||
|
||||
if (!times) {
|
||||
if (times < 0) {
|
||||
pr_err("QAT: clear GPR of AE %d failed", ae);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -693,14 +697,12 @@ int qat_hal_init(struct adf_accel_dev *accel_dev)
|
|||
struct adf_hw_device_data *hw_data = accel_dev->hw_device;
|
||||
struct adf_bar *misc_bar =
|
||||
&pci_info->pci_bars[hw_data->get_misc_bar_id(hw_data)];
|
||||
struct adf_bar *sram_bar =
|
||||
&pci_info->pci_bars[hw_data->get_sram_bar_id(hw_data)];
|
||||
struct adf_bar *sram_bar;
|
||||
|
||||
handle = kzalloc(sizeof(*handle), GFP_KERNEL);
|
||||
if (!handle)
|
||||
return -ENOMEM;
|
||||
|
||||
handle->hal_sram_addr_v = sram_bar->virt_addr;
|
||||
handle->hal_cap_g_ctl_csr_addr_v =
|
||||
(void __iomem *)((uintptr_t)misc_bar->virt_addr +
|
||||
ICP_QAT_CAP_OFFSET);
|
||||
|
@ -714,6 +716,11 @@ int qat_hal_init(struct adf_accel_dev *accel_dev)
|
|||
(void __iomem *)((uintptr_t)handle->hal_cap_ae_xfer_csr_addr_v +
|
||||
LOCAL_TO_XFER_REG_OFFSET);
|
||||
handle->pci_dev = pci_info->pci_dev;
|
||||
if (handle->pci_dev->device != ADF_C3XXX_PCI_DEVICE_ID) {
|
||||
sram_bar =
|
||||
&pci_info->pci_bars[hw_data->get_sram_bar_id(hw_data)];
|
||||
handle->hal_sram_addr_v = sram_bar->virt_addr;
|
||||
}
|
||||
handle->fw_auth = (handle->pci_dev->device ==
|
||||
ADF_DH895XCC_PCI_DEVICE_ID) ? false : true;
|
||||
handle->hal_handle = kzalloc(sizeof(*handle->hal_handle), GFP_KERNEL);
|
||||
|
|
|
@ -204,6 +204,7 @@ struct crypto_ahash {
|
|||
unsigned int keylen);
|
||||
|
||||
unsigned int reqsize;
|
||||
bool has_setkey;
|
||||
struct crypto_tfm base;
|
||||
};
|
||||
|
||||
|
@ -375,6 +376,11 @@ static inline void *ahash_request_ctx(struct ahash_request *req)
|
|||
int crypto_ahash_setkey(struct crypto_ahash *tfm, const u8 *key,
|
||||
unsigned int keylen);
|
||||
|
||||
static inline bool crypto_ahash_has_setkey(struct crypto_ahash *tfm)
|
||||
{
|
||||
return tfm->has_setkey;
|
||||
}
|
||||
|
||||
/**
|
||||
* crypto_ahash_finup() - update and finalize message digest
|
||||
* @req: reference to the ahash_request handle that holds all information
|
||||
|
|
|
@ -30,6 +30,9 @@ struct alg_sock {
|
|||
|
||||
struct sock *parent;
|
||||
|
||||
unsigned int refcnt;
|
||||
unsigned int nokey_refcnt;
|
||||
|
||||
const struct af_alg_type *type;
|
||||
void *private;
|
||||
};
|
||||
|
@ -50,9 +53,11 @@ struct af_alg_type {
|
|||
void (*release)(void *private);
|
||||
int (*setkey)(void *private, const u8 *key, unsigned int keylen);
|
||||
int (*accept)(void *private, struct sock *sk);
|
||||
int (*accept_nokey)(void *private, struct sock *sk);
|
||||
int (*setauthsize)(void *private, unsigned int authsize);
|
||||
|
||||
struct proto_ops *ops;
|
||||
struct proto_ops *ops_nokey;
|
||||
struct module *owner;
|
||||
char name[14];
|
||||
};
|
||||
|
@ -67,6 +72,7 @@ int af_alg_register_type(const struct af_alg_type *type);
|
|||
int af_alg_unregister_type(const struct af_alg_type *type);
|
||||
|
||||
int af_alg_release(struct socket *sock);
|
||||
void af_alg_release_parent(struct sock *sk);
|
||||
int af_alg_accept(struct sock *sk, struct socket *newsock);
|
||||
|
||||
int af_alg_make_sg(struct af_alg_sgl *sgl, struct iov_iter *iter, int len);
|
||||
|
@ -83,11 +89,6 @@ static inline struct alg_sock *alg_sk(struct sock *sk)
|
|||
return (struct alg_sock *)sk;
|
||||
}
|
||||
|
||||
static inline void af_alg_release_parent(struct sock *sk)
|
||||
{
|
||||
sock_put(alg_sk(sk)->parent);
|
||||
}
|
||||
|
||||
static inline void af_alg_init_completion(struct af_alg_completion *completion)
|
||||
{
|
||||
init_completion(&completion->completion);
|
||||
|
|
|
@ -61,6 +61,8 @@ struct crypto_skcipher {
|
|||
unsigned int ivsize;
|
||||
unsigned int reqsize;
|
||||
|
||||
bool has_setkey;
|
||||
|
||||
struct crypto_tfm base;
|
||||
};
|
||||
|
||||
|
@ -305,6 +307,11 @@ static inline int crypto_skcipher_setkey(struct crypto_skcipher *tfm,
|
|||
return tfm->setkey(tfm, key, keylen);
|
||||
}
|
||||
|
||||
static inline bool crypto_skcipher_has_setkey(struct crypto_skcipher *tfm)
|
||||
{
|
||||
return tfm->has_setkey;
|
||||
}
|
||||
|
||||
/**
|
||||
* crypto_skcipher_reqtfm() - obtain cipher handle from request
|
||||
* @req: skcipher_request out of which the cipher handle is to be obtained
|
||||
|
|
|
@ -210,9 +210,11 @@ config RANDOM32_SELFTEST
|
|||
# compression support is select'ed if needed
|
||||
#
|
||||
config 842_COMPRESS
|
||||
select CRC32
|
||||
tristate
|
||||
|
||||
config 842_DECOMPRESS
|
||||
select CRC32
|
||||
tristate
|
||||
|
||||
config ZLIB_INFLATE
|
||||
|
|
|
@ -75,3 +75,4 @@ module_exit(libcrc32c_mod_fini);
|
|||
MODULE_AUTHOR("Clay Haapala <chaapala@cisco.com>");
|
||||
MODULE_DESCRIPTION("CRC32c (Castagnoli) calculations");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_SOFTDEP("pre: crc32c");
|
||||
|
|
Loading…
Reference in New Issue