File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / curl / lib / hmac.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Jun 3 10:01:15 2020 UTC (5 years ago) by misho
Branches: curl, MAIN
CVS tags: v7_70_0p4, HEAD
curl

    1: /***************************************************************************
    2:  *                                  _   _ ____  _
    3:  *  Project                     ___| | | |  _ \| |
    4:  *                             / __| | | | |_) | |
    5:  *                            | (__| |_| |  _ <| |___
    6:  *                             \___|\___/|_| \_\_____|
    7:  *
    8:  * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
    9:  *
   10:  * This software is licensed as described in the file COPYING, which
   11:  * you should have received as part of this distribution. The terms
   12:  * are also available at https://curl.haxx.se/docs/copyright.html.
   13:  *
   14:  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
   15:  * copies of the Software, and permit persons to whom the Software is
   16:  * furnished to do so, under the terms of the COPYING file.
   17:  *
   18:  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
   19:  * KIND, either express or implied.
   20:  *
   21:  * RFC2104 Keyed-Hashing for Message Authentication
   22:  *
   23:  ***************************************************************************/
   24: 
   25: #include "curl_setup.h"
   26: 
   27: #ifndef CURL_DISABLE_CRYPTO_AUTH
   28: 
   29: #include <curl/curl.h>
   30: 
   31: #include "curl_hmac.h"
   32: #include "curl_memory.h"
   33: #include "warnless.h"
   34: 
   35: /* The last #include file should be: */
   36: #include "memdebug.h"
   37: 
   38: /*
   39:  * Generic HMAC algorithm.
   40:  *
   41:  *   This module computes HMAC digests based on any hash function. Parameters
   42:  * and computing procedures are set-up dynamically at HMAC computation
   43:  * context initialisation.
   44:  */
   45: 
   46: static const unsigned char hmac_ipad = 0x36;
   47: static const unsigned char hmac_opad = 0x5C;
   48: 
   49: 
   50: 
   51: HMAC_context *
   52: Curl_HMAC_init(const HMAC_params * hashparams,
   53:                const unsigned char *key,
   54:                unsigned int keylen)
   55: {
   56:   size_t i;
   57:   HMAC_context *ctxt;
   58:   unsigned char *hkey;
   59:   unsigned char b;
   60: 
   61:   /* Create HMAC context. */
   62:   i = sizeof(*ctxt) + 2 * hashparams->hmac_ctxtsize +
   63:     hashparams->hmac_resultlen;
   64:   ctxt = malloc(i);
   65: 
   66:   if(!ctxt)
   67:     return ctxt;
   68: 
   69:   ctxt->hmac_hash = hashparams;
   70:   ctxt->hmac_hashctxt1 = (void *) (ctxt + 1);
   71:   ctxt->hmac_hashctxt2 = (void *) ((char *) ctxt->hmac_hashctxt1 +
   72:       hashparams->hmac_ctxtsize);
   73: 
   74:   /* If the key is too long, replace it by its hash digest. */
   75:   if(keylen > hashparams->hmac_maxkeylen) {
   76:     (*hashparams->hmac_hinit)(ctxt->hmac_hashctxt1);
   77:     (*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt1, key, keylen);
   78:     hkey = (unsigned char *) ctxt->hmac_hashctxt2 + hashparams->hmac_ctxtsize;
   79:     (*hashparams->hmac_hfinal)(hkey, ctxt->hmac_hashctxt1);
   80:     key = hkey;
   81:     keylen = hashparams->hmac_resultlen;
   82:   }
   83: 
   84:   /* Prime the two hash contexts with the modified key. */
   85:   (*hashparams->hmac_hinit)(ctxt->hmac_hashctxt1);
   86:   (*hashparams->hmac_hinit)(ctxt->hmac_hashctxt2);
   87: 
   88:   for(i = 0; i < keylen; i++) {
   89:     b = (unsigned char)(*key ^ hmac_ipad);
   90:     (*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt1, &b, 1);
   91:     b = (unsigned char)(*key++ ^ hmac_opad);
   92:     (*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt2, &b, 1);
   93:   }
   94: 
   95:   for(; i < hashparams->hmac_maxkeylen; i++) {
   96:     (*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt1, &hmac_ipad, 1);
   97:     (*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt2, &hmac_opad, 1);
   98:   }
   99: 
  100:   /* Done, return pointer to HMAC context. */
  101:   return ctxt;
  102: }
  103: 
  104: int Curl_HMAC_update(HMAC_context * ctxt,
  105:                      const unsigned char *data,
  106:                      unsigned int len)
  107: {
  108:   /* Update first hash calculation. */
  109:   (*ctxt->hmac_hash->hmac_hupdate)(ctxt->hmac_hashctxt1, data, len);
  110:   return 0;
  111: }
  112: 
  113: 
  114: int Curl_HMAC_final(HMAC_context *ctxt, unsigned char *result)
  115: {
  116:   const HMAC_params * hashparams = ctxt->hmac_hash;
  117: 
  118:   /* Do not get result if called with a null parameter: only release
  119:      storage. */
  120: 
  121:   if(!result)
  122:     result = (unsigned char *) ctxt->hmac_hashctxt2 +
  123:      ctxt->hmac_hash->hmac_ctxtsize;
  124: 
  125:   (*hashparams->hmac_hfinal)(result, ctxt->hmac_hashctxt1);
  126:   (*hashparams->hmac_hupdate)(ctxt->hmac_hashctxt2,
  127:    result, hashparams->hmac_resultlen);
  128:   (*hashparams->hmac_hfinal)(result, ctxt->hmac_hashctxt2);
  129:   free((char *) ctxt);
  130:   return 0;
  131: }
  132: 
  133: /*
  134:  * Curl_hmacit()
  135:  *
  136:  * This is used to generate a HMAC hash, for the specified input data, given
  137:  * the specified hash function and key.
  138:  *
  139:  * Parameters:
  140:  *
  141:  * hashparams [in]     - The hash function (Curl_HMAC_MD5).
  142:  * key        [in]     - The key to use.
  143:  * keylen     [in]     - The length of the key.
  144:  * data       [in]     - The data to encrypt.
  145:  * datalen    [in]     - The length of the data.
  146:  * output     [in/out] - The output buffer.
  147:  *
  148:  * Returns CURLE_OK on success.
  149:  */
  150: CURLcode Curl_hmacit(const HMAC_params *hashparams,
  151:                      const unsigned char *key, const size_t keylen,
  152:                      const unsigned char *data, const size_t datalen,
  153:                      unsigned char *output)
  154: {
  155:   HMAC_context *ctxt = Curl_HMAC_init(hashparams, key, curlx_uztoui(keylen));
  156: 
  157:   if(!ctxt)
  158:     return CURLE_OUT_OF_MEMORY;
  159: 
  160:   /* Update the digest with the given challenge */
  161:   Curl_HMAC_update(ctxt, data, curlx_uztoui(datalen));
  162: 
  163:   /* Finalise the digest */
  164:   Curl_HMAC_final(ctxt, output);
  165: 
  166:   return CURLE_OK;
  167: }
  168: 
  169: #endif /* CURL_DISABLE_CRYPTO_AUTH */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>