Skip to content

Commit

Permalink
Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git…
Browse files Browse the repository at this point in the history
…/herbert/crypto-2.6

Pull crypto updates from Herbert Xu:
 "Here is the crypto update for 4.9:

  API:
   - The crypto engine code now supports hashes.

  Algorithms:
   - Allow keys >= 2048 bits in FIPS mode for RSA.

  Drivers:
   - Memory overwrite fix for vmx ghash.
   - Add support for building ARM sha1-neon in Thumb2 mode.
   - Reenable ARM ghash-ce code by adding import/export.
   - Reenable img-hash by adding import/export.
   - Add support for multiple cores in omap-aes.
   - Add little-endian support for sha1-powerpc.
   - Add Cavium HWRNG driver for ThunderX SoC"

* 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6: (137 commits)
  crypto: caam - treat SGT address pointer as u64
  crypto: ccp - Make syslog errors human-readable
  crypto: ccp - clean up data structure
  crypto: vmx - Ensure ghash-generic is enabled
  crypto: testmgr - add guard to dst buffer for ahash_export
  crypto: caam - Unmap region obtained by of_iomap
  crypto: sha1-powerpc - little-endian support
  crypto: gcm - Fix IV buffer size in crypto_gcm_setkey
  crypto: vmx - Fix memory corruption caused by p8_ghash
  crypto: ghash-generic - move common definitions to a new header file
  crypto: caam - fix sg dump
  hwrng: omap - Only fail if pm_runtime_get_sync returns < 0
  crypto: omap-sham - shrink the internal buffer size
  crypto: omap-sham - add support for export/import
  crypto: omap-sham - convert driver logic to use sgs for data xmit
  crypto: omap-sham - change the DMA threshold value to a define
  crypto: omap-sham - add support functions for sg based data handling
  crypto: omap-sham - rename sgl to sgl_tmp for deprecation
  crypto: omap-sham - align algorithms on word offset
  crypto: omap-sham - add context export/import stubs
  ...
  • Loading branch information
torvalds committed Oct 10, 2016
2 parents 6763afe + c3afafa commit 30066ce
Show file tree
Hide file tree
Showing 77 changed files with 3,852 additions and 1,654 deletions.
38 changes: 26 additions & 12 deletions Documentation/DocBook/crypto-API.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -797,7 +797,8 @@ kernel crypto API | Caller
include/linux/crypto.h and their definition can be seen below.
The former function registers a single transformation, while
the latter works on an array of transformation descriptions.
The latter is useful when registering transformations in bulk.
The latter is useful when registering transformations in bulk,
for example when a driver implements multiple transformations.
</para>

<programlisting>
Expand All @@ -822,18 +823,31 @@ kernel crypto API | Caller
</para>

<para>
The bulk registration / unregistration functions require
that struct crypto_alg is an array of count size. These
functions simply loop over that array and register /
unregister each individual algorithm. If an error occurs,
the loop is terminated at the offending algorithm definition.
That means, the algorithms prior to the offending algorithm
are successfully registered. Note, the caller has no way of
knowing which cipher implementations have successfully
registered. If this is important to know, the caller should
loop through the different implementations using the single
instance *_alg functions for each individual implementation.
The bulk registration/unregistration functions
register/unregister each transformation in the given array of
length count. They handle errors as follows:
</para>
<itemizedlist>
<listitem>
<para>
crypto_register_algs() succeeds if and only if it
successfully registers all the given transformations. If an
error occurs partway through, then it rolls back successful
registrations before returning the error code. Note that if
a driver needs to handle registration errors for individual
transformations, then it will need to use the non-bulk
function crypto_register_alg() instead.
</para>
</listitem>
<listitem>
<para>
crypto_unregister_algs() tries to unregister all the given
transformations, continuing on error. It logs errors and
always returns zero.
</para>
</listitem>
</itemizedlist>

</sect1>

<sect1><title>Single-Block Symmetric Ciphers [CIPHER]</title>
Expand Down
26 changes: 25 additions & 1 deletion arch/arm/crypto/ghash-ce-glue.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ static struct shash_alg ghash_alg = {
.setkey = ghash_setkey,
.descsize = sizeof(struct ghash_desc_ctx),
.base = {
.cra_name = "ghash",
.cra_name = "__ghash",
.cra_driver_name = "__driver-ghash-ce",
.cra_priority = 0,
.cra_flags = CRYPTO_ALG_TYPE_SHASH | CRYPTO_ALG_INTERNAL,
Expand Down Expand Up @@ -220,6 +220,27 @@ static int ghash_async_digest(struct ahash_request *req)
}
}

static int ghash_async_import(struct ahash_request *req, const void *in)
{
struct ahash_request *cryptd_req = ahash_request_ctx(req);
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
struct ghash_async_ctx *ctx = crypto_ahash_ctx(tfm);
struct shash_desc *desc = cryptd_shash_desc(cryptd_req);

desc->tfm = cryptd_ahash_child(ctx->cryptd_tfm);
desc->flags = req->base.flags;

return crypto_shash_import(desc, in);
}

static int ghash_async_export(struct ahash_request *req, void *out)
{
struct ahash_request *cryptd_req = ahash_request_ctx(req);
struct shash_desc *desc = cryptd_shash_desc(cryptd_req);

return crypto_shash_export(desc, out);
}

static int ghash_async_setkey(struct crypto_ahash *tfm, const u8 *key,
unsigned int keylen)
{
Expand Down Expand Up @@ -268,7 +289,10 @@ static struct ahash_alg ghash_async_alg = {
.final = ghash_async_final,
.setkey = ghash_async_setkey,
.digest = ghash_async_digest,
.import = ghash_async_import,
.export = ghash_async_export,
.halg.digestsize = GHASH_DIGEST_SIZE,
.halg.statesize = sizeof(struct ghash_desc_ctx),
.halg.base = {
.cra_name = "ghash",
.cra_driver_name = "ghash-ce",
Expand Down
1 change: 0 additions & 1 deletion arch/arm/crypto/sha1-armv7-neon.S
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
#include <asm/assembler.h>

.syntax unified
.code 32
.fpu neon

.text
Expand Down
13 changes: 11 additions & 2 deletions arch/powerpc/crypto/sha1-powerpc-asm.S
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@
#include <asm/ppc_asm.h>
#include <asm/asm-offsets.h>

#ifdef __BIG_ENDIAN__
#define LWZ(rt, d, ra) \
lwz rt,d(ra)
#else
#define LWZ(rt, d, ra) \
li rt,d; \
lwbrx rt,rt,ra
#endif

/*
* We roll the registers for T, A, B, C, D, E around on each
* iteration; T on iteration t is A on iteration t+1, and so on.
Expand All @@ -23,7 +32,7 @@
#define W(t) (((t)%16)+16)

#define LOADW(t) \
lwz W(t),(t)*4(r4)
LWZ(W(t),(t)*4,r4)

#define STEPD0_LOAD(t) \
andc r0,RD(t),RB(t); \
Expand All @@ -33,7 +42,7 @@
add r0,RE(t),r15; \
add RT(t),RT(t),r6; \
add r14,r0,W(t); \
lwz W((t)+4),((t)+4)*4(r4); \
LWZ(W((t)+4),((t)+4)*4,r4); \
rotlwi RB(t),RB(t),30; \
add RT(t),RT(t),r14

Expand Down
73 changes: 61 additions & 12 deletions crypto/algif_hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,37 @@ struct algif_hash_tfm {
bool has_key;
};

static int hash_alloc_result(struct sock *sk, struct hash_ctx *ctx)
{
unsigned ds;

if (ctx->result)
return 0;

ds = crypto_ahash_digestsize(crypto_ahash_reqtfm(&ctx->req));

ctx->result = sock_kmalloc(sk, ds, GFP_KERNEL);
if (!ctx->result)
return -ENOMEM;

memset(ctx->result, 0, ds);

return 0;
}

static void hash_free_result(struct sock *sk, struct hash_ctx *ctx)
{
unsigned ds;

if (!ctx->result)
return;

ds = crypto_ahash_digestsize(crypto_ahash_reqtfm(&ctx->req));

sock_kzfree_s(sk, ctx->result, ds);
ctx->result = NULL;
}

static int hash_sendmsg(struct socket *sock, struct msghdr *msg,
size_t ignored)
{
Expand All @@ -54,6 +85,9 @@ static int hash_sendmsg(struct socket *sock, struct msghdr *msg,

lock_sock(sk);
if (!ctx->more) {
if ((msg->msg_flags & MSG_MORE))
hash_free_result(sk, ctx);

err = af_alg_wait_for_completion(crypto_ahash_init(&ctx->req),
&ctx->completion);
if (err)
Expand Down Expand Up @@ -90,6 +124,10 @@ static int hash_sendmsg(struct socket *sock, struct msghdr *msg,

ctx->more = msg->msg_flags & MSG_MORE;
if (!ctx->more) {
err = hash_alloc_result(sk, ctx);
if (err)
goto unlock;

ahash_request_set_crypt(&ctx->req, NULL, ctx->result, 0);
err = af_alg_wait_for_completion(crypto_ahash_final(&ctx->req),
&ctx->completion);
Expand All @@ -116,6 +154,13 @@ static ssize_t hash_sendpage(struct socket *sock, struct page *page,
sg_init_table(ctx->sgl.sg, 1);
sg_set_page(ctx->sgl.sg, page, size, offset);

if (!(flags & MSG_MORE)) {
err = hash_alloc_result(sk, ctx);
if (err)
goto unlock;
} else if (!ctx->more)
hash_free_result(sk, ctx);

ahash_request_set_crypt(&ctx->req, ctx->sgl.sg, ctx->result, size);

if (!(flags & MSG_MORE)) {
Expand Down Expand Up @@ -153,6 +198,7 @@ static int hash_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
struct alg_sock *ask = alg_sk(sk);
struct hash_ctx *ctx = ask->private;
unsigned ds = crypto_ahash_digestsize(crypto_ahash_reqtfm(&ctx->req));
bool result;
int err;

if (len > ds)
Expand All @@ -161,17 +207,29 @@ static int hash_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
msg->msg_flags |= MSG_TRUNC;

lock_sock(sk);
result = ctx->result;
err = hash_alloc_result(sk, ctx);
if (err)
goto unlock;

ahash_request_set_crypt(&ctx->req, NULL, ctx->result, 0);

if (ctx->more) {
ctx->more = 0;
ahash_request_set_crypt(&ctx->req, NULL, ctx->result, 0);
err = af_alg_wait_for_completion(crypto_ahash_final(&ctx->req),
&ctx->completion);
if (err)
goto unlock;
} else if (!result) {
err = af_alg_wait_for_completion(
crypto_ahash_digest(&ctx->req),
&ctx->completion);
}

err = memcpy_to_msg(msg, ctx->result, len);

hash_free_result(sk, ctx);

unlock:
release_sock(sk);

Expand Down Expand Up @@ -394,8 +452,7 @@ static void hash_sock_destruct(struct sock *sk)
struct alg_sock *ask = alg_sk(sk);
struct hash_ctx *ctx = ask->private;

sock_kzfree_s(sk, ctx->result,
crypto_ahash_digestsize(crypto_ahash_reqtfm(&ctx->req)));
hash_free_result(sk, ctx);
sock_kfree_s(sk, ctx, ctx->len);
af_alg_release_parent(sk);
}
Expand All @@ -407,20 +464,12 @@ static int hash_accept_parent_nokey(void *private, struct sock *sk)
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)
return -ENOMEM;

ctx->result = sock_kmalloc(sk, ds, GFP_KERNEL);
if (!ctx->result) {
sock_kfree_s(sk, ctx, len);
return -ENOMEM;
}

memset(ctx->result, 0, ds);

ctx->result = NULL;
ctx->len = len;
ctx->more = 0;
af_alg_init_completion(&ctx->completion);
Expand Down
5 changes: 1 addition & 4 deletions crypto/crct10dif_generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,7 @@ static struct shash_alg alg = {

static int __init crct10dif_mod_init(void)
{
int ret;

ret = crypto_register_shash(&alg);
return ret;
return crypto_register_shash(&alg);
}

static void __exit crct10dif_mod_fini(void)
Expand Down
Loading

0 comments on commit 30066ce

Please sign in to comment.