]>
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 "pbkdDigest.h"
27 #include <MiscCSPAlgs/SHA1.h>
28 #include <MiscCSPAlgs/MD5.h>
30 #include <stdlib.h> // for malloc - maybe we should use CssmAllocator?
31 #include <Security/cssmerr.h>
37 UInt8 k_opad
[kSHA1BlockSize
];
40 hmacContextRef
hmacAlloc()
42 hmacContextRef hmac
= (hmacContextRef
)malloc(sizeof(struct hmacContext
));
43 memset(hmac
, 0, sizeof(struct hmacContext
));
51 DigestCtxFree(&hmac
->digest
);
52 memset(hmac
, 0, sizeof(struct hmacContext
));
62 CSSM_BOOL isSha1
) // true -> SHA1; false -> MD5
64 UInt8 tk
[kSHA1DigestSize
];
67 UInt8 k_ipad
[kSHA1BlockSize
];
68 UInt32 digestSize
= sha1Digest
? kSHA1DigestSize
: MD5_DIGEST_SIZE
;
70 DigestCtxInit(&hmac
->digest
, isSha1
);
72 /* If the key is longer than kSHA1BlockSize reset it to key=digest(key) */
73 if (keyLen
<= kSHA1BlockSize
)
76 DigestCtxUpdate(&hmac
->digest
, (UInt8
*)keyPtr
, keyLen
);
77 DigestCtxFinal(&hmac
->digest
, tk
);
80 DigestCtxInit(&hmac
->digest
, isSha1
);
83 /* The HMAC_<DIG> transform looks like:
84 <DIG> (K XOR opad || <DIG> (K XOR ipad || text))
85 Where K is a n byte key
86 ipad is the byte 0x36 repeated 64 times.
87 opad is the byte 0x5c repeated 64 times.
88 text is the data being protected.
90 /* Copy the key into k_ipad and k_opad while doing the XOR. */
91 for (byte
= 0; byte
< keyLen
; byte
++)
93 k_ipad
[byte
] = key
[byte
] ^ 0x36;
94 hmac
->k_opad
[byte
] = key
[byte
] ^ 0x5c;
96 /* Fill the remainder of k_ipad and k_opad with 0 XORed with the appropriate value. */
97 if (keyLen
< kSHA1BlockSize
)
99 memset (k_ipad
+ keyLen
, 0x36, kSHA1BlockSize
- keyLen
);
100 memset (hmac
->k_opad
+ keyLen
, 0x5c, kSHA1BlockSize
- keyLen
);
102 DigestCtxUpdate(&hmac
->digest
, k_ipad
, kSHA1BlockSize
);
106 CSSM_RETURN
hmacUpdate(
111 DigestCtxUpdate(&hmac
->digest
, textPtr
, textLen
);
115 CSSM_RETURN
hmacFinal(
117 void *resultPtr
) // caller mallocs, must be appropriate output size for
118 // current digest algorithm
120 UInt32 digestSize
= hmac
->digest
.isSha1
? kSHA1DigestSize
: kHMACMD5DigestSize
;
122 DigestCtxFinal(&hmac
->digest
, resultPtr
);
123 DigestCtxInit(&hmac
->digest
, hmac
->digest
.isSha1
);
124 /* Perform outer digest */
125 DigestCtxUpdate(&hmac
->digest
, hmac
->k_opad
, kSHA1BlockSize
);
126 DigestCtxUpdate(&hmac
->digest
, resultPtr
, digestSize
);
127 DigestCtxFinal(&hmac
->digest
, resultPtr
);
131 /* one-shot, ignoring memory errors. */
133 hmacsha1 (const void *keyPtr
, UInt32 keyLen
,
134 const void *textPtr
, UInt32 textLen
,
137 hmacContextRef hmac
= hmacAlloc();
138 hmacInit(hmac
, keyPtr
, keyLen
, CSSM_TRUE
);
139 hmacUpdate(hmac
, textPtr
, textLen
);
140 hmacFinal(hmac
, resultPtr
);