Commit 055bcee3102dc35f019b69df9c2618e9d6dd1c09

Authored by Herbert Xu
1 parent 7226bc877a

[CRYPTO] digest: Added user API for new hash type

The existing digest user interface is inadequate for support asynchronous
operations.  For one it doesn't return a value to indicate success or
failure, nor does it take a per-operation descriptor which is essential
for the issuing of requests while other requests are still outstanding.

This patch is the first in a series of steps to remodel the interface
for asynchronous operations.

For the ease of transition the new interface will be known as "hash"
while the old one will remain as "digest".

This patch also changes sg_next to allow chaining.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Showing 8 changed files with 321 additions and 70 deletions Side-by-side Diff

... ... @@ -20,6 +20,10 @@
20 20 tristate
21 21 select CRYPTO_ALGAPI
22 22  
  23 +config CRYPTO_HASH
  24 + tristate
  25 + select CRYPTO_ALGAPI
  26 +
23 27 config CRYPTO_MANAGER
24 28 tristate "Cryptographic algorithm manager"
25 29 select CRYPTO_ALGAPI
... ... @@ -10,6 +10,9 @@
10 10  
11 11 obj-$(CONFIG_CRYPTO_BLKCIPHER) += blkcipher.o
12 12  
  13 +crypto_hash-objs := hash.o
  14 +obj-$(CONFIG_CRYPTO_HASH) += crypto_hash.o
  15 +
13 16 obj-$(CONFIG_CRYPTO_MANAGER) += cryptomgr.o
14 17 obj-$(CONFIG_CRYPTO_HMAC) += hmac.o
15 18 obj-$(CONFIG_CRYPTO_NULL) += crypto_null.o
... ... @@ -11,30 +11,90 @@
11 11 * any later version.
12 12 *
13 13 */
14   -#include <linux/crypto.h>
  14 +
15 15 #include <linux/mm.h>
16 16 #include <linux/errno.h>
17 17 #include <linux/highmem.h>
18   -#include <asm/scatterlist.h>
  18 +#include <linux/module.h>
  19 +#include <linux/scatterlist.h>
  20 +
19 21 #include "internal.h"
  22 +#include "scatterwalk.h"
20 23  
21   -static void init(struct crypto_tfm *tfm)
  24 +void crypto_digest_init(struct crypto_tfm *tfm)
22 25 {
23   - tfm->__crt_alg->cra_digest.dia_init(tfm);
  26 + struct crypto_hash *hash = crypto_hash_cast(tfm);
  27 + struct hash_desc desc = { .tfm = hash, .flags = tfm->crt_flags };
  28 +
  29 + crypto_hash_init(&desc);
24 30 }
  31 +EXPORT_SYMBOL_GPL(crypto_digest_init);
25 32  
26   -static void update(struct crypto_tfm *tfm,
27   - struct scatterlist *sg, unsigned int nsg)
  33 +void crypto_digest_update(struct crypto_tfm *tfm,
  34 + struct scatterlist *sg, unsigned int nsg)
