algapi.h 6.0 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*
 * Cryptographic API for algorithms (i.e., low-level API).
 *
 * 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.
 *
 */
#ifndef _CRYPTO_ALGAPI_H
#define _CRYPTO_ALGAPI_H

#include <linux/crypto.h>
16 17
#include <linux/list.h>
#include <linux/kernel.h>
18

19
struct module;
20
struct rtattr;
21 22 23
struct seq_file;

struct crypto_type {
24 25
	unsigned int (*ctxsize)(struct crypto_alg *alg, u32 type, u32 mask);
	int (*init)(struct crypto_tfm *tfm, u32 type, u32 mask);
26 27 28
	void (*exit)(struct crypto_tfm *tfm);
	void (*show)(struct seq_file *m, struct crypto_alg *alg);
};
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43

struct crypto_instance {
	struct crypto_alg alg;

	struct crypto_template *tmpl;
	struct hlist_node list;

	void *__ctx[] CRYPTO_MINALIGN_ATTR;
};

struct crypto_template {
	struct list_head list;
	struct hlist_head instances;
	struct module *module;

44
	struct crypto_instance *(*alloc)(struct rtattr **tb);
45 46 47 48 49
	void (*free)(struct crypto_instance *inst);

	char name[CRYPTO_MAX_ALG_NAME];
};

H
Herbert Xu 已提交
50 51 52 53 54 55
struct crypto_spawn {
	struct list_head list;
	struct crypto_alg *alg;
	struct crypto_instance *inst;
};

56 57 58 59 60 61 62 63
struct crypto_queue {
	struct list_head list;
	struct list_head *backlog;

	unsigned int qlen;
	unsigned int max_qlen;
};

64 65 66 67 68
struct scatter_walk {
	struct scatterlist *sg;
	unsigned int offset;
};

69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
struct blkcipher_walk {
	union {
		struct {
			struct page *page;
			unsigned long offset;
		} phys;

		struct {
			u8 *page;
			u8 *addr;
		} virt;
	} src, dst;

	struct scatter_walk in;
	unsigned int nbytes;

	struct scatter_walk out;
	unsigned int total;

	void *page;
	u8 *buffer;
	u8 *iv;

	int flags;
};

95
extern const struct crypto_type crypto_ablkcipher_type;
96
extern const struct crypto_type crypto_blkcipher_type;
97
extern const struct crypto_type crypto_hash_type;
98

99 100
void crypto_mod_put(struct crypto_alg *alg);

101 102 103 104
int crypto_register_template(struct crypto_template *tmpl);
void crypto_unregister_template(struct crypto_template *tmpl);
struct crypto_template *crypto_lookup_template(const char *name);

H
Herbert Xu 已提交
105 106 107
int crypto_init_spawn(struct crypto_spawn *spawn, struct crypto_alg *alg,
		      struct crypto_instance *inst);
void crypto_drop_spawn(struct crypto_spawn *spawn);
H
Herbert Xu 已提交
108 109
struct crypto_tfm *crypto_spawn_tfm(struct crypto_spawn *spawn, u32 type,
				    u32 mask);
H
Herbert Xu 已提交
110

111 112 113
struct crypto_attr_type *crypto_get_attr_type(struct rtattr **tb);
int crypto_check_attr_type(struct rtattr **tb, u32 type);
struct crypto_alg *crypto_get_attr_alg(struct rtattr **tb, u32 type, u32 mask);
114 115 116
struct crypto_instance *crypto_alloc_instance(const char *name,
					      struct crypto_alg *alg);

117 118 119 120 121 122
void crypto_init_queue(struct crypto_queue *queue, unsigned int max_qlen);
int crypto_enqueue_request(struct crypto_queue *queue,
			   struct crypto_async_request *request);
struct crypto_async_request *crypto_dequeue_request(struct crypto_queue *queue);
int crypto_tfm_in_queue(struct crypto_queue *queue, struct crypto_tfm *tfm);

123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
int blkcipher_walk_done(struct blkcipher_desc *desc,
			struct blkcipher_walk *walk, int err);
int blkcipher_walk_virt(struct blkcipher_desc *desc,
			struct blkcipher_walk *walk);
