Ejemplo n.º 1
0
void do_integrity_check(void)
{
	u8 *rbuf = (u8 *) ZIMAGE_ADDR;
	u32 len;
	u8 hmac[SHA256_DIGEST_SIZE];
	struct hash_desc desc;
	struct scatterlist sg;
	u8 *key = "12345678";

	printk(KERN_INFO "FIPS: do kernel integrity check\n");

	if (unlikely(!need_integrity_check || in_fips_err()))
		return;

	if (*((u32 *) &rbuf[36]) != 0x016F2818) {
		printk(KERN_ERR "FIPS: invalid zImage magic number.");
		set_in_fips_err();
		goto err1;
	}

	if (*(u32 *) &rbuf[44] <= *(u32 *) &rbuf[40]) {
		printk(KERN_ERR "FIPS: invalid zImage calculated len");
		set_in_fips_err();
		goto err1;
	}

	len = *(u32 *) &rbuf[44] - *(u32 *) &rbuf[40];

	desc.tfm = crypto_alloc_hash("hmac(sha256)", 0, 0);

	if (IS_ERR(desc.tfm)) {
		printk(KERN_ERR "FIPS: integ failed to allocate tfm %ld\n",
		       PTR_ERR(desc.tfm));
		set_in_fips_err();
		goto err;
	}

	sg_init_one(&sg, rbuf, len);
	crypto_hash_setkey(desc.tfm, key, strlen(key));
	crypto_hash_digest(&desc, &sg, len, hmac);

	if (!strncmp(hmac, &rbuf[len], SHA256_DIGEST_SIZE)) {
		printk(KERN_INFO "FIPS: integrity check passed\n");
	} else {
		printk(KERN_ERR "FIPS: integrity check failed\n");
		set_in_fips_err();
	}

 err:
	crypto_free_hash(desc.tfm);
 err1:
	need_integrity_check = false;

	return;
}
void do_integrity_check(void) {
	u8* rbuf=__va(ZIMAGE_START);
	u32 len;
	u8 hmac[SHA256_DIGEST_SIZE];
	struct hash_desc desc;
	struct scatterlist sg;
	u8* key="12345678";

	printk(KERN_INFO "do kernel integrity check\n");

	if (integrity_checked || in_fips_err()) return;

	if ( *((u32*) &rbuf[36]) != 0x016F2818) {
		printk(KERN_ERR "integ: invalid zImage magic number.");
		set_in_fips_err();
		goto err;
	}

	len = *(u32*)&rbuf[44] - *(u32*)&rbuf[40];

	if (len < 0) {
                printk(KERN_ERR "integ: invalid zImage calculated len");
                set_in_fips_err();
                goto err;
	}

	desc.tfm = crypto_alloc_hash("hmac(sha256)",0,0);

	if (IS_ERR(desc.tfm)) {
		printk(KERN_ERR "integ: failed to allocate tfm %ld\n",PTR_ERR(desc.tfm));
		set_in_fips_err();
		goto err;	
	}

	sg_init_one(&sg, rbuf, len);
	crypto_hash_setkey(desc.tfm,key,strlen(key));
	crypto_hash_digest(&desc,&sg,len,hmac);	

	if (!strncmp(hmac,&rbuf[len],SHA256_DIGEST_SIZE)) {
		printk(KERN_INFO "integrity check passed");
	} else {
		printk(KERN_ERR "integrity check failed");
		set_in_fips_err();
	}

err:
	integrity_checked=true;
	crypto_free_hash(desc.tfm);

	return;
}
Ejemplo n.º 3
0
int
do_integrity_check (void)
{
	int i,rows, err;
	unsigned long start_addr = 0;
	unsigned long end_addr   = 0;
	unsigned char runtime_hmac[32];
	struct hash_desc desc;
	const char * builtime_hmac = 0;
	unsigned int size = 0;

	err = init_hash (&desc);

	if (err)
	{
		printk (KERN_ERR "FIPS(%s): init_hash failed", __FUNCTION__);
		return -1;
	}

	rows = (unsigned int) sizeof (symtab) / sizeof (symtab[0]);

	for (i = 0; i < rows; i++)
	{
		err = query_symbol_addresses (symtab[i][1], symtab[i][2], &start_addr, &end_addr);

		if (err)
		{
			printk (KERN_ERR "FIPS(%s): Error to get start / end addresses", __FUNCTION__);
			crypto_free_hash (desc.tfm);
			return -1;
		}

#ifdef FIPS_DEBUG
		dump_bytes(symtab[i][0],  symtab[i][1], symtab[i][2]);
#endif

		size = end_addr - start_addr;

		err = update_hash (&desc, (unsigned char *)start_addr, size);	

		if (err)
		{
			printk (KERN_ERR "FIPS(%s): Error to update hash", __FUNCTION__);
			crypto_free_hash (desc.tfm);
			return -1;
		}
	}

	err = finalize_hash (&desc, runtime_hmac, sizeof(runtime_hmac));

	crypto_free_hash (desc.tfm);

	if (err)
	{
		printk (KERN_ERR "FIPS(%s): Error in finalize", __FUNCTION__);
		return -1;
	}


	builtime_hmac =  get_builtime_crypto_hmac();

	if (!builtime_hmac)
	{
		printk (KERN_ERR "FIPS(%s): Unable to retrieve builtime_hmac", __FUNCTION__);
		return -1;
	}

#ifdef FIPS_DEBUG
	print_hex_dump_bytes ("FIPS CRYPTO RUNTIME : runtime hmac  = ",DUMP_PREFIX_NONE, runtime_hmac, sizeof(runtime_hmac));
	print_hex_dump_bytes ("FIPS CRYPTO RUNTIME : builtime_hmac = ",DUMP_PREFIX_NONE, builtime_hmac , sizeof(runtime_hmac));
#endif

	if (!memcmp (builtime_hmac, runtime_hmac, sizeof(runtime_hmac))) 
	{
		printk (KERN_INFO "FIPS: Integrity Check Passed");
		return 0;
	}
	else
	{
		printk (KERN_ERR "FIPS(%s): Integrity Check Failed", __FUNCTION__);
		set_in_fips_err();
		return -1;
	}

	return -1;
}
/*
 * Returns DEFAULT_BLK_SZ bytes of random data per call
 * returns 0 if generation succeded, <0 if something went wrong
 */
static int _get_more_prng_bytes(struct prng_context *ctx, int cont_test)
{
	int i;
	unsigned char tmp[DEFAULT_BLK_SZ];
	unsigned char *output = NULL;


	dbgprint(KERN_CRIT "Calling _get_more_prng_bytes for context %p\n",
		ctx);

	hexdump("Input DT: ", ctx->DT, DEFAULT_BLK_SZ);
	hexdump("Input I: ", ctx->I, DEFAULT_BLK_SZ);
	hexdump("Input V: ", ctx->V, DEFAULT_BLK_SZ);

	/*
	 * This algorithm is a 3 stage state machine
	 */
	for (i = 0; i < 3; i++) {

		switch (i) {
		case 0:
			/*
			 * Start by encrypting the counter value
			 * This gives us an intermediate value I
			 */
			memcpy(tmp, ctx->DT, DEFAULT_BLK_SZ);
			output = ctx->I;
			hexdump("tmp stage 0: ", tmp, DEFAULT_BLK_SZ);
			break;
		case 1:

			/*
			 * Next xor I with our secret vector V
			 * encrypt that result to obtain our
			 * pseudo random data which we output
			 */
			xor_vectors(ctx->I, ctx->V, tmp, DEFAULT_BLK_SZ);
			hexdump("tmp stage 1: ", tmp, DEFAULT_BLK_SZ);
			output = ctx->rand_data;
			break;
		case 2:
// [email protected] - disable kernel panic in FIPS mode - starts
			if(in_fips_err()) {
				return -EINVAL;
			}
// [email protected] - disable kernel panic in FIPS mode - ends			
			/*
			 * First check that we didn't produce the same
			 * random data that we did last time around through this
			 */
			if (!memcmp(ctx->rand_data, ctx->last_rand_data,
					DEFAULT_BLK_SZ)) {
				if (cont_test) {
// [email protected] - disable kernel panic in FIPS mode - starts
					set_in_fips_err();
// [email protected] - disable kernel panic in FIPS mode - ends
				}

				printk(KERN_ERR
					"ctx %p Failed repetition check!\n",
					ctx);

				ctx->flags |= PRNG_NEED_RESET;
				return -EINVAL;
			}
			memcpy(ctx->last_rand_data, ctx->rand_data,
				DEFAULT_BLK_SZ);

			/*
			 * Lastly xor the random data with I
			 * and encrypt that to obtain a new secret vector V
			 */
			xor_vectors(ctx->rand_data, ctx->I, tmp,
				DEFAULT_BLK_SZ);
			output = ctx->V;
			hexdump("tmp stage 2: ", tmp, DEFAULT_BLK_SZ);
			break;
		}


		/* do the encryption */
		crypto_cipher_encrypt_one(ctx->tfm, output, tmp);

	}

	/*
	 * Now update our DT value
	 */
	for (i = DEFAULT_BLK_SZ - 1; i >= 0; i--) {
		ctx->DT[i] += 1;
		if (ctx->DT[i] != 0)
			break;
	}

	dbgprint("Returning new block for context %p\n", ctx);
	ctx->rand_data_valid = 0;

	hexdump("Output DT: ", ctx->DT, DEFAULT_BLK_SZ);
	hexdump("Output I: ", ctx->I, DEFAULT_BLK_SZ);
	hexdump("Output V: ", ctx->V, DEFAULT_BLK_SZ);
	hexdump("New Random Data: ", ctx->rand_data, DEFAULT_BLK_SZ);

	return 0;
}
void do_integrity_check(void)
{
	u8 *rbuf = 0;
	u32 len;
	u8 hmac[SHA256_DIGEST_SIZE];
	struct hash_desc desc;
	struct scatterlist sg;
	u8 *key = "12345678";
    int i, step_len = PAGE_SIZE, err;
    u8 *pAllocBuf = 0;

    printk(KERN_INFO "FIPS: integrity start\n");

	if (unlikely(!need_integrity_check || in_fips_err())) {
        printk(KERN_INFO "FIPS: integrity check not needed\n");
		return;
	}
	rbuf = (u8*)phys_to_virt((unsigned long)CONFIG_CRYPTO_FIPS_INTEG_COPY_ADDRESS);

	if (*((u32 *) &rbuf[36]) != 0x016F2818) {
		printk(KERN_ERR "FIPS: invalid zImage magic number.");
		set_in_fips_err();
		goto err1;
	}

	if (*(u32 *) &rbuf[44] <= *(u32 *) &rbuf[40]) {
		printk(KERN_ERR "FIPS: invalid zImage calculated len");
		set_in_fips_err();
		goto err1;
	}

	len = *(u32 *) &rbuf[44] - *(u32 *) &rbuf[40];

    printk(KERN_INFO "FIPS: integrity actual zImageLen = %d\n", len);
    printk(KERN_INFO "FIPS: do kernel integrity check address: %lx \n", (unsigned long)rbuf);

	desc.tfm = crypto_alloc_hash("hmac(sha256)", 0, 0);

	if (IS_ERR(desc.tfm)) {
		printk(KERN_ERR "FIPS: integ failed to allocate tfm %ld\n",
		       PTR_ERR(desc.tfm));
		set_in_fips_err();
		goto err1;
	}
#if FIPS_FUNC_TEST == 2
    rbuf[1024] = rbuf[1024] + 1;
#endif
	crypto_hash_setkey(desc.tfm, key, strlen(key));

	pAllocBuf = kmalloc(step_len,GFP_KERNEL);
	if (!pAllocBuf) {
		printk(KERN_INFO "Fail to alloc memory, length %d\n", step_len);
		set_in_fips_err();
		goto err1;
	}

	err = crypto_hash_init(&desc);
	if (err) {
		printk(KERN_INFO "fail at crypto_hash_init\n");
        set_in_fips_err();
		kfree(pAllocBuf);
		goto err1;
	}

	for (i = 0; i < len; i += step_len) 	{

		//last is reached
		if (i + step_len >= len - 1)  {
			memcpy(pAllocBuf, &rbuf[i], len - i);
			sg_init_one(&sg, pAllocBuf, len - i);
			err = crypto_hash_update(&desc, &sg, len - i);
			if (err) {
				printk(KERN_INFO "Fail to crypto_hash_update1\n");
                set_in_fips_err();
				goto err;
			}
			err = crypto_hash_final(&desc, hmac);
			if (err) {
				printk(KERN_INFO "Fail to crypto_hash_final\n");
                set_in_fips_err();
				goto err;
			}
		} else {
		    memcpy(pAllocBuf, &rbuf[i], step_len);
		    sg_init_one(&sg, pAllocBuf, step_len);
		    err = crypto_hash_update(&desc, &sg, step_len);

		    if (err) {
			    printk(KERN_INFO "Fail to crypto_hash_update\n");
                set_in_fips_err();
			    goto err;
		    }
        }
	}
#if FIPS_FUNC_TEST == 2
    rbuf[1024] = rbuf[1024] - 1;
#endif
	if (!strncmp(hmac, &rbuf[len], SHA256_DIGEST_SIZE)) {
		printk(KERN_INFO "FIPS: integrity check passed\n");
	} else {
		printk(KERN_ERR "FIPS: integrity check failed. hmac:%lx, buf:%lx.\n",(long) hmac, (long)rbuf[len] );
		set_in_fips_err();
	}

 err:
	kfree(pAllocBuf);
	crypto_free_hash(desc.tfm);
 err1:
	need_integrity_check = false;

/*	if(integrity_mem_reservoir != 0) {
		printk(KERN_NOTICE "FIPS free integrity_mem_reservoir = %ld\n", integrity_mem_reservoir);
		free_bootmem((unsigned long)CONFIG_CRYPTO_FIPS_INTEG_COPY_ADDRESS, integrity_mem_reservoir);
	}
*/
}