The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/crypto/hmac.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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 = ((long)key & ~PAGE_MASK);
   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 = ((long)ipad & ~PAGE_MASK);
   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 = ((long)opad & ~PAGE_MASK);
  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 = ((long)out & ~PAGE_MASK);
  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 

Cache object: e279311a2c01ed9b100e531e155a4cec


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.