diff options
author | codeworkx <daniel.hillenbrand@codeworkx.de> | 2012-06-02 13:09:29 +0200 |
---|---|---|
committer | codeworkx <daniel.hillenbrand@codeworkx.de> | 2012-06-02 13:09:29 +0200 |
commit | c6da2cfeb05178a11c6d062a06f8078150ee492f (patch) | |
tree | f3b4021d252c52d6463a9b3c1bb7245e399b009c /crypto/fips_integrity.c | |
parent | c6d7c4dbff353eac7919342ae6b3299a378160a6 (diff) | |
download | kernel_samsung_smdk4412-c6da2cfeb05178a11c6d062a06f8078150ee492f.zip kernel_samsung_smdk4412-c6da2cfeb05178a11c6d062a06f8078150ee492f.tar.gz kernel_samsung_smdk4412-c6da2cfeb05178a11c6d062a06f8078150ee492f.tar.bz2 |
samsung update 1
Diffstat (limited to 'crypto/fips_integrity.c')
-rw-r--r-- | crypto/fips_integrity.c | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/crypto/fips_integrity.c b/crypto/fips_integrity.c new file mode 100644 index 0000000..2a51f92 --- /dev/null +++ b/crypto/fips_integrity.c @@ -0,0 +1,76 @@ +/* + * Integrity check code for crypto module. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + */ +#include <crypto/hash.h> +#include <crypto/sha.h> +#include <linux/err.h> +#include <linux/scatterlist.h> +#include <asm-generic/sections.h> + +#include "internal.h" + +#define ZIMAGE_ADDR (_stext + CONFIG_CRYPTO_FIPS_INTEG_OFFSET) + +static bool need_integrity_check = true; + +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; +} |