Пример #1
0
TPM_RC
TPM2_Startup(
	     Startup_In      *in             // IN: input parameter list
	     )
{
    STARTUP_TYPE         startup;
    BYTE                 locality = _plat__LocalityGet();
    // The command needs NV update.
    RETURN_IF_NV_IS_NOT_AVAILABLE;
    // Get the flags for the current startup locality and the H-CRTM.
    // Rather than generalizing the locality setting, this code takes advantage
    // of the fact that the PC Client specification only allows Startup()
    // from locality 0 and 3. To generalize this probably would require a
    // redo of the NV space and since this is a feature that is hardly ever used
    // outside of the PC Client, this code just support the PC Client needs.
    // Input Validation
    // Check that the locality is a supported value
    if(locality != 0 && locality != 3)
	return TPM_RC_LOCALITY;
    // If there was a H-CRTM, then treat the locality as being 3
    // regardless of what the Startup() was. This is done to preserve the
    // H-CRTM PCR so that they don't get overwritten with the normal
    // PCR startup initialization. This basically means that g_StartupLocality3
    // and g_DrtmPreStartup can't both be SET at the same time.
    if(g_DrtmPreStartup)
	locality = 0;
    g_StartupLocality3 = (locality == 3);
#if USE_DA_USED
    // If there was no orderly shutdown, then their might have been a write to
    // failedTries that didn't get recorded but only if g_daUsed was SET in the
    // shutdown state
    g_daUsed = (gp.orderlyState == SU_DA_USED_VALUE);
    if(g_daUsed)
	gp.orderlyState = SU_NONE_VALUE;
#endif
    g_prevOrderlyState = gp.orderlyState;
    // If there was a proper shutdown, then the startup modifiers are in the
    // orderlyState. Turn them off in the copy.
    if(IS_ORDERLY(g_prevOrderlyState))
	g_prevOrderlyState &=  ~(PRE_STARTUP_FLAG | STARTUP_LOCALITY_3);
    // If this is a Resume,
    if(in->startupType == TPM_SU_STATE)
	{
	    // then there must have been a prior TPM2_ShutdownState(STATE)
	    if(g_prevOrderlyState != TPM_SU_STATE)
		return TPM_RCS_VALUE + RC_Startup_startupType;
	    // and the part of NV used for state save must have been recovered
	    // correctly.
	    // NOTE: if this fails, then the caller will need to do Startup(CLEAR). The
	    // code for Startup(Clear) cannot fail if the NV can't be read correctly
	    // because that would prevent the TPM from ever getting unstuck.
	    if(g_nvOk == FALSE)
		return TPM_RC_NV_UNINITIALIZED;
	    // For Resume, the H-CRTM has to be the same as the previous boot
	    if(g_DrtmPreStartup != ((gp.orderlyState & PRE_STARTUP_FLAG) != 0))
		return TPM_RCS_VALUE + RC_Startup_startupType;
	    if(g_StartupLocality3 != ((gp.orderlyState & STARTUP_LOCALITY_3) != 0))
		return TPM_RC_LOCALITY;
	}
    // Clean up the gp state
    gp.orderlyState = g_prevOrderlyState;

    // Internal Date Update
    if((gp.orderlyState == TPM_SU_STATE) && (g_nvOk == TRUE))
	{
	    // Always read the data that is only cleared on a Reset because this is not
	    // a reset
	    NvRead(&gr, NV_STATE_RESET_DATA, sizeof(gr));
	    if(in->startupType == TPM_SU_STATE)
	        {
	            // If this is a startup STATE (a Resume) need to read the data
	            // that is cleared on a startup CLEAR because this is not a Reset
	            // or Restart.
	            NvRead(&gc, NV_STATE_CLEAR_DATA, sizeof(gc));
	            startup = SU_RESUME;
	        }
	    else
		startup = SU_RESTART;
	}
    else
	// Will do a TPM reset if Shutdown(CLEAR) and Startup(CLEAR) or no shutdown
	// or there was a failure reading the NV data.
	startup = SU_RESET;
    // Startup for cryptographic library. Don't do this until after the orderly
    // state has been read in from NV.
    if (CryptStartup(startup) == FALSE) { // libtpms changed begin
        FAIL(FATAL_ERROR_INTERNAL);
    }                                     // libtpms changed end
    // When the cryptographic library has been started, indicate that a TPM2_Startup
    // command has been received.
    TPMRegisterStartup();
    // Read the platform unique value that is used as VENDOR_PERMANENT
    // authorization value
    g_platformUniqueDetails.t.size
	= (UINT16)_plat__GetUnique(1, sizeof(g_platformUniqueDetails.t.buffer),
				   g_platformUniqueDetails.t.buffer);
    // Start up subsystems
    // Start set the safe flag
    TimeStartup(startup);
    // Start dictionary attack subsystem
    DAStartup(startup);
    // Enable hierarchies
    HierarchyStartup(startup);
    // Restore/Initialize PCR
    PCRStartup(startup, locality);
    // Restore/Initialize command audit information
    CommandAuditStartup(startup);
    //// The following code was moved from Time.c where it made no sense
    switch (startup)
	{
	  case SU_RESUME:
	    // Resume sequence
	    gr.restartCount++;
	    break;
	  case SU_RESTART:
	    // Hibernate sequence
	    gr.clearCount++;
	    gr.restartCount++;
	    break;
	  default:
	    // Reset object context ID to 0
	    gr.objectContextID = 0;
	    // Reset clearCount to 0
	    gr.clearCount = 0;
	    // Reset sequence
	    // Increase resetCount
	    gp.resetCount++;
	    // Write resetCount to NV
	    NV_SYNC_PERSISTENT(resetCount);
	    gp.totalResetCount++;
	    // We do not expect the total reset counter overflow during the life
	    // time of TPM.  if it ever happens, TPM will be put to failure mode
	    // and there is no way to recover it.
	    // The reason that there is no recovery is that we don't increment
	    // the NV totalResetCount when incrementing would make it 0. When the
	    // TPM starts up again, the old value of totalResetCount will be read
	    // and we will get right back to here with the increment failing.
#if 0   /* libtpms added */
	    if(gp.totalResetCount == 0)
		FAIL(FATAL_ERROR_INTERNAL);
#endif  /* libtpms added */
	    // Write total reset counter to NV
	    NV_SYNC_PERSISTENT(totalResetCount);
	    // Reset restartCount
	    gr.restartCount = 0;
	    break;
	}
    // Initialize session table
    SessionStartup(startup);
    // Initialize object table
    ObjectStartup();
    // Initialize index/evict data.  This function clears read/write locks
    // in NV index
    NvEntityStartup(startup);
    // Initialize the orderly shut down flag for this cycle to SU_NONE_VALUE.
    gp.orderlyState = SU_NONE_VALUE;
    NV_SYNC_PERSISTENT(orderlyState);
    // This can be reset after the first completion of a TPM2_Startup() after
    // a power loss. It can probably be reset earlier but this is an OK place.
    g_powerWasLost = FALSE;
    return TPM_RC_SUCCESS;
}
Пример #2
0
int main(int argc, char **argv)
{
	Base32 b32;
	AES_KEY AESEncKey;
	MD5Context ctx;
	unsigned char alphabet[] = "123456789ABCDEFGHJKMNPQRSTUVWXYZ";
	unsigned char szKey32[33]; // AES Key
	unsigned char AESEncryptIv[] = 
			{ 0x55, 0x12, 0x90, 0x32, 0x41, 0x85, 0xBC, 0x54, 0x04, 0x19, 0xAE, 0x49, 0x32, 0x99, 0x2D, 0x08 };
	char *signature = 0; // rsa signature
	
	unsigned char plaintext[33], ciphertext[33], *pKey = 0;
	unsigned char *pSzData32, szData255[33]; 
	int encodeLength = 0, keylength = 0, i, x; // NOTE: TEMP SAMPLE HARDWARE ID USED
	unsigned long int prng, licensetype = 0, features = 0, hwid[2] = { 0xDEADBEEF, 0xCAFEBABE };
	
	//printf(">> KOrUPt's Keygen for KKeygenMe #2\n");
	
	if(argc != 2){
		printf("\tUsage: %s <registration name>\n", argv[0]);
		return -1;
	}else if(strlen(argv[1]) > 9){
		printf("Name too long\n");
		return -1;
	}
	
	SetErrorMode(SEM_NOGPFAULTERRORBOX);
	
	// md5 hash our name
	CryptStartup();
	MD5Init(&ctx);
	MD5Update(&ctx, (unsigned char *)argv[1], strlen(argv[1]));
	MD5Final(&ctx);
	
	memset(ciphertext, 0, sizeof(ciphertext));
	memset(szKey32, 0, sizeof(szKey32));
	
	// set up our AES key(= md5 hashed name)
	for(i = 0; i < 16; i++)
		sprintf((char *)szKey32 + strlen((char *)szKey32), "%02x", ctx.digest[i]);
	CryptCleanup();
	
#ifdef _LOCALTEST
	// we'll encode the key with our local hwid as opposed to one given to us by our customer
	char drive[4] = "A:\\";
	hwid[0] = GetProcessorFeatures();
	
	for(drive[0] = 'A'; drive[0] <= 'Z'; drive[0]++){
		if(GetDriveType(drive) == DRIVE_FIXED){
			hwid[1] = GetSystemVolumeSerial(drive);
			break;
		}
	}
#endif	
	
	// Create key
	srand(GetTickCount());
	memset(plaintext, 0, 33);
	*(u_long *)(plaintext)		= prng = (rand() % 0xffffffff) + 0xdeadbeef;
	*(u_long *)(plaintext + 4)	= KEY_MAGIC;
	*(u_long *)(plaintext + 8)	= prng + 512;
	features |= SKILL_UNDEAD | SKILL_YOUCANFLY;
	*(u_long *)(plaintext + 12)	= features;
	*(u_long *)(plaintext + 16) = hwid[0];
	*(u_long *)(plaintext + 20) = hwid[1];
	licensetype = PRO_KEY;
	*(u_long *)(plaintext + 24) = licensetype; 
	prng = (rand() % 1000000) + 0xBADC0DED;
	*(u_long *)(plaintext + 28) = prng; // this part of the key has to be >= 0xBADCODED

#ifdef _DEBUG
	printf("\n>> Md5 of name: %s\n", szKey32);
	hexdump(stdout, "\n--------\nPlaintext:", plaintext, 32);
#endif
	
	AES_set_encrypt_key(szKey32, 32 * 8, &AESEncKey);
	AES_cbc_encrypt(plaintext, ciphertext, 32, &AESEncKey, AESEncryptIv, AES_ENCRYPT);
	
#ifdef _DEBUG
	hexdump(stdout, "Ciphertext:", ciphertext, 32);
	printf("\nHardware id: %04X-%04X\n", hwid[0], hwid[1]);
#endif
	
	encodeLength = b32.GetEncode32Length(32);
	pSzData32 = (unsigned char *)malloc(encodeLength + 1);
	if(pSzData32){
		memset(pSzData32, 0, encodeLength + 1);
		if(b32.Encode32(ciphertext, 32, pSzData32)){
			b32.Map32(pSzData32, encodeLength, alphabet);
		}else{
			printf("An error occoured during Base32 translation\n");
			free(pSzData32);
			return -1;
		}
		
		// add hypthens
		i = 0, x = 0;
		pKey = (unsigned char *)malloc(encodeLength + 13);
		if(pKey){
			memset(pKey, 0, encodeLength + 13);
			while(x < encodeLength){
				memcpy(pKey + i, pSzData32 + x, 4);
				i += 4, x += 4;
				*(pKey + (i++)) = '-';
			}
			
			// remove trailing hythen
			*(pKey + (encodeLength + 12)) = 0;
			
			// sign key
			SignLicenseKey((char *)pKey, &signature);
			
			// write key details to file
			FILE* signatureFile;
			signatureFile = fopen("license.key", "w");
			if(signatureFile){
				printf("Generated key file license.key\n");
				fprintf(signatureFile, "%s*%s*%s*", argv[1], pKey, signature);
				fclose(signatureFile);
			}
			
			
			free(pKey);
		}
		
		free(pSzData32);
	}
	
	return 0;
}