"Fossies" - the Fresh Open Source Software Archive

Member "nss-3.35/nss/lib/freebl/alghmac.c" (18 Jan 2018, 4548 Bytes) of package /linux/misc/nss-3.35.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "alghmac.c" see the Fossies "Dox" file reference documentation.

    1 /* This Source Code Form is subject to the terms of the Mozilla Public
    2  * License, v. 2.0. If a copy of the MPL was not distributed with this
    3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
    4 
    5 #ifdef FREEBL_NO_DEPEND
    6 #include "stubs.h"
    7 #endif
    8 
    9 #include "secport.h"
   10 #include "hasht.h"
   11 #include "blapit.h"
   12 #include "alghmac.h"
   13 #include "secerr.h"
   14 
   15 #define HMAC_PAD_SIZE HASH_BLOCK_LENGTH_MAX
   16 
   17 struct HMACContextStr {
   18     void *hash;
   19     const SECHashObject *hashobj;
   20     PRBool wasAllocated;
   21     unsigned char ipad[HMAC_PAD_SIZE];
   22     unsigned char opad[HMAC_PAD_SIZE];
   23 };
   24 
   25 void
   26 HMAC_Destroy(HMACContext *cx, PRBool freeit)
   27 {
   28     if (cx == NULL)
   29         return;
   30 
   31     PORT_Assert(!freeit == !cx->wasAllocated);
   32     if (cx->hash != NULL) {
   33         cx->hashobj->destroy(cx->hash, PR_TRUE);
   34         PORT_Memset(cx, 0, sizeof *cx);
   35     }
   36     if (freeit)
   37         PORT_Free(cx);
   38 }
   39 
   40 SECStatus
   41 HMAC_Init(HMACContext *cx, const SECHashObject *hash_obj,
   42           const unsigned char *secret, unsigned int secret_len, PRBool isFIPS)
   43 {
   44     unsigned int i;
   45     unsigned char hashed_secret[HASH_LENGTH_MAX];
   46 
   47     /* required by FIPS 198 Section 3 */
   48     if (isFIPS && secret_len < hash_obj->length / 2) {
   49         PORT_SetError(SEC_ERROR_INVALID_ARGS);
   50         return SECFailure;
   51     }
   52     if (cx == NULL) {
   53         PORT_SetError(SEC_ERROR_INVALID_ARGS);
   54         return SECFailure;
   55     }
   56     cx->wasAllocated = PR_FALSE;
   57     cx->hashobj = hash_obj;
   58     cx->hash = cx->hashobj->create();
   59     if (cx->hash == NULL)
   60         goto loser;
   61 
   62     if (secret_len > cx->hashobj->blocklength) {
   63         cx->hashobj->begin(cx->hash);
   64         cx->hashobj->update(cx->hash, secret, secret_len);
   65         PORT_Assert(cx->hashobj->length <= sizeof hashed_secret);
   66         cx->hashobj->end(cx->hash, hashed_secret, &secret_len,
   67                          sizeof hashed_secret);
   68         if (secret_len != cx->hashobj->length) {
   69             PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
   70             goto loser;
   71         }
   72         secret = (const unsigned char *)&hashed_secret[0];
   73     }
   74 
   75     PORT_Memset(cx->ipad, 0x36, cx->hashobj->blocklength);
   76     PORT_Memset(cx->opad, 0x5c, cx->hashobj->blocklength);
   77 
   78     /* fold secret into padding */
   79     for (i = 0; i < secret_len; i++) {
   80         cx->ipad[i] ^= secret[i];
   81         cx->opad[i] ^= secret[i];
   82     }
   83     PORT_Memset(hashed_secret, 0, sizeof hashed_secret);
   84     return SECSuccess;
   85 
   86 loser:
   87     PORT_Memset(hashed_secret, 0, sizeof hashed_secret);
   88     if (cx->hash != NULL)
   89         cx->hashobj->destroy(cx->hash, PR_TRUE);
   90     return SECFailure;
   91 }
   92 
   93 HMACContext *
   94 HMAC_Create(const SECHashObject *hash_obj, const unsigned char *secret,
   95             unsigned int secret_len, PRBool isFIPS)
   96 {
   97     SECStatus rv;
   98     HMACContext *cx = PORT_ZNew(HMACContext);
   99     if (cx == NULL)
  100         return NULL;
  101     rv = HMAC_Init(cx, hash_obj, secret, secret_len, isFIPS);
  102     cx->wasAllocated = PR_TRUE;
  103     if (rv != SECSuccess) {
  104         PORT_Free(cx); /* contains no secret info */
  105         cx = NULL;
  106     }
  107     return cx;
  108 }
  109 
  110 void
  111 HMAC_Begin(HMACContext *cx)
  112 {
  113     /* start inner hash */
  114     cx->hashobj->begin(cx->hash);
  115     cx->hashobj->update(cx->hash, cx->ipad, cx->hashobj->blocklength);
  116 }
  117 
  118 void
  119 HMAC_Update(HMACContext *cx, const unsigned char *data, unsigned int data_len)
  120 {
  121     cx->hashobj->update(cx->hash, data, data_len);
  122 }
  123 
  124 SECStatus
  125 HMAC_Finish(HMACContext *cx, unsigned char *result, unsigned int *result_len,
  126             unsigned int max_result_len)
  127 {
  128     if (max_result_len < cx->hashobj->length) {
  129         PORT_SetError(SEC_ERROR_INVALID_ARGS);
  130         return SECFailure;
  131     }
  132 
  133     cx->hashobj->end(cx->hash, result, result_len, max_result_len);
  134     if (*result_len != cx->hashobj->length)
  135         return SECFailure;
  136 
  137     cx->hashobj->begin(cx->hash);
  138     cx->hashobj->update(cx->hash, cx->opad, cx->hashobj->blocklength);
  139     cx->hashobj->update(cx->hash, result, *result_len);
  140     cx->hashobj->end(cx->hash, result, result_len, max_result_len);
  141     return SECSuccess;
  142 }
  143 
  144 HMACContext *
  145 HMAC_Clone(HMACContext *cx)
  146 {
  147     HMACContext *newcx;
  148 
  149     newcx = (HMACContext *)PORT_ZAlloc(sizeof(HMACContext));
  150     if (newcx == NULL)
  151         goto loser;
  152 
  153     newcx->wasAllocated = PR_TRUE;
  154     newcx->hashobj = cx->hashobj;
  155     newcx->hash = cx->hashobj->clone(cx->hash);
  156     if (newcx->hash == NULL)
  157         goto loser;
  158     PORT_Memcpy(newcx->ipad, cx->ipad, cx->hashobj->blocklength);
  159     PORT_Memcpy(newcx->opad, cx->opad, cx->hashobj->blocklength);
  160     return newcx;
  161 
  162 loser:
  163     HMAC_Destroy(newcx, PR_TRUE);
  164     return NULL;
  165 }