Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 34248
b: refs/heads/master
c: 055bcee
h: refs/heads/master
v: v3
  • Loading branch information
Herbert Xu committed Sep 21, 2006
1 parent e6a34aa commit d9b5800
Show file tree
Hide file tree
Showing 9 changed files with 322 additions and 71 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 7226bc877a22244e8003924031435a4bffd52654
refs/heads/master: 055bcee3102dc35f019b69df9c2618e9d6dd1c09
4 changes: 4 additions & 0 deletions trunk/crypto/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ config CRYPTO_BLKCIPHER
tristate
select CRYPTO_ALGAPI

config CRYPTO_HASH
tristate
select CRYPTO_ALGAPI

config CRYPTO_MANAGER
tristate "Cryptographic algorithm manager"
select CRYPTO_ALGAPI
Expand Down
3 changes: 3 additions & 0 deletions trunk/crypto/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ obj-$(CONFIG_CRYPTO_ALGAPI) += crypto_algapi.o

obj-$(CONFIG_CRYPTO_BLKCIPHER) += blkcipher.o

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

obj-$(CONFIG_CRYPTO_MANAGER) += cryptomgr.o
obj-$(CONFIG_CRYPTO_HMAC) += hmac.o
obj-$(CONFIG_CRYPTO_NULL) += crypto_null.o
Expand Down
129 changes: 102 additions & 27 deletions trunk/crypto/digest.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,29 +11,89 @@
* any later version.
*
*/
#include <linux/crypto.h>

#include <linux/mm.h>
#include <linux/errno.h>
#include <linux/highmem.h>
#include <asm/scatterlist.h>
#include <linux/module.h>
#include <linux/scatterlist.h>

#include "internal.h"
#include "scatterwalk.h"

static void init(struct crypto_tfm *tfm)
void crypto_digest_init(struct crypto_tfm *tfm)
{
tfm->__crt_alg->cra_digest.dia_init(tfm);
struct crypto_hash *hash = crypto_hash_cast(tfm);
struct hash_desc desc = { .tfm = hash, .flags = tfm->crt_flags };

crypto_hash_init(&desc);
}
EXPORT_SYMBOL_GPL(crypto_digest_init);

static void update(struct crypto_tfm *tfm,
struct scatterlist *sg, unsigned int nsg)
void crypto_digest_update(struct crypto_tfm *tfm,
struct scatterlist *sg, unsigned int nsg)
{
struct crypto_hash *hash = crypto_hash_cast(tfm);
struct hash_desc desc = { .tfm = hash, .flags = tfm->crt_flags };
unsigned int nbytes = 0;
unsigned int i;

for (i = 0; i < nsg; i++)
nbytes += sg[i].length;

crypto_hash_update(&desc, sg, nbytes);
}
EXPORT_SYMBOL_GPL(crypto_digest_update);

void crypto_digest_final(struct crypto_tfm *tfm, u8 *out)
{
struct crypto_hash *hash = crypto_hash_cast(tfm);
struct hash_desc desc = { .tfm = hash, .flags = tfm->crt_flags };

crypto_hash_final(&desc, out);
}
EXPORT_SYMBOL_GPL(crypto_digest_final);

void crypto_digest_digest(struct crypto_tfm *tfm,
struct scatterlist *sg, unsigned int nsg, u8 *out)
{
struct crypto_hash *hash = crypto_hash_cast(tfm);
struct hash_desc desc = { .tfm = hash, .flags = tfm->crt_flags };
unsigned int nbytes = 0;
unsigned int i;

for (i = 0; i < nsg; i++)
nbytes += sg[i].length;

crypto_hash_digest(&desc, sg, nbytes, out);
}
EXPORT_SYMBOL_GPL(crypto_digest_digest);

static int init(struct hash_desc *desc)
{
struct crypto_tfm *tfm = crypto_hash_tfm(desc->tfm);

tfm->__crt_alg->cra_digest.dia_init(tfm);
return 0;
}

