#ifndef _LINUX_CRYPTO_H
#define _LINUX_CRYPTO_H
-#include <linux/config.h>
+#include <asm/atomic.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/list.h>
+#include <linux/slab.h>
#include <linux/string.h>
-#include <asm/page.h>
+#include <linux/uaccess.h>
/*
* Algorithm masks and types.
*/
-#define CRYPTO_ALG_TYPE_MASK 0x000000ff
+#define CRYPTO_ALG_TYPE_MASK 0x0000000f
#define CRYPTO_ALG_TYPE_CIPHER 0x00000001
#define CRYPTO_ALG_TYPE_DIGEST 0x00000002
#define CRYPTO_ALG_TYPE_COMPRESS 0x00000004
+#define CRYPTO_ALG_LARVAL 0x00000010
+#define CRYPTO_ALG_DEAD 0x00000020
+#define CRYPTO_ALG_DYING 0x00000040
+
/*
* Transform masks and values (for crt_flags).
*/
#define CRYPTO_DIR_ENCRYPT 1
#define CRYPTO_DIR_DECRYPT 0
+/*
+ * The macro CRYPTO_MINALIGN_ATTR (along with the void * type in the actual
+ * declaration) is used to ensure that the crypto_tfm context structure is
+ * aligned correctly for the given architecture so that there are no alignment
+ * faults for C data types. In particular, this is required on platforms such
+ * as arm where pointers are 32-bit aligned but there are data types such as
+ * u64 which require 64-bit alignment.
+ */
+#if defined(ARCH_KMALLOC_MINALIGN)
+#define CRYPTO_MINALIGN ARCH_KMALLOC_MINALIGN
+#elif defined(ARCH_SLAB_MINALIGN)
+#define CRYPTO_MINALIGN ARCH_SLAB_MINALIGN
+#endif
+
+#ifdef CRYPTO_MINALIGN
+#define CRYPTO_MINALIGN_ATTR __attribute__ ((__aligned__(CRYPTO_MINALIGN)))
+#else
+#define CRYPTO_MINALIGN_ATTR
+#endif
+
struct scatterlist;
struct crypto_tfm;
struct cipher_desc {
struct crypto_tfm *tfm;
- void (*crfn)(void *ctx, u8 *dst, const u8 *src);
+ void (*crfn)(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
unsigned int (*prfn)(const struct cipher_desc *desc, u8 *dst,
const u8 *src, unsigned int nbytes);
void *info;
struct cipher_alg {
unsigned int cia_min_keysize;
unsigned int cia_max_keysize;
- int (*cia_setkey)(void *ctx, const u8 *key,
+ int (*cia_setkey)(struct crypto_tfm *tfm, const u8 *key,
unsigned int keylen, u32 *flags);
- void (*cia_encrypt)(void *ctx, u8 *dst, const u8 *src);
- void (*cia_decrypt)(void *ctx, u8 *dst, const u8 *src);
+ void (*cia_encrypt)(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
+ void (*cia_decrypt)(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
unsigned int (*cia_encrypt_ecb)(const struct cipher_desc *desc,
u8 *dst, const u8 *src,
struct digest_alg {
unsigned int dia_digestsize;
- void (*dia_init)(void *ctx);
- void (*dia_update)(void *ctx, const u8 *data, unsigned int len);
- void (*dia_final)(void *ctx, u8 *out);
- int (*dia_setkey)(void *ctx, const u8 *key,
+ void (*dia_init)(struct crypto_tfm *tfm);
+ void (*dia_update)(struct crypto_tfm *tfm, const u8 *data,
+ unsigned int len);
+ void (*dia_final)(struct crypto_tfm *tfm, u8 *out);
+ int (*dia_setkey)(struct crypto_tfm *tfm, const u8 *key,
unsigned int keylen, u32 *flags);
};
struct compress_alg {
- int (*coa_init)(void *ctx);
- void (*coa_exit)(void *ctx);
- int (*coa_compress)(void *ctx, const u8 *src, unsigned int slen,
- u8 *dst, unsigned int *dlen);
- int (*coa_decompress)(void *ctx, const u8 *src, unsigned int slen,
- u8 *dst, unsigned int *dlen);
+ int (*coa_compress)(struct crypto_tfm *tfm, const u8 *src,
+ unsigned int slen, u8 *dst, unsigned int *dlen);
+ int (*coa_decompress)(struct crypto_tfm *tfm, const u8 *src,
+ unsigned int slen, u8 *dst, unsigned int *dlen);
};
#define cra_cipher cra_u.cipher
struct crypto_alg {
struct list_head cra_list;
+ struct list_head cra_users;
+
u32 cra_flags;
unsigned int cra_blocksize;
unsigned int cra_ctxsize;
unsigned int cra_alignmask;
int cra_priority;
+ atomic_t cra_refcnt;
- const char cra_name[CRYPTO_MAX_ALG_NAME];
- const char cra_driver_name[CRYPTO_MAX_ALG_NAME];
+ char cra_name[CRYPTO_MAX_ALG_NAME];
+ char cra_driver_name[CRYPTO_MAX_ALG_NAME];
union {
struct cipher_alg cipher;
struct digest_alg digest;
struct compress_alg compress;
} cra_u;
+
+ int (*cra_init)(struct crypto_tfm *tfm);
+ void (*cra_exit)(struct crypto_tfm *tfm);
+ void (*cra_destroy)(struct crypto_alg *alg);
struct module *cra_module;
};
} crt_u;
struct crypto_alg *__crt_alg;
+
+ void *__crt_ctx[] CRYPTO_MINALIGN_ATTR;
+};
+
+enum {
+ CRYPTOA_UNSPEC,
+ CRYPTOA_ALG,
+};
+
+struct crypto_attr_alg {
+ char name[CRYPTO_MAX_ALG_NAME];
};
/*
static inline void *crypto_tfm_ctx(struct crypto_tfm *tfm)
{
- return (void *)&tfm[1];
+ return tfm->__crt_ctx;
+}
+
+static inline unsigned int crypto_tfm_ctx_alignment(void)
+{
+ struct crypto_tfm *tfm;
+ return __alignof__(tfm->__crt_ctx);
}
/*