]>
git.saurik.com Git - apple/security.git/blob - AppleCSP/PBKDF2/HMACSHA1.c
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
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
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.
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>
26 #include <CryptKit/SHA1.h>
28 #include <stdlib.h> // for malloc - maybe we should use CssmAllocator?
29 #include <Security/cssmerr.h>
33 UInt8 k_opad
[kSHA1BlockSize
];
36 hmacContextRef
hmacAlloc()
38 hmacContextRef hmac
= (hmacContextRef
)malloc(sizeof(struct hmacContext
));
39 memset(hmac
, 0, sizeof(struct hmacContext
));
47 if(hmac
->sha1Context
!= NULL
) {
48 sha1Free (hmac
->sha1Context
);
50 memset(hmac
, 0, sizeof(struct hmacContext
));
61 UInt8 tk
[kSHA1DigestSize
];
64 UInt8 k_ipad
[kSHA1BlockSize
];
66 if(hmac
->sha1Context
== NULL
) {
67 hmac
->sha1Context
= sha1Alloc();
68 if(hmac
->sha1Context
== NULL
) {
69 return CSSMERR_CSP_MEMORY_ERROR
;
73 sha1Reinit(hmac
->sha1Context
);
76 /* If the key is longer than kSHA1BlockSize reset it to key=SHA1(key) */
77 if (keyLen
<= kSHA1BlockSize
)
80 sha1AddData(hmac
->sha1Context
, (UInt8
*)keyPtr
, keyLen
);
81 memcpy (tk
, sha1Digest(hmac
->sha1Context
), kSHA1DigestSize
);
83 keyLen
= kSHA1DigestSize
;
84 sha1Reinit (hmac
->sha1Context
);
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.
94 /* Copy the key into k_ipad and k_opad while doing the XOR. */
95 for (byte
= 0; byte
< keyLen
; byte
++)
97 k_ipad
[byte
] = key
[byte
] ^ 0x36;
98 hmac
->k_opad
[byte
] = key
[byte
] ^ 0x5c;
100 /* Fill the remainder of k_ipad and k_opad with 0 XORed with the appropriate value. */
101 if (keyLen
< kSHA1BlockSize
)
103 memset (k_ipad
+ keyLen
, 0x36, kSHA1BlockSize
- keyLen
);
104 memset (hmac
->k_opad
+ keyLen
, 0x5c, kSHA1BlockSize
- keyLen
);
106 sha1AddData (hmac
->sha1Context
, k_ipad
, kSHA1BlockSize
);
110 CSSM_RETURN
hmacUpdate(
115 sha1AddData (hmac
->sha1Context
, (UInt8
*)textPtr
, textLen
);
119 CSSM_RETURN
hmacFinal(
121 void *resultPtr
) // caller mallocs, must be HMACSHA1_OUT_SIZE bytes
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
);
132 /* one-shot, ignoring memory errors. */
134 hmacsha1 (const void *keyPtr
, UInt32 keyLen
,
135 const void *textPtr
, UInt32 textLen
,
138 hmacContextRef hmac
= hmacAlloc();
139 hmacInit(hmac
, keyPtr
, keyLen
);
140 hmacUpdate(hmac
, textPtr
, textLen
);
141 hmacFinal(hmac
, resultPtr
);