cregit-Linux how code gets into the kernel

Release 4.9 crypto/skcipher.c

Directory: crypto
/*
 * Symmetric key cipher operations.
 *
 * Generic encrypt/decrypt wrapper for ciphers, handles operations across
 * multiple page boundaries by using temporary blocks.  In user context,
 * the kernel is given a chance to schedule us once per page.
 *
 * Copyright (c) 2015 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/internal/skcipher.h>
#include <linux/bug.h>
#include <linux/cryptouser.h>
#include <linux/module.h>
#include <linux/rtnetlink.h>
#include <linux/seq_file.h>
#include <net/netlink.h>

#include "internal.h"


static unsigned int crypto_skcipher_extsize(struct crypto_alg *alg) { if (alg->cra_type == &crypto_blkcipher_type) return sizeof(struct crypto_blkcipher *); if (alg->cra_type == &crypto_ablkcipher_type || alg->cra_type == &crypto_givcipher_type) return sizeof(struct crypto_ablkcipher *); return crypto_alg_extsize(alg); }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu59100.00%2100.00%
Total59100.00%2100.00%


static int skcipher_setkey_blkcipher(struct crypto_skcipher *tfm, const u8 *key, unsigned int keylen) { struct crypto_blkcipher **ctx = crypto_skcipher_ctx(tfm); struct crypto_blkcipher *blkcipher = *ctx; int err; crypto_blkcipher_clear_flags(blkcipher, ~0); crypto_blkcipher_set_flags(blkcipher, crypto_skcipher_get_flags(tfm) & CRYPTO_TFM_REQ_MASK); err = crypto_blkcipher_setkey(blkcipher, key, keylen); crypto_skcipher_set_flags(tfm, crypto_blkcipher_get_flags(blkcipher) & CRYPTO_TFM_RES_MASK); return err; }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu88100.00%1100.00%
Total88100.00%1100.00%


static int skcipher_crypt_blkcipher(struct skcipher_request *req, int (*crypt)(struct blkcipher_desc *, struct scatterlist *, struct scatterlist *, unsigned int)) { struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); struct crypto_blkcipher **ctx = crypto_skcipher_ctx(tfm); struct blkcipher_desc desc = { .tfm = *ctx, .info = req->iv, .flags = req->base.flags, }; return crypt(&desc, req->dst, req->src, req->cryptlen); }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu101100.00%1100.00%
Total101100.00%1100.00%


static int skcipher_encrypt_blkcipher(struct skcipher_request *req) { struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req); struct crypto_tfm *tfm = crypto_skcipher_tfm(skcipher); struct blkcipher_alg *alg = &tfm->__crt_alg->cra_blkcipher; return skcipher_crypt_blkcipher(req, alg->encrypt); }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu53100.00%1100.00%
Total53100.00%1100.00%


static int skcipher_decrypt_blkcipher(struct skcipher_request *req) { struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req); struct crypto_tfm *tfm = crypto_skcipher_tfm(skcipher); struct blkcipher_alg *alg = &tfm->__crt_alg->cra_blkcipher; return skcipher_crypt_blkcipher(req, alg->decrypt); }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu53100.00%1100.00%
Total53100.00%1100.00%


static void crypto_exit_skcipher_ops_blkcipher(struct crypto_tfm *tfm) { struct crypto_blkcipher **ctx = crypto_tfm_ctx(tfm); crypto_free_blkcipher(*ctx); }

Contributors

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


static int crypto_init_skcipher_ops_blkcipher(struct crypto_tfm *tfm) { struct crypto_alg *calg = tfm->__crt_alg; struct crypto_skcipher *skcipher = __crypto_skcipher_cast(tfm); struct crypto_blkcipher **ctx = crypto_tfm_ctx(tfm); struct crypto_blkcipher *blkcipher; struct crypto_tfm *btfm; if (!crypto_mod_get(calg)) return -EAGAIN; btfm = __crypto_alloc_tfm(calg, CRYPTO_ALG_TYPE_BLKCIPHER, CRYPTO_ALG_TYPE_MASK); if (IS_ERR(btfm)) { crypto_mod_put(calg); return PTR_ERR(btfm); } blkcipher = __crypto_blkcipher_cast(btfm); *ctx = blkcipher; tfm->exit = crypto_exit_skcipher_ops_blkcipher; skcipher->setkey = skcipher_setkey_blkcipher; skcipher->encrypt = skcipher_encrypt_blkcipher; skcipher->decrypt = skcipher_decrypt_blkcipher; skcipher->ivsize = crypto_blkcipher_ivsize(blkcipher); skcipher->keysize = calg->cra_blkcipher.max_keysize; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu15199.34%375.00%
geliang tanggeliang tang10.66%125.00%
Total152100.00%4100.00%


static int skcipher_setkey_ablkcipher(struct crypto_skcipher *tfm, const u8 *key, unsigned int keylen) { struct crypto_ablkcipher **ctx = crypto_skcipher_ctx(tfm); struct crypto_ablkcipher *ablkcipher = *ctx; int err; crypto_ablkcipher_clear_flags(ablkcipher, ~0); crypto_ablkcipher_set_flags(ablkcipher, crypto_skcipher_get_flags(tfm) & CRYPTO_TFM_REQ_MASK); err = crypto_ablkcipher_setkey(ablkcipher, key, keylen); crypto_skcipher_set_flags(tfm, crypto_ablkcipher_get_flags(ablkcipher) & CRYPTO_TFM_RES_MASK); return err; }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu88100.00%1100.00%
Total88100.00%1100.00%


static int skcipher_crypt_ablkcipher(struct skcipher_request *req, int (*crypt)(struct ablkcipher_request *)) { struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req); struct crypto_ablkcipher **ctx = crypto_skcipher_ctx(tfm); struct ablkcipher_request *subreq = skcipher_request_ctx(req); ablkcipher_request_set_tfm(subreq, *ctx); ablkcipher_request_set_callback(subreq, skcipher_request_flags(req), req->base.complete, req->base.data); ablkcipher_request_set_crypt(subreq, req->src, req->dst, req->cryptlen, req->iv); return crypt(subreq); }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu110100.00%1100.00%
Total110100.00%1100.00%


static int skcipher_encrypt_ablkcipher(struct skcipher_request *req) { struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req); struct crypto_tfm *tfm = crypto_skcipher_tfm(skcipher); struct ablkcipher_alg *alg = &tfm->__crt_alg->cra_ablkcipher; return skcipher_crypt_ablkcipher(req, alg->encrypt); }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu53100.00%1100.00%
Total53100.00%1100.00%


static int skcipher_decrypt_ablkcipher(struct skcipher_request *req) { struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req); struct crypto_tfm *tfm = crypto_skcipher_tfm(skcipher); struct ablkcipher_alg *alg = &tfm->__crt_alg->cra_ablkcipher; return skcipher_crypt_ablkcipher(req, alg->decrypt); }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu53100.00%1100.00%
Total53100.00%1100.00%


static void crypto_exit_skcipher_ops_ablkcipher(struct crypto_tfm *tfm) { struct crypto_ablkcipher **ctx = crypto_tfm_ctx(tfm); crypto_free_ablkcipher(*ctx); }

Contributors

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


static int crypto_init_skcipher_ops_ablkcipher(struct crypto_tfm *tfm) { struct crypto_alg *calg = tfm->__crt_alg; struct crypto_skcipher *skcipher = __crypto_skcipher_cast(tfm); struct crypto_ablkcipher **ctx = crypto_tfm_ctx(tfm); struct crypto_ablkcipher *ablkcipher; struct crypto_tfm *abtfm; if (!crypto_mod_get(calg)) return -EAGAIN; abtfm = __crypto_alloc_tfm(calg, 0, 0); if (IS_ERR(abtfm)) { crypto_mod_put(calg); return PTR_ERR(abtfm); } ablkcipher = __crypto_ablkcipher_cast(abtfm); *ctx = ablkcipher; tfm->exit = crypto_exit_skcipher_ops_ablkcipher; skcipher->setkey = skcipher_setkey_ablkcipher; skcipher->encrypt = skcipher_encrypt_ablkcipher; skcipher->decrypt = skcipher_decrypt_ablkcipher; skcipher->ivsize = crypto_ablkcipher_ivsize(ablkcipher); skcipher->reqsize = crypto_ablkcipher_reqsize(ablkcipher) + sizeof(struct ablkcipher_request); skcipher->keysize = calg->cra_ablkcipher.max_keysize; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu16699.40%375.00%
geliang tanggeliang tang10.60%125.00%
Total167100.00%4100.00%


static void crypto_skcipher_exit_tfm(struct crypto_tfm *tfm) { struct crypto_skcipher *skcipher = __crypto_skcipher_cast(tfm); struct skcipher_alg *alg = crypto_skcipher_alg(skcipher); alg->exit(skcipher); }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu38100.00%1100.00%
Total38100.00%1100.00%


static int crypto_skcipher_init_tfm(struct crypto_tfm *tfm) { struct crypto_skcipher *skcipher = __crypto_skcipher_cast(tfm); struct skcipher_alg *alg = crypto_skcipher_alg(skcipher); if (tfm->__crt_alg->cra_type == &crypto_blkcipher_type) return crypto_init_skcipher_ops_blkcipher(tfm); if (tfm->__crt_alg->cra_type == &crypto_ablkcipher_type || tfm->__crt_alg->cra_type == &crypto_givcipher_type) return crypto_init_skcipher_ops_ablkcipher(tfm); skcipher->setkey = alg->setkey; skcipher->encrypt = alg->encrypt; skcipher->decrypt = alg->decrypt; skcipher->ivsize = alg->ivsize; skcipher->keysize = alg->max_keysize; if (alg->exit) skcipher->base.exit = crypto_skcipher_exit_tfm; if (alg->init) return alg->init(skcipher); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu145100.00%2100.00%
Total145100.00%2100.00%


static void crypto_skcipher_free_instance(struct crypto_instance *inst) { struct skcipher_instance *skcipher = container_of(inst, struct skcipher_instance, s.base); skcipher->free(skcipher); }

Contributors

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

static void crypto_skcipher_show(struct seq_file *m, struct crypto_alg *alg) __attribute__ ((unused));
static void crypto_skcipher_show(struct seq_file *m, struct crypto_alg *alg) { struct skcipher_alg *skcipher = container_of(alg, struct skcipher_alg, base); seq_printf(m, "type : skcipher\n"); seq_printf(m, "async : %s\n", alg->cra_flags & CRYPTO_ALG_ASYNC ? "yes" : "no"); seq_printf(m, "blocksize : %u\n", alg->cra_blocksize); seq_printf(m, "min keysize : %u\n", skcipher->min_keysize); seq_printf(m, "max keysize : %u\n", skcipher->max_keysize); seq_printf(m, "ivsize : %u\n", skcipher->ivsize); seq_printf(m, "chunksize : %u\n", skcipher->chunksize); }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu110100.00%2100.00%
Total110100.00%2100.00%

#ifdef CONFIG_NET
static int crypto_skcipher_report(struct sk_buff *skb, struct crypto_alg *alg) { struct crypto_report_blkcipher rblkcipher; struct skcipher_alg *skcipher = container_of(alg, struct skcipher_alg, base); strncpy(rblkcipher.type, "skcipher", sizeof(rblkcipher.type)); strncpy(rblkcipher.geniv, "<none>", sizeof(rblkcipher.geniv)); rblkcipher.blocksize = alg->cra_blocksize; rblkcipher.min_keysize = skcipher->min_keysize; rblkcipher.max_keysize = skcipher->max_keysize; rblkcipher.ivsize = skcipher->ivsize; if (nla_put(skb, CRYPTOCFGA_REPORT_BLKCIPHER, sizeof(struct crypto_report_blkcipher), &rblkcipher)) goto nla_put_failure; return 0; nla_put_failure: return -EMSGSIZE; }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu129100.00%1100.00%
Total129100.00%1100.00%

#else
static int crypto_skcipher_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 const struct crypto_type crypto_skcipher_type2 = { .extsize = crypto_skcipher_extsize, .init_tfm = crypto_skcipher_init_tfm, .free = crypto_skcipher_free_instance, #ifdef CONFIG_PROC_FS .show = crypto_skcipher_show, #endif .report = crypto_skcipher_report, .maskclear = ~CRYPTO_ALG_TYPE_MASK, .maskset = CRYPTO_ALG_TYPE_BLKCIPHER_MASK, .type = CRYPTO_ALG_TYPE_SKCIPHER, .tfmsize = offsetof(struct crypto_skcipher, base), };
int crypto_grab_skcipher(struct crypto_skcipher_spawn *spawn, const char *name, u32 type, u32 mask) { spawn->base.frontend = &crypto_skcipher_type2; return crypto_grab_spawn(&spawn->base, name, type, mask); }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu45100.00%2100.00%
Total45100.00%2100.00%

EXPORT_SYMBOL_GPL(crypto_grab_skcipher);
struct crypto_skcipher *crypto_alloc_skcipher(const char *alg_name, u32 type, u32 mask) { return crypto_alloc_tfm(alg_name, &crypto_skcipher_type2, type, mask); }

Contributors

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

EXPORT_SYMBOL_GPL(crypto_alloc_skcipher);
int crypto_has_skcipher2(const char *alg_name, u32 type, u32 mask) { return crypto_type_has_alg(alg_name, &crypto_skcipher_type2, type, mask); }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu29100.00%2100.00%
Total29100.00%2100.00%

EXPORT_SYMBOL_GPL(crypto_has_skcipher2);
static int skcipher_prepare_alg(struct skcipher_alg *alg) { struct crypto_alg *base = &alg->base; if (alg->ivsize > PAGE_SIZE / 8 || alg->chunksize > PAGE_SIZE / 8) return -EINVAL; if (!alg->chunksize) alg->chunksize = base->cra_blocksize; base->cra_type = &crypto_skcipher_type2; base->cra_flags &= ~CRYPTO_ALG_TYPE_MASK; base->cra_flags |= CRYPTO_ALG_TYPE_SKCIPHER; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu81100.00%1100.00%
Total81100.00%1100.00%


int crypto_register_skcipher(struct skcipher_alg *alg) { struct crypto_alg *base = &alg->base; int err; err = skcipher_prepare_alg(alg); if (err) return err; return crypto_register_alg(base); }

Contributors

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

EXPORT_SYMBOL_GPL(crypto_register_skcipher);
void crypto_unregister_skcipher(struct skcipher_alg *alg) { crypto_unregister_alg(&alg->base); }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu18100.00%1100.00%
Total18100.00%1100.00%

EXPORT_SYMBOL_GPL(crypto_unregister_skcipher);
int crypto_register_skciphers(struct skcipher_alg *algs, int count) { int i, ret; for (i = 0; i < count; i++) { ret = crypto_register_skcipher(&algs[i]); if (ret) goto err; } return 0; err: for (--i; i >= 0; --i) crypto_unregister_skcipher(&algs[i]); return ret; }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu80100.00%1100.00%
Total80100.00%1100.00%

EXPORT_SYMBOL_GPL(crypto_register_skciphers);
void crypto_unregister_skciphers(struct skcipher_alg *algs, int count) { int i; for (i = count - 1; i >= 0; --i) crypto_unregister_skcipher(&algs[i]); }

Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu40100.00%1100.00%
Total40100.00%1100.00%

EXPORT_SYMBOL_GPL(crypto_unregister_skciphers);
int skcipher_register_instance(struct crypto_template *tmpl, struct skcipher_instance *inst) { int err; err = skcipher_prepare_alg(&inst->alg); if (err) return err; return crypto_register_instance(tmpl, skcipher_crypto_instance(inst)); }

Contributors

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

EXPORT_SYMBOL_GPL(skcipher_register_instance); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Symmetric key cipher type");

Overall Contributors

PersonTokensPropCommitsCommitProp
herbert xuherbert xu208799.90%583.33%
geliang tanggeliang tang20.10%116.67%
Total2089100.00%6100.00%
Directory: crypto