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 36extern "C" int Log2(char* msg1, 37 char* msg2); 38 39#ifdef METAWARE 40#include "debug.h" 41#endif 42 43 44/** 45 * ComputeChallengeResponse 46 */ 47bool 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 */ 164bool 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 */ 249bool 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