cregit-Linux how code gets into the kernel

Release 4.8 crypto/shash.c

Directory: crypto
/*
 * Synchronous Cryptographic Hash operations.
 *
 * Copyright (c) 2008 Herbert Xu <herbert@gondor.apana.org.au>
 *
 * 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/scatterwalk.h>
#include <crypto/internal/hash.h>
#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/seq_file.h>
#include <linux/cryptouser.h>
#include <net/netlink.h>

#include "internal.h"


static const struct crypto_type crypto_shash_type;


static int shash_no_setkey(struct crypto_shash *tfm, const u8 *key, unsigned int keylen) { return -ENOSYS; }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu24100.00%1100.00%
Total24100.00%1100.00%


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; }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu136100.00%3100.00%
Total136100.00%3100.00%


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

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu70100.00%1100.00%
Total70100.00%1100.00%

EXPORT_SYMBOL_GPL(crypto_shash_setkey);
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)); }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu3173.81%150.00%
mark charleboismark charlebois1126.19%150.00%
Total42100.00%2100.00%


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

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu15393.87%375.00%
yehuda sadehyehuda sadeh106.13%125.00%
Total163100.00%4100.00%


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

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu79100.00%1100.00%
Total79100.00%1100.00%

EXPORT_SYMBOL_GPL(crypto_shash_update);
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; }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu130100.00%3100.00%
Total130100.00%3100.00%


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

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu70100.00%1100.00%
Total70100.00%1100.00%

EXPORT_SYMBOL_GPL(crypto_shash_final);
static int shash_finup_unaligned(struct shash_desc *desc, const u8 *data, unsigned int len, u8 *out) { return crypto_shash_update(desc, data, len) ?: crypto_shash_final(desc, out); }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu42100.00%1100.00%
Total42100.00%1100.00%


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

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu95100.00%1100.00%
Total95100.00%1100.00%

EXPORT_SYMBOL_GPL(crypto_shash_finup);
static int shash_digest_unaligned(struct shash_desc *desc, const u8 *data, unsigned int len, u8 *out) { return crypto_shash_init(desc) ?: crypto_shash_finup(desc, data, len, out); }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu42100.00%2100.00%
Total42100.00%2100.00%


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

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu95100.00%1100.00%
Total95100.00%1100.00%

EXPORT_SYMBOL_GPL(crypto_shash_digest);
static int shash_default_export(struct shash_desc *desc, void *out) { memcpy(out, shash_desc_ctx(desc), crypto_shash_descsize(desc->tfm)); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu35100.00%3100.00%
Total35100.00%3100.00%


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; }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu36100.00%3100.00%
Total36100.00%3100.00%


static int shash_async_setkey(struct crypto_ahash *tfm, const u8 *key, unsigned int keylen) { struct crypto_shash **ctx = crypto_ahash_ctx(tfm); return crypto_shash_setkey(*ctx, key, keylen); }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu42100.00%2100.00%
Total42100.00%2100.00%


static int shash_async_init(struct ahash_request *req) { struct crypto_shash **ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req)); struct shash_desc *desc = ahash_request_ctx(req); desc->tfm = *ctx; desc->flags = req->base.flags; return crypto_shash_init(desc); }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu58100.00%2100.00%
Total58100.00%2100.00%


int shash_ahash_update(struct ahash_request *req, struct shash_desc *desc) { struct crypto_hash_walk walk; int nbytes; for (nbytes = crypto_hash_walk_first(req, &walk); nbytes > 0; nbytes = crypto_hash_walk_done(&walk, nbytes)) nbytes = crypto_shash_update(desc, walk.data, nbytes); return nbytes; }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu64100.00%3100.00%
Total64100.00%3100.00%

EXPORT_SYMBOL_GPL(shash_ahash_update);
static int shash_async_update(struct ahash_request *req) { return shash_ahash_update(req, ahash_request_ctx(req)); }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu22100.00%1100.00%
Total22100.00%1100.00%


static int shash_async_final(struct ahash_request *req) { return crypto_shash_final(ahash_request_ctx(req), req->result); }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu24100.00%2100.00%
Total24100.00%2100.00%


int shash_ahash_finup(struct ahash_request *req, struct shash_desc *desc) { struct crypto_hash_walk walk; int nbytes; nbytes = crypto_hash_walk_first(req, &walk); if (!nbytes) return crypto_shash_final(desc, req->result); do { nbytes = crypto_hash_walk_last(&walk) ? crypto_shash_finup(desc, walk.data, nbytes, req->result) : crypto_shash_update(desc, walk.data, nbytes); nbytes = crypto_hash_walk_done(&walk, nbytes); } while (nbytes > 0); return nbytes; }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu104100.00%2100.00%
Total104100.00%2100.00%

EXPORT_SYMBOL_GPL(shash_ahash_finup);
static int shash_async_finup(struct ahash_request *req) { struct crypto_shash **ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req)); struct shash_desc *desc = ahash_request_ctx(req); desc->tfm = *ctx; desc->flags = req->base.flags; return shash_ahash_finup(req, desc); }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu60100.00%1100.00%
Total60100.00%1100.00%


int shash_ahash_digest(struct ahash_request *req, struct shash_desc *desc) { struct scatterlist *sg = req->src; unsigned int offset = sg->offset; unsigned int nbytes = req->nbytes; int err; if (nbytes < min(sg->length, ((unsigned int)(PAGE_SIZE)) - offset)) { void *data; data = kmap_atomic(sg_page(sg)); err = crypto_shash_digest(desc, data + offset, nbytes, req->result); kunmap_atomic(data); crypto_yield(desc->flags); } else err = crypto_shash_init(desc) ?: shash_ahash_finup(req, desc); return err; }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu12898.46%480.00%
americo wangamerico wang21.54%120.00%
Total130100.00%5100.00%

EXPORT_SYMBOL_GPL(shash_ahash_digest);
static int shash_async_digest(struct ahash_request *req) { struct crypto_shash **ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req)); struct shash_desc *desc = ahash_request_ctx(req); desc->tfm = *ctx; desc->flags = req->base.flags; return shash_ahash_digest(req, desc); }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu60100.00%2100.00%
Total60100.00%2100.00%


static int shash_async_export(struct ahash_request *req, void *out) { return crypto_shash_export(ahash_request_ctx(req), out); }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu26100.00%1100.00%
Total26100.00%1100.00%


static int shash_async_import(struct ahash_request *req, const void *in) { struct crypto_shash **ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req)); struct shash_desc *desc = ahash_request_ctx(req); desc->tfm = *ctx; desc->flags = req->base.flags; return crypto_shash_import(desc, in); }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu65100.00%2100.00%
Total65100.00%2100.00%


static void crypto_exit_shash_ops_async(struct crypto_tfm *tfm) { struct crypto_shash **ctx = crypto_tfm_ctx(tfm); crypto_free_shash(*ctx); }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu28100.00%1100.00%
Total28100.00%1100.00%


int crypto_init_shash_ops_async(struct crypto_tfm *tfm) { struct crypto_alg *calg = tfm->__crt_alg; struct shash_alg *alg = __crypto_shash_alg(calg); struct crypto_ahash *crt = __crypto_ahash_cast(tfm); struct crypto_shash **ctx = crypto_tfm_ctx(tfm); struct crypto_shash *shash; if (!crypto_mod_get(calg)) return -EAGAIN; shash = crypto_create_tfm(calg, &crypto_shash_type); if (IS_ERR(shash)) { crypto_mod_put(calg); return PTR_ERR(shash); } *ctx = shash; tfm->exit = crypto_exit_shash_ops_async; crt->init = shash_async_init; crt->update = shash_async_update; crt->final = shash_async_final; crt->finup = shash_async_finup; crt->digest = shash_async_digest; crt->setkey = shash_async_setkey; crt->has_setkey = alg->setkey != shash_no_setkey; if (alg->export) crt->export = shash_async_export; if (alg->import) crt->import = shash_async_import; crt->reqsize = sizeof(struct shash_desc) + crypto_shash_descsize(shash); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu19599.49%583.33%
steffen klassertsteffen klassert10.51%116.67%
Total196100.00%6100.00%


static int crypto_shash_init_tfm(struct crypto_tfm *tfm) { struct crypto_shash *hash = __crypto_shash_cast(tfm); hash->descsize = crypto_shash_alg(hash)->descsize; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu35100.00%2100.00%
Total35100.00%2100.00%

#ifdef CONFIG_NET
static int crypto_shash_report(struct sk_buff *skb, struct crypto_alg *alg) { struct crypto_report_hash rhash; struct shash_alg *salg = __crypto_shash_alg(alg); strncpy(rhash.type, "shash", sizeof(rhash.type)); rhash.blocksize = alg->cra_blocksize; rhash.digestsize = salg->digestsize; if (nla_put(skb, CRYPTOCFGA_REPORT_HASH, sizeof(struct crypto_report_hash), &rhash)) goto nla_put_failure; return 0; nla_put_failure: return -EMSGSIZE; }

Contributors

PersonTokensPropCommitsCommitProp
steffen klassertsteffen klassert7783.70%133.33%
mathias krausemathias krause88.70%133.33%
david s. millerdavid s. miller77.61%133.33%
Total92100.00%3100.00%

#else
static int crypto_shash_report(struct sk_buff *skb, struct crypto_alg *alg) { return -ENOSYS; }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu20100.00%1100.00%
Total20100.00%1100.00%

#endif static void crypto_shash_show(struct seq_file *m, struct crypto_alg *alg) __attribute__ ((unused));
static void crypto_shash_show(struct seq_file *m, struct crypto_alg *alg) { struct shash_alg *salg = __crypto_shash_alg(alg); seq_printf(m, "type : shash\n"); seq_printf(m, "blocksize : %u\n", alg->cra_blocksize); seq_printf(m, "digestsize : %u\n", salg->digestsize); }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu55100.00%1100.00%
Total55100.00%1100.00%

static const struct crypto_type crypto_shash_type = { .extsize = crypto_alg_extsize, .init_tfm = crypto_shash_init_tfm, #ifdef CONFIG_PROC_FS .show = crypto_shash_show, #endif .report = crypto_shash_report, .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) { return crypto_alloc_tfm(alg_name, &crypto_shash_type, type, mask); }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu31100.00%1100.00%
Total31100.00%1100.00%

EXPORT_SYMBOL_GPL(crypto_alloc_shash);
static int shash_prepare_alg(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; 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; }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu142100.00%6100.00%
Total142100.00%6100.00%


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; return crypto_register_alg(base); }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu43100.00%2100.00%
Total43100.00%2100.00%

EXPORT_SYMBOL_GPL(crypto_register_shash);
int crypto_unregister_shash(struct shash_alg *alg) { return crypto_unregister_alg(&alg->base); }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu19100.00%1100.00%
Total19100.00%1100.00%

EXPORT_SYMBOL_GPL(crypto_unregister_shash);
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; }

Contributors

PersonTokensPropCommitsCommitProp
jussi kivilinnajussi kivilinna80100.00%1100.00%
Total80100.00%1100.00%

EXPORT_SYMBOL_GPL(crypto_register_shashes);
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; }

Contributors

PersonTokensPropCommitsCommitProp
jussi kivilinnajussi kivilinna78100.00%1100.00%
Total78100.00%1100.00%

EXPORT_SYMBOL_GPL(crypto_unregister_shashes);
int shash_register_instance(struct crypto_template *tmpl, struct shash_instance *inst) { int err; err = shash_prepare_alg(&inst->alg); if (err) return err; return crypto_register_instance(tmpl, shash_crypto_instance(inst)); }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu46100.00%1100.00%
Total46100.00%1100.00%

EXPORT_SYMBOL_GPL(shash_register_instance);
void shash_free_instance(struct crypto_instance *inst) { crypto_drop_spawn(crypto_instance_ctx(inst)); kfree(shash_instance(inst)); }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu26100.00%1100.00%
Total26100.00%1100.00%

EXPORT_SYMBOL_GPL(shash_free_instance);
int crypto_init_shash_spawn(struct crypto_shash_spawn *spawn, struct shash_alg *alg, struct crypto_instance *inst) { return crypto_init_spawn2(&spawn->base, &alg->base, inst, &crypto_shash_type); }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu39100.00%1100.00%
Total39100.00%1100.00%

EXPORT_SYMBOL_GPL(crypto_init_shash_spawn);
struct shash_alg *shash_attr_alg(struct rtattr *rta, u32 type, u32 mask) { struct crypto_alg *alg; alg = crypto_attr_alg2(rta, &crypto_shash_type, type, mask); return IS_ERR(alg) ? ERR_CAST(alg) : container_of(alg, struct shash_alg, base); }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu58100.00%1100.00%
Total58100.00%1100.00%

EXPORT_SYMBOL_GPL(shash_attr_alg); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Synchronous cryptographic hash type");

Overall Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu262589.90%2676.47%
jussi kivilinnajussi kivilinna1685.75%12.94%
steffen klassertsteffen klassert893.05%25.88%
mark charleboismark charlebois110.38%1