static int update(struct hash_desc *desc,
struct scatterlist *sg, unsigned int nbytes)
{
struct crypto_tfm *tfm = crypto_hash_tfm(desc->tfm);
unsigned int alignmask = crypto_tfm_alg_alignmask(tfm);

for (i = 0; i < nsg; i++) {
if (!nbytes)
return 0;

for (;;) {
struct page *pg = sg->page;
unsigned int offset = sg->offset;
unsigned int l = sg->length;

struct page *pg = sg[i].page;
unsigned int offset = sg[i].offset;
unsigned int l = sg[i].length;
if (unlikely(l > nbytes))
l = nbytes;
nbytes -= l;

do {
unsigned int bytes_from_page = min(l, ((unsigned int)
Expand All @@ -55,16 +115,23 @@ static void update(struct crypto_tfm *tfm,
tfm->__crt_alg->cra_digest.dia_update(tfm, p,
bytes_from_page);
crypto_kunmap(src, 0);
crypto_yield(tfm->crt_flags);
crypto_yield(desc->flags);
offset = 0;
pg++;
l -= bytes_from_page;
} while (l > 0);

if (!nbytes)
break;
sg = sg_next(sg);
}

return 0;
}

static void final(struct crypto_tfm *tfm, u8 *out)
static int final(struct hash_desc *desc, u8 *out)
{
struct crypto_tfm *tfm = crypto_hash_tfm(desc->tfm);
unsigned long alignmask = crypto_tfm_alg_alignmask(tfm);
struct digest_alg *digest = &tfm->__crt_alg->cra_digest;

Expand All @@ -78,26 +145,30 @@ static void final(struct crypto_tfm *tfm, u8 *out)
memcpy(out, dst, digest->dia_digestsize);
} else
digest->dia_final(tfm, out);

return 0;
}

static int nosetkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
static int nosetkey(struct crypto_hash *tfm, const u8 *key, unsigned int keylen)
{
tfm->crt_flags &= ~CRYPTO_TFM_RES_MASK;
crypto_hash_clear_flags(tfm, CRYPTO_TFM_RES_MASK);
return -ENOSYS;
}

static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
static int setkey(struct crypto_hash *hash, const u8 *key, unsigned int keylen)
{
tfm->crt_flags &= ~CRYPTO_TFM_RES_MASK;
struct crypto_tfm *tfm = crypto_hash_tfm(hash);

crypto_hash_clear_flags(hash, CRYPTO_TFM_RES_MASK);
return tfm->__crt_alg->cra_digest.dia_setkey(tfm, key, keylen);
}

static void digest(struct crypto_tfm *tfm,
struct scatterlist *sg, unsigned int nsg, u8 *out)
static int digest(struct hash_desc *desc,
struct scatterlist *sg, unsigned int nbytes, u8 *out)
{
init(tfm);
update(tfm, sg, nsg);
final(tfm, out);
init(desc);
update(desc, sg, nbytes);
return final(desc, out);
}

int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags)
Expand All @@ -107,14 +178,18 @@ int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags)

int crypto_init_digest_ops(struct crypto_tfm *tfm)
{
struct digest_tfm *ops = &tfm->crt_digest;
struct hash_tfm *ops = &tfm->crt_hash;
struct digest_alg *dalg = &tfm->__crt_alg->cra_digest;

if (dalg->dia_digestsize > crypto_tfm_alg_blocksize(tfm))
return -EINVAL;

ops->dit_init = init;
ops->dit_update = update;
ops->dit_final = final;
ops->dit_digest = digest;
ops->dit_setkey = dalg->dia_setkey ? setkey : nosetkey;
ops->init = init;
ops->update = update;
ops->final = final;
ops->digest = digest;
ops->setkey = dalg->dia_setkey ? setkey : nosetkey;
ops->digestsize = dalg->dia_digestsize;

return crypto_alloc_hmac_block(tfm);
}
Expand Down
61 changes: 61 additions & 0 deletions trunk/crypto/hash.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Cryptographic Hash operations.
*
* Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
*
* 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 <linux/errno.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/seq_file.h>

#include "internal.h"

static unsigned int crypto_hash_ctxsize(struct crypto_alg *alg)
{
return alg->cra_ctxsize;
}

static int crypto_init_hash_ops(struct crypto_tfm *tfm)
{
struct hash_tfm *crt = &tfm->crt_hash;
struct hash_alg *alg = &tfm->__crt_alg->cra_hash;

if (alg->digestsize > crypto_tfm_alg_blocksize(tfm))
return -EINVAL;

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

return 0;
}

static void crypto_hash_show(struct seq_file *m, struct crypto_alg *alg)
__attribute_used__;
static void crypto_hash_show(struct seq_file *m, struct crypto_alg *alg)
{
seq_printf(m, "type : hash\n");
seq_printf(m, "blocksize : %u\n", alg->cra_blocksize);
seq_printf(m, "digestsize : %u\n", alg->cra_hash.digestsize);
}

const struct crypto_type crypto_hash_type = {
.ctxsize = crypto_hash_ctxsize,
.init = crypto_init_hash_ops,
#ifdef CONFIG_PROC_FS
.show = crypto_hash_show,
#endif
};
EXPORT_SYMBOL_GPL(crypto_hash_type);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Generic cryptographic hash type");
12 changes: 6 additions & 6 deletions trunk/crypto/hmac.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ int crypto_alloc_hmac_block(struct crypto_tfm *tfm)

BUG_ON(!crypto_tfm_alg_blocksize(tfm));

tfm->crt_digest.dit_hmac_block = kmalloc(crypto_tfm_alg_blocksize(tfm),
GFP_KERNEL);
if (tfm->crt_digest.dit_hmac_block == NULL)
tfm->crt_hash.hmac_block = kmalloc(crypto_tfm_alg_blocksize(tfm),
GFP_KERNEL);
if (tfm->crt_hash.hmac_block == NULL)
ret = -ENOMEM;

return ret;
Expand All @@ -46,14 +46,14 @@ int crypto_alloc_hmac_block(struct crypto_tfm *tfm)

void crypto_free_hmac_block(struct crypto_tfm *tfm)
{
kfree(tfm->crt_digest.dit_hmac_block);
kfree(tfm->crt_hash.hmac_block);
}

void crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen)
{
unsigned int i;
struct scatterlist tmp;
char *ipad = tfm->crt_digest.dit_hmac_block;
char *ipad = tfm->crt_hash.hmac_block;

if (*keylen > crypto_tfm_alg_blocksize(tfm)) {
hash_key(tfm, key, *keylen);
Expand Down Expand Up @@ -83,7 +83,7 @@ void crypto_hmac_final(struct crypto_tfm *tfm, u8 *key,
{
unsigned int i;
struct scatterlist tmp;
char *opad = tfm->crt_digest.dit_hmac_block;
char *opad = tfm->crt_hash.hmac_block;

if (*keylen > crypto_tfm_alg_blocksize(tfm)) {
hash_key(tfm, key, *keylen);
Expand Down
4 changes: 1 addition & 3 deletions trunk/crypto/scatterwalk.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,9 @@

#include "internal.h"

/* Define sg_next is an inline routine now in case we want to change
scatterlist to a linked list later. */
static inline struct scatterlist *sg_next(struct scatterlist *sg)
{
return sg + 1;
return (++sg)->length ? sg : (void *)sg->page;
}

static inline unsigned long scatterwalk_samebuf(struct scatter_walk *walk_in,
Expand Down
6 changes: 6 additions & 0 deletions trunk/include/crypto/algapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ struct blkcipher_walk {
};

extern const struct crypto_type crypto_blkcipher_type;
extern const struct crypto_type crypto_hash_type;

void crypto_mod_put(struct crypto_alg *alg);

Expand Down Expand Up @@ -136,6 +137,11 @@ static inline struct cipher_alg *crypto_cipher_alg(struct crypto_cipher *tfm)
return &crypto_cipher_tfm(tfm)->__crt_alg->cra_cipher;
}

static inline void *crypto_hash_ctx_aligned(struct crypto_hash *tfm)
{
return crypto_tfm_ctx_aligned(&tfm->base);
}

static inline void blkcipher_walk_init(struct blkcipher_walk *walk,
struct scatterlist *dst,
struct scatterlist *src,
Expand Down
Loading

0 comments on commit d9b5800

Please sign in to comment.