Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
Browse files Browse the repository at this point in the history
* git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6: (50 commits)
  crypto: ixp4xx - Select CRYPTO_AUTHENC
  crypto: s390 - Respect STFL bit
  crypto: talitos - Add support for sha256 and md5 variants
  crypto: hash - Move ahash functions into crypto/hash.h
  crypto: crc32c - Add ahash implementation
  crypto: hash - Added scatter list walking helper
  crypto: prng - Deterministic CPRNG
  crypto: hash - Removed vestigial ahash fields
  crypto: hash - Fixed digest size check
  crypto: rmd - sparse annotations
  crypto: rmd128 - sparse annotations
  crypto: camellia - Use kernel-provided bitops, unaligned access helpers
  crypto: talitos - Use proper form for algorithm driver names
  crypto: talitos - Add support for 3des
  crypto: padlock - Make module loading quieter when hardware isn't available
  crypto: tcrpyt - Remove unnecessary kmap/kunmap calls
  crypto: ixp4xx - Hardware crypto support for IXP4xx CPUs
  crypto: talitos - Freescale integrated security engine (SEC) driver
  [CRYPTO] tcrypt: Add self test for des3_ebe cipher operating in cbc mode
  [CRYPTO] rmd: Use pointer form of endian swapping operations
  ...
  • Loading branch information
Linus Torvalds committed Jul 14, 2008
2 parents 6c118e4 + 090657e commit 3b23e66
Show file tree
Hide file tree
Showing 32 changed files with 7,227 additions and 326 deletions.
4 changes: 4 additions & 0 deletions arch/s390/crypto/crypt_s390.h
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,10 @@ static inline int crypt_s390_func_available(int func)
unsigned char status[16];
int ret;

/* check if CPACF facility (bit 17) is available */
if (!(stfl() & 1ULL << (31 - 17)))
return 0;

