| 1 |
|
|---|
| 2 |
|
|---|
| 3 |
|
|---|
| 4 |
|
|---|
| 5 |
|
|---|
| 6 |
|
|---|
| 7 |
|
|---|
| 8 |
|
|---|
| 9 |
|
|---|
| 10 |
|
|---|
| 11 |
|
|---|
| 12 |
|
|---|
| 13 |
|
|---|
| 14 |
#include <linux/crypto.h> |
|---|
| 15 |
#include <linux/mm.h> |
|---|
| 16 |
#include <linux/errno.h> |
|---|
| 17 |
#include <linux/highmem.h> |
|---|
| 18 |
#include <asm/scatterlist.h> |
|---|
| 19 |
#include "internal.h" |
|---|
| 20 |
|
|---|
| 21 |
static void init(struct crypto_tfm *tfm) |
|---|
| 22 |
{ |
|---|
| 23 |
tfm->__crt_alg->cra_digest.dia_init(crypto_tfm_ctx(tfm)); |
|---|
| 24 |
} |
|---|
| 25 |
|
|---|
| 26 |
static void update(struct crypto_tfm *tfm, |
|---|
| 27 |
struct scatterlist *sg, unsigned int nsg) |
|---|
| 28 |
{ |
|---|
| 29 |
unsigned int i; |
|---|
| 30 |
|
|---|
| 31 |
for (i = 0; i < nsg; i++) { |
|---|
| 32 |
|
|---|
| 33 |
struct page *pg = sg[i].page; |
|---|
| 34 |
unsigned int offset = sg[i].offset; |
|---|
| 35 |
unsigned int l = sg[i].length; |
|---|
| 36 |
|
|---|
| 37 |
do { |
|---|
| 38 |
unsigned int bytes_from_page = min(l, ((unsigned int) |
|---|
| 39 |
(PAGE_SIZE)) - |
|---|
| 40 |
offset); |
|---|
| 41 |
char *p = crypto_kmap(pg, 0) + offset; |
|---|
| 42 |
|
|---|
| 43 |
tfm->__crt_alg->cra_digest.dia_update |
|---|
| 44 |
(crypto_tfm_ctx(tfm), p, |
|---|
| 45 |
bytes_from_page); |
|---|
| 46 |
crypto_kunmap(p, 0); |
|---|
| 47 |
crypto_yield(tfm); |
|---|
| 48 |
offset = 0; |
|---|
| 49 |
pg++; |
|---|
| 50 |
l -= bytes_from_page; |
|---|
| 51 |
} while (l > 0); |
|---|
| 52 |
} |
|---|
| 53 |
} |
|---|
| 54 |
|
|---|
| 55 |
static void final(struct crypto_tfm *tfm, u8 *out) |
|---|
| 56 |
{ |
|---|
| 57 |
tfm->__crt_alg->cra_digest.dia_final(crypto_tfm_ctx(tfm), out); |
|---|
| 58 |
} |
|---|
| 59 |
|
|---|
| 60 |
static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) |
|---|
| 61 |
{ |
|---|
| 62 |
u32 flags; |
|---|
| 63 |
if (tfm->__crt_alg->cra_digest.dia_setkey == NULL) |
|---|
| 64 |
return -ENOSYS; |
|---|
| 65 |
return tfm->__crt_alg->cra_digest.dia_setkey(crypto_tfm_ctx(tfm), |
|---|
| 66 |
key, keylen, &flags); |
|---|
| 67 |
} |
|---|
| 68 |
|
|---|
| 69 |
static void digest(struct crypto_tfm *tfm, |
|---|
| 70 |
struct scatterlist *sg, unsigned int nsg, u8 *out) |
|---|
| 71 |
{ |
|---|
| 72 |
unsigned int i; |
|---|
| 73 |
|
|---|
| 74 |
tfm->crt_digest.dit_init(tfm); |
|---|
| 75 |
|
|---|
| 76 |
for (i = 0; i < nsg; i++) { |
|---|
| 77 |
char *p = crypto_kmap(sg[i].page, 0) + sg[i].offset; |
|---|
| 78 |
tfm->__crt_alg->cra_digest.dia_update(crypto_tfm_ctx(tfm), |
|---|
| 79 |
p, sg[i].length); |
|---|
| 80 |
crypto_kunmap(p, 0); |
|---|
| 81 |
crypto_yield(tfm); |
|---|
| 82 |
} |
|---|
| 83 |
crypto_digest_final(tfm, out); |
|---|
| 84 |
} |
|---|
| 85 |
|
|---|
| 86 |
int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags) |
|---|
| 87 |
{ |
|---|
| 88 |
return flags ? -EINVAL : 0; |
|---|
| 89 |
} |
|---|
| 90 |
|
|---|
| 91 |
int crypto_init_digest_ops(struct crypto_tfm *tfm) |
|---|
| 92 |
{ |
|---|
| 93 |
struct digest_tfm *ops = &tfm->crt_digest; |
|---|
| 94 |
|
|---|
| 95 |
ops->dit_init = init; |
|---|
| 96 |
ops->dit_update = update; |
|---|
| 97 |
ops->dit_final = final; |
|---|
| 98 |
ops->dit_digest = digest; |
|---|
| 99 |
ops->dit_setkey = setkey; |
|---|
| 100 |
|
|---|
| 101 |
return crypto_alloc_hmac_block(tfm); |
|---|
| 102 |
} |
|---|
| 103 |
|
|---|
| 104 |
void crypto_exit_digest_ops(struct crypto_tfm *tfm) |
|---|
| 105 |
{ |
|---|
| 106 |
crypto_free_hmac_block(tfm); |
|---|
| 107 |
} |
|---|