Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 99300
b: refs/heads/master
c: 2003625
h: refs/heads/master
v: v3
  • Loading branch information
Herbert Xu committed Jul 10, 2008
1 parent 251c666 commit 94fb2b5
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 2 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: b8454eebe380677789735fd6bad368af2e6b2d1e
refs/heads/master: 20036252fc61c624a49770fb89684ea5cfdfa05e
91 changes: 90 additions & 1 deletion trunk/crypto/ahash.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
*
*/

#include <crypto/algapi.h>
#include <crypto/internal/hash.h>
#include <crypto/scatterwalk.h>
#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/module.h>
Expand All @@ -23,6 +24,94 @@

#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)
{
Expand Down
41 changes: 41 additions & 0 deletions trunk/include/crypto/internal/hash.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Hash algorithms.
*
* Copyright (c) 2008 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.
*
*/

#ifndef _CRYPTO_INTERNAL_HASH_H
#define _CRYPTO_INTERNAL_HASH_H

#include <crypto/algapi.h>

struct ahash_request;
struct scatterlist;

struct crypto_hash_walk {
char *data;

unsigned int offset;
unsigned int alignmask;

struct page *pg;
unsigned int entrylen;

unsigned int total;
struct scatterlist *sg;

unsigned int flags;
};

int crypto_hash_walk_done(struct crypto_hash_walk *walk, int err);
int crypto_hash_walk_first(struct ahash_request *req,
struct crypto_hash_walk *walk);

#endif /* _CRYPTO_INTERNAL_HASH_H */

0 comments on commit 94fb2b5

Please sign in to comment.