switch (func & CRYPT_S390_OP_MASK) {
case CRYPT_S390_KM:
ret = crypt_s390_km(KM_QUERY, &status, NULL, NULL, 0);
Expand Down
63 changes: 62 additions & 1 deletion crypto/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ config CRYPTO_NULL
config CRYPTO_CRYPTD
tristate "Software async crypto daemon"
select CRYPTO_BLKCIPHER
select CRYPTO_HASH
select CRYPTO_MANAGER
help
This is a generic software asynchronous crypto daemon that
Expand Down Expand Up @@ -212,7 +213,7 @@ comment "Digest"

config CRYPTO_CRC32C
tristate "CRC32c CRC algorithm"
select CRYPTO_ALGAPI
select CRYPTO_HASH
select LIBCRC32C
help
Castagnoli, et al Cyclic Redundancy-Check Algorithm. Used
Expand Down Expand Up @@ -241,6 +242,57 @@ config CRYPTO_MICHAEL_MIC
should not be used for other purposes because of the weakness
of the algorithm.

config CRYPTO_RMD128
tristate "RIPEMD-128 digest algorithm"
select CRYPTO_ALGAPI
help
RIPEMD-128 (ISO/IEC 10118-3:2004).

RIPEMD-128 is a 128-bit cryptographic hash function. It should only
to be used as a secure replacement for RIPEMD. For other use cases
RIPEMD-160 should be used.

Developed by Hans Dobbertin, Antoon Bosselaers and Bart Preneel.
See <http://home.esat.kuleuven.be/~bosselae/ripemd160.html>

config CRYPTO_RMD160
tristate "RIPEMD-160 digest algorithm"
select CRYPTO_ALGAPI
help
RIPEMD-160 (ISO/IEC 10118-3:2004).

RIPEMD-160 is a 160-bit cryptographic hash function. It is intended
to be used as a secure replacement for the 128-bit hash functions
MD4, MD5 and it's predecessor RIPEMD (not to be confused with RIPEMD-128).

It's speed is comparable to SHA1 and there are no known attacks against
RIPEMD-160.

Developed by Hans Dobbertin, Antoon Bosselaers and Bart Preneel.
See <http://home.esat.kuleuven.be/~bosselae/ripemd160.html>

config CRYPTO_RMD256
tristate "RIPEMD-256 digest algorithm"
select CRYPTO_ALGAPI
help
RIPEMD-256 is an optional extension of RIPEMD-128 with a 256 bit hash.
It is intended for applications that require longer hash-results, without
needing a larger security level (than RIPEMD-128).

Developed by Hans Dobbertin, Antoon Bosselaers and Bart Preneel.
See <http://home.esat.kuleuven.be/~bosselae/ripemd160.html>

config CRYPTO_RMD320
tristate "RIPEMD-320 digest algorithm"
select CRYPTO_ALGAPI
help
RIPEMD-320 is an optional extension of RIPEMD-160 with a 320 bit hash.
It is intended for applications that require longer hash-results, without
needing a larger security level (than RIPEMD-160).

Developed by Hans Dobbertin, Antoon Bosselaers and Bart Preneel.
See <http://home.esat.kuleuven.be/~bosselae/ripemd160.html>

config CRYPTO_SHA1
tristate "SHA1 digest algorithm"
select CRYPTO_ALGAPI
Expand Down Expand Up @@ -614,6 +666,15 @@ config CRYPTO_LZO
help
This is the LZO algorithm.

comment "Random Number Generation"

config CRYPTO_PRNG
tristate "Pseudo Random Number Generation for Cryptographic modules"
help
This option enables the generic pseudo random number generator
for cryptographic modules. Uses the Algorithm specified in
ANSI X9.31 A.2.4

source "drivers/crypto/Kconfig"

endif # if CRYPTO
7 changes: 6 additions & 1 deletion crypto/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ obj-$(CONFIG_CRYPTO_BLKCIPHER) += crypto_blkcipher.o
obj-$(CONFIG_CRYPTO_SEQIV) += seqiv.o

crypto_hash-objs := hash.o
crypto_hash-objs += ahash.o
obj-$(CONFIG_CRYPTO_HASH) += crypto_hash.o

obj-$(CONFIG_CRYPTO_MANAGER) += cryptomgr.o
Expand All @@ -27,6 +28,10 @@ obj-$(CONFIG_CRYPTO_XCBC) += xcbc.o
obj-$(CONFIG_CRYPTO_NULL) += crypto_null.o
obj-$(CONFIG_CRYPTO_MD4) += md4.o
obj-$(CONFIG_CRYPTO_MD5) += md5.o
obj-$(CONFIG_CRYPTO_RMD128) += rmd128.o
obj-$(CONFIG_CRYPTO_RMD160) += rmd160.o
obj-$(CONFIG_CRYPTO_RMD256) += rmd256.o
obj-$(CONFIG_CRYPTO_RMD320) += rmd320.o
obj-$(CONFIG_CRYPTO_SHA1) += sha1_generic.o
obj-$(CONFIG_CRYPTO_SHA256) += sha256_generic.o
obj-$(CONFIG_CRYPTO_SHA512) += sha512_generic.o
Expand Down Expand Up @@ -64,7 +69,7 @@ obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += michael_mic.o
obj-$(CONFIG_CRYPTO_CRC32C) += crc32c.o
obj-$(CONFIG_CRYPTO_AUTHENC) += authenc.o
obj-$(CONFIG_CRYPTO_LZO) += lzo.o

obj-$(CONFIG_CRYPTO_PRNG) += prng.o
obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o

#
Expand Down
194 changes: 194 additions & 0 deletions crypto/ahash.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
/*
* Asynchronous Cryptographic Hash operations.
*
* This is the asynchronous version of hash.c with notification of
* completion via a callback.
*
* Copyright (c) 2008 Loc Ho <lho@amcc.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
*/

#include <crypto/internal/hash.h>
#include <crypto/scatterwalk.h>
#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/seq_file.h>

#include "internal.h"

static int hash_walk_next(struct crypto_hash_walk *walk)
{
unsigned int alignmask = walk->alignmask;
unsigned int offset = walk->offset;
unsigned int nbytes = min(walk->entrylen,
((unsigned int)(PAGE_SIZE)) - offset);

walk->data = crypto_kmap(walk->pg, 0);
walk->data += offset;

if (offset & alignmask)
nbytes = alignmask + 1 - (offset & alignmask);

walk->entrylen -= nbytes;
return nbytes;
}

static int hash_walk_new_entry(struct crypto_hash_walk *walk)
{
struct scatterlist *sg;

sg = walk->sg;
walk->pg = sg_page(sg);
walk->offset = sg->offset;
walk->entrylen = sg->length;

if (walk->entrylen > walk->total)
walk->entrylen = walk->total;
walk->total -= walk->entrylen;

return hash_walk_next(walk);
}

int crypto_hash_walk_done(struct crypto_hash_walk *walk, int err)
{
unsigned int alignmask = walk->alignmask;
unsigned int nbytes = walk->entrylen;

walk->data -= walk->offset;

if (nbytes && walk->offset & alignmask && !err) {
walk->offset += alignmask - 1;
walk->offset = ALIGN(walk->offset, alignmask + 1);
walk->data += walk->offset;

nbytes = min(nbytes,
((unsigned int)(PAGE_SIZE)) - walk->offset);
walk->entrylen -= nbytes;

return nbytes;
}

crypto_kunmap(walk->data, 0);
crypto_yield(walk->flags);

if (err)
return err;

walk->offset = 0;

if (nbytes)
return hash_walk_next(walk);

if (!walk->total)
return 0;

walk->sg = scatterwalk_sg_next(walk->sg);

return hash_walk_new_entry(walk);
}
EXPORT_SYMBOL_GPL(crypto_hash_walk_done);

int crypto_hash_walk_first(struct ahash_request *req,
struct crypto_hash_walk *walk)
{
walk->total = req->nbytes;

if (!walk->total)
return 0;

walk->alignmask = crypto_ahash_alignmask(crypto_ahash_reqtfm(req));
walk->sg = req->src;
walk->flags = req->base.flags;

return hash_walk_new_entry(walk);
}
EXPORT_SYMBOL_GPL(crypto_hash_walk_first);

static int ahash_setkey_unaligned(struct crypto_ahash *tfm, const u8 *key,
unsigned int keylen)
{
struct ahash_alg *ahash = crypto_ahash_alg(tfm);
unsigned long alignmask = crypto_ahash_alignmask(tfm);
int ret;
u8 *buffer, *alignbuffer;
unsigned long absize;

absize = keylen + alignmask;
buffer = kmalloc(absize, GFP_ATOMIC);
if (!buffer)
return -ENOMEM;

alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1);
memcpy(alignbuffer, key, keylen);
ret = ahash->setkey(tfm, alignbuffer, keylen);
memset(alignbuffer, 0, keylen);
kfree(buffer);
return ret;
}

