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 <crypto/internal/hash.h>
13 #include <linux/errno.h>
14 #include <linux/kernel.h>
15 #include <linux/module.h>
16 #include <linux/slab.h>
17 #include <linux/seq_file.h>
21 static unsigned int crypto_hash_ctxsize(struct crypto_alg
*alg
, u32 type
,
24 return alg
->cra_ctxsize
;
27 static int hash_setkey_unaligned(struct crypto_hash
*crt
, const u8
*key
,
30 struct crypto_tfm
*tfm
= crypto_hash_tfm(crt
);
31 struct hash_alg
*alg
= &tfm
->__crt_alg
->cra_hash
;
32 unsigned long alignmask
= crypto_hash_alignmask(crt
);
34 u8
*buffer
, *alignbuffer
;
37 absize
= keylen
+ alignmask
;
38 buffer
= kmalloc(absize
, GFP_ATOMIC
);
42 alignbuffer
= (u8
*)ALIGN((unsigned long)buffer
, alignmask
+ 1);
43 memcpy(alignbuffer
, key
, keylen
);
44 ret
= alg
->setkey(crt
, alignbuffer
, keylen
);
45 memset(alignbuffer
, 0, keylen
);
50 static int hash_setkey(struct crypto_hash
*crt
, const u8
*key
,
53 struct crypto_tfm
*tfm
= crypto_hash_tfm(crt
);
54 struct hash_alg
*alg
= &tfm
->__crt_alg
->cra_hash
;
55 unsigned long alignmask
= crypto_hash_alignmask(crt
);
57 if ((unsigned long)key
& alignmask
)
58 return hash_setkey_unaligned(crt
, key
, keylen
);
60 return alg
->setkey(crt
, key
, keylen
);
63 static int hash_async_setkey(struct crypto_ahash
*tfm_async
, const u8
*key
,
66 struct crypto_tfm
*tfm
= crypto_ahash_tfm(tfm_async
);
67 struct crypto_hash
*tfm_hash
= __crypto_hash_cast(tfm
);
68 struct hash_alg
*alg
= &tfm
->__crt_alg
->cra_hash
;
70 return alg
->setkey(tfm_hash
, key
, keylen
);
73 static int hash_async_init(struct ahash_request
*req
)
75 struct crypto_tfm
*tfm
= req
->base
.tfm
;
76 struct hash_alg
*alg
= &tfm
->__crt_alg
->cra_hash
;
77 struct hash_desc desc
= {
78 .tfm
= __crypto_hash_cast(tfm
),
79 .flags
= req
->base
.flags
,
82 return alg
->init(&desc
);
85 static int hash_async_update(struct ahash_request
*req
)
87 struct crypto_tfm
*tfm
= req
->base
.tfm
;
88 struct hash_alg
*alg
= &tfm
->__crt_alg
->cra_hash
;
89 struct hash_desc desc
= {
90 .tfm
= __crypto_hash_cast(tfm
),
91 .flags
= req
->base
.flags
,
94 return alg
->update(&desc
, req
->src
, req
->nbytes
);
97 static int hash_async_final(struct ahash_request
*req
)
99 struct crypto_tfm
*tfm
= req
->base
.tfm
;
100 struct hash_alg
*alg
= &tfm
->__crt_alg
->cra_hash
;
101 struct hash_desc desc
= {
102 .tfm
= __crypto_hash_cast(tfm
),
103 .flags
= req
->base
.flags
,
106 return alg
->final(&desc
, req
->result
);
109 static int hash_async_digest(struct ahash_request
*req
)
111 struct crypto_tfm
*tfm
= req
->base
.tfm
;
112 struct hash_alg
*alg
= &tfm
->__crt_alg
->cra_hash
;
113 struct hash_desc desc
= {
114 .tfm
= __crypto_hash_cast(tfm
),
115 .flags
= req
->base
.flags
,
118 return alg
->digest(&desc
, req
->src
, req
->nbytes
, req
->result
);
121 static int crypto_init_hash_ops_async(struct crypto_tfm
*tfm
)
123 struct ahash_tfm
*crt
= &tfm
->crt_ahash
;
124 struct hash_alg
*alg
= &tfm
->__crt_alg
->cra_hash
;
126 crt
->init
= hash_async_init
;
127 crt
->update
= hash_async_update
;
128 crt
->final
= hash_async_final
;
129 crt
->digest
= hash_async_digest
;
130 crt
->setkey
= hash_async_setkey
;
131 crt
->digestsize
= alg
->digestsize
;
136 static int crypto_init_hash_ops_sync(struct crypto_tfm
*tfm
)
138 struct hash_tfm
*crt
= &tfm
->crt_hash
;
139 struct hash_alg
*alg
= &tfm
->__crt_alg
->cra_hash
;
141 crt
->init
= alg
->init
;
142 crt
->update
= alg
->update
;
143 crt
->final
= alg
->final
;
144 crt
->digest
= alg
->digest
;
145 crt
->setkey
= hash_setkey
;
146 crt
->digestsize
= alg
->digestsize
;
151 static int crypto_init_hash_ops(struct crypto_tfm
*tfm
, u32 type
, u32 mask
)
153 struct hash_alg
*alg
= &tfm
->__crt_alg
->cra_hash
;
155 if (alg
->digestsize
> PAGE_SIZE
/ 8)
158 if ((mask
& CRYPTO_ALG_TYPE_HASH_MASK
) != CRYPTO_ALG_TYPE_HASH_MASK
)
159 return crypto_init_hash_ops_async(tfm
);
161 return crypto_init_hash_ops_sync(tfm
);
164 static void crypto_hash_show(struct seq_file
*m
, struct crypto_alg
*alg
)
165 __attribute__ ((unused
));
166 static void crypto_hash_show(struct seq_file
*m
, struct crypto_alg
*alg
)
168 seq_printf(m
, "type : hash\n");
169 seq_printf(m
, "blocksize : %u\n", alg
->cra_blocksize
);
170 seq_printf(m
, "digestsize : %u\n", alg
->cra_hash
.digestsize
);
173 const struct crypto_type crypto_hash_type
= {
174 .ctxsize
= crypto_hash_ctxsize
,
175 .init
= crypto_init_hash_ops
,
176 #ifdef CONFIG_PROC_FS
177 .show
= crypto_hash_show
,
180 EXPORT_SYMBOL_GPL(crypto_hash_type
);
182 MODULE_LICENSE("GPL");
183 MODULE_DESCRIPTION("Generic cryptographic hash type");