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; }
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); } */ }