root/source4/heimdal/lib/hcrypto/hmac.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. HMAC_CTX_init
  2. HMAC_CTX_cleanup
  3. HMAC_size
  4. HMAC_Init_ex
  5. HMAC_Update
  6. HMAC_Final
  7. HMAC

   1 /*
   2  * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan
   3  * (Royal Institute of Technology, Stockholm, Sweden).
   4  * All rights reserved.
   5  *
   6  * Redistribution and use in source and binary forms, with or without
   7  * modification, are permitted provided that the following conditions
   8  * are met:
   9  *
  10  * 1. Redistributions of source code must retain the above copyright
  11  *    notice, this list of conditions and the following disclaimer.
  12  *
  13  * 2. Redistributions in binary form must reproduce the above copyright
  14  *    notice, this list of conditions and the following disclaimer in the
  15  *    documentation and/or other materials provided with the distribution.
  16  *
  17  * 3. Neither the name of the Institute nor the names of its contributors
  18  *    may be used to endorse or promote products derived from this software
  19  *    without specific prior written permission.
  20  *
  21  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
  22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
  25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31  * SUCH DAMAGE.
  32  */
  33 
  34 #include <sys/types.h>
  35 #include <stdio.h>
  36 #include <stdlib.h>
  37 #include <string.h>
  38 #include <hmac.h>
  39 
  40 void
  41 HMAC_CTX_init(HMAC_CTX *ctx)
     /* [<][>][^][v][top][bottom][index][help] */
  42 {
  43     memset(ctx, 0, sizeof(*ctx));
  44 }
  45 
  46 void
  47 HMAC_CTX_cleanup(HMAC_CTX *ctx)
     /* [<][>][^][v][top][bottom][index][help] */
  48 {
  49     if (ctx->buf) {
  50         memset(ctx->buf, 0, ctx->key_length);
  51         free(ctx->buf);
  52         ctx->buf = NULL;
  53     }
  54     if (ctx->opad) {
  55         memset(ctx->ipad, 0, ctx->key_length);
  56         free(ctx->opad);
  57         ctx->opad = NULL;
  58     }
  59     if (ctx->ipad) {
  60         memset(ctx->ipad, 0, ctx->key_length);
  61         free(ctx->ipad);
  62         ctx->ipad = NULL;
  63     }
  64     if (ctx->ctx) {
  65         EVP_MD_CTX_destroy(ctx->ctx);
  66         ctx->ctx = NULL;
  67     }
  68 }
  69 
  70 size_t
  71 HMAC_size(const HMAC_CTX *ctx)
     /* [<][>][^][v][top][bottom][index][help] */
  72 {
  73     return EVP_MD_size(ctx->md);
  74 }
  75 
  76 void
  77 HMAC_Init_ex(HMAC_CTX *ctx,
     /* [<][>][^][v][top][bottom][index][help] */
  78              const void *key,
  79              size_t keylen,
  80              const EVP_MD *md,
  81              ENGINE *engine)
  82 {
  83     unsigned char *p;
  84     size_t i;
  85 
  86     if (ctx->md != md) {
  87         ctx->md = md;
  88         if (ctx->buf) {
  89             memset(ctx->buf, 0, ctx->key_length);
  90             free (ctx->buf);
  91         }
  92         ctx->key_length = EVP_MD_size(ctx->md);
  93         ctx->buf = malloc(ctx->key_length);
  94     }
  95 #if 0
  96     ctx->engine = engine;
  97 #endif
  98 
  99     if (keylen > EVP_MD_block_size(ctx->md)) {
 100         EVP_Digest(key, keylen, ctx->buf, NULL, ctx->md, engine);
 101         key = ctx->buf;
 102         keylen = EVP_MD_size(ctx->md);
 103     }
 104 
 105     if (ctx->opad) {
 106         memset(ctx->opad, 0, ctx->key_length);
 107         free(ctx->opad);
 108     }
 109     if (ctx->ipad) {
 110         memset(ctx->ipad, 0, ctx->key_length);
 111         free(ctx->ipad);
 112     }
 113 
 114     ctx->opad = malloc(EVP_MD_block_size(ctx->md));
 115     ctx->ipad = malloc(EVP_MD_block_size(ctx->md));
 116     memset(ctx->ipad, 0x36, EVP_MD_block_size(ctx->md));
 117     memset(ctx->opad, 0x5c, EVP_MD_block_size(ctx->md));
 118 
 119     for (i = 0, p = ctx->ipad; i < keylen; i++)
 120         p[i] ^= ((const unsigned char *)key)[i];
 121     for (i = 0, p = ctx->opad; i < keylen; i++)
 122         p[i] ^= ((const unsigned char *)key)[i];
 123 
 124     ctx->ctx = EVP_MD_CTX_create();
 125 
 126     EVP_DigestInit_ex(ctx->ctx, ctx->md, ctx->engine);
 127     EVP_DigestUpdate(ctx->ctx, ctx->ipad, EVP_MD_block_size(ctx->md));
 128 }
 129 
 130 void
 131 HMAC_Update(HMAC_CTX *ctx, const void *data, size_t len)
     /* [<][>][^][v][top][bottom][index][help] */
 132 {
 133     EVP_DigestUpdate(ctx->ctx, data, len);
 134 }
 135 
 136 void
 137 HMAC_Final(HMAC_CTX *ctx, void *md, unsigned int *len)
     /* [<][>][^][v][top][bottom][index][help] */
 138 {
 139     EVP_DigestFinal_ex(ctx->ctx, ctx->buf, NULL);
 140 
 141     EVP_DigestInit_ex(ctx->ctx, ctx->md, ctx->engine);
 142     EVP_DigestUpdate(ctx->ctx, ctx->opad, EVP_MD_block_size(ctx->md));
 143     EVP_DigestUpdate(ctx->ctx, ctx->buf, ctx->key_length);
 144     EVP_DigestFinal_ex(ctx->ctx, md, len);
 145 }
 146 
 147 void *
 148 HMAC(const EVP_MD *md,
     /* [<][>][^][v][top][bottom][index][help] */
 149      const void *key, size_t key_size,
 150      const void *data, size_t data_size,
 151      void *hash, unsigned int *hash_len)
 152 {
 153     HMAC_CTX ctx;
 154 
 155     HMAC_CTX_init(&ctx);
 156     HMAC_Init_ex(&ctx, key, key_size, md, NULL);
 157     HMAC_Update(&ctx, data, data_size);
 158     HMAC_Final(&ctx, hash, hash_len);
 159     HMAC_CTX_cleanup(&ctx);
 160     return hash;
 161 }

/* [<][>][^][v][top][bottom][index][help] */