28 35 {
  36 + struct crypto_hash *hash = crypto_hash_cast(tfm);
  37 + struct hash_desc desc = { .tfm = hash, .flags = tfm->crt_flags };
  38 + unsigned int nbytes = 0;
29 39 unsigned int i;
  40 +
  41 + for (i = 0; i < nsg; i++)
  42 + nbytes += sg[i].length;
  43 +
  44 + crypto_hash_update(&desc, sg, nbytes);
  45 +}
  46 +EXPORT_SYMBOL_GPL(crypto_digest_update);
  47 +
  48 +void crypto_digest_final(struct crypto_tfm *tfm, u8 *out)
  49 +{
  50 + struct crypto_hash *hash = crypto_hash_cast(tfm);
  51 + struct hash_desc desc = { .tfm = hash, .flags = tfm->crt_flags };
  52 +
  53 + crypto_hash_final(&desc, out);
  54 +}
  55 +EXPORT_SYMBOL_GPL(crypto_digest_final);
  56 +
  57 +void crypto_digest_digest(struct crypto_tfm *tfm,
  58 + struct scatterlist *sg, unsigned int nsg, u8 *out)
  59 +{
  60 + struct crypto_hash *hash = crypto_hash_cast(tfm);
  61 + struct hash_desc desc = { .tfm = hash, .flags = tfm->crt_flags };
  62 + unsigned int nbytes = 0;
  63 + unsigned int i;
  64 +
  65 + for (i = 0; i < nsg; i++)
  66 + nbytes += sg[i].length;
  67 +
  68 + crypto_hash_digest(&desc, sg, nbytes, out);
  69 +}
  70 +EXPORT_SYMBOL_GPL(crypto_digest_digest);
  71 +
  72 +static int init(struct hash_desc *desc)
  73 +{
  74 + struct crypto_tfm *tfm = crypto_hash_tfm(desc->tfm);
  75 +
  76 + tfm->__crt_alg->cra_digest.dia_init(tfm);
  77 + return 0;
  78 +}
  79 +
  80 +static int update(struct hash_desc *desc,
  81 + struct scatterlist *sg, unsigned int nbytes)
  82 +{
  83 + struct crypto_tfm *tfm = crypto_hash_tfm(desc->tfm);
30 84 unsigned int alignmask = crypto_tfm_alg_alignmask(tfm);
31 85  
32   - for (i = 0; i < nsg; i++) {
  86 + if (!nbytes)
  87 + return 0;
33 88  
34   - struct page *pg = sg[i].page;
35   - unsigned int offset = sg[i].offset;
36   - unsigned int l = sg[i].length;
  89 + for (;;) {
  90 + struct page *pg = sg->page;
  91 + unsigned int offset = sg->offset;
  92 + unsigned int l = sg->length;
37 93  
  94 + if (unlikely(l > nbytes))
  95 + l = nbytes;
  96 + nbytes -= l;
  97 +
38 98 do {
39 99 unsigned int bytes_from_page = min(l, ((unsigned int)
40 100 (PAGE_SIZE)) -
41 101  
42 102  
43 103  
44 104  
... ... @@ -55,16 +115,23 @@
55 115 tfm->__crt_alg->cra_digest.dia_update(tfm, p,
56 116 bytes_from_page);
57 117 crypto_kunmap(src, 0);
58   - crypto_yield(tfm->crt_flags);
  118 + crypto_yield(desc->flags);
59 119 offset = 0;
60 120 pg++;
61 121 l -= bytes_from_page;
62 122 } while (l > 0);
  123 +
  124 + if (!nbytes)
  125 + break;
  126 + sg = sg_next(sg);
63 127 }
  128 +
  129 + return 0;
64 130 }
65 131  
66   -static void final(struct crypto_tfm *tfm, u8 *out)
  132 +static int final(struct hash_desc *desc, u8 *out)
67 133 {
  134 + struct crypto_tfm *tfm = crypto_hash_tfm(desc->tfm);
68 135 unsigned long alignmask = crypto_tfm_alg_alignmask(tfm);
69 136 struct digest_alg *digest = &tfm->__crt_alg->cra_digest;
70 137  
71 138  
72 139  
73 140  
74 141  
75 142  
76 143  
... ... @@ -78,26 +145,30 @@
78 145 memcpy(out, dst, digest->dia_digestsize);
79 146 } else
80 147 digest->dia_final(tfm, out);
  148 +
  149 + return 0;
81 150 }
82 151  
83   -static int nosetkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
  152 +static int nosetkey(struct crypto_hash *tfm, const u8 *key, unsigned int keylen)
84 153 {
85   - tfm->crt_flags &= ~CRYPTO_TFM_RES_MASK;
  154 + crypto_hash_clear_flags(tfm, CRYPTO_TFM_RES_MASK);
86 155 return -ENOSYS;
87 156 }
88 157  
89   -static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen)
  158 +static int setkey(struct crypto_hash *hash, const u8 *key, unsigned int keylen)
