~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/crypto/hmac.c

Version: ~ [ linux-5.9 ] ~ [ linux-5.8.14 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.70 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.150 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.200 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.238 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.238 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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  *
  8  * The HMAC implementation is derived from USAGI.
  9  * Copyright (c) 2002 Kazunori Miyazawa <miyazawa@linux-ipv6.org> / USAGI
 10  *
 11  * This program is free software; you can redistribute it and/or modify it
 12  * under the terms of the GNU General Public License as published by the Free
 13  * Software Foundation; either version 2 of the License, or (at your option) 
 14  * any later version.
 15  *
 16  */
 17 #include <linux/crypto.h>
 18 #include <linux/mm.h>
 19 #include <linux/highmem.h>
 20 #include <linux/slab.h>
 21 #include <asm/scatterlist.h>
 22 #include "internal.h"
 23 
 24 static void hash_key(struct crypto_tfm *tfm, u8 *key, unsigned int keylen)
 25 {
 26         struct scatterlist tmp;
 27         
 28         tmp.page = virt_to_page(key);
 29         tmp.offset = offset_in_page(key);
 30         tmp.length = keylen;
 31         crypto_digest_digest(tfm, &tmp, 1, key);
 32                 
 33 }
 34 
 35 int crypto_alloc_hmac_block(struct crypto_tfm *tfm)
 36 {
 37         int ret = 0;
 38 
 39         BUG_ON(!crypto_tfm_alg_blocksize(tfm));
 40         
 41         tfm->crt_digest.dit_hmac_block = kmalloc(crypto_tfm_alg_blocksize(tfm),
 42                                                  GFP_KERNEL);
 43         if (tfm->crt_digest.dit_hmac_block == NULL)
 44                 ret = -ENOMEM;
 45 
 46         return ret;
 47                 
 48 }
 49 
 50 void crypto_free_hmac_block(struct crypto_tfm *tfm)
 51 {
 52         if (tfm->crt_digest.dit_hmac_block)
 53                 kfree(tfm->crt_digest.dit_hmac_block);
 54 }
 55 
 56 void crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen)
 57 {
 58         unsigned int i;
 59         struct scatterlist tmp;
 60         char *ipad = tfm->crt_digest.dit_hmac_block;
 61         
 62         if (*keylen > crypto_tfm_alg_blocksize(tfm)) {
 63                 hash_key(tfm, key, *keylen);
 64                 *keylen = crypto_tfm_alg_digestsize(tfm);
 65         }
 66 
 67         memset(ipad, 0, crypto_tfm_alg_blocksize(tfm));
 68         memcpy(ipad, key, *keylen);
 69 
 70         for (i = 0; i < crypto_tfm_alg_blocksize(tfm); i++)
 71                 ipad[i] ^= 0x36;
 72 
 73         tmp.page = virt_to_page(ipad);
 74         tmp.offset = offset_in_page(ipad);
 75         tmp.length = crypto_tfm_alg_blocksize(tfm);
 76         
 77         crypto_digest_init(tfm);
 78         crypto_digest_update(tfm, &tmp, 1);
 79 }
 80 
 81 void crypto_hmac_update(struct crypto_tfm *tfm,
 82                         struct scatterlist *sg, unsigned int nsg)
 83 {
 84         crypto_digest_update(tfm, sg, nsg);
 85 }
 86 
 87 void crypto_hmac_final(struct crypto_tfm *tfm, u8 *key,
 88                        unsigned int *keylen, u8 *out)
 89 {
 90         unsigned int i;
 91         struct scatterlist tmp;
 92         char *opad = tfm->crt_digest.dit_hmac_block;
 93         
 94         if (*keylen > crypto_tfm_alg_blocksize(tfm)) {
 95                 hash_key(tfm, key, *keylen);
 96                 *keylen = crypto_tfm_alg_digestsize(tfm);
 97         }
 98 
 99         crypto_digest_final(tfm, out);
100 
101         memset(opad, 0, crypto_tfm_alg_blocksize(tfm));
102         memcpy(opad, key, *keylen);
103                 
104         for (i = 0; i < crypto_tfm_alg_blocksize(tfm); i++)
105                 opad[i] ^= 0x5c;
106 
107         tmp.page = virt_to_page(opad);
108         tmp.offset = offset_in_page(opad);
109         tmp.length = crypto_tfm_alg_blocksize(tfm);
110 
111         crypto_digest_init(tfm);
112         crypto_digest_update(tfm, &tmp, 1);
113         
114         tmp.page = virt_to_page(out);
115         tmp.offset = offset_in_page(out);
116         tmp.length = crypto_tfm_alg_digestsize(tfm);
117         
118         crypto_digest_update(tfm, &tmp, 1);
119         crypto_digest_final(tfm, out);
120 }
121 
122 void crypto_hmac(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen,
123                  struct scatterlist *sg, unsigned int nsg, u8 *out)
124 {
125         crypto_hmac_init(tfm, key, keylen);
126         crypto_hmac_update(tfm, sg, nsg);
127         crypto_hmac_final(tfm, key, keylen, out);
128 }
129 
130 EXPORT_SYMBOL_GPL(crypto_hmac_init);
131 EXPORT_SYMBOL_GPL(crypto_hmac_update);
132 EXPORT_SYMBOL_GPL(crypto_hmac_final);
133 EXPORT_SYMBOL_GPL(crypto_hmac);
134 
135 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp