5 // Created by Jonathan Wight on 4/8/8.
6 // Copyright 2008 Jonathan Wight. All rights reserved.
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
9 // of this software and associated documentation files (the "Software"), to deal
10 // in the Software without restriction, including without limitation the rights
11 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 // copies of the Software, and to permit persons to whom the Software is
13 // furnished to do so, subject to the following conditions:
15 // The above copyright notice and this permission notice shall be included in
16 // all copies or substantial portions of the Software.
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 * Implementation of HMAC-SHA1. Adapted from example at http://tools.ietf.org/html/rfc2104
36 void hmac_sha1(const unsigned char *inText, size_t inTextLength, unsigned char* inKey, size_t inKeyLength, unsigned char *outDigest)
41 SHA1_CTX theSHA1Context;
42 unsigned char k_ipad[B + 1]; /* inner padding - key XORd with ipad */
43 unsigned char k_opad[B + 1]; /* outer padding - key XORd with opad */
45 /* if key is longer than 64 bytes reset it to key=SHA1 (key) */
48 SHA1Init(&theSHA1Context);
49 SHA1Update(&theSHA1Context, inKey, inKeyLength);
50 SHA1Final(inKey, &theSHA1Context);
54 /* start out by storing key in pads */
55 memset(k_ipad, 0, sizeof k_ipad);
56 memset(k_opad, 0, sizeof k_opad);
57 memcpy(k_ipad, inKey, inKeyLength);
58 memcpy(k_opad, inKey, inKeyLength);
60 /* XOR key with ipad and opad values */
62 for (i = 0; i < B; i++)
71 SHA1Init(&theSHA1Context); /* init context for 1st pass */
72 SHA1Update(&theSHA1Context, k_ipad, B); /* start with inner pad */
73 SHA1Update(&theSHA1Context, (unsigned char *)inText, inTextLength); /* then text of datagram */
74 SHA1Final((unsigned char *)outDigest, &theSHA1Context); /* finish up 1st pass */
79 SHA1Init(&theSHA1Context); /* init context for 2nd
81 SHA1Update(&theSHA1Context, k_opad, B); /* start with outer pad */
82 SHA1Update(&theSHA1Context, outDigest, L); /* then results of 1st
84 SHA1Final(outDigest, &theSHA1Context); /* finish up 2nd pass */