2 * Cryptographic Hash operations.
4 * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
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)
12 #include <linux/errno.h>
13 #include <linux/kernel.h>
14 #include <linux/module.h>
15 #include <linux/slab.h>
16 #include <linux/seq_file.h>
20 static unsigned int crypto_hash_ctxsize(struct crypto_alg
*alg
, u32 type
,
23 return alg
->cra_ctxsize
;
26 static int hash_setkey_unaligned(struct crypto_hash
*crt
, const u8
*key
,
29 struct crypto_tfm
*tfm
= crypto_hash_tfm(crt
);
30 struct hash_alg
*alg
= &tfm
->__crt_alg
->cra_hash
;
31 unsigned long alignmask
= crypto_hash_alignmask(crt
);
33 u8
*buffer
, *alignbuffer
;
36 absize
= keylen
+ alignmask
;
37 buffer
= kmalloc(absize
, GFP_ATOMIC
);
41 alignbuffer
= (u8
*)ALIGN((unsigned long)buffer
, alignmask
+ 1);
42 memcpy(alignbuffer
, key
, keylen
);
43 ret
= alg
->setkey(crt
, alignbuffer
, keylen
);
44 memset(alignbuffer
, 0, keylen
);
49 static int hash_setkey(struct crypto_hash
*crt
, const u8
*key
,
52 struct crypto_tfm
*tfm
= crypto_hash_tfm(crt
);
53 struct hash_alg
*alg
= &tfm
->__crt_alg
->cra_hash
;
54 unsigned long alignmask
= crypto_hash_alignmask(crt
);
56 if ((unsigned long)key
& alignmask
)
57 return hash_setkey_unaligned(crt
, key
, keylen
);
59 return alg
->setkey(crt
, key
, keylen
);
62 static int hash_async_setkey(struct crypto_ahash
*tfm_async
, const u8
*key
,
65 struct crypto_tfm
*tfm
= crypto_ahash_tfm(tfm_async
);
66 struct crypto_hash
*tfm_hash
= __crypto_hash_cast(tfm
);
67 struct hash_alg
*alg
= &tfm
->__crt_alg
->cra_hash
;
69 return alg
->setkey(tfm_hash
, key
, keylen
);
72 static int hash_async_init(struct ahash_request
*req
)
74 struct crypto_tfm
*tfm
= req
->base
.tfm
;
75 struct hash_alg
*alg
= &tfm
->__crt_alg
->cra_hash
;
76 struct hash_desc desc
= {
77 .tfm
= __crypto_hash_cast(tfm
),
78 .flags
= req
->base
.flags
,
81 return alg
->init(&desc
);
84 static int hash_async_update(struct ahash_request
*req
)
86 struct crypto_tfm
*tfm
= req
->base
.tfm
;
87 struct hash_alg
*alg
= &tfm
->__crt_alg
->cra_hash
;
88 struct hash_desc desc
= {
89 .tfm
= __crypto_hash_cast(tfm
),
90 .flags
= req
->base
.flags
,
93 return alg
->update(&desc
, req
->src
, req
->nbytes
);
96 static int hash_async_final(struct ahash_request
*req
)
98 struct crypto_tfm
*tfm
= req
->base
.tfm
;
99 struct hash_alg
*alg
= &tfm
->__crt_alg
->cra_hash
;
100 struct hash_desc desc
= {
101 .tfm
= __crypto_hash_cast(tfm
),
102 .flags
= req
->base
.flags
,
105 return alg
->final(&desc
, req
->result
);
108 static int hash_async_digest(struct ahash_request
*req
)
110 struct crypto_tfm
*tfm
= req
->base
.tfm
;
111 struct hash_alg
*alg
= &tfm
->__crt_alg
->cra_hash
;
112 struct hash_desc desc
= {
113 .tfm
= __crypto_hash_cast(tfm
),
114 .flags
= req
->base
.flags
,
117 return alg
->digest(&desc
, req
->src
, req
->nbytes
, req
->result
);
120 static int crypto_init_hash_ops_async(struct crypto_tfm
*tfm
)
122 struct ahash_tfm
*crt
= &tfm
->crt_ahash
;
123 struct hash_alg
*alg
= &tfm
->__crt_alg
->cra_hash
;
125 crt
->init
= hash_async_init
;
126 crt
->update
= hash_async_update
;
127 crt
->final
= hash_async_final
;
128 crt
->digest
= hash_async_digest
;
129 crt
->setkey
= hash_async_setkey
;
130 crt
->digestsize
= alg
->digestsize
;
135 static int crypto_init_hash_ops_sync(struct crypto_tfm
*tfm
)
137 struct hash_tfm
*crt
= &tfm
->crt_hash
;
138 struct hash_alg
*alg
= &tfm
->__crt_alg
->cra_hash
;
140 crt
->init
= alg
->init
;
141 crt
->update
= alg
->update
;
142 crt
->final
= alg
->final
;
143 crt
->digest
= alg
->digest
;
144 crt
->setkey
= hash_setkey
;
145 crt
->digestsize
= alg
->digestsize
;
150 static int crypto_init_hash_ops(struct crypto_tfm
*tfm
, u32 type
, u32 mask
)
152 struct hash_alg
*alg
= &tfm
->__crt_alg
->cra_hash
;
154 if (alg
->digestsize
> PAGE_SIZE
/ 8)
157 if ((mask
& CRYPTO_ALG_TYPE_HASH_MASK
) != CRYPTO_ALG_TYPE_HASH_MASK
)
158 return crypto_init_hash_ops_async(tfm
);
160 return crypto_init_hash_ops_sync(tfm
);
163 static void crypto_hash_show(struct seq_file
*m
, struct crypto_alg
*alg
)
164 __attribute__ ((unused
));
165 static void crypto_hash_show(struct seq_file
*m
, struct crypto_alg
*alg
)
167 seq_printf(m
, "type : hash\n");
168 seq_printf(m
, "blocksize : %u\n", alg
->cra_blocksize
);
169 seq_printf(m
, "digestsize : %u\n", alg
->cra_hash
.digestsize
);
172 const struct crypto_type crypto_hash_type
= {
173 .ctxsize
= crypto_hash_ctxsize
,
174 .init
= crypto_init_hash_ops
,
175 #ifdef CONFIG_PROC_FS
176 .show
= crypto_hash_show
,
179 EXPORT_SYMBOL_GPL(crypto_hash_type
);
181 MODULE_LICENSE("GPL");
182 MODULE_DESCRIPTION("Generic cryptographic hash type");