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 (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25
26 /**
27 * \file KMSAgentChallenge.cpp
28 */
29
30 #include "KMSAgentChallenge.h"
31 #include "KMSAgentCryptoUtilities.h"
32 #include "KMSAgentStringUtilities.h"
33 #include "ApplianceParameters.h"
34 #include "SYSCommon.h"
35
36 extern "C" int Log2(char* msg1,
37 char* msg2);
38
39 #ifdef METAWARE
40 #include "debug.h"
41 #endif
42
43
44 /**
45 * ComputeChallengeResponse
46 */
ComputeChallengeResponse(const unsigned char * i_pAuthenticationSecret,int i_iAuthenticationSecretLength,const unsigned char * i_pRootCACertificate,int i_iRootCACertificateLength,const unsigned char * i_pAuthenticationChallenge,int i_iAuthenticationChallengeLength,unsigned char * o_pAuthenticationChallengeResponse,int i_iAuthenticationChallengeResponseLength)47 bool ComputeChallengeResponse(
48 const unsigned char* i_pAuthenticationSecret,
49 int i_iAuthenticationSecretLength,
50 const unsigned char* i_pRootCACertificate,
51 int i_iRootCACertificateLength,
52 const unsigned char* i_pAuthenticationChallenge,
53 int i_iAuthenticationChallengeLength,
54 unsigned char* o_pAuthenticationChallengeResponse,
55 int i_iAuthenticationChallengeResponseLength )
56 {
57
58 bool rc;
59
60 #ifdef DEBUG
61 Log2 ("KMSAgent_LoadProfile::ComputeChallengeResponse", "Entered");
62 #endif
63 FATAL_ASSERT( i_iAuthenticationChallengeResponseLength == HMAC_LENGTH );
64
65 // challenge response is HMAC-SHA1( RootCACertificate ||
66 // AuthenticationChallenge, AuthenticationSecret )
67 const unsigned char* aBuffersToHMAC[2];
68 int aBuffersToHMACSize[2];
69
70 aBuffersToHMAC[0] = i_pRootCACertificate;
71 aBuffersToHMACSize[0] = i_iRootCACertificateLength;
72
73 aBuffersToHMAC[1] = i_pAuthenticationChallenge;
74 aBuffersToHMACSize[1] = i_iAuthenticationChallengeLength;
75
76 rc = HMACBuffers(
77 2,
78 aBuffersToHMAC,
79 aBuffersToHMACSize,
80 i_pAuthenticationSecret,
81 i_iAuthenticationSecretLength,
82 o_pAuthenticationChallengeResponse );
83
84 #if defined(METAWARE) && defined(DEBUG)
85 int j=0;
86
87 j+=snprintf(outmsg+j, OUTMSG_SIZE,
88 "length=%x\n",
89 i_iAuthenticationSecretLength);
90
91 for (int i=0 ; i< i_iAuthenticationSecretLength; i++)
92 {
93 j+=snprintf(outmsg+j, OUTMSG_SIZE,
94 "%x",
95 i_pAuthenticationSecret[i]);
96 }
97 snprintf(outmsg+j, OUTMSG_SIZE, "\n");
98
99 Log2("Secret = ",outmsg);
100 #endif
101
102 #if defined(METAWARE) && defined(DEBUG)
103 j=0;
104
105 j+=snprintf(outmsg+j, OUTMSG_SIZE,
106 "length=%x\n",
107 i_iRootCACertificateLength);
108
109 for (i=0 ; i< i_iRootCACertificateLength; i++)
110 {
111 j+=snprintf(outmsg+j, OUTMSG_SIZE,
112 "%x",
113 i_pRootCACertificate[i]);
114 }
115 snprintf(outmsg+j, OUTMSG_SIZE, "\n");
116
117 Log2("i_pRootCACertificate = ",outmsg);
118 #endif
119
120 #if defined(METAWARE) && defined(DEBUG)
121 j=0;
122
123 j+=snprintf(outmsg+j, OUTMSG_SIZE,
124 "length=%x\n",
125 i_iAuthenticationChallengeLength);
126
127 for (i=0 ; i< i_iAuthenticationChallengeLength; i++)
128 {
129 j+=snprintf(outmsg+j, OUTMSG_SIZE,
130 "%x",
131 i_pAuthenticationChallenge[i]);
132 }
133 snprintf(outmsg+j, OUTMSG_SIZE, "\n");
134
135 Log2("i_pAuthenticationChallenge = ",outmsg);
136 #endif
137
138 #if defined(METAWARE) && defined(DEBUG)
139 j=0;
140
141 j+=snprintf(outmsg+j, OUTMSG_SIZE,
142 "length=%x\n",
143 i_iAuthenticationChallengeResponseLength);
144
145 for (i=0 ; i< i_iAuthenticationChallengeResponseLength; i++)
146 {
147 j+=snprintf(outmsg+j, OUTMSG_SIZE,
148 "%x",
149 o_pAuthenticationChallengeResponse[i]);
150 }
151 snprintf(outmsg+j, OUTMSG_SIZE, "\n");
152
153 Log2("o_pAuthenticationChallengeResponse = ",outmsg);
154 #endif
155
156 return rc;
157
158 #undef __IAM__
159 }
160
161 /**
162 * ComputeEntityHashedPassphraseAndAuthenticationSecret
163 */
ComputeEntityHashedPassphraseAndAuthenticationSecret(const char * i_sPassphrase,char * const o_sHexHashedPassphrase,int * const o_piAuthenticationHashIterationCount,char * const o_sHexAuthenticationSecret)164 bool ComputeEntityHashedPassphraseAndAuthenticationSecret(
165 const char* i_sPassphrase,
166 char* const o_sHexHashedPassphrase,
167 int* const o_piAuthenticationHashIterationCount,
168 char* const o_sHexAuthenticationSecret )
169 {
170 // HashedPassphrase is SHA1( Passphrase-UTF-8 )
171 // Using UTF-8 ensures the same result on different platforms with
172 // different wide character representations.
173 // This hashed passphrase value is used to wrap entity
174 // private key materials.
175 #if defined(METAWARE) && defined(DEBUG)
176 Log2 ("KMSAgent_LoadProfile::ComputeEntityHashedPassphraseAndAuthenticationSecret",
177 "Entered");
178 #endif
179
180 unsigned char aHashedPassphrase[HASH_LENGTH];
181
182 memset(aHashedPassphrase, 0, HASH_LENGTH);
183
184 if ( strlen(i_sPassphrase) > 0 )
185 {
186 if ( !HashBuffer(
187 (unsigned char*)i_sPassphrase,
188 strlen(i_sPassphrase),
189 aHashedPassphrase) )
190 {
191 return false;
192 }
193 }
194
195 ConvertBinaryToUTF8HexString( o_sHexHashedPassphrase,
196 aHashedPassphrase,
197 HASH_LENGTH );
198
199 // HexAuthenticationSecret is SHA1( SHA1( ... ( SHA1(
200 // HashedPassphrase ) ) ) The number of iterations is time bounded
201 // at 1/10 of a second, and also bounded by fixed minimum and
202 // maximum values (to prevent too weak of a computation and to
203 // prevent a DoS, respectively). This value is used as the shared
204 // secret in challenge-response authentication exchanges.
205
206 *o_piAuthenticationHashIterationCount = 0;
207
208 unsigned long iStartTickCount = K_GetTickCount();
209
210 while ( *o_piAuthenticationHashIterationCount <
211 MAX_AUTHENTICATION_ITERATION_COUNT
212 && ( *o_piAuthenticationHashIterationCount <
213 MIN_AUTHENTICATION_ITERATION_COUNT
214 || iStartTickCount +
215 AUTHENTICATION_ITERATION_TIME_IN_MILLISECONDS >
216 K_GetTickCount() ) )
217 {
218 if ( !HashBuffer(
219 aHashedPassphrase,
220 HASH_LENGTH,
221 aHashedPassphrase) )
222 {
223 return false;
224 }
225
226 (*o_piAuthenticationHashIterationCount)++;
227 }
228
229 ConvertBinaryToUTF8HexString( o_sHexAuthenticationSecret,
230 aHashedPassphrase, HASH_LENGTH );
231
232 #if defined(METAWARE) && defined(DEBUG)
233 snprintf(outmsg, OUTMSG_SIZE,
234 "o_sHexAuthenticationSecret=%x o_piAuth..."
235 "= %x aHashedPassphrase=%s\n",
236 o_sHexAuthenticationSecret,
237 *o_piAuthenticationHashIterationCount,
238 aHashedPassphrase);
239 Log2("ComputeEntityHashedPassphraseAndAuthenticationSecret ",
240 outmsg);
241 #endif
242
243 return true;
244 }
245
246 /**
247 * ComputeFixedEntityHashedPassphraseAndAuthenticationSecret
248 */
ComputeFixedEntityHashedPassphraseAndAuthenticationSecret(const char * i_sPassphrase,char * const o_sHexHashedPassphrase,int i_iAuthenticationHashIterationCount,char * const o_sHexAuthenticationSecret)249 bool ComputeFixedEntityHashedPassphraseAndAuthenticationSecret(
250 const char* i_sPassphrase,
251 char* const o_sHexHashedPassphrase,
252 int i_iAuthenticationHashIterationCount,
253 char* const o_sHexAuthenticationSecret )
254 {
255 // compute same values as
256 // ComputeEntityHashedPassphraseAndAuthenticationSecret, except
257 // iteration count is fixed
258 #if defined(METAWARE) && defined(DEBUG)
259 Log2 ("KMSAgent_LoadProfile::"
260 "ComputeFixedEntityHashedPassphraseAndAuthenticationSecret", "Entered");
261 #endif
262
263 // detect attempts to cause weak computation or DoS attack
264 if ( i_iAuthenticationHashIterationCount <
265 MIN_AUTHENTICATION_ITERATION_COUNT ||
266 i_iAuthenticationHashIterationCount >
267 MAX_AUTHENTICATION_ITERATION_COUNT )
268 {
269 return false;
270 }
271
272
273 unsigned char aHashedPassphrase[HASH_LENGTH];
274
275 memset(aHashedPassphrase, 0, HASH_LENGTH);
276
277 if ( strlen(i_sPassphrase) > 0 )
278 {
279 if ( !HashBuffer(
280 (unsigned char*)i_sPassphrase,
281 strlen(i_sPassphrase),
282 aHashedPassphrase) )
283 {
284 return false;
285 }
286 }
287
288 ConvertBinaryToUTF8HexString( o_sHexHashedPassphrase,
289 aHashedPassphrase, HASH_LENGTH );
290
291 int i;
292 for ( i = 0; i < i_iAuthenticationHashIterationCount; i++ )
293 {
294 if ( !HashBuffer(
295 aHashedPassphrase,
296 HASH_LENGTH,
297 aHashedPassphrase) )
298 {
299 return false;
300 }
301 }
302
303 ConvertBinaryToUTF8HexString( o_sHexAuthenticationSecret,
304 aHashedPassphrase, HASH_LENGTH );
305
306 #if defined(METAWARE) && defined(DEBUG)
307 snprintf(outmsg, OUTMSG_SIZE,
308 "i_iAuth %x \n",
309 i_iAuthenticationHashIterationCount);
310
311 Log2("ComputeEntityHashedPassphraseAndAuthenticationSecret ",
312 outmsg);
313 #endif
314
315
316 return true;
317 }
318