int blkcipher_walk_phys(struct blkcipher_desc *desc,
			struct blkcipher_walk *walk);

static inline void *crypto_tfm_ctx_aligned(struct crypto_tfm *tfm)
{
	unsigned long addr = (unsigned long)crypto_tfm_ctx(tfm);
	unsigned long align = crypto_tfm_alg_alignmask(tfm);

	if (align <= crypto_tfm_ctx_alignment())
		align = 1;
	return (void *)ALIGN(addr, align);
}

140 141 142 143 144
static inline void *crypto_instance_ctx(struct crypto_instance *inst)
{
	return inst->__ctx;
}

145 146 147 148 149 150 151 152 153 154 155
static inline struct ablkcipher_alg *crypto_ablkcipher_alg(
	struct crypto_ablkcipher *tfm)
{
	return &crypto_ablkcipher_tfm(tfm)->__crt_alg->cra_ablkcipher;
}

static inline void *crypto_ablkcipher_ctx(struct crypto_ablkcipher *tfm)
{
	return crypto_tfm_ctx(&tfm->base);
}

156 157 158 159 160 161 162 163 164 165
static inline void *crypto_blkcipher_ctx(struct crypto_blkcipher *tfm)
{
	return crypto_tfm_ctx(&tfm->base);
}

static inline void *crypto_blkcipher_ctx_aligned(struct crypto_blkcipher *tfm)
{
	return crypto_tfm_ctx_aligned(&tfm->base);
}

H
Herbert Xu 已提交
166 167 168 169 170 171 172 173 174
static inline struct crypto_cipher *crypto_spawn_cipher(
	struct crypto_spawn *spawn)
{
	u32 type = CRYPTO_ALG_TYPE_CIPHER;
	u32 mask = CRYPTO_ALG_TYPE_MASK;

	return __crypto_cipher_cast(crypto_spawn_tfm(spawn, type, mask));
}

175 176 177 178 179
static inline struct cipher_alg *crypto_cipher_alg(struct crypto_cipher *tfm)
{
	return &crypto_cipher_tfm(tfm)->__crt_alg->cra_cipher;
}

H
Herbert Xu 已提交
180 181 182 183 184 185 186 187
static inline struct crypto_hash *crypto_spawn_hash(struct crypto_spawn *spawn)
{
	u32 type = CRYPTO_ALG_TYPE_HASH;
	u32 mask = CRYPTO_ALG_TYPE_HASH_MASK;

	return __crypto_hash_cast(crypto_spawn_tfm(spawn, type, mask));
}

188 189 190 191 192
static inline void *crypto_hash_ctx_aligned(struct crypto_hash *tfm)
{
	return crypto_tfm_ctx_aligned(&tfm->base);
}

193 194 195 196 197 198 199 200 201 202
static inline void blkcipher_walk_init(struct blkcipher_walk *walk,
				       struct scatterlist *dst,
				       struct scatterlist *src,
				       unsigned int nbytes)
{
	walk->in.sg = src;
	walk->out.sg = dst;
	walk->total = nbytes;
}

203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232
static inline struct crypto_async_request *crypto_get_backlog(
	struct crypto_queue *queue)
{
	return queue->backlog == &queue->list ? NULL :
	       container_of(queue->backlog, struct crypto_async_request, list);
}

static inline int ablkcipher_enqueue_request(struct ablkcipher_alg *alg,
					     struct ablkcipher_request *request)
{
	return crypto_enqueue_request(alg->queue, &request->base);
}

static inline struct ablkcipher_request *ablkcipher_dequeue_request(
	struct ablkcipher_alg *alg)
{
	return ablkcipher_request_cast(crypto_dequeue_request(alg->queue));
}

static inline void *ablkcipher_request_ctx(struct ablkcipher_request *req)
{
	return req->__ctx;
}

static inline int ablkcipher_tfm_in_queue(struct crypto_ablkcipher *tfm)
{
	return crypto_tfm_in_queue(crypto_ablkcipher_alg(tfm)->queue,
				   crypto_ablkcipher_tfm(tfm));
}

233 234
#endif	/* _CRYPTO_ALGAPI_H */