90 159 {
91   - tfm->crt_flags &= ~CRYPTO_TFM_RES_MASK;
  160 + struct crypto_tfm *tfm = crypto_hash_tfm(hash);
  161 +
  162 + crypto_hash_clear_flags(hash, CRYPTO_TFM_RES_MASK);
92 163 return tfm->__crt_alg->cra_digest.dia_setkey(tfm, key, keylen);
93 164 }
94 165  
95   -static void digest(struct crypto_tfm *tfm,
96   - struct scatterlist *sg, unsigned int nsg, u8 *out)
  166 +static int digest(struct hash_desc *desc,
  167 + struct scatterlist *sg, unsigned int nbytes, u8 *out)
97 168 {
98   - init(tfm);
99   - update(tfm, sg, nsg);
100   - final(tfm, out);
  169 + init(desc);
  170 + update(desc, sg, nbytes);
  171 + return final(desc, out);
101 172 }
102 173  
103 174 int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags)
104 175  
105 176  
... ... @@ -107,14 +178,18 @@
107 178  
108 179 int crypto_init_digest_ops(struct crypto_tfm *tfm)
109 180 {
110   - struct digest_tfm *ops = &tfm->crt_digest;
  181 + struct hash_tfm *ops = &tfm->crt_hash;
111 182 struct digest_alg *dalg = &tfm->__crt_alg->cra_digest;
  183 +
  184 + if (dalg->dia_digestsize > crypto_tfm_alg_blocksize(tfm))
  185 + return -EINVAL;
112 186  
113   - ops->dit_init = init;
114   - ops->dit_update = update;
115   - ops->dit_final = final;
116   - ops->dit_digest = digest;
117   - ops->dit_setkey = dalg->dia_setkey ? setkey : nosetkey;
  187 + ops->init = init;
  188 + ops->update = update;
  189 + ops->final = final;
  190 + ops->digest = digest;
  191 + ops->setkey = dalg->dia_setkey ? setkey : nosetkey;
  192 + ops->digestsize = dalg->dia_digestsize;
118 193  
119 194 return crypto_alloc_hmac_block(tfm);
120 195 }
  1 +/*
  2 + * Cryptographic Hash operations.
  3 + *
  4 + * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
  5 + *
  6 + * This program is free software; you can redistribute it and/or modify it
  7 + * under the terms of the GNU General Public License as published by the Free
  8 + * Software Foundation; either version 2 of the License, or (at your option)
  9 + * any later version.
  10 + */
  11 +
  12 +#include <linux/errno.h>
  13 +#include <linux/kernel.h>
  14 +#include <linux/module.h>
  15 +#include <linux/seq_file.h>
  16 +
  17 +#include "internal.h"
  18 +
  19 +static unsigned int crypto_hash_ctxsize(struct crypto_alg *alg)
  20 +{
  21 + return alg->cra_ctxsize;
  22 +}
  23 +
  24 +static int crypto_init_hash_ops(struct crypto_tfm *tfm)
  25 +{
  26 + struct hash_tfm *crt = &tfm->crt_hash;
  27 + struct hash_alg *alg = &tfm->__crt_alg->cra_hash;
  28 +
  29 + if (alg->digestsize > crypto_tfm_alg_blocksize(tfm))
  30 + return -EINVAL;
  31 +
  32 + crt->init = alg->init;
  33 + crt->update = alg->update;
  34 + crt->final = alg->final;
  35 + crt->digest = alg->digest;
  36 + crt->setkey = alg->setkey;
  37 + crt->digestsize = alg->digestsize;
  38 +
  39 + return 0;
  40 +}
  41 +
  42 +static void crypto_hash_show(struct seq_file *m, struct crypto_alg *alg)
  43 + __attribute_used__;
  44 +static void crypto_hash_show(struct seq_file *m, struct crypto_alg *alg)
  45 +{
  46 + seq_printf(m, "type : hash\n");
  47 + seq_printf(m, "blocksize : %u\n", alg->cra_blocksize);
  48 + seq_printf(m, "digestsize : %u\n", alg->cra_hash.digestsize);
  49 +}
  50 +
  51 +const struct crypto_type crypto_hash_type = {
  52 + .ctxsize = crypto_hash_ctxsize,
  53 + .init = crypto_init_hash_ops,
  54 +#ifdef CONFIG_PROC_FS
  55 + .show = crypto_hash_show,
  56 +#endif
  57 +};
  58 +EXPORT_SYMBOL_GPL(crypto_hash_type);
  59 +
  60 +MODULE_LICENSE("GPL");
  61 +MODULE_DESCRIPTION("Generic cryptographic hash type");
... ... @@ -35,9 +35,9 @@
35 35  
36 36 BUG_ON(!crypto_tfm_alg_blocksize(tfm));
37 37  
38   - tfm->crt_digest.dit_hmac_block = kmalloc(crypto_tfm_alg_blocksize(tfm),
39   - GFP_KERNEL);
40   - if (tfm->crt_digest.dit_hmac_block == NULL)
  38 + tfm->crt_hash.hmac_block = kmalloc(crypto_tfm_alg_blocksize(tfm),
  39 + GFP_KERNEL);
  40 + if (tfm->crt_hash.hmac_block == NULL)
41 41 ret = -ENOMEM;
42 42  
43 43 return ret;
44 44  
... ... @@ -46,14 +46,14 @@
46 46  
47 47 void crypto_free_hmac_block(struct crypto_tfm *tfm)
48 48 {
49   - kfree(tfm->crt_digest.dit_hmac_block);
  49 + kfree(tfm->crt_hash.hmac_block);
50 50 }
51 51  
52 52 void crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen)
53 53 {
54 54 unsigned int i;
55 55 struct scatterlist tmp;
56   - char *ipad = tfm->crt_digest.dit_hmac_block;
  56 + char *ipad = tfm->crt_hash.hmac_block;
57 57  
58 58 if (*keylen > crypto_tfm_alg_blocksize(tfm)) {
59 59 hash_key(tfm, key, *keylen);
... ... @@ -83,7 +83,7 @@
83 83 {
84 84 unsigned int i;
85 85 struct scatterlist tmp;
86   - char *opad = tfm->crt_digest.dit_hmac_block;
  86 + char *opad = tfm->crt_hash.hmac_block;
87 87  
88 88 if (*keylen > crypto_tfm_alg_blocksize(tfm)) {
89 89 hash_key(tfm, key, *keylen);
crypto/scatterwalk.h
... ... @@ -20,11 +20,9 @@
20 20  
21 21 #include "internal.h"
22 22  
23   -/* Define sg_next is an inline routine now in case we want to change
24   - scatterlist to a linked list later. */
25 23 static inline struct scatterlist *sg_next(struct scatterlist *sg)
26 24 {
27   - return sg + 1;
  25 + return (++sg)->length ? sg : (void *)sg->page;
28 26 }
29 27  
30 28 static inline unsigned long scatterwalk_samebuf(struct scatter_walk *walk_in,
include/crypto/algapi.h
... ... @@ -82,6 +82,7 @@
82 82 };
83 83  
84 84 extern const struct crypto_type crypto_blkcipher_type;
  85 +extern const struct crypto_type crypto_hash_type;
85 86  
86 87 void crypto_mod_put(struct crypto_alg *alg);
87 88  
... ... @@ -134,6 +135,11 @@
134 135 static inline struct cipher_alg *crypto_cipher_alg(struct crypto_cipher *tfm)
135 136 {
136 137 return &crypto_cipher_tfm(tfm)->__crt_alg->cra_cipher;
  138 +}
  139 +
  140 +static inline void *crypto_hash_ctx_aligned(struct crypto_hash *tfm)
  141 +{
  142 + return crypto_tfm_ctx_aligned(&tfm->base);
137 143 }
138 144  
139 145 static inline void blkcipher_walk_init(struct blkcipher_walk *walk,
include/linux/crypto.h
... ... @@ -31,9 +31,12 @@
31 31 #define CRYPTO_ALG_TYPE_MASK 0x0000000f
32 32 #define CRYPTO_ALG_TYPE_CIPHER 0x00000001
33 33 #define CRYPTO_ALG_TYPE_DIGEST 0x00000002
34   -#define CRYPTO_ALG_TYPE_BLKCIPHER 0x00000003
35   -#define CRYPTO_ALG_TYPE_COMPRESS 0x00000004
  34 +#define CRYPTO_ALG_TYPE_HASH 0x00000003
  35 +#define CRYPTO_ALG_TYPE_BLKCIPHER 0x00000004
  36 +#define CRYPTO_ALG_TYPE_COMPRESS 0x00000005
36 37  
  38 +#define CRYPTO_ALG_TYPE_HASH_MASK 0x0000000e
  39 +
37 40 #define CRYPTO_ALG_LARVAL 0x00000010
38 41 #define CRYPTO_ALG_DEAD 0x00000020
39 42 #define CRYPTO_ALG_DYING 0x00000040
... ... @@ -90,6 +93,7 @@
90 93  
91 94 struct scatterlist;
92 95 struct crypto_blkcipher;
  96 +struct crypto_hash;
93 97 struct crypto_tfm;
94 98 struct crypto_type;
95 99  
... ... @@ -107,6 +111,11 @@
107 111 void *info;
108 112 };
109 113  
  114 +struct hash_desc {
  115 + struct crypto_hash *tfm;
  116 + u32 flags;
  117 +};
  118 +
110 119 /*
111 120 * Algorithms: modular crypto algorithm implementations, managed
112 121 * via crypto_register_alg() and crypto_unregister_alg().
... ... @@ -158,6 +167,19 @@
158 167 unsigned int keylen);
159 168 };
160 169  
  170 +struct hash_alg {
  171 + int (*init)(struct hash_desc *desc);
  172 + int (*update)(struct hash_desc *desc, struct scatterlist *sg,
  173 + unsigned int nbytes);
  174 + int (*final)(struct hash_desc *desc, u8 *out);
  175 + int (*digest)(struct hash_desc *desc, struct scatterlist *sg,
  176 + unsigned int nbytes, u8 *out);
  177 + int (*setkey)(struct crypto_hash *tfm, const u8 *key,
  178 + unsigned int keylen);
  179 +
  180 + unsigned int digestsize;
  181 +};
  182 +
161 183 struct compress_alg {
162 184 int (*coa_compress)(struct crypto_tfm *tfm, const u8 *src,
163 185 unsigned int slen, u8 *dst, unsigned int *dlen);
... ... @@ -168,6 +190,7 @@
168 190 #define cra_blkcipher cra_u.blkcipher
169 191 #define cra_cipher cra_u.cipher
170 192 #define cra_digest cra_u.digest
  193 +#define cra_hash cra_u.hash
171 194 #define cra_compress cra_u.compress
172 195  
173 196 struct crypto_alg {
... ... @@ -191,6 +214,7 @@
191 214 struct blkcipher_alg blkcipher;
192 215 struct cipher_alg cipher;
193 216 struct digest_alg digest;
  217 + struct hash_alg hash;
194 218 struct compress_alg compress;
195 219 } cra_u;
196 220  
197 221  
198 222  
... ... @@ -262,18 +286,19 @@
262 286 void (*cit_decrypt_one)(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
263 287 };
264 288  
265   -struct digest_tfm {
266   - void (*dit_init)(struct crypto_tfm *tfm);
267   - void (*dit_update)(struct crypto_tfm *tfm,
268   - struct scatterlist *sg, unsigned int nsg);
269   - void (*dit_final)(struct crypto_tfm *tfm, u8 *out);
270   - void (*dit_digest)(struct crypto_tfm *tfm, struct scatterlist *sg,
271   - unsigned int nsg, u8 *out);
272   - int (*dit_setkey)(struct crypto_tfm *tfm,
273   - const u8 *key, unsigned int keylen);
  289 +struct hash_tfm {
  290 + int (*init)(struct hash_desc *desc);
  291 + int (*update)(struct hash_desc *desc,
  292 + struct scatterlist *sg, unsigned int nsg);
  293 + int (*final)(struct hash_desc *desc, u8 *out);
  294 + int (*digest)(struct hash_desc *desc, struct scatterlist *sg,
  295 + unsigned int nsg, u8 *out);
  296 + int (*setkey)(struct crypto_hash *tfm, const u8 *key,
  297 + unsigned int keylen);
274 298 #ifdef CONFIG_CRYPTO_HMAC
275   - void *dit_hmac_block;
  299 + void *hmac_block;
276 300 #endif
  301 + unsigned int digestsize;
277 302 };
278 303  
279 304 struct compress_tfm {
... ... @@ -287,7 +312,7 @@
287 312  
288 313 #define crt_blkcipher crt_u.blkcipher
289 314 #define crt_cipher crt_u.cipher
290   -#define crt_digest crt_u.digest
  315 +#define crt_hash crt_u.hash
291 316 #define crt_compress crt_u.compress
292 317  
293 318 struct crypto_tfm {
... ... @@ -297,7 +322,7 @@
297 322 union {
298 323 struct blkcipher_tfm blkcipher;
299 324 struct cipher_tfm cipher;
300   - struct digest_tfm digest;
  325 + struct hash_tfm hash;
301 326 struct compress_tfm compress;
302 327 } crt_u;
303 328  
... ... @@ -312,6 +337,10 @@
312 337 struct crypto_tfm base;
313 338 };
314 339  
  340 +struct crypto_hash {
  341 + struct crypto_tfm base;
  342 +};
  343 +
315 344 enum {
316 345 CRYPTOA_UNSPEC,
317 346 CRYPTOA_ALG,
318 347  
319 348  
320 349  
321 350  
322 351  
323 352  
324 353  
325 354  
326 355  
... ... @@ -647,39 +676,114 @@
647 676 dst, src);
648 677 }
649 678  
650   -static inline void crypto_digest_init(struct crypto_tfm *tfm)
  679 +void crypto_digest_init(struct crypto_tfm *tfm);
  680 +void crypto_digest_update(struct crypto_tfm *tfm,
  681 + struct scatterlist *sg, unsigned int nsg);
  682 +void crypto_digest_final(struct crypto_tfm *tfm, u8 *out);
  683 +void crypto_digest_digest(struct crypto_tfm *tfm,
  684 + struct scatterlist *sg, unsigned int nsg, u8 *out);
  685 +
  686 +static inline struct crypto_hash *__crypto_hash_cast(struct crypto_tfm *tfm)
651 687 {
652   - BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
653   - tfm->crt_digest.dit_init(tfm);
  688 + return (struct crypto_hash *)tfm;
654 689 }
655 690  
656   -static inline void crypto_digest_update(struct crypto_tfm *tfm,
657   - struct scatterlist *sg,
658   - unsigned int nsg)
  691 +static inline struct crypto_hash *crypto_hash_cast(struct crypto_tfm *tfm)
659 692 {
660   - BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
661   - tfm->crt_digest.dit_update(tfm, sg, nsg);
  693 + BUG_ON((crypto_tfm_alg_type(tfm) ^ CRYPTO_ALG_TYPE_HASH) &
  694 + CRYPTO_ALG_TYPE_HASH_MASK);
  695 + return __crypto_hash_cast(tfm);
662 696 }
663 697  
664   -static inline void crypto_digest_final(struct crypto_tfm *tfm, u8 *out)
  698 +static inline int crypto_digest_setkey(struct crypto_tfm *tfm,
  699 + const u8 *key, unsigned int keylen)
665 700 {
666   - BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
667   - tfm->crt_digest.dit_final(tfm, out);
  701 + return tfm->crt_hash.setkey(crypto_hash_cast(tfm), key, keylen);
668 702 }
669 703  
670   -static inline void crypto_digest_digest(struct crypto_tfm *tfm,
671   - struct scatterlist *sg,
672   - unsigned int nsg, u8 *out)
  704 +static inline struct crypto_hash *crypto_alloc_hash(const char *alg_name,
  705 + u32 type, u32 mask)
673 706 {
674   - BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
675   - tfm->crt_digest.dit_digest(tfm, sg, nsg, out);
  707 + type &= ~CRYPTO_ALG_TYPE_MASK;
  708 + type |= CRYPTO_ALG_TYPE_HASH;
  709 + mask |= CRYPTO_ALG_TYPE_HASH_MASK;
  710 +
  711 + return __crypto_hash_cast(crypto_alloc_base(alg_name, type, mask));
676 712 }
677 713  
678   -static inline int crypto_digest_setkey(struct crypto_tfm *tfm,
679   - const u8 *key, unsigned int keylen)
  714 +static inline struct crypto_tfm *crypto_hash_tfm(struct crypto_hash *tfm)
680 715 {
681   - BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
682   - return tfm->crt_digest.dit_setkey(tfm, key, keylen);
  716 + return &tfm->base;
  717 +}
  718 +
  719 +static inline void crypto_free_hash(struct crypto_hash *tfm)
  720 +{
  721 + crypto_free_tfm(crypto_hash_tfm(tfm));
  722 +}
  723 +
  724 +static inline struct hash_tfm *crypto_hash_crt(struct crypto_hash *tfm)
  725 +{
  726 + return &crypto_hash_tfm(tfm)->crt_hash;
  727 +}
  728 +
  729 +static inline unsigned int crypto_hash_blocksize(struct crypto_hash *tfm)
  730 +{
  731 + return crypto_tfm_alg_blocksize(crypto_hash_tfm(tfm));
  732 +}
  733 +
  734 +static inline unsigned int crypto_hash_alignmask(struct crypto_hash *tfm)
  735 +{
  736 + return crypto_tfm_alg_alignmask(crypto_hash_tfm(tfm));
  737 +}
  738 +
  739 +static inline unsigned int crypto_hash_digestsize(struct crypto_hash *tfm)
  740 +{
  741 + return crypto_hash_crt(tfm)->digestsize;
  742 +}
  743 +
  744 +static inline u32 crypto_hash_get_flags(struct crypto_hash *tfm)
  745 +{
  746 + return crypto_tfm_get_flags(crypto_hash_tfm(tfm));
  747 +}
  748 +
  749 +static inline void crypto_hash_set_flags(struct crypto_hash *tfm, u32 flags)
  750 +{
  751 + crypto_tfm_set_flags(crypto_hash_tfm(tfm), flags);
  752 +}
  753 +
  754 +static inline void crypto_hash_clear_flags(struct crypto_hash *tfm, u32 flags)
  755 +{
  756 + crypto_tfm_clear_flags(crypto_hash_tfm(tfm), flags);
  757 +}
  758 +
  759 +static inline int crypto_hash_init(struct hash_desc *desc)
  760 +{
  761 + return crypto_hash_crt(desc->tfm)->init(desc);
  762 +}
  763 +
  764 +static inline int crypto_hash_update(struct hash_desc *desc,
  765 + struct scatterlist *sg,
  766 + unsigned int nbytes)
  767 +{
  768 + return crypto_hash_crt(desc->tfm)->update(desc, sg, nbytes);
  769 +}
  770 +
  771 +static inline int crypto_hash_final(struct hash_desc *desc, u8 *out)
  772 +{
  773 + return crypto_hash_crt(desc->tfm)->final(desc, out);
  774 +}
  775 +
  776 +static inline int crypto_hash_digest(struct hash_desc *desc,
  777 + struct scatterlist *sg,
  778 + unsigned int nbytes, u8 *out)
  779 +{
  780 + return crypto_hash_crt(desc->tfm)->digest(desc, sg, nbytes, out);
  781 +}
  782 +
  783 +static inline int crypto_hash_setkey(struct crypto_hash *hash,
  784 + const u8 *key, unsigned int keylen)
  785 +{
  786 + return crypto_hash_crt(hash)->setkey(hash, key, keylen);
683 787 }
684 788  
685 789 static int crypto_cipher_encrypt(struct crypto_tfm *tfm,