diff options
author | Kent Overstreet <kent.overstreet@gmail.com> | 2016-10-03 19:22:17 -0800 |
---|---|---|
committer | Kent Overstreet <kent.overstreet@gmail.com> | 2017-02-28 03:05:38 -0900 |
commit | a5b5eba7f788bb77cf57f9c94f3474a2d439ab0b (patch) | |
tree | 278813d1b1a9024174531376d41a2ba04a3b27f6 /linux/crypto/shash.c | |
parent | e4d1c93d85a5b86c04599bfc9f658308d741fd41 (diff) |
New on disk format - encryption
Diffstat (limited to 'linux/crypto/shash.c')
-rw-r--r-- | linux/crypto/shash.c | 252 |
1 files changed, 15 insertions, 237 deletions
diff --git a/linux/crypto/shash.c b/linux/crypto/shash.c index 406ddfe8..4f07a8b8 100644 --- a/linux/crypto/shash.c +++ b/linux/crypto/shash.c @@ -13,181 +13,25 @@ #include <crypto/internal/hash.h> #include <linux/err.h> #include <linux/kernel.h> -#include <linux/module.h> #include <linux/printk.h> #include <linux/slab.h> #include "internal.h" -static int shash_no_setkey(struct crypto_shash *tfm, const u8 *key, - unsigned int keylen) -{ - return -ENOSYS; -} - -static int shash_setkey_unaligned(struct crypto_shash *tfm, const u8 *key, - unsigned int keylen) -{ - struct shash_alg *shash = crypto_shash_alg(tfm); - unsigned long alignmask = crypto_shash_alignmask(tfm); - unsigned long absize; - u8 *buffer, *alignbuffer; - int err; - - absize = keylen + (alignmask & ~(crypto_tfm_ctx_alignment() - 1)); - buffer = kmalloc(absize, GFP_KERNEL); - if (!buffer) - return -ENOMEM; - - alignbuffer = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); - memcpy(alignbuffer, key, keylen); - err = shash->setkey(tfm, alignbuffer, keylen); - kzfree(buffer); - return err; -} - -int crypto_shash_setkey(struct crypto_shash *tfm, const u8 *key, - unsigned int keylen) -{ - struct shash_alg *shash = crypto_shash_alg(tfm); - unsigned long alignmask = crypto_shash_alignmask(tfm); - - if ((unsigned long)key & alignmask) - return shash_setkey_unaligned(tfm, key, keylen); - - return shash->setkey(tfm, key, keylen); -} - -static inline unsigned int shash_align_buffer_size(unsigned len, - unsigned long mask) -{ - typedef u8 __attribute__ ((aligned)) u8_aligned; - return len + (mask & ~(__alignof__(u8_aligned) - 1)); -} - -static int shash_update_unaligned(struct shash_desc *desc, const u8 *data, - unsigned int len) -{ - struct crypto_shash *tfm = desc->tfm; - struct shash_alg *shash = crypto_shash_alg(tfm); - unsigned long alignmask = crypto_shash_alignmask(tfm); - unsigned int unaligned_len = alignmask + 1 - - ((unsigned long)data & alignmask); - u8 ubuf[shash_align_buffer_size(unaligned_len, alignmask)] - __attribute__ ((aligned)); - u8 *buf = PTR_ALIGN(&ubuf[0], alignmask + 1); - int err; - - if (unaligned_len > len) - unaligned_len = len; - - memcpy(buf, data, unaligned_len); - err = shash->update(desc, buf, unaligned_len); - memset(buf, 0, unaligned_len); - - return err ?: - shash->update(desc, data + unaligned_len, len - unaligned_len); -} - -int crypto_shash_update(struct shash_desc *desc, const u8 *data, - unsigned int len) -{ - struct crypto_shash *tfm = desc->tfm; - struct shash_alg *shash = crypto_shash_alg(tfm); - unsigned long alignmask = crypto_shash_alignmask(tfm); - - if ((unsigned long)data & alignmask) - return shash_update_unaligned(desc, data, len); - - return shash->update(desc, data, len); -} - -static int shash_final_unaligned(struct shash_desc *desc, u8 *out) -{ - struct crypto_shash *tfm = desc->tfm; - unsigned long alignmask = crypto_shash_alignmask(tfm); - struct shash_alg *shash = crypto_shash_alg(tfm); - unsigned int ds = crypto_shash_digestsize(tfm); - u8 ubuf[shash_align_buffer_size(ds, alignmask)] - __attribute__ ((aligned)); - u8 *buf = PTR_ALIGN(&ubuf[0], alignmask + 1); - int err; - - err = shash->final(desc, buf); - if (err) - goto out; - - memcpy(out, buf, ds); - -out: - memset(buf, 0, ds); - return err; -} - -int crypto_shash_final(struct shash_desc *desc, u8 *out) -{ - struct crypto_shash *tfm = desc->tfm; - struct shash_alg *shash = crypto_shash_alg(tfm); - unsigned long alignmask = crypto_shash_alignmask(tfm); - - if ((unsigned long)out & alignmask) - return shash_final_unaligned(desc, out); - - return shash->final(desc, out); -} - -static int shash_finup_unaligned(struct shash_desc *desc, const u8 *data, - unsigned int len, u8 *out) +static int shash_finup(struct shash_desc *desc, const u8 *data, + unsigned len, u8 *out) { return crypto_shash_update(desc, data, len) ?: crypto_shash_final(desc, out); } -int crypto_shash_finup(struct shash_desc *desc, const u8 *data, - unsigned int len, u8 *out) -{ - struct crypto_shash *tfm = desc->tfm; - struct shash_alg *shash = crypto_shash_alg(tfm); - unsigned long alignmask = crypto_shash_alignmask(tfm); - - if (((unsigned long)data | (unsigned long)out) & alignmask) - return shash_finup_unaligned(desc, data, len, out); - - return shash->finup(desc, data, len, out); -} - -static int shash_digest_unaligned(struct shash_desc *desc, const u8 *data, - unsigned int len, u8 *out) +static int shash_digest(struct shash_desc *desc, const u8 *data, + unsigned len, u8 *out) { return crypto_shash_init(desc) ?: crypto_shash_finup(desc, data, len, out); } -int crypto_shash_digest(struct shash_desc *desc, const u8 *data, - unsigned int len, u8 *out) -{ - struct crypto_shash *tfm = desc->tfm; - struct shash_alg *shash = crypto_shash_alg(tfm); - unsigned long alignmask = crypto_shash_alignmask(tfm); - - if (((unsigned long)data | (unsigned long)out) & alignmask) - return shash_digest_unaligned(desc, data, len, out); - - return shash->digest(desc, data, len, out); -} - -static int shash_default_export(struct shash_desc *desc, void *out) -{ - memcpy(out, shash_desc_ctx(desc), crypto_shash_descsize(desc->tfm)); - return 0; -} - -static int shash_default_import(struct shash_desc *desc, const void *in) -{ - memcpy(shash_desc_ctx(desc), in, crypto_shash_descsize(desc->tfm)); - return 0; -} - static int crypto_shash_init_tfm(struct crypto_tfm *tfm) { struct crypto_shash *hash = __crypto_shash_cast(tfm); @@ -197,98 +41,32 @@ static int crypto_shash_init_tfm(struct crypto_tfm *tfm) } static const struct crypto_type crypto_shash_type = { - .extsize = crypto_alg_extsize, - .init_tfm = crypto_shash_init_tfm, - .maskclear = ~CRYPTO_ALG_TYPE_MASK, - .maskset = CRYPTO_ALG_TYPE_MASK, - .type = CRYPTO_ALG_TYPE_SHASH, - .tfmsize = offsetof(struct crypto_shash, base), + .extsize = crypto_alg_extsize, + .init_tfm = crypto_shash_init_tfm, + .maskclear = ~CRYPTO_ALG_TYPE_MASK, + .maskset = CRYPTO_ALG_TYPE_MASK, + .type = CRYPTO_ALG_TYPE_SHASH, + .tfmsize = offsetof(struct crypto_shash, base), }; -struct crypto_shash *crypto_alloc_shash(const char *alg_name, u32 type, - u32 mask) +struct crypto_shash *crypto_alloc_shash(const char *alg_name, + u32 type, u32 mask) { return crypto_alloc_tfm(alg_name, &crypto_shash_type, type, mask); } -static int shash_prepare_alg(struct shash_alg *alg) +int crypto_register_shash(struct shash_alg *alg) { struct crypto_alg *base = &alg->base; - if (alg->digestsize > PAGE_SIZE / 8 || - alg->descsize > PAGE_SIZE / 8 || - alg->statesize > PAGE_SIZE / 8) - return -EINVAL; - base->cra_type = &crypto_shash_type; base->cra_flags &= ~CRYPTO_ALG_TYPE_MASK; base->cra_flags |= CRYPTO_ALG_TYPE_SHASH; if (!alg->finup) - alg->finup = shash_finup_unaligned; + alg->finup = shash_finup; if (!alg->digest) - alg->digest = shash_digest_unaligned; - if (!alg->export) { - alg->export = shash_default_export; - alg->import = shash_default_import; - alg->statesize = alg->descsize; - } - if (!alg->setkey) - alg->setkey = shash_no_setkey; - - return 0; -} - -int crypto_register_shash(struct shash_alg *alg) -{ - struct crypto_alg *base = &alg->base; - int err; - - err = shash_prepare_alg(alg); - if (err) - return err; + alg->digest = shash_digest; return crypto_register_alg(base); } - -int crypto_unregister_shash(struct shash_alg *alg) -{ - return crypto_unregister_alg(&alg->base); -} - -int crypto_register_shashes(struct shash_alg *algs, int count) -{ - int i, ret; - - for (i = 0; i < count; i++) { - ret = crypto_register_shash(&algs[i]); - if (ret) - goto err; - } - - return 0; - -err: - for (--i; i >= 0; --i) - crypto_unregister_shash(&algs[i]); - - return ret; -} - -int crypto_unregister_shashes(struct shash_alg *algs, int count) -{ - int i, ret; - - for (i = count - 1; i >= 0; --i) { - ret = crypto_unregister_shash(&algs[i]); - if (ret) - pr_err("Failed to unregister %s %s: %d\n", - algs[i].base.cra_driver_name, - algs[i].base.cra_name, ret); - } - - return 0; -} - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Synchronous cryptographic hash type"); |