]> git.saurik.com Git - apple/security.git/blame - AppleCSP/PBKDF2/HMACSHA1.c
Security-29.tar.gz
[apple/security.git] / AppleCSP / PBKDF2 / HMACSHA1.c
CommitLineData
bac41a7b
A
1/*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
8 * using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
16 */
17
18
19/*
20 File: HMACSHA1.c
21 Contains: Apple Data Security Services HMACSHA1 function definition.
22 Copyright: (C) 1999 by Apple Computer, Inc., all rights reserved
23 Written by: Michael Brouwer <mb@apple.com>
24*/
25#include "HMACSHA1.h"
26#include <CryptKit/SHA1.h>
27#include <string.h>
28#include <stdlib.h> // for malloc - maybe we should use CssmAllocator?
29#include <Security/cssmerr.h>
30
31struct hmacContext {
32 sha1Obj sha1Context;
33 UInt8 k_opad[kSHA1BlockSize];
34};
35
36hmacContextRef hmacAlloc()
37{
38 hmacContextRef hmac = (hmacContextRef)malloc(sizeof(struct hmacContext));
39 memset(hmac, 0, sizeof(struct hmacContext));
40 return hmac;
41}
42
43void hmacFree(
44 hmacContextRef hmac)
45{
46 if(hmac != NULL) {
47 if(hmac->sha1Context != NULL) {
48 sha1Free (hmac->sha1Context);
49 }
50 memset(hmac, 0, sizeof(struct hmacContext));
51 free(hmac);
52 }
53}
54
55/* reusable init */
56CSSM_RETURN hmacInit(
57 hmacContextRef hmac,
58 const void *keyPtr,
59 UInt32 keyLen)
60{
61 UInt8 tk[kSHA1DigestSize];
62 UInt8 *key;
63 UInt32 byte;
64 UInt8 k_ipad[kSHA1BlockSize];
65
66 if(hmac->sha1Context == NULL) {
67 hmac->sha1Context = sha1Alloc();
68 if(hmac->sha1Context == NULL) {
69 return CSSMERR_CSP_MEMORY_ERROR;
70 }
71 }
72 else {
73 sha1Reinit(hmac->sha1Context);
74 }
75
76 /* If the key is longer than kSHA1BlockSize reset it to key=SHA1(key) */
77 if (keyLen <= kSHA1BlockSize)
78 key = (UInt8*)keyPtr;
79 else {
80 sha1AddData(hmac->sha1Context, (UInt8*)keyPtr, keyLen);
81 memcpy (tk, sha1Digest(hmac->sha1Context), kSHA1DigestSize);
82 key = tk;
83 keyLen = kSHA1DigestSize;
84 sha1Reinit (hmac->sha1Context);
85 }
86
87 /* The HMAC_SHA_1 transform looks like:
88 SHA1 (K XOR opad || SHA1 (K XOR ipad || text))
89 Where K is a n byte key
90 ipad is the byte 0x36 repeated 64 times.
91 opad is the byte 0x5c repeated 64 times.
92 text is the data being protected.
93 */
94 /* Copy the key into k_ipad and k_opad while doing the XOR. */
95 for (byte = 0; byte < keyLen; byte++)
96 {
97 k_ipad[byte] = key[byte] ^ 0x36;
98 hmac->k_opad[byte] = key[byte] ^ 0x5c;
99 }
100 /* Fill the remainder of k_ipad and k_opad with 0 XORed with the appropriate value. */
101 if (keyLen < kSHA1BlockSize)
102 {
103 memset (k_ipad + keyLen, 0x36, kSHA1BlockSize - keyLen);
104 memset (hmac->k_opad + keyLen, 0x5c, kSHA1BlockSize - keyLen);
105 }
106 sha1AddData (hmac->sha1Context, k_ipad, kSHA1BlockSize);
107 return CSSM_OK;
108}
109
110CSSM_RETURN hmacUpdate(
111 hmacContextRef hmac,
112 const void *textPtr,
113 UInt32 textLen)
114{
115 sha1AddData (hmac->sha1Context, (UInt8*)textPtr, textLen);
116 return CSSM_OK;
117}
118
119CSSM_RETURN hmacFinal(
120 hmacContextRef hmac,
121 void *resultPtr) // caller mallocs, must be HMACSHA1_OUT_SIZE bytes
122{
123 memcpy (resultPtr, sha1Digest (hmac->sha1Context), kSHA1DigestSize);
124 sha1Reinit (hmac->sha1Context);
125 /* Perform outer SHA1 */
126 sha1AddData (hmac->sha1Context, hmac->k_opad, kSHA1BlockSize);
127 sha1AddData (hmac->sha1Context, (UInt8*)resultPtr, kSHA1DigestSize);
128 memcpy (resultPtr, sha1Digest (hmac->sha1Context), kSHA1DigestSize);
129 return CSSM_OK;
130}
131
132/* one-shot, ignoring memory errors. */
133void
134hmacsha1 (const void *keyPtr, UInt32 keyLen,
135 const void *textPtr, UInt32 textLen,
136 void *resultPtr)
137{
138 hmacContextRef hmac = hmacAlloc();
139 hmacInit(hmac, keyPtr, keyLen);
140 hmacUpdate(hmac, textPtr, textLen);
141 hmacFinal(hmac, resultPtr);
142 hmacFree(hmac);
143}
144