xref: /onnv-gate/usr/src/lib/libkmsagent/common/KMSAgentChallenge.cpp (revision 12720:3db6e0082404)
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