summaryrefslogtreecommitdiff
path: root/linux/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'linux/crypto')
-rw-r--r--linux/crypto/api.c216
-rw-r--r--linux/crypto/blkcipher.c47
-rw-r--r--linux/crypto/chacha20_generic.c43
-rw-r--r--linux/crypto/internal.h23
-rw-r--r--linux/crypto/poly1305_generic.c30
-rw-r--r--linux/crypto/sha256_generic.c28
-rw-r--r--linux/crypto/shash.c72
7 files changed, 116 insertions, 343 deletions
diff --git a/linux/crypto/api.c b/linux/crypto/api.c
index 63efee30..2f3ab2b5 100644
--- a/linux/crypto/api.c
+++ b/linux/crypto/api.c
@@ -20,217 +20,95 @@
#include <linux/string.h>
#include <crypto/algapi.h>
-#include "internal.h"
static LIST_HEAD(crypto_alg_list);
static DECLARE_RWSEM(crypto_alg_sem);
-static unsigned crypto_ctxsize(struct crypto_alg *alg, u32 type, u32 mask)
-{
- return alg->cra_type->ctxsize(alg, type, mask);
-}
+struct crypto_type {
+};
-unsigned crypto_alg_extsize(struct crypto_alg *alg)
+int crypto_register_alg(struct crypto_alg *alg)
{
- return alg->cra_ctxsize;
+ down_write(&crypto_alg_sem);
+ list_add(&alg->cra_list, &crypto_alg_list);
+ up_write(&crypto_alg_sem);
+
+ return 0;
}
-struct crypto_alg *crypto_alg_mod_lookup(const char *name, u32 type, u32 mask)
+static void *crypto_alloc_tfm(const char *name,
+ const struct crypto_type *type)
{
struct crypto_alg *alg;
down_read(&crypto_alg_sem);
list_for_each_entry(alg, &crypto_alg_list, cra_list)
- if (!((alg->cra_flags ^ type) & mask) &&
- !strcmp(alg->cra_name, name))
+ if (alg->cra_type == type && !strcmp(alg->cra_name, name))
goto found;
alg = ERR_PTR(-ENOENT);
found:
up_read(&crypto_alg_sem);
- return alg;
-}
+ if (IS_ERR(alg))
+ return ERR_CAST(alg);
-static void crypto_exit_ops(struct crypto_tfm *tfm)
-{
- if (tfm->exit)
- tfm->exit(tfm);
+ return alg->alloc_tfm() ?: ERR_PTR(-ENOMEM);
}
-static struct crypto_tfm *__crypto_alloc_tfm(struct crypto_alg *alg,
- u32 type, u32 mask)
-{
- struct crypto_tfm *tfm = NULL;
- unsigned tfm_size;
- int err = -ENOMEM;
-
- tfm_size = sizeof(*tfm) + crypto_ctxsize(alg, type, mask);
- tfm = kzalloc(tfm_size, GFP_KERNEL);
- if (tfm == NULL)
- return ERR_PTR(-ENOMEM);
-
- tfm->__crt_alg = alg;
-
- err = alg->cra_type->init(tfm, type, mask);
- if (err)
- goto out_free_tfm;
-
- if (!tfm->exit && alg->cra_init && (err = alg->cra_init(tfm)))
- goto cra_init_failed;
-
- return tfm;
+/* skcipher: */
-cra_init_failed:
- crypto_exit_ops(tfm);
-out_free_tfm:
- kfree(tfm);
- return ERR_PTR(err);
-}
+static const struct crypto_type crypto_skcipher_type2 = {
+};
-struct crypto_tfm *crypto_alloc_base(const char *alg_name, u32 type, u32 mask)
+struct crypto_skcipher *crypto_alloc_skcipher(const char *name,
+ u32 type, u32 mask)
{
- struct crypto_alg *alg;
- struct crypto_tfm *tfm;
-
- alg = crypto_alg_mod_lookup(alg_name, type, mask);
- if (IS_ERR(alg)) {
- fprintf(stderr, "unknown cipher %s\n", alg_name);
- return ERR_CAST(alg);
- }
-
- tfm = __crypto_alloc_tfm(alg, type, mask);
- if (IS_ERR(tfm))
- return tfm;
-
- return tfm;
+ return crypto_alloc_tfm(name, &crypto_skcipher_type2);
}
-static void *crypto_create_tfm(struct crypto_alg *alg,
- const struct crypto_type *frontend)
+int crypto_register_skcipher(struct skcipher_alg *alg)
{
- struct crypto_tfm *tfm = NULL;
- unsigned tfmsize;
- unsigned total;
- void *mem;
- int err = -ENOMEM;
-
- tfmsize = frontend->tfmsize;
- total = tfmsize + sizeof(*tfm) + frontend->extsize(alg);
-
- mem = kzalloc(total, GFP_KERNEL);
- if (!mem)
- goto out_err;
-
- tfm = mem + tfmsize;
- tfm->__crt_alg = alg;
-
- err = frontend->init_tfm(tfm);
- if (err)
- goto out_free_tfm;
-
- if (!tfm->exit && alg->cra_init && (err = alg->cra_init(tfm)))
- goto cra_init_failed;
-
- goto out;
-
-cra_init_failed:
- crypto_exit_ops(tfm);
-out_free_tfm:
- kfree(mem);
-out_err:
- mem = ERR_PTR(err);
-out:
- return mem;
-}
+ alg->base.cra_type = &crypto_skcipher_type2;
-static struct crypto_alg *crypto_find_alg(const char *alg_name,
- const struct crypto_type *frontend,
- u32 type, u32 mask)
-{
- if (frontend) {
- type &= frontend->maskclear;
- mask &= frontend->maskclear;
- type |= frontend->type;
- mask |= frontend->maskset;
- }
-
- return crypto_alg_mod_lookup(alg_name, type, mask);
+ return crypto_register_alg(&alg->base);
}
-void *crypto_alloc_tfm(const char *alg_name,
- const struct crypto_type *frontend,
- u32 type, u32 mask)
-{
- struct crypto_alg *alg;
- void *tfm;
-
- alg = crypto_find_alg(alg_name, frontend, type, mask);
- if (IS_ERR(alg))
- return ERR_CAST(alg);
-
- tfm = crypto_create_tfm(alg, frontend);
- if (IS_ERR(tfm))
- return tfm;
+/* shash: */
- return tfm;
-}
+#include <crypto/hash.h>
-void crypto_destroy_tfm(void *mem, struct crypto_tfm *tfm)
+static int shash_finup(struct shash_desc *desc, const u8 *data,
+ unsigned len, u8 *out)
{
- struct crypto_alg *alg;
-
- if (unlikely(!mem))
- return;
-
- alg = tfm->__crt_alg;
-
- if (!tfm->exit && alg->cra_exit)
- alg->cra_exit(tfm);
- crypto_exit_ops(tfm);
- kzfree(mem);
+ return crypto_shash_update(desc, data, len) ?:
+ crypto_shash_final(desc, out);
}
-int crypto_register_alg(struct crypto_alg *alg)
+static int shash_digest(struct shash_desc *desc, const u8 *data,
+ unsigned len, u8 *out)
{
- INIT_LIST_HEAD(&alg->cra_users);
-
- down_write(&crypto_alg_sem);
- list_add(&alg->cra_list, &crypto_alg_list);
- up_write(&crypto_alg_sem);
-
- return 0;
+ return crypto_shash_init(desc) ?:
+ crypto_shash_finup(desc, data, len, out);
}
-/* skcipher: */
+static const struct crypto_type crypto_shash_type = {
+};
-static int crypto_skcipher_init_tfm(struct crypto_tfm *tfm)
+struct crypto_shash *crypto_alloc_shash(const char *name,
+ u32 type, u32 mask)
{
- struct crypto_skcipher *skcipher = __crypto_skcipher_cast(tfm);
- struct skcipher_alg *alg = crypto_skcipher_alg(skcipher);
-
- skcipher->setkey = alg->setkey;
- skcipher->encrypt = alg->encrypt;
- skcipher->decrypt = alg->decrypt;
- skcipher->ivsize = alg->ivsize;
- skcipher->keysize = alg->max_keysize;
-
- if (alg->init)
- return alg->init(skcipher);
-
- return 0;
+ return crypto_alloc_tfm(name, &crypto_shash_type);
}
-static const struct crypto_type crypto_skcipher_type2 = {
- .extsize = crypto_alg_extsize,
- .init_tfm = crypto_skcipher_init_tfm,
- .maskclear = ~CRYPTO_ALG_TYPE_MASK,
- .maskset = CRYPTO_ALG_TYPE_BLKCIPHER_MASK,
- .tfmsize = offsetof(struct crypto_skcipher, base),
-};
-
-struct crypto_skcipher *crypto_alloc_skcipher(const char *alg_name,
- u32 type, u32 mask)
+int crypto_register_shash(struct shash_alg *alg)
{
- return crypto_alloc_tfm(alg_name, &crypto_skcipher_type2, type, mask);
+ alg->base.cra_type = &crypto_shash_type;
+
+ if (!alg->finup)
+ alg->finup = shash_finup;
+ if (!alg->digest)
+ alg->digest = shash_digest;
+
+ return crypto_register_alg(&alg->base);
}
diff --git a/linux/crypto/blkcipher.c b/linux/crypto/blkcipher.c
deleted file mode 100644
index 31f91418..00000000
--- a/linux/crypto/blkcipher.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Block chaining 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) 2006 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 <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-
-#include <crypto/algapi.h>
-#include "internal.h"
-
-static unsigned crypto_blkcipher_ctxsize(struct crypto_alg *alg,
- u32 type, u32 mask)
-{
- return alg->cra_ctxsize;
-}
-
-static int crypto_init_blkcipher_ops(struct crypto_tfm *tfm, u32 type, u32 mask)
-{
- struct blkcipher_tfm *crt = &tfm->crt_blkcipher;
- struct blkcipher_alg *alg = &tfm->__crt_alg->cra_blkcipher;
-
- BUG_ON((mask & CRYPTO_ALG_TYPE_MASK) != CRYPTO_ALG_TYPE_MASK);
-
- crt->setkey = alg->setkey;
- crt->encrypt = alg->encrypt;
- crt->decrypt = alg->decrypt;
- return 0;
-}
-
-const struct crypto_type crypto_blkcipher_type = {
- .ctxsize = crypto_blkcipher_ctxsize,
- .init = crypto_init_blkcipher_ops,
-};
diff --git a/linux/crypto/chacha20_generic.c b/linux/crypto/chacha20_generic.c
index df4c0e04..c6f14945 100644
--- a/linux/crypto/chacha20_generic.c
+++ b/linux/crypto/chacha20_generic.c
@@ -22,14 +22,18 @@
#include <sodium/crypto_stream_chacha20.h>
-struct chacha20_ctx {
- u32 key[8];
+static struct skcipher_alg alg;
+
+struct chacha20_tfm {
+ struct crypto_skcipher tfm;
+ u32 key[8];
};
static int crypto_chacha20_setkey(struct crypto_skcipher *tfm, const u8 *key,
unsigned int keysize)
{
- struct chacha20_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct chacha20_tfm *ctx =
+ container_of(tfm, struct chacha20_tfm, tfm);
int i;
if (keysize != CHACHA20_KEY_SIZE)
@@ -43,8 +47,8 @@ static int crypto_chacha20_setkey(struct crypto_skcipher *tfm, const u8 *key,
static int crypto_chacha20_crypt(struct skcipher_request *req)
{
- struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
- struct chacha20_ctx *ctx = crypto_skcipher_ctx(tfm);
+ struct chacha20_tfm *ctx =
+ container_of(req->tfm, struct chacha20_tfm, tfm.base);
struct scatterlist *sg = req->src;
unsigned nbytes = req->cryptlen;
u32 iv[4];
@@ -78,21 +82,30 @@ static int crypto_chacha20_crypt(struct skcipher_request *req)
return 0;
}
+static void *crypto_chacha20_alloc_tfm(void)
+{
+ struct chacha20_tfm *tfm = kzalloc(sizeof(*tfm), GFP_KERNEL);
+
+ if (!tfm)
+ return NULL;
+
+ tfm->tfm.base.alg = &alg.base;
+ tfm->tfm.setkey = crypto_chacha20_setkey;
+ tfm->tfm.encrypt = crypto_chacha20_crypt;
+ tfm->tfm.decrypt = crypto_chacha20_crypt;
+ tfm->tfm.ivsize = CHACHA20_IV_SIZE;
+ tfm->tfm.keysize = CHACHA20_KEY_SIZE;
+
+ return tfm;
+}
+
static struct skcipher_alg alg = {
.base.cra_name = "chacha20",
- .base.cra_ctxsize = sizeof(struct chacha20_ctx),
-
- .min_keysize = CHACHA20_KEY_SIZE,
- .max_keysize = CHACHA20_KEY_SIZE,
- .ivsize = CHACHA20_IV_SIZE,
- .chunksize = CHACHA20_BLOCK_SIZE,
- .setkey = crypto_chacha20_setkey,
- .encrypt = crypto_chacha20_crypt,
- .decrypt = crypto_chacha20_crypt,
+ .base.alloc_tfm = crypto_chacha20_alloc_tfm,
};
__attribute__((constructor(110)))
static int chacha20_generic_mod_init(void)
{
- return crypto_register_alg(&alg.base);
+ return crypto_register_skcipher(&alg);
}
diff --git a/linux/crypto/internal.h b/linux/crypto/internal.h
deleted file mode 100644
index 5b21f836..00000000
--- a/linux/crypto/internal.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Cryptographic API.
- *
- * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
- * Copyright (c) 2005 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.
- *
- */
-#ifndef _CRYPTO_INTERNAL_H
-#define _CRYPTO_INTERNAL_H
-
-struct crypto_type;
-struct crypto_alg;
-
-void *crypto_alloc_tfm(const char *, const struct crypto_type *, u32, u32);
-unsigned int crypto_alg_extsize(struct crypto_alg *);
-
-#endif /* _CRYPTO_INTERNAL_H */
-
diff --git a/linux/crypto/poly1305_generic.c b/linux/crypto/poly1305_generic.c
index 5d385d54..acb554c0 100644
--- a/linux/crypto/poly1305_generic.c
+++ b/linux/crypto/poly1305_generic.c
@@ -18,18 +18,19 @@
#include <linux/crypto.h>
#include <crypto/algapi.h>
-#include <crypto/internal/hash.h>
+#include <crypto/hash.h>
#include <crypto/poly1305.h>
+static struct shash_alg poly1305_alg;
+
struct poly1305_desc_ctx {
bool key_done;
crypto_onetimeauth_poly1305_state s;
};
-
static int poly1305_init(struct shash_desc *desc)
{
- struct poly1305_desc_ctx *state = shash_desc_ctx(desc);
+ struct poly1305_desc_ctx *state = (void *) desc->ctx;
state->key_done = false;
return 0;
@@ -38,7 +39,7 @@ static int poly1305_init(struct shash_desc *desc)
static int poly1305_update(struct shash_desc *desc,
const u8 *src, unsigned len)
{
- struct poly1305_desc_ctx *state = shash_desc_ctx(desc);
+ struct poly1305_desc_ctx *state = (void *) desc->ctx;
if (!state->key_done) {
BUG_ON(len != crypto_onetimeauth_poly1305_KEYBYTES);
@@ -52,21 +53,32 @@ static int poly1305_update(struct shash_desc *desc,
static int poly1305_final(struct shash_desc *desc, u8 *out)
{
- struct poly1305_desc_ctx *state = shash_desc_ctx(desc);
+ struct poly1305_desc_ctx *state = (void *) desc->ctx;
return crypto_onetimeauth_poly1305_final(&state->s, out);
}
+static void *poly1305_alloc_tfm(void)
+{
+ struct crypto_shash *tfm = kzalloc(sizeof(*tfm), GFP_KERNEL);
+
+ if (!tfm)
+ return NULL;
+
+ tfm->base.alg = &poly1305_alg.base;
+ tfm->descsize = sizeof(struct poly1305_desc_ctx);
+ return tfm;
+}
+
static struct shash_alg poly1305_alg = {
.digestsize = crypto_onetimeauth_poly1305_BYTES,
.init = poly1305_init,
.update = poly1305_update,
.final = poly1305_final,
.descsize = sizeof(struct poly1305_desc_ctx),
- .base = {
- .cra_name = "poly1305",
- .cra_flags = CRYPTO_ALG_TYPE_SHASH,
- },
+
+ .base.cra_name = "poly1305",
+ .base.alloc_tfm = poly1305_alloc_tfm,
};
__attribute__((constructor(110)))
diff --git a/linux/crypto/sha256_generic.c b/linux/crypto/sha256_generic.c
index 0bd272f0..9326bfe7 100644
--- a/linux/crypto/sha256_generic.c
+++ b/linux/crypto/sha256_generic.c
@@ -24,13 +24,15 @@
#include <asm/unaligned.h>
#include <linux/crypto.h>
-#include <crypto/internal/hash.h>
+#include <crypto/hash.h>
#include <sodium/crypto_hash_sha256.h>
+static struct shash_alg sha256_alg;
+
static int sha256_init(struct shash_desc *desc)
{
- crypto_hash_sha256_state *state = shash_desc_ctx(desc);
+ crypto_hash_sha256_state *state = (void *) desc->ctx;
return crypto_hash_sha256_init(state);
}
@@ -38,28 +40,38 @@ static int sha256_init(struct shash_desc *desc)
static int sha256_update(struct shash_desc *desc, const u8 *data,
unsigned int len)
{
- crypto_hash_sha256_state *state = shash_desc_ctx(desc);
+ crypto_hash_sha256_state *state = (void *) desc->ctx;
return crypto_hash_sha256_update(state, data, len);
}
static int sha256_final(struct shash_desc *desc, u8 *out)
{
- crypto_hash_sha256_state *state = shash_desc_ctx(desc);
+ crypto_hash_sha256_state *state = (void *) desc->ctx;
return crypto_hash_sha256_final(state, out);
}
+static void *sha256_alloc_tfm(void)
+{
+ struct crypto_shash *tfm = kzalloc(sizeof(*tfm), GFP_KERNEL);
+
+ if (!tfm)
+ return NULL;
+
+ tfm->base.alg = &sha256_alg.base;
+ tfm->descsize = sizeof(crypto_hash_sha256_state);
+ return tfm;
+}
+
static struct shash_alg sha256_alg = {
.digestsize = crypto_hash_sha256_BYTES,
.init = sha256_init,
.update = sha256_update,
.final = sha256_final,
.descsize = sizeof(crypto_hash_sha256_state),
- .base = {
- .cra_name = "sha256",
- .cra_flags = CRYPTO_ALG_TYPE_SHASH,
- }
+ .base.cra_name = "sha256",
+ .base.alloc_tfm = sha256_alloc_tfm,
};
__attribute__((constructor(110)))
diff --git a/linux/crypto/shash.c b/linux/crypto/shash.c
deleted file mode 100644
index 4f07a8b8..00000000
--- a/linux/crypto/shash.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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/internal/hash.h>
-#include <linux/err.h>
-#include <linux/kernel.h>
-#include <linux/printk.h>
-#include <linux/slab.h>
-
-#include "internal.h"
-
-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);
-}
-
-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);
-}
-
-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;
-}
-
-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),
-};
-
-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);
-}
-
-int crypto_register_shash(struct shash_alg *alg)
-{
- struct crypto_alg *base = &alg->base;
-
- 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;
- if (!alg->digest)
- alg->digest = shash_digest;
-
- return crypto_register_alg(base);
-}