1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2002-2003 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #pragma ident "%Z%%M% %I% %E% SMI"
28
29 #include <sys/sha1.h>
30 #include <sys/sha1_consts.h>
31 #include "hmac_sha1.h"
32
33 static void
HMACHashKey(uchar_t * hashedKey,const uchar_t * key,size_t klen)34 HMACHashKey(uchar_t *hashedKey, const uchar_t *key, size_t klen)
35 {
36 SHA1_CTX keyContext;
37
38 SHA1Init(&keyContext);
39 SHA1Update(&keyContext, key, klen);
40 SHA1Final(hashedKey, &keyContext);
41 }
42
43 void
HMACInit(SHA1_CTX * sha1Context,const uchar_t * key,size_t klen)44 HMACInit(SHA1_CTX *sha1Context, const uchar_t *key, size_t klen)
45 {
46 uchar_t hashedKey[20];
47 const uchar_t *keyptr;
48 uchar_t kipad[64];
49 int i;
50
51 if (klen > 64) {
52 HMACHashKey(hashedKey, key, klen);
53 keyptr = hashedKey;
54 klen = 20;
55 } else {
56 keyptr = key;
57 }
58
59 /* kipad = K XOR ipad */
60 for (i = 0; i < 64; i++) {
61 kipad[i] = (i < klen ? keyptr[i] : 0) ^ 0x36;
62 }
63
64 SHA1Init(sha1Context);
65 SHA1Update(sha1Context, kipad, 64);
66 }
67
68 void
HMACUpdate(SHA1_CTX * sha1Context,const uchar_t * data,size_t dlen)69 HMACUpdate(SHA1_CTX *sha1Context, const uchar_t *data, size_t dlen)
70 {
71 SHA1Update(sha1Context, data, dlen);
72 }
73
74 void
HMACFinal(SHA1_CTX * sha1Context,const uchar_t * key,size_t klen,uchar_t digest[20])75 HMACFinal(SHA1_CTX *sha1Context, const uchar_t *key, size_t klen,
76 uchar_t digest[20])
77 {
78 uchar_t hashedKey[20];
79 const uchar_t *keyptr;
80 uchar_t kopad[64];
81 int i;
82
83 if (klen > 64) {
84 HMACHashKey(hashedKey, key, klen);
85 keyptr = hashedKey;
86 klen = 20;
87 } else {
88 keyptr = key;
89 }
90
91 /* kopad = K XOR opad */
92 for (i = 0; i < 64; i++) {
93 kopad[i] = (i < klen ? keyptr[i] : 0) ^ 0x5c;
94 }
95
96 /* Compute H(kopad, H(kipad, text)) */
97 SHA1Final(digest, sha1Context);
98
99 SHA1Init(sha1Context);
100 SHA1Update(sha1Context, kopad, 64);
101 SHA1Update(sha1Context, digest, 20);
102 SHA1Final(digest, sha1Context);
103 }
104