static int ahash_setkey(struct crypto_ahash *tfm, const u8 *key,
unsigned int keylen)
{
struct ahash_alg *ahash = crypto_ahash_alg(tfm);
unsigned long alignmask = crypto_ahash_alignmask(tfm);

if ((unsigned long)key & alignmask)
return ahash_setkey_unaligned(tfm, key, keylen);

return ahash->setkey(tfm, key, keylen);
}

static unsigned int crypto_ahash_ctxsize(struct crypto_alg *alg, u32 type,
u32 mask)
{
return alg->cra_ctxsize;
}

static int crypto_init_ahash_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
{
struct ahash_alg *alg = &tfm->__crt_alg->cra_ahash;
struct ahash_tfm *crt = &tfm->crt_ahash;

if (alg->digestsize > PAGE_SIZE / 8)
return -EINVAL;

crt->init = alg->init;
crt->update = alg->update;
crt->final = alg->final;
crt->digest = alg->digest;
crt->setkey = ahash_setkey;
crt->digestsize = alg->digestsize;

return 0;
}

static void crypto_ahash_show(struct seq_file *m, struct crypto_alg *alg)
__attribute__ ((unused));
static void crypto_ahash_show(struct seq_file *m, struct crypto_alg *alg)
{
seq_printf(m, "type : ahash\n");
seq_printf(m, "async : %s\n", alg->cra_flags & CRYPTO_ALG_ASYNC ?
"yes" : "no");
seq_printf(m, "blocksize : %u\n", alg->cra_blocksize);
seq_printf(m, "digestsize : %u\n", alg->cra_hash.digestsize);
}

const struct crypto_type crypto_ahash_type = {
.ctxsize = crypto_ahash_ctxsize,
.init = crypto_init_ahash_ops,
#ifdef CONFIG_PROC_FS
.show = crypto_ahash_show,
#endif
};
EXPORT_SYMBOL_GPL(crypto_ahash_type);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Asynchronous cryptographic hash type");
8 changes: 6 additions & 2 deletions crypto/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,8 +235,12 @@ static int crypto_init_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
return crypto_init_cipher_ops(tfm);

case CRYPTO_ALG_TYPE_DIGEST:
return crypto_init_digest_ops(tfm);

if ((mask & CRYPTO_ALG_TYPE_HASH_MASK) !=
CRYPTO_ALG_TYPE_HASH_MASK)
return crypto_init_digest_ops_async(tfm);
else
return crypto_init_digest_ops(tfm);

case CRYPTO_ALG_TYPE_COMPRESS:
return crypto_init_compress_ops(tfm);

Expand Down
Loading

0 comments on commit 3b23e66

Please sign in to comment.