hmac.c (0796ae061e6da5de7cfc1af57dfd42a73908b1bf) hmac.c (8425165dfed27945e8509c141cea245d1739e372)
1/*
2 * Cryptographic API.
3 *
4 * HMAC: Keyed-Hashing for Message Authentication (RFC2104).
5 *
6 * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
7 * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
8 *

--- 15 unchanged lines hidden (view full) ---

24#include <linux/scatterlist.h>
25#include <linux/slab.h>
26#include <linux/string.h>
27
28struct hmac_ctx {
29 struct crypto_hash *child;
30};
31
1/*
2 * Cryptographic API.
3 *
4 * HMAC: Keyed-Hashing for Message Authentication (RFC2104).
5 *
6 * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
7 * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
8 *

--- 15 unchanged lines hidden (view full) ---

24#include <linux/scatterlist.h>
25#include <linux/slab.h>
26#include <linux/string.h>
27
28struct hmac_ctx {
29 struct crypto_hash *child;
30};
31
32static void hash_key(struct crypto_tfm *tfm, u8 *key, unsigned int keylen)
33{
34 struct scatterlist tmp;
35
36 sg_set_buf(&tmp, key, keylen);
37 crypto_digest_digest(tfm, &tmp, 1, key);
38}
39
40int crypto_alloc_hmac_block(struct crypto_tfm *tfm)
41{
42 int ret = 0;
43
44 BUG_ON(!crypto_tfm_alg_blocksize(tfm));
45
46 tfm->crt_hash.hmac_block = kmalloc(crypto_tfm_alg_blocksize(tfm),
47 GFP_KERNEL);
48 if (tfm->crt_hash.hmac_block == NULL)
49 ret = -ENOMEM;
50
51 return ret;
52
53}
54
55void crypto_free_hmac_block(struct crypto_tfm *tfm)
56{
57 kfree(tfm->crt_hash.hmac_block);
58}
59
60void crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen)
61{
62 unsigned int i;
63 struct scatterlist tmp;
64 char *ipad = tfm->crt_hash.hmac_block;
65
66 if (*keylen > crypto_tfm_alg_blocksize(tfm)) {
67 hash_key(tfm, key, *keylen);
68 *keylen = crypto_tfm_alg_digestsize(tfm);
69 }
70
71 memset(ipad, 0, crypto_tfm_alg_blocksize(tfm));
72 memcpy(ipad, key, *keylen);
73
74 for (i = 0; i < crypto_tfm_alg_blocksize(tfm); i++)
75 ipad[i] ^= 0x36;
76
77 sg_set_buf(&tmp, ipad, crypto_tfm_alg_blocksize(tfm));
78
79 crypto_digest_init(tfm);
80 crypto_digest_update(tfm, &tmp, 1);
81}
82
83void crypto_hmac_update(struct crypto_tfm *tfm,
84 struct scatterlist *sg, unsigned int nsg)
85{
86 crypto_digest_update(tfm, sg, nsg);
87}
88
89void crypto_hmac_final(struct crypto_tfm *tfm, u8 *key,
90 unsigned int *keylen, u8 *out)
91{
92 unsigned int i;
93 struct scatterlist tmp;
94 char *opad = tfm->crt_hash.hmac_block;
95
96 if (*keylen > crypto_tfm_alg_blocksize(tfm)) {
97 hash_key(tfm, key, *keylen);
98 *keylen = crypto_tfm_alg_digestsize(tfm);
99 }
100
101 crypto_digest_final(tfm, out);
102
103 memset(opad, 0, crypto_tfm_alg_blocksize(tfm));
104 memcpy(opad, key, *keylen);
105
106 for (i = 0; i < crypto_tfm_alg_blocksize(tfm); i++)
107 opad[i] ^= 0x5c;
108
109 sg_set_buf(&tmp, opad, crypto_tfm_alg_blocksize(tfm));
110
111 crypto_digest_init(tfm);
112 crypto_digest_update(tfm, &tmp, 1);
113
114 sg_set_buf(&tmp, out, crypto_tfm_alg_digestsize(tfm));
115
116 crypto_digest_update(tfm, &tmp, 1);
117 crypto_digest_final(tfm, out);
118}
119
120void crypto_hmac(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen,
121 struct scatterlist *sg, unsigned int nsg, u8 *out)
122{
123 crypto_hmac_init(tfm, key, keylen);
124 crypto_hmac_update(tfm, sg, nsg);
125 crypto_hmac_final(tfm, key, keylen, out);
126}
127
128EXPORT_SYMBOL_GPL(crypto_hmac_init);
129EXPORT_SYMBOL_GPL(crypto_hmac_update);
130EXPORT_SYMBOL_GPL(crypto_hmac_final);
131EXPORT_SYMBOL_GPL(crypto_hmac);
132
133static inline void *align_ptr(void *p, unsigned int align)
134{
135 return (void *)ALIGN((unsigned long)p, align);
136}
137
138static inline struct hmac_ctx *hmac_ctx(struct crypto_hash *tfm)
139{
140 return align_ptr(crypto_hash_ctx_aligned(tfm) +

--- 213 unchanged lines hidden ---
32static inline void *align_ptr(void *p, unsigned int align)
33{
34 return (void *)ALIGN((unsigned long)p, align);
35}
36
37static inline struct hmac_ctx *hmac_ctx(struct crypto_hash *tfm)
38{
39 return align_ptr(crypto_hash_ctx_aligned(tfm) +

--- 213 unchanged lines hidden ---