Esempio n. 1
0
static int hmac_dbrg_update(struct ccdrbg_state *drbg,
                            unsigned long daLen, const void *da,
                            unsigned long dbLen, const void *db,
                            unsigned long dcLen, const void *dc
                            )
{
    struct ccdrbg_nisthmac_state *state = (struct ccdrbg_nisthmac_state *)drbg;
    const struct ccdrbg_nisthmac_custom *custom = state->info->custom;
    const struct ccdigest_info *di = custom->di;

    const unsigned char cZero = 0x00;
    const unsigned char cOne  = 0x01;
    cchmac_ctx_decl(di->state_size, di->block_size, ctx);

    cchmac_init(di, ctx, state->keysize, state->key);
    // 1. K = HMAC (K, V || 0x00 || provided_data).
    cchmac_update(di, ctx, state->vsize, state->v);
    cchmac_update(di, ctx, 1, &cZero);
    if (da && daLen) cchmac_update(di, ctx, daLen, da);
    if (db && dbLen) cchmac_update(di, ctx, dbLen, db);
    if (dc && dcLen) cchmac_update(di, ctx, dcLen, dc);
    cchmac_final(di, ctx, state->key);

    //  2. V=HMAC(K,V).
    cchmac(di, state->keysize, state->key, state->vsize, state->v, state->v);

    // 3. If (provided_data = Null), then return K and V.
    // One parameter must be non-empty, or return
    if (!((da && daLen) || (db && dbLen) || (dc && dcLen)))
        return 0;

    // 4. K = HMAC (K, V || 0x01 || provided_data).
    cchmac_init(di, ctx, state->keysize, state->key);
    cchmac_update(di, ctx, state->vsize, state->v);
    cchmac_update(di, ctx, 1, &cOne);
    if (da && daLen) cchmac_update(di, ctx, daLen, da);
    if (db && dbLen) cchmac_update(di, ctx, dbLen, db);
    if (dc && dcLen) cchmac_update(di, ctx, dcLen, dc);
    cchmac_final(di, ctx, state->key);

    //  5. V=HMAC(K,V).
    cchmac(di, state->keysize, state->key, state->vsize, state->v, state->v);

    return 0;
}
Esempio n. 2
0
static int hmac_dbrg_update(struct ccdrbg_state *drbg,
                            size_t daLen, const void *da,
                            size_t dbLen, const void *db,
                            size_t dcLen, const void *dc
                            )
{
    int rc=CCDRBG_STATUS_ERROR;
    struct ccdrbg_nisthmac_state *state = (struct ccdrbg_nisthmac_state *)drbg;
    const struct ccdigest_info *di = state->custom->di;
    
    const unsigned char cZero = 0x00;
    const unsigned char cOne  = 0x01;

    cchmac_ctx_decl(di->state_size, di->block_size, ctx);
    cchmac_init(di, ctx, state->keysize, state->key);
    
    // 1. K = HMAC (K, V || 0x00 || provided_data).
    cchmac_update(di, ctx, state->vsize, state->vptr);
    cchmac_update(di, ctx, 1, &cZero);
    if (da && daLen) cchmac_update(di, ctx, daLen, da);
    if (db && dbLen) cchmac_update(di, ctx, dbLen, db);
    if (dc && dcLen) cchmac_update(di, ctx, dcLen, dc);
    cchmac_final(di, ctx, state->key);

    // One parameter must be non-empty, or return
    if (((da && daLen) || (db && dbLen) || (dc && dcLen))) {
        //  2. V=HMAC(K,V).
        cchmac(di, state->keysize, state->key, state->vsize, state->vptr, state->vptr);
        //  4. K = HMAC (K, V || 0x01 || provided_data).
        cchmac_init(di, ctx, state->keysize, state->key);
        cchmac_update(di, ctx, state->vsize, state->vptr);
        cchmac_update(di, ctx, 1, &cOne);
        if (da && daLen) cchmac_update(di, ctx, daLen, da);
        if (db && dbLen) cchmac_update(di, ctx, dbLen, db);
        if (dc && dcLen) cchmac_update(di, ctx, dcLen, dc);
        cchmac_final(di, ctx, state->key);
    }
    //  If additional data 5. V=HMAC(K,V)
    //  If no addtional data, this is step 2. V=HMAC(K,V).
    state->bytesLeft = 0;

    // FIPS 140-2 4.9.2 Conditional Tests
    // "the first n-bit block generated after power-up, initialization, or reset shall not be used, but shall be saved for comparison with the next n-bit block to be generated"
    // Generate the first block and the second block. Compare for FIPS and discard the first block
    // We keep the second block as the first set of data to be returned
    cchmac(di, state->keysize, state->key, state->vsize, state->vptr, state->vptr);     // First block
    cchmac(di, state->keysize, state->key, state->vsize, state->vptr, state->nextvptr); // First to be returned
    if (0==cc_cmp_safe(state->vsize, state->vptr, state->nextvptr)) {
        //The world as we know it has come to an end
        //the DRBG data structure is zeroized. subsequent calls to
        //DRBG ends up in NULL dereferencing and/or unpredictable state.
        //catastrophic error in SP 800-90A
        done(drbg);
        rc=CCDRBG_STATUS_ABORT;
        cc_abort(NULL);
        goto errOut;
    }
    rc=CCDRBG_STATUS_OK;
errOut:
    return rc;
}
Esempio n. 3
0
static int Integrity_POST(kmod_info_t* pkmod, void* d, int verbose)
{
	int result = -1; // Set to zero for sucesses until it all works
	size_t sha256DigestBufferLength = 32;

	if (NULL == d)
	{
		if (verbose)
		{
			kprintf("The AppleTEXTHash_t pointer was NOT passed to the Integrity_POST function\n");
		}
		return result;
	}

	AppleTEXTHash_t* pHashData = (AppleTEXTHash_t*)d;
	
	if (pHashData->ath_version != 1 || pHashData->ath_length != (int)sha256DigestBufferLength)
	{
		if (verbose)
		{
			kprintf("The AppleTEXTHash_t pointer passed to Integrity_POST function, is invalid\n");
		}
		return result;
	}
	
	if (NULL == pHashData->ath_hash)
	{
		if (verbose)
		{
			kprintf("The AppleTEXTHash_t pointer passed to Integrity_POST function,has a null HASH pointer\n");
		}
		return result;
	}
	
	unsigned long plist_hash_output_buffer_size = (sha256DigestBufferLength * 2) + 1;
	unsigned char plist_hash_output_buffer[plist_hash_output_buffer_size];
	char* pPlistHexBuf = (char*)bytesToHexString(pHashData->ath_hash, pHashData->ath_length, plist_hash_output_buffer, plist_hash_output_buffer_size);
	
	if (verbose)
	{
		kprintf("Plist hmac value is    %s\n", pPlistHexBuf);
	}
	
	// Now calcuate the HMAC
    struct mach_header* pmach_header = (struct mach_header*)pkmod->address;
    
	struct load_command* pLoadCommand = NULL;

	uint32_t num_load_commands = 0;
	if (pmach_header->magic == MH_MAGIC_64)
	{
		struct mach_header_64* pmach64_header = (struct mach_header_64*)pmach_header;
		num_load_commands = pmach64_header->ncmds;		
		pLoadCommand = (struct load_command*)(((unsigned char*)pmach_header) + sizeof(struct mach_header_64));
	}
	else if (pmach_header->magic == MH_MAGIC)
	{
		num_load_commands = pmach_header->ncmds;
		pLoadCommand = (struct load_command*)(((unsigned char*)pmach_header) + sizeof(struct mach_header));
	}

	if (NULL == pLoadCommand)
	{
		if (verbose)
		{
			kprintf("pLoadCommand is NULL!\n");
		}
		return result;
	}
	
	const struct ccdigest_info* di = ccsha256_di();
    unsigned char hmac_key = 0;
    cchmac_ctx_decl(di->state_size, di->block_size, ctx);
    cchmac_init(di, ctx, 1, &hmac_key);
	int hashCreated = 0;
    unsigned long iCnt;
    unsigned long jCnt;
	
	struct segment_command* pSniffPtr = (struct segment_command*)pLoadCommand;
    
	
	// Loop through the Segments to find the __TEXT, __text segment
	for (iCnt = 0; iCnt < num_load_commands; iCnt++)
    {
        // The struct segment_command and the struct segment_command_64  have the same
        // first three fields so sniff the name by casting to a struct segment_command 

        if (strncmp("__TEXT", pSniffPtr->segname, strlen("__TEXT")))
        {
            // These are not the droids we are looking for
			// MOve the SniffPtr to the next segment;
            if (LC_SEGMENT_64 == pSniffPtr->cmd)
            {
                struct segment_command_64* pSegmentPtr = (struct segment_command_64*)pSniffPtr;
                pSniffPtr = (struct segment_command*)(((unsigned char *)pSegmentPtr) + pSegmentPtr->cmdsize);
            }
            else if (LC_SEGMENT == pSniffPtr->cmd)
            {
                pSniffPtr = (struct segment_command*)(((unsigned char *)pSniffPtr) + pSniffPtr->cmdsize);
            }
			
			// Go back to the top of the loop and look again
            continue; 
        }
        
		// Bingo! We found the __TEXT segment!
		// Deal with a 64 bit segment
        if (LC_SEGMENT_64 == pLoadCommand->cmd)
        {
            struct segment_command_64* pSegmentPtr = NULL;

            // This is a 64 bit load segment command
            pSegmentPtr = (struct segment_command_64*)pSniffPtr;
            unsigned int numSections = (unsigned int)pSegmentPtr->nsects;
            struct section_64* pSectionPtr = (struct section_64*)(((unsigned char*)pSegmentPtr) + sizeof(struct segment_command_64));
            int texttextsectionprocessed = 0;

            // Need to find the __text __TEXT section
            for (jCnt = 0; jCnt < numSections; jCnt++)
            {
                if ( !strcmp(pSectionPtr->sectname, "__text") && !strcmp(pSectionPtr->segname, "__TEXT"))
                {
                    // Found it
                    unsigned char* pSectionData = (unsigned char*)(((unsigned char*)pmach_header) + pSectionPtr->offset);

                    cchmac_update(di, ctx, (unsigned long)pSectionPtr->size, pSectionData);	
					hashCreated = 1;

                    texttextsectionprocessed = 1;
                    break;
                }
                else
                {
                    // Move to the next section record
                    pSectionPtr++;
                }
            }
            if (texttextsectionprocessed)
            {
                // The text text section was found and processed
                break;
            }
        }
		else if (LC_SEGMENT == pLoadCommand->cmd) // Deal with a 32 bit segment
		{
			struct segment_command* pSegmentPtr = NULL;

            // This is a 32 bit load segment command
            pSegmentPtr = (struct segment_command*)pLoadCommand;
            unsigned int numSections = (unsigned int)pSegmentPtr->nsects;
            struct section* pSectionPtr = (struct section*)(((unsigned char*)pSegmentPtr) + sizeof(struct segment_command));
			int texttextsectionprocessed = 0;

            // Need to find the __text __TEXT section
            for (jCnt = 0; jCnt < numSections; jCnt++)
			{
				if ( !strcmp(pSectionPtr->sectname, "__text") && !strcmp(pSectionPtr->segname, "__TEXT"))
				{
					// Found it
					unsigned char* pSectionData = (unsigned char*)(((unsigned char*)pmach_header) + pSectionPtr->offset);

					cchmac_update(di, ctx, (unsigned long)pSectionPtr->size, pSectionData);	
					hashCreated = 1;

					texttextsectionprocessed = 1;
                    break;
				}
				else
                {
                    // Move to the next section record
                    pSectionPtr++;
                }
			}
			if (texttextsectionprocessed)
			{
				// The text text section was found and processed
				// Time to bail on the loop
				break;
			}
		}
    }
	
	unsigned long hash_output_buffer_size = (sha256DigestBufferLength * 2) + 1;
	unsigned char hash_output_buffer[hash_output_buffer_size];
	unsigned char hmac_buffer[sha256DigestBufferLength];
    memset(hmac_buffer, 0, sha256DigestBufferLength);
		
	// Check to see if the hash was created 
	if (hashCreated) 
	{
		// finalize the HMAC
        
		cchmac_final(di, ctx, hmac_buffer);
	    char* pHexBuf = (char*)bytesToHexString(hmac_buffer, sha256DigestBufferLength, hash_output_buffer, hash_output_buffer_size);
		if (verbose)
		{
	    	kprintf("Computed hmac value is %s\n", pHexBuf);
		}
        
	}  
	else
	{
		if (verbose)
		{
			kprintf("Integrity_POST: WARNING! could not create the hash!\n");
		}
		return -1;
	}
	
#ifdef FORCE_FAIL
    // futz with the generated hmac
	hash_output_buffer[0] = 0;	// This will always work because it is the charter representation of the 
								// hash that is being checked.
#endif 
	result = memcmp(hash_output_buffer, plist_hash_output_buffer, hash_output_buffer_size);
	
	return result;
}