aboutsummaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-12-08 18:55:13 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-12-08 18:55:13 -0500
commite069efb6bbf8f739a2e084183709b5eb76abf90d (patch)
tree0866058fa6e1b77d9defc6f45f39d1f851afe327 /crypto
parent324889b6bd2a89e0d69a2f9d133d6cf24579ab6c (diff)
parenteed89d0f9d3383851cec634565a6414fae70fe91 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6: hwrng: core - Prevent too-small buffer sizes hwrng: virtio-rng - Convert to new API hwrng: core - Replace u32 in driver API with byte array crypto: ansi_cprng - Move FIPS functions under CONFIG_CRYPTO_FIPS crypto: testmgr - Add ghash algorithm test before provide to users crypto: ghash-clmulni-intel - Put proper .data section in place crypto: ghash-clmulni-intel - Use gas macro for PCLMULQDQ-NI and PSHUFB crypto: aesni-intel - Use gas macro for AES-NI instructions x86: Generate .byte code for some new instructions via gas macro crypto: ghash-intel - Fix irq_fpu_usable usage crypto: ghash-intel - Add PSHUFB macros crypto: ghash-intel - Hard-code pshufb crypto: ghash-intel - Fix building failure on x86_32 crypto: testmgr - Fix warning crypto: ansi_cprng - Fix test in get_prng_bytes crypto: hash - Remove cra_u.{digest,hash} crypto: api - Remove digest case from procfs show handler crypto: hash - Remove legacy hash/digest code crypto: ansi_cprng - Add FIPS wrapper crypto: ghash - Add PCLMULQDQ accelerated implementation
Diffstat (limited to 'crypto')
-rw-r--r--crypto/Kconfig9
-rw-r--r--crypto/ansi_cprng.c82
-rw-r--r--crypto/cryptd.c7
-rw-r--r--crypto/digest.c240
-rw-r--r--crypto/hash.c183
-rw-r--r--crypto/proc.c7
-rw-r--r--crypto/testmgr.c11
-rw-r--r--crypto/testmgr.h15
8 files changed, 111 insertions, 443 deletions
diff --git a/crypto/Kconfig b/crypto/Kconfig
index 26b5dd0cb564..81c185a6971f 100644
--- a/crypto/Kconfig
+++ b/crypto/Kconfig
@@ -440,6 +440,15 @@ config CRYPTO_WP512
440 See also: 440 See also:
441 <http://planeta.terra.com.br/informatica/paulobarreto/WhirlpoolPage.html> 441 <http://planeta.terra.com.br/informatica/paulobarreto/WhirlpoolPage.html>
442 442
443config CRYPTO_GHASH_CLMUL_NI_INTEL
444 tristate "GHASH digest algorithm (CLMUL-NI accelerated)"
445 depends on (X86 || UML_X86) && 64BIT
446 select CRYPTO_SHASH
447 select CRYPTO_CRYPTD
448 help
449 GHASH is message digest algorithm for GCM (Galois/Counter Mode).
450 The implementation is accelerated by CLMUL-NI of Intel.
451
443comment "Ciphers" 452comment "Ciphers"
444 453
445config CRYPTO_AES 454config CRYPTO_AES
diff --git a/crypto/ansi_cprng.c b/crypto/ansi_cprng.c
index 3aa6e3834bfe..2bc332142849 100644
--- a/crypto/ansi_cprng.c
+++ b/crypto/ansi_cprng.c
@@ -85,7 +85,7 @@ static void xor_vectors(unsigned char *in1, unsigned char *in2,
85 * Returns DEFAULT_BLK_SZ bytes of random data per call 85 * Returns DEFAULT_BLK_SZ bytes of random data per call
86 * returns 0 if generation succeded, <0 if something went wrong 86 * returns 0 if generation succeded, <0 if something went wrong
87 */ 87 */
88static int _get_more_prng_bytes(struct prng_context *ctx) 88static int _get_more_prng_bytes(struct prng_context *ctx, int cont_test)
89{ 89{
90 int i; 90 int i;
91 unsigned char tmp[DEFAULT_BLK_SZ]; 91 unsigned char tmp[DEFAULT_BLK_SZ];
@@ -132,7 +132,7 @@ static int _get_more_prng_bytes(struct prng_context *ctx)
132 */ 132 */
133 if (!memcmp(ctx->rand_data, ctx->last_rand_data, 133 if (!memcmp(ctx->rand_data, ctx->last_rand_data,
134 DEFAULT_BLK_SZ)) { 134 DEFAULT_BLK_SZ)) {
135 if (fips_enabled) { 135 if (cont_test) {
136 panic("cprng %p Failed repetition check!\n", 136 panic("cprng %p Failed repetition check!\n",
137 ctx); 137 ctx);
138 } 138 }
@@ -185,16 +185,14 @@ static int _get_more_prng_bytes(struct prng_context *ctx)
185} 185}
186 186
187/* Our exported functions */ 187/* Our exported functions */
188static int get_prng_bytes(char *buf, size_t nbytes, struct prng_context *ctx) 188static int get_prng_bytes(char *buf, size_t nbytes, struct prng_context *ctx,
189 int do_cont_test)
189{ 190{
190 unsigned char *ptr = buf; 191 unsigned char *ptr = buf;
191 unsigned int byte_count = (unsigned int)nbytes; 192 unsigned int byte_count = (unsigned int)nbytes;
192 int err; 193 int err;
193 194
194 195
195 if (nbytes < 0)
196 return -EINVAL;
197
198 spin_lock_bh(&ctx->prng_lock); 196 spin_lock_bh(&ctx->prng_lock);
199 197
200 err = -EINVAL; 198 err = -EINVAL;
@@ -220,7 +218,7 @@ static int get_prng_bytes(char *buf, size_t nbytes, struct prng_context *ctx)
220 218
221remainder: 219remainder:
222 if (ctx->rand_data_valid == DEFAULT_BLK_SZ) { 220 if (ctx->rand_data_valid == DEFAULT_BLK_SZ) {
223 if (_get_more_prng_bytes(ctx) < 0) { 221 if (_get_more_prng_bytes(ctx, do_cont_test) < 0) {
224 memset(buf, 0, nbytes); 222 memset(buf, 0, nbytes);
225 err = -EINVAL; 223 err = -EINVAL;
226 goto done; 224 goto done;
@@ -247,7 +245,7 @@ empty_rbuf:
247 */ 245 */
248 for (; byte_count >= DEFAULT_BLK_SZ; byte_count -= DEFAULT_BLK_SZ) { 246 for (; byte_count >= DEFAULT_BLK_SZ; byte_count -= DEFAULT_BLK_SZ) {
249 if (ctx->rand_data_valid == DEFAULT_BLK_SZ) { 247 if (ctx->rand_data_valid == DEFAULT_BLK_SZ) {
250 if (_get_more_prng_bytes(ctx) < 0) { 248 if (_get_more_prng_bytes(ctx, do_cont_test) < 0) {
251 memset(buf, 0, nbytes); 249 memset(buf, 0, nbytes);
252 err = -EINVAL; 250 err = -EINVAL;
253 goto done; 251 goto done;
@@ -356,7 +354,7 @@ static int cprng_get_random(struct crypto_rng *tfm, u8 *rdata,
356{ 354{
357 struct prng_context *prng = crypto_rng_ctx(tfm); 355 struct prng_context *prng = crypto_rng_ctx(tfm);
358 356
359 return get_prng_bytes(rdata, dlen, prng); 357 return get_prng_bytes(rdata, dlen, prng, 0);
360} 358}
361 359
362/* 360/*
@@ -404,19 +402,79 @@ static struct crypto_alg rng_alg = {
404 } 402 }
405}; 403};
406 404
405#ifdef CONFIG_CRYPTO_FIPS
406static int fips_cprng_get_random(struct crypto_rng *tfm, u8 *rdata,
407 unsigned int dlen)
408{
409 struct prng_context *prng = crypto_rng_ctx(tfm);
410
411 return get_prng_bytes(rdata, dlen, prng, 1);
412}
413
414static int fips_cprng_reset(struct crypto_rng *tfm, u8 *seed, unsigned int slen)
415{
416 u8 rdata[DEFAULT_BLK_SZ];
417 int rc;
418
419 struct prng_context *prng = crypto_rng_ctx(tfm);
420
421 rc = cprng_reset(tfm, seed, slen);
422
423 if (!rc)
424 goto out;
425
426 /* this primes our continuity test */
427 rc = get_prng_bytes(rdata, DEFAULT_BLK_SZ, prng, 0);
428 prng->rand_data_valid = DEFAULT_BLK_SZ;
429
430out:
431 return rc;
432}
433
434static struct crypto_alg fips_rng_alg = {
435 .cra_name = "fips(ansi_cprng)",
436 .cra_driver_name = "fips_ansi_cprng",
437 .cra_priority = 300,
438 .cra_flags = CRYPTO_ALG_TYPE_RNG,
439 .cra_ctxsize = sizeof(struct prng_context),
440 .cra_type = &crypto_rng_type,
441 .cra_module = THIS_MODULE,
442 .cra_list = LIST_HEAD_INIT(rng_alg.cra_list),
443 .cra_init = cprng_init,
444 .cra_exit = cprng_exit,
445 .cra_u = {
446 .rng = {
447 .rng_make_random = fips_cprng_get_random,
448 .rng_reset = fips_cprng_reset,
449 .seedsize = DEFAULT_PRNG_KSZ + 2*DEFAULT_BLK_SZ,
450 }
451 }
452};
453#endif
407 454
408/* Module initalization */ 455/* Module initalization */
409static int __init prng_mod_init(void) 456static int __init prng_mod_init(void)
410{ 457{
411 if (fips_enabled) 458 int rc = 0;
412 rng_alg.cra_priority += 200;
413 459
414 return crypto_register_alg(&rng_alg); 460 rc = crypto_register_alg(&rng_alg);
461#ifdef CONFIG_CRYPTO_FIPS
462 if (rc)
463 goto out;
464
465 rc = crypto_register_alg(&fips_rng_alg);
466
467out:
468#endif
469 return rc;
415} 470}
416 471
417static void __exit prng_mod_fini(void) 472static void __exit prng_mod_fini(void)
418{ 473{
419 crypto_unregister_alg(&rng_alg); 474 crypto_unregister_alg(&rng_alg);
475#ifdef CONFIG_CRYPTO_FIPS
476 crypto_unregister_alg(&fips_rng_alg);
477#endif
420 return; 478 return;
421} 479}
422 480
diff --git a/crypto/cryptd.c b/crypto/cryptd.c
index 35335825a4ef..f8ae0d94a647 100644
--- a/crypto/cryptd.c
+++ b/crypto/cryptd.c
@@ -711,6 +711,13 @@ struct crypto_shash *cryptd_ahash_child(struct cryptd_ahash *tfm)
711} 711}
712EXPORT_SYMBOL_GPL(cryptd_ahash_child); 712EXPORT_SYMBOL_GPL(cryptd_ahash_child);
713 713
714struct shash_desc *cryptd_shash_desc(struct ahash_request *req)
715{
716 struct cryptd_hash_request_ctx *rctx = ahash_request_ctx(req);
717 return &rctx->desc;
718}
719EXPORT_SYMBOL_GPL(cryptd_shash_desc);
720
714void cryptd_free_ahash(struct cryptd_ahash *tfm) 721void cryptd_free_ahash(struct cryptd_ahash *tfm)
715{ 722{
716 crypto_free_ahash(&tfm->base); 723 crypto_free_ahash(&tfm->base);
diff --git a/crypto/digest.c b/crypto/digest.c
deleted file mode 100644
index 5d3f1303da98..000000000000
--- a/crypto/digest.c
+++ /dev/null
@@ -1,240 +0,0 @@
1/*
2 * Cryptographic API.
3 *
4 * Digest operations.
5 *
6 * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the Free
10 * Software Foundation; either version 2 of the License, or (at your option)
11 * any later version.
12 *
13 */
14
15#include <crypto/internal/hash.h>
16#include <crypto/scatterwalk.h>
17#include <linux/mm.h>
18#include <linux/errno.h>
19#include <linux/hardirq.h>
20#include <linux/highmem.h>
21#include <linux/kernel.h>
22#include <linux/module.h>
23#include <linux/scatterlist.h>
24
25#include "internal.h"
26
27static int init(struct hash_desc *desc)
28{
29 struct crypto_tfm *tfm = crypto_hash_tfm(desc->tfm);
30
31 tfm->__crt_alg->cra_digest.dia_init(tfm);
32 return 0;
33}
34
35static int update2(struct hash_desc *desc,
36 struct scatterlist *sg, unsigned int nbytes)
37{
38 struct crypto_tfm *tfm = crypto_hash_tfm(desc->tfm);
39 unsigned int alignmask = crypto_tfm_alg_alignmask(tfm);
40
41 if (!nbytes)
42 return 0;
43
44 for (;;) {
45 struct page *pg = sg_page(sg);
46 unsigned int offset = sg->offset;
47 unsigned int l = sg->length;
48
49 if (unlikely(l > nbytes))
50 l = nbytes;
51 nbytes -= l;
52
53 do {
54 unsigned int bytes_from_page = min(l, ((unsigned int)
55 (PAGE_SIZE)) -
56 offset);
57 char *src = crypto_kmap(pg, 0);
58 char *p = src + offset;
59
60 if (unlikely(offset & alignmask)) {
61 unsigned int bytes =
62 alignmask + 1 - (offset & alignmask);
63 bytes = min(bytes, bytes_from_page);
64 tfm->__crt_alg->cra_digest.dia_update(tfm, p,
65 bytes);
66 p += bytes;
67 bytes_from_page -= bytes;
68 l -= bytes;
69 }
70 tfm->__crt_alg->cra_digest.dia_update(tfm, p,
71 bytes_from_page);
72 crypto_kunmap(src, 0);
73 crypto_yield(desc->flags);
74 offset = 0;
75 pg++;
76 l -= bytes_from_page;
77 } while (l > 0);
78
79 if (!nbytes)
80 break;
81 sg = scatterwalk_sg_next(sg);
82 }
83
84 return 0;
85}
86
87static int update(struct hash_desc *desc,
88 struct scatterlist *sg, unsigned int nbytes)
89{
90 if (WARN_ON_ONCE(in_irq()))
91 return -EDEADLK;
92 return update2(desc, sg, nbytes);
93}
94
95static int final(struct hash_desc *desc, u8 *out)
96{
97 struct crypto_tfm *tfm = crypto_hash_tfm(desc->tfm);
98 unsigned long alignmask = crypto_tfm_alg_alignmask(tfm);
99 struct digest_alg *digest = &tfm->__crt_alg->cra_digest;
100
101 if (unlikely((unsigned long)out & alignmask)) {
102 unsigned long align = alignmask + 1;
103 unsigned long addr = (unsigned long)crypto_tfm_ctx(tfm);
104 u8 *dst = (u8 *)ALIGN(addr, align) +
105 ALIGN(tfm->__crt_alg->cra_ctxsize, align);
106
107 digest->dia_final(tfm, dst);
108 memcpy(out, dst, digest->dia_digestsize);
109 } else
110 digest->dia_final(tfm, out);
111
112 return 0;
113}
114
115static int nosetkey(struct crypto_hash *tfm, const u8 *key, unsigned int keylen)
116{
117 crypto_hash_clear_flags(tfm, CRYPTO_TFM_RES_MASK);
118 return -ENOSYS;
119}
120
121static int setkey(struct crypto_hash *hash, const u8 *key, unsigned int keylen)
122{
123 struct crypto_tfm *tfm = crypto_hash_tfm(hash);
124
125 crypto_hash_clear_flags(hash, CRYPTO_TFM_RES_MASK);
126 return tfm->__crt_alg->cra_digest.dia_setkey(tfm, key, keylen);
127}
128
129static int digest(struct hash_desc *desc,
130 struct scatterlist *sg, unsigned int nbytes, u8 *out)
131{
132 if (WARN_ON_ONCE(in_irq()))
133 return -EDEADLK;
134
135 init(desc);
136 update2(desc, sg, nbytes);
137 return final(desc, out);
138}
139
140int crypto_init_digest_ops(struct crypto_tfm *tfm)
141{
142 struct hash_tfm *ops = &tfm->crt_hash;
143 struct digest_alg *dalg = &tfm->__crt_alg->cra_digest;
144
145 if (dalg->dia_digestsize > PAGE_SIZE / 8)
146 return -EINVAL;
147
148 ops->init = init;
149 ops->update = update;
150 ops->final = final;
151 ops->digest = digest;
152 ops->setkey = dalg->dia_setkey ? setkey : nosetkey;
153 ops->digestsize = dalg->dia_digestsize;
154
155 return 0;
156}
157
158void crypto_exit_digest_ops(struct crypto_tfm *tfm)
159{
160}
161
162static int digest_async_nosetkey(struct crypto_ahash *tfm_async, const u8 *key,
163 unsigned int keylen)
164{
165 crypto_ahash_clear_flags(tfm_async, CRYPTO_TFM_RES_MASK);
166 return -ENOSYS;
167}
168
169static int digest_async_setkey(struct crypto_ahash *tfm_async, const u8 *key,
170 unsigned int keylen)
171{
172 struct crypto_tfm *tfm = crypto_ahash_tfm(tfm_async);
173 struct digest_alg *dalg = &tfm->__crt_alg->cra_digest;
174
175 crypto_ahash_clear_flags(tfm_async, CRYPTO_TFM_RES_MASK);
176 return dalg->dia_setkey(tfm, key, keylen);
177}
178
179static int digest_async_init(struct ahash_request *req)
180{
181 struct crypto_tfm *tfm = req->base.tfm;
182 struct digest_alg *dalg = &tfm->__crt_alg->cra_digest;
183
184 dalg->dia_init(tfm);
185 return 0;
186}
187
188static int digest_async_update(struct ahash_request *req)
189{
190 struct crypto_tfm *tfm = req->base.tfm;
191 struct hash_desc desc = {
192 .tfm = __crypto_hash_cast(tfm),
193 .flags = req->base.flags,
194 };
195
196 update(&desc, req->src, req->nbytes);
197 return 0;
198}
199
200static int digest_async_final(struct ahash_request *req)
201{
202 struct crypto_tfm *tfm = req->base.tfm;
203 struct hash_desc desc = {
204 .tfm = __crypto_hash_cast(tfm),
205 .flags = req->base.flags,
206 };
207
208 final(&desc, req->result);
209 return 0;
210}
211
212static int digest_async_digest(struct ahash_request *req)
213{
214 struct crypto_tfm *tfm = req->base.tfm;
215 struct hash_desc desc = {
216 .tfm = __crypto_hash_cast(tfm),
217 .flags = req->base.flags,
218 };
219
220 return digest(&desc, req->src, req->nbytes, req->result);
221}
222
223int crypto_init_digest_ops_async(struct crypto_tfm *tfm)
224{
225 struct ahash_tfm *crt = &tfm->crt_ahash;
226 struct digest_alg *dalg = &tfm->__crt_alg->cra_digest;
227
228 if (dalg->dia_digestsize > PAGE_SIZE / 8)
229 return -EINVAL;
230
231 crt->init = digest_async_init;
232 crt->update = digest_async_update;
233 crt->final = digest_async_final;
234 crt->digest = digest_async_digest;
235 crt->setkey = dalg->dia_setkey ? digest_async_setkey :
236 digest_async_nosetkey;
237 crt->digestsize = dalg->dia_digestsize;
238
239 return 0;
240}
diff --git a/crypto/hash.c b/crypto/hash.c
deleted file mode 100644
index cb86b19fd105..000000000000
--- a/crypto/hash.c
+++ /dev/null
@@ -1,183 +0,0 @@
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 <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>
18
19#include "internal.h"
20
21static unsigned int crypto_hash_ctxsize(struct crypto_alg *alg, u32 type,
22 u32 mask)
23{
24 return alg->cra_ctxsize;
25}
26
27static int hash_setkey_unaligned(struct crypto_hash *crt, const u8 *key,
28 unsigned int keylen)
29{
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);
33 int ret;
34 u8 *buffer, *alignbuffer;
35 unsigned long absize;
36
37 absize = keylen + alignmask;
38 buffer = kmalloc(absize, GFP_ATOMIC);
39 if (!buffer)
40 return -ENOMEM;
41
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);
46 kfree(buffer);
47 return ret;
48}
49
50static int hash_setkey(struct crypto_hash *crt, const u8 *key,
51 unsigned int keylen)
52{
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);
56
57 if ((unsigned long)key & alignmask)
58 return hash_setkey_unaligned(crt, key, keylen);
59
60 return alg->setkey(crt, key, keylen);
61}
62
63static int hash_async_setkey(struct crypto_ahash *tfm_async, const u8 *key,
64 unsigned int keylen)
65{
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;
69
70 return alg->setkey(tfm_hash, key, keylen);
71}
72
73static int hash_async_init(struct ahash_request *req)
74{
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,
80 };
81
82 return alg->init(&desc);
83}
84
85static int hash_async_update(struct ahash_request *req)
86{
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,
92 };
93
94 return alg->update(&desc, req->src, req->nbytes);
95}
96
97static int hash_async_final(struct ahash_request *req)
98{
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,
104 };
105
106 return alg->final(&desc, req->result);
107}
108
109static int hash_async_digest(struct ahash_request *req)
110{
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,
116 };
117
118 return alg->digest(&desc, req->src, req->nbytes, req->result);
119}
120
121static int crypto_init_hash_ops_async(struct crypto_tfm *tfm)
122{
123 struct ahash_tfm *crt = &tfm->crt_ahash;
124 struct hash_alg *alg = &tfm->__crt_alg->cra_hash;
125
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;
132
133 return 0;
134}
135
136static int crypto_init_hash_ops_sync(struct crypto_tfm *tfm)
137{
138 struct hash_tfm *crt = &tfm->crt_hash;
139 struct hash_alg *alg = &tfm->__crt_alg->cra_hash;
140
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;
147
148 return 0;
149}
150
151static int crypto_init_hash_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
152{
153 struct hash_alg *alg = &tfm->__crt_alg->cra_hash;
154
155 if (alg->digestsize > PAGE_SIZE / 8)
156 return -EINVAL;
157
158 if ((mask & CRYPTO_ALG_TYPE_HASH_MASK) != CRYPTO_ALG_TYPE_HASH_MASK)
159 return crypto_init_hash_ops_async(tfm);
160 else
161 return crypto_init_hash_ops_sync(tfm);
162}
163
164static void crypto_hash_show(struct seq_file *m, struct crypto_alg *alg)
165 __attribute__ ((unused));
166static void crypto_hash_show(struct seq_file *m, struct crypto_alg *alg)
167{
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);
171}
172
173const 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,
178#endif
179};
180EXPORT_SYMBOL_GPL(crypto_hash_type);
181
182MODULE_LICENSE("GPL");
183MODULE_DESCRIPTION("Generic cryptographic hash type");
diff --git a/crypto/proc.c b/crypto/proc.c
index 1c38733c224d..58fef67d4f4d 100644
--- a/crypto/proc.c
+++ b/crypto/proc.c
@@ -109,13 +109,6 @@ static int c_show(struct seq_file *m, void *p)
109 seq_printf(m, "max keysize : %u\n", 109 seq_printf(m, "max keysize : %u\n",
110 alg->cra_cipher.cia_max_keysize); 110 alg->cra_cipher.cia_max_keysize);
111 break; 111 break;
112
113 case CRYPTO_ALG_TYPE_DIGEST:
114 seq_printf(m, "type : digest\n");
115 seq_printf(m, "blocksize : %u\n", alg->cra_blocksize);
116 seq_printf(m, "digestsize : %u\n",
117 alg->cra_digest.dia_digestsize);
118 break;
119 case CRYPTO_ALG_TYPE_COMPRESS: 112 case CRYPTO_ALG_TYPE_COMPRESS:
120 seq_printf(m, "type : compression\n"); 113 seq_printf(m, "type : compression\n");
121 break; 114 break;
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index 6d5b746637be..7620bfce92f2 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -1201,7 +1201,7 @@ static int test_cprng(struct crypto_rng *tfm, struct cprng_testvec *template,
1201 unsigned int tcount) 1201 unsigned int tcount)
1202{ 1202{
1203 const char *algo = crypto_tfm_alg_driver_name(crypto_rng_tfm(tfm)); 1203 const char *algo = crypto_tfm_alg_driver_name(crypto_rng_tfm(tfm));
1204 int err, i, j, seedsize; 1204 int err = 0, i, j, seedsize;
1205 u8 *seed; 1205 u8 *seed;
1206 char result[32]; 1206 char result[32];
1207 1207
@@ -1943,6 +1943,15 @@ static const struct alg_test_desc alg_test_descs[] = {
1943 } 1943 }
1944 } 1944 }
1945 }, { 1945 }, {
1946 .alg = "ghash",
1947 .test = alg_test_hash,
1948 .suite = {
1949 .hash = {
1950 .vecs = ghash_tv_template,
1951 .count = GHASH_TEST_VECTORS
1952 }
1953 }
1954 }, {
1946 .alg = "hmac(md5)", 1955 .alg = "hmac(md5)",
1947 .test = alg_test_hash, 1956 .test = alg_test_hash,
1948 .suite = { 1957 .suite = {
diff --git a/crypto/testmgr.h b/crypto/testmgr.h
index 9963b18983ab..fb765173d41c 100644
--- a/crypto/testmgr.h
+++ b/crypto/testmgr.h
@@ -1003,6 +1003,21 @@ static struct hash_testvec tgr128_tv_template[] = {
1003 }, 1003 },
1004}; 1004};
1005 1005
1006#define GHASH_TEST_VECTORS 1
1007
1008static struct hash_testvec ghash_tv_template[] =
1009{
1010 {
1011
1012 .key = "\xdf\xa6\xbf\x4d\xed\x81\xdb\x03\xff\xca\xff\x95\xf8\x30\xf0\x61",
1013 .ksize = 16,
1014 .plaintext = "\x95\x2b\x2a\x56\xa5\x60\x04a\xc0\xb3\x2b\x66\x56\xa0\x5b\x40\xb6",
1015 .psize = 16,
1016 .digest = "\xda\x53\xeb\x0a\xd2\xc5\x5b\xb6"
1017 "\x4f\xc4\x80\x2c\xc3\xfe\xda\x60",
1018 },
1019};
1020
1006/* 1021/*
1007 * HMAC-MD5 test vectors from RFC2202 1022 * HMAC-MD5 test vectors from RFC2202
1008 * (These need to be fixed to not use strlen). 1023 * (These need to be fixed to not use strlen).