Commit 48162a20 authored by Linus Torvalds's avatar Linus Torvalds

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
  ...
parents e7cc3edd 202736d9
...@@ -76,6 +76,8 @@ int af_alg_register_type(const struct af_alg_type *type) ...@@ -76,6 +76,8 @@ int af_alg_register_type(const struct af_alg_type *type)
goto unlock; goto unlock;
type->ops->owner = THIS_MODULE; type->ops->owner = THIS_MODULE;
if (type->ops_nokey)
type->ops_nokey->owner = THIS_MODULE;
node->type = type; node->type = type;
list_add(&node->list, &alg_types); list_add(&node->list, &alg_types);
err = 0; err = 0;
...@@ -125,6 +127,26 @@ int af_alg_release(struct socket *sock) ...@@ -125,6 +127,26 @@ int af_alg_release(struct socket *sock)
} }
EXPORT_SYMBOL_GPL(af_alg_release); 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) static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
{ {
const u32 forbidden = CRYPTO_ALG_INTERNAL; const u32 forbidden = CRYPTO_ALG_INTERNAL;
...@@ -133,6 +155,7 @@ static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) ...@@ -133,6 +155,7 @@ static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
struct sockaddr_alg *sa = (void *)uaddr; struct sockaddr_alg *sa = (void *)uaddr;
const struct af_alg_type *type; const struct af_alg_type *type;
void *private; void *private;
int err;
if (sock->state == SS_CONNECTED) if (sock->state == SS_CONNECTED)
return -EINVAL; return -EINVAL;
...@@ -160,16 +183,22 @@ static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) ...@@ -160,16 +183,22 @@ static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
return PTR_ERR(private); return PTR_ERR(private);
} }
err = -EBUSY;
lock_sock(sk); lock_sock(sk);
if (ask->refcnt | ask->nokey_refcnt)
goto unlock;
swap(ask->type, type); swap(ask->type, type);
swap(ask->private, private); swap(ask->private, private);
err = 0;
unlock:
release_sock(sk); release_sock(sk);
alg_do_release(type, private); alg_do_release(type, private);
return 0; return err;
} }
static int alg_setkey(struct sock *sk, char __user *ukey, 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, ...@@ -202,11 +231,15 @@ static int alg_setsockopt(struct socket *sock, int level, int optname,
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
struct alg_sock *ask = alg_sk(sk); struct alg_sock *ask = alg_sk(sk);
const struct af_alg_type *type; const struct af_alg_type *type;
int err = -ENOPROTOOPT; int err = -EBUSY;
lock_sock(sk); lock_sock(sk);
if (ask->refcnt)
goto unlock;
type = ask->type; type = ask->type;
err = -ENOPROTOOPT;
if (level != SOL_ALG || !type) if (level != SOL_ALG || !type)
goto unlock; goto unlock;
...@@ -238,6 +271,7 @@ int af_alg_accept(struct sock *sk, struct socket *newsock) ...@@ -238,6 +271,7 @@ int af_alg_accept(struct sock *sk, struct socket *newsock)
struct alg_sock *ask = alg_sk(sk); struct alg_sock *ask = alg_sk(sk);
const struct af_alg_type *type; const struct af_alg_type *type;
struct sock *sk2; struct sock *sk2;
unsigned int nokey;
int err; int err;
lock_sock(sk); lock_sock(sk);
...@@ -257,20 +291,29 @@ int af_alg_accept(struct sock *sk, struct socket *newsock) ...@@ -257,20 +291,29 @@ int af_alg_accept(struct sock *sk, struct socket *newsock)
security_sk_clone(sk, sk2); security_sk_clone(sk, sk2);
err = type->accept(ask->private, 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; goto unlock;
}
sk2->sk_family = PF_ALG; sk2->sk_family = PF_ALG;
if (nokey || !ask->refcnt++)
sock_hold(sk); sock_hold(sk);
ask->nokey_refcnt += nokey;
alg_sk(sk2)->parent = sk; alg_sk(sk2)->parent = sk;
alg_sk(sk2)->type = type; alg_sk(sk2)->type = type;
alg_sk(sk2)->nokey_refcnt = nokey;
newsock->ops = type->ops; newsock->ops = type->ops;
newsock->state = SS_CONNECTED; newsock->state = SS_CONNECTED;
if (nokey)
newsock->ops = type->ops_nokey;
err = 0; err = 0;
unlock: unlock:
......
...@@ -451,6 +451,7 @@ static int crypto_ahash_init_tfm(struct crypto_tfm *tfm) ...@@ -451,6 +451,7 @@ static int crypto_ahash_init_tfm(struct crypto_tfm *tfm)
struct ahash_alg *alg = crypto_ahash_alg(hash); struct ahash_alg *alg = crypto_ahash_alg(hash);
hash->setkey = ahash_nosetkey; hash->setkey = ahash_nosetkey;
hash->has_setkey = false;
hash->export = ahash_no_export; hash->export = ahash_no_export;
hash->import = ahash_no_import; hash->import = ahash_no_import;
...@@ -463,8 +464,10 @@ static int crypto_ahash_init_tfm(struct crypto_tfm *tfm) ...@@ -463,8 +464,10 @@ static int crypto_ahash_init_tfm(struct crypto_tfm *tfm)
hash->finup = alg->finup ?: ahash_def_finup; hash->finup = alg->finup ?: ahash_def_finup;
hash->digest = alg->digest; hash->digest = alg->digest;
if (alg->setkey) if (alg->setkey) {
hash->setkey = alg->setkey; hash->setkey = alg->setkey;
hash->has_setkey = true;
}
if (alg->export) if (alg->export)
hash->export = alg->export; hash->export = alg->export;
if (alg->import) if (alg->import)
......
...@@ -34,6 +34,11 @@ struct hash_ctx { ...@@ -34,6 +34,11 @@ struct hash_ctx {
struct ahash_request req; 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, static int hash_sendmsg(struct socket *sock, struct msghdr *msg,
size_t ignored) size_t ignored)
{ {
...@@ -235,19 +240,151 @@ static struct proto_ops algif_hash_ops = { ...@@ -235,19 +240,151 @@ static struct proto_ops algif_hash_ops = {
.accept = hash_accept, .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) 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) 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) 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) static void hash_sock_destruct(struct sock *sk)
...@@ -261,12 +398,14 @@ 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); 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 hash_ctx *ctx;
struct alg_sock *ask = alg_sk(sk); struct alg_sock *ask = alg_sk(sk);
unsigned len = sizeof(*ctx) + crypto_ahash_reqsize(private); struct algif_hash_tfm *tfm = private;
unsigned ds = crypto_ahash_digestsize(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); ctx = sock_kmalloc(sk, len, GFP_KERNEL);
if (!ctx) if (!ctx)
...@@ -286,7 +425,7 @@ static int hash_accept_parent(void *private, struct sock *sk) ...@@ -286,7 +425,7 @@ static int hash_accept_parent(void *private, struct sock *sk)
ask->private = ctx; 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, ahash_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_BACKLOG,
af_alg_complete, &ctx->completion); af_alg_complete, &ctx->completion);
...@@ -295,12 +434,24 @@ static int hash_accept_parent(void *private, struct sock *sk) ...@@ -295,12 +434,24 @@ static int hash_accept_parent(void *private, struct sock *sk)
return 0; 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 = { static const struct af_alg_type algif_type_hash = {
.bind = hash_bind, .bind = hash_bind,
.release = hash_release, .release = hash_release,
.setkey = hash_setkey, .setkey = hash_setkey,
.accept = hash_accept_parent, .accept = hash_accept_parent,
.accept_nokey = hash_accept_parent_nokey,
.ops = &algif_hash_ops, .ops = &algif_hash_ops,
.ops_nokey = &algif_hash_ops_nokey,
.name = "hash", .name = "hash",
.owner = THIS_MODULE .owner = THIS_MODULE
}; };
......
...@@ -31,6 +31,11 @@ struct skcipher_sg_list { ...@@ -31,6 +31,11 @@ struct skcipher_sg_list {
struct scatterlist sg[0]; struct scatterlist sg[0];
}; };
struct skcipher_tfm {
struct crypto_skcipher *skcipher;
bool has_key;
};
struct skcipher_ctx { struct skcipher_ctx {
struct list_head tsgl; struct list_head tsgl;
struct af_alg_sgl rsgl; struct af_alg_sgl rsgl;
...@@ -387,7 +392,8 @@ static int skcipher_sendmsg(struct socket *sock, struct msghdr *msg, ...@@ -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); sgl = list_entry(ctx->tsgl.prev, struct skcipher_sg_list, list);
sg = sgl->sg; sg = sgl->sg;
sg_unmark_end(sg + sgl->cur); if (sgl->cur)
sg_unmark_end(sg + sgl->cur - 1);
do { do {
i = sgl->cur; i = sgl->cur;
plen = min_t(size_t, len, PAGE_SIZE); plen = min_t(size_t, len, PAGE_SIZE);
...@@ -642,13 +648,6 @@ static int skcipher_recvmsg_sync(struct socket *sock, struct msghdr *msg, ...@@ -642,13 +648,6 @@ static int skcipher_recvmsg_sync(struct socket *sock, struct msghdr *msg,
lock_sock(sk); lock_sock(sk);
while (msg_data_left(msg)) { 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) { if (!ctx->used) {
err = skcipher_wait_for_data(sk, flags); err = skcipher_wait_for_data(sk, flags);
if (err) if (err)
...@@ -669,6 +668,13 @@ static int skcipher_recvmsg_sync(struct socket *sock, struct msghdr *msg, ...@@ -669,6 +668,13 @@ static int skcipher_recvmsg_sync(struct socket *sock, struct msghdr *msg,
if (!used) if (!used)
goto free; 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, skcipher_request_set_crypt(&ctx->req, sg, ctx->rsgl.sg, used,
ctx->iv); ctx->iv);
...@@ -748,19 +754,139 @@ static struct proto_ops algif_skcipher_ops = { ...@@ -748,19 +754,139 @@ static struct proto_ops algif_skcipher_ops = {
.poll = skcipher_poll, .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) 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) 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) 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) static void skcipher_wait(struct sock *sk)
...@@ -788,24 +914,26 @@ static void skcipher_sock_destruct(struct sock *sk) ...@@ -788,24 +914,26 @@ static void skcipher_sock_destruct(struct sock *sk)
af_alg_release_parent(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 skcipher_ctx *ctx;
struct alg_sock *ask = alg_sk(sk); 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); ctx = sock_kmalloc(sk, len, GFP_KERNEL);
if (!ctx) if (!ctx)
return -ENOMEM; return -ENOMEM;
ctx->iv = sock_kmalloc(sk, crypto_skcipher_ivsize(private), ctx->iv = sock_kmalloc(sk, crypto_skcipher_ivsize(skcipher),
GFP_KERNEL); GFP_KERNEL);
if (!ctx->iv) { if (!ctx->iv) {
sock_kfree_s(sk, ctx, len); sock_kfree_s(sk, ctx, len);
return -ENOMEM; return -ENOMEM;
} }
memset(ctx->iv, 0, crypto_skcipher_ivsize(private)); memset(ctx->iv, 0, crypto_skcipher_ivsize(skcipher));
INIT_LIST_HEAD(&ctx->tsgl); INIT_LIST_HEAD(&ctx->tsgl);
ctx->len = len; ctx->len = len;
...@@ -818,7 +946,7 @@ static int skcipher_accept_parent(void *private, struct sock *sk) ...@@ -818,7 +946,7 @@ static int skcipher_accept_parent(void *private, struct sock *sk)
ask->private = ctx; 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, skcipher_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_BACKLOG,
af_alg_complete, &ctx->completion); af_alg_complete, &ctx->completion);
...@@ -827,12 +955,24 @@ static int skcipher_accept_parent(void *private, struct sock *sk) ...@@ -827,12 +955,24 @@ static int skcipher_accept_parent(void *private, struct sock *sk)
return 0; 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 = { static const struct af_alg_type algif_type_skcipher = {
.bind = skcipher_bind, .bind = skcipher_bind,
.release = skcipher_release, .release = skcipher_release,
.setkey = skcipher_setkey, .setkey = skcipher_setkey,
.accept = skcipher_accept_parent, .accept = skcipher_accept_parent,
.accept_nokey = skcipher_accept_parent_nokey,
.ops = &algif_skcipher_ops, .ops = &algif_skcipher_ops,
.ops_nokey = &algif_skcipher_ops_nokey,
.name = "skcipher", .name = "skcipher",
.owner = THIS_MODULE .owner = THIS_MODULE
}; };
......
...@@ -172,4 +172,3 @@ MODULE_DESCRIPTION("CRC32c (Castagnoli) calculations wrapper for lib/crc32c"); ...@@ -172,4 +172,3 @@ MODULE_DESCRIPTION("CRC32c (Castagnoli) calculations wrapper for lib/crc32c");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_ALIAS_CRYPTO("crc32c"); MODULE_ALIAS_CRYPTO("crc32c");
MODULE_ALIAS_CRYPTO("crc32c-generic"); MODULE_ALIAS_CRYPTO("crc32c-generic");
MODULE_SOFTDEP("pre: crc32c");
...@@ -355,8 +355,10 @@ int crypto_init_shash_ops_async(struct crypto_tfm *tfm) ...@@ -355,8 +355,10 @@ int crypto_init_shash_ops_async(struct crypto_tfm *tfm)
crt->finup = shash_async_finup; crt->finup = shash_async_finup;
crt->digest = shash_async_digest; crt->digest = shash_async_digest;
if (alg->setkey) if (alg->setkey) {
crt->setkey = shash_async_setkey; crt->setkey = shash_async_setkey;
crt->has_setkey = true;
}
if (alg->export) if (alg->export)
crt->export = shash_async_export; crt->export = shash_async_export;
if (alg->import) if (alg->import)
......
...@@ -118,6 +118,7 @@ static int crypto_init_skcipher_ops_blkcipher(struct crypto_tfm *tfm) ...@@ -118,6 +118,7 @@ static int crypto_init_skcipher_ops_blkcipher(struct crypto_tfm *tfm)
skcipher->decrypt = skcipher_decrypt_blkcipher; skcipher->decrypt = skcipher_decrypt_blkcipher;
skcipher->ivsize = crypto_blkcipher_ivsize(blkcipher); skcipher->ivsize = crypto_blkcipher_ivsize(blkcipher);
skcipher->has_setkey = calg->cra_blkcipher.max_keysize;
return 0; return 0;
} }
...@@ -210,6 +211,7 @@ static int crypto_init_skcipher_ops_ablkcipher(struct crypto_tfm *tfm) ...@@ -210,6 +211,7 @@ static int crypto_init_skcipher_ops_ablkcipher(struct crypto_tfm *tfm)
skcipher->ivsize = crypto_ablkcipher_ivsize(ablkcipher); skcipher->ivsize = crypto_ablkcipher_ivsize(ablkcipher);
skcipher->reqsize = crypto_ablkcipher_reqsize(ablkcipher) + skcipher->reqsize = crypto_ablkcipher_reqsize(ablkcipher) +
sizeof(struct ablkcipher_request); sizeof(struct ablkcipher_request);
skcipher->has_setkey = calg->cra_ablkcipher.max_keysize;
return 0; return 0;
} }
......
...@@ -381,6 +381,7 @@ config CRYPTO_DEV_BFIN_CRC ...@@ -381,6 +381,7 @@ config CRYPTO_DEV_BFIN_CRC
config CRYPTO_DEV_ATMEL_AES config CRYPTO_DEV_ATMEL_AES
tristate "Support for Atmel AES hw accelerator" tristate "Support for Atmel AES hw accelerator"
depends on HAS_DMA
depends on AT_XDMAC || AT_HDMAC || COMPILE_TEST depends on AT_XDMAC || AT_HDMAC || COMPILE_TEST
select CRYPTO_AES select CRYPTO_AES
select CRYPTO_AEAD select CRYPTO_AEAD
......
...@@ -280,6 +280,7 @@ static const char *atmel_aes_reg_name(u32 offset, char *tmp, size_t sz) ...@@ -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(2):
case AES_GCMHR(3): case AES_GCMHR(3):
snprintf(tmp, sz, "GCMHR[%u]", (offset - AES_GCMHR(0)) >> 2); snprintf(tmp, sz, "GCMHR[%u]", (offset - AES_GCMHR(0)) >> 2);
break;
default: default:
snprintf(tmp, sz, "0x%02x", offset); snprintf(tmp, sz, "0x%02x", offset);
......
...@@ -389,7 +389,7 @@ static int qat_hal_check_ae_alive(struct icp_qat_fw_loader_handle *handle) ...@@ -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 int base_cnt, cur_cnt;
unsigned char ae; 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++) { for (ae = 0; ae < handle->hal_handle->ae_max_num; ae++) {
qat_hal_rd_ae_csr(handle, ae, PROFILE_COUNT, 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) ...@@ -402,7 +402,7 @@ static int qat_hal_check_ae_alive(struct icp_qat_fw_loader_handle *handle)
cur_cnt &= 0xffff; cur_cnt &= 0xffff;
} while (times-- && (cur_cnt == base_cnt)); } while (times-- && (cur_cnt == base_cnt));
if (!times) { if (times < 0) {
pr_err("QAT: AE%d is inactive!!\n", ae); pr_err("QAT: AE%d is inactive!!\n", ae);
return -EFAULT; return -EFAULT;
} }
...@@ -453,7 +453,11 @@ static int qat_hal_init_esram(struct icp_qat_fw_loader_handle *handle) ...@@ -453,7 +453,11 @@ static int qat_hal_init_esram(struct icp_qat_fw_loader_handle *handle)
void __iomem *csr_addr = void __iomem *csr_addr =
(void __iomem *)((uintptr_t)handle->hal_ep_csr_addr_v + (void __iomem *)((uintptr_t)handle->hal_ep_csr_addr_v +
ESRAM_AUTO_INIT_CSR_OFFSET); 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); csr_val = ADF_CSR_RD(csr_addr, 0);
if ((csr_val & ESRAM_AUTO_TINIT) && (csr_val & ESRAM_AUTO_TINIT_DONE)) 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) ...@@ -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); qat_hal_wait_cycles(handle, 0, ESRAM_AUTO_INIT_USED_CYCLES, 0);
csr_val = ADF_CSR_RD(csr_addr, 0); csr_val = ADF_CSR_RD(csr_addr, 0);
} while (!(csr_val & ESRAM_AUTO_TINIT_DONE) && times--); } while (!(csr_val & ESRAM_AUTO_TINIT_DONE) && times--);
if ((!times)) { if ((times < 0)) {
pr_err("QAT: Fail to init eSram!\n"); pr_err("QAT: Fail to init eSram!\n");
return -EFAULT; return -EFAULT;
} }
...@@ -658,7 +662,7 @@ static int qat_hal_clear_gpr(struct icp_qat_fw_loader_handle *handle) ...@@ -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); ret = qat_hal_wait_cycles(handle, ae, 20, 1);
} while (ret && times--); } while (ret && times--);
if (!times) { if (times < 0) {
pr_err("QAT: clear GPR of AE %d failed", ae); pr_err("QAT: clear GPR of AE %d failed", ae);
return -EINVAL; return -EINVAL;
} }
...@@ -693,14 +697,12 @@ int qat_hal_init(struct adf_accel_dev *accel_dev) ...@@ -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_hw_device_data *hw_data = accel_dev->hw_device;
struct adf_bar *misc_bar = struct adf_bar *misc_bar =
&pci_info->pci_bars[hw_data->get_misc_bar_id(hw_data)]; &pci_info->pci_bars[hw_data->get_misc_bar_id(hw_data)];
struct adf_bar *sram_bar = struct adf_bar *sram_bar;
&pci_info->pci_bars[hw_data->get_sram_bar_id(hw_data)];
handle = kzalloc(sizeof(*handle), GFP_KERNEL); handle = kzalloc(sizeof(*handle), GFP_KERNEL);
if (!handle) if (!handle)
return -ENOMEM; return -ENOMEM;
handle->hal_sram_addr_v = sram_bar->virt_addr;
handle->hal_cap_g_ctl_csr_addr_v = handle->hal_cap_g_ctl_csr_addr_v =
(void __iomem *)((uintptr_t)misc_bar->virt_addr + (void __iomem *)((uintptr_t)misc_bar->virt_addr +
ICP_QAT_CAP_OFFSET); ICP_QAT_CAP_OFFSET);
...@@ -714,6 +716,11 @@ int qat_hal_init(struct adf_accel_dev *accel_dev) ...@@ -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 + (void __iomem *)((uintptr_t)handle->hal_cap_ae_xfer_csr_addr_v +
LOCAL_TO_XFER_REG_OFFSET); LOCAL_TO_XFER_REG_OFFSET);
handle->pci_dev = pci_info->pci_dev; 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 == handle->fw_auth = (handle->pci_dev->device ==
ADF_DH895XCC_PCI_DEVICE_ID) ? false : true; ADF_DH895XCC_PCI_DEVICE_ID) ? false : true;
handle->hal_handle = kzalloc(sizeof(*handle->hal_handle), GFP_KERNEL); handle->hal_handle = kzalloc(sizeof(*handle->hal_handle), GFP_KERNEL);
......
...@@ -204,6 +204,7 @@ struct crypto_ahash { ...@@ -204,6 +204,7 @@ struct crypto_ahash {
unsigned int keylen); unsigned int keylen);
unsigned int reqsize; unsigned int reqsize;
bool has_setkey;
struct crypto_tfm base; struct crypto_tfm base;
}; };
...@@ -375,6 +376,11 @@ static inline void *ahash_request_ctx(struct ahash_request *req) ...@@ -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, int crypto_ahash_setkey(struct crypto_ahash *tfm, const u8 *key,
unsigned int keylen); 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 * crypto_ahash_finup() - update and finalize message digest
* @req: reference to the ahash_request handle that holds all information * @req: reference to the ahash_request handle that holds all information
......
...@@ -30,6 +30,9 @@ struct alg_sock { ...@@ -30,6 +30,9 @@ struct alg_sock {
struct sock *parent; struct sock *parent;
unsigned int refcnt;
unsigned int nokey_refcnt;
const struct af_alg_type *type; const struct af_alg_type *type;
void *private; void *private;
}; };
...@@ -50,9 +53,11 @@ struct af_alg_type { ...@@ -50,9 +53,11 @@ struct af_alg_type {
void (*release)(void *private); void (*release)(void *private);
int (*setkey)(void *private, const u8 *key, unsigned int keylen); int (*setkey)(void *private, const u8 *key, unsigned int keylen);
int (*accept)(void *private, struct sock *sk); int (*accept)(void *private, struct sock *sk);
int (*accept_nokey)(void *private, struct sock *sk);
int (*setauthsize)(void *private, unsigned int authsize); int (*setauthsize)(void *private, unsigned int authsize);
struct proto_ops *ops; struct proto_ops *ops;
struct proto_ops *ops_nokey;
struct module *owner; struct module *owner;
char name[14]; char name[14];
}; };
...@@ -67,6 +72,7 @@ int af_alg_register_type(const struct af_alg_type *type); ...@@ -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_unregister_type(const struct af_alg_type *type);
int af_alg_release(struct socket *sock); 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_accept(struct sock *sk, struct socket *newsock);
int af_alg_make_sg(struct af_alg_sgl *sgl, struct iov_iter *iter, int len); 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) ...@@ -83,11 +89,6 @@ static inline struct alg_sock *alg_sk(struct sock *sk)
return (struct alg_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) static inline void af_alg_init_completion(struct af_alg_completion *completion)
{ {
init_completion(&completion->completion); init_completion(&completion->completion);
......
...@@ -61,6 +61,8 @@ struct crypto_skcipher { ...@@ -61,6 +61,8 @@ struct crypto_skcipher {
unsigned int ivsize; unsigned int ivsize;
unsigned int reqsize; unsigned int reqsize;
bool has_setkey;
struct crypto_tfm base; struct crypto_tfm base;
}; };
...@@ -305,6 +307,11 @@ static inline int crypto_skcipher_setkey(struct crypto_skcipher *tfm, ...@@ -305,6 +307,11 @@ static inline int crypto_skcipher_setkey(struct crypto_skcipher *tfm,
return tfm->setkey(tfm, key, keylen); 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 * crypto_skcipher_reqtfm() - obtain cipher handle from request
* @req: skcipher_request out of which the cipher handle is to be obtained * @req: skcipher_request out of which the cipher handle is to be obtained
......
...@@ -210,9 +210,11 @@ config RANDOM32_SELFTEST ...@@ -210,9 +210,11 @@ config RANDOM32_SELFTEST
# compression support is select'ed if needed # compression support is select'ed if needed
# #
config 842_COMPRESS config 842_COMPRESS
select CRC32
tristate tristate
config 842_DECOMPRESS config 842_DECOMPRESS
select CRC32
tristate tristate
config ZLIB_INFLATE config ZLIB_INFLATE
......
...@@ -75,3 +75,4 @@ module_exit(libcrc32c_mod_fini); ...@@ -75,3 +75,4 @@ module_exit(libcrc32c_mod_fini);
MODULE_AUTHOR("Clay Haapala <chaapala@cisco.com>"); MODULE_AUTHOR("Clay Haapala <chaapala@cisco.com>");
MODULE_DESCRIPTION("CRC32c (Castagnoli) calculations"); MODULE_DESCRIPTION("CRC32c (Castagnoli) calculations");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_SOFTDEP("pre: crc